064f064e9cdffce42eb187d3e889a21c21657068
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGArithMode.h
1 /*
2  * Copyright (C) 2014 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef DFGArithMode_h
27 #define DFGArithMode_h
28
29 #if ENABLE(DFG_JIT)
30
31 namespace JSC { namespace DFG {
32
33 // Arith::Mode describes the mode of an arithmetic operation that speculates integer.
34 // Note that not all modes are valid for all operations.
35 namespace Arith {
36 enum Mode {
37     NotSet, // Arithmetic mode is either not relevant because we're using doubles anyway or we are at a phase in compilation where we don't know what we're doing, yet. Should never see this after FixupPhase except for nodes that take doubles as inputs already.
38     Unchecked, // Don't check anything and just do the direct hardware operation.
39     CheckOverflow, // Check for overflow but don't bother with negative zero.
40     CheckOverflowAndNegativeZero, // Check for both overflow and negative zero.
41     DoOverflow // Up-convert to the smallest type that soundly represents all possible results after input type speculation.
42 };
43 } // namespace Arith
44
45 inline bool doesOverflow(Arith::Mode mode)
46 {
47     switch (mode) {
48     case Arith::NotSet:
49         ASSERT_NOT_REACHED();
50 #if ASSERT_DISABLED
51         FALLTHROUGH;
52 #endif
53     case Arith::Unchecked:
54     case Arith::CheckOverflow:
55     case Arith::CheckOverflowAndNegativeZero:
56         return false;
57     case Arith::DoOverflow:
58         return true;
59     }
60     ASSERT_NOT_REACHED();
61     return true;
62 }
63
64 // It's only valid to call this once you've determined that you don't need to *do*
65 // overflow. For most nodes, that's implicit.
66 inline bool shouldCheckOverflow(Arith::Mode mode)
67 {
68     switch (mode) {
69     case Arith::NotSet:
70     case Arith::DoOverflow:
71         ASSERT_NOT_REACHED();
72         return true;
73     case Arith::Unchecked:
74         return false;
75     case Arith::CheckOverflow:
76     case Arith::CheckOverflowAndNegativeZero:
77         return true;
78     }
79     ASSERT_NOT_REACHED();
80     return true;
81 }
82
83 inline bool shouldCheckNegativeZero(Arith::Mode mode)
84 {
85     switch (mode) {
86     case Arith::NotSet:
87     case Arith::DoOverflow:
88         ASSERT_NOT_REACHED();
89         return true;
90     case Arith::Unchecked:
91     case Arith::CheckOverflow:
92         return false;
93     case Arith::CheckOverflowAndNegativeZero:
94         return true;
95     }
96     ASSERT_NOT_REACHED();
97     return true;
98 }
99
100 inline bool subsumes(Arith::Mode earlier, Arith::Mode later)
101 {
102     switch (earlier) {
103     case Arith::CheckOverflow:
104         switch (later) {
105         case Arith::Unchecked:
106         case Arith::CheckOverflow:
107             return true;
108         default:
109             return false;
110         }
111     case Arith::CheckOverflowAndNegativeZero:
112         switch (later) {
113         case Arith::Unchecked:
114         case Arith::CheckOverflow:
115         case Arith::CheckOverflowAndNegativeZero:
116             return true;
117         default:
118             return false;
119         }
120     default:
121         return earlier == later;
122     }
123 }
124
125 } } // namespace JSC::DFG
126
127 namespace WTF {
128
129 class PrintStream;
130 void printInternal(PrintStream&, JSC::DFG::Arith::Mode);
131
132 } // namespace WTF
133
134 #endif // ENABLE(DFG_JIT)
135
136 #endif // DFGArithMode_h
137