AX: Progress: [Mac] Content in label element should be used as AXTitle or AXDescription
[WebKit-https.git] / Source / JavaScriptCore / jit / JITSubGenerator.cpp
1 /*
2  * Copyright (C) 2015-2016 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 #include "config.h"
27 #include "JITSubGenerator.h"
28
29 #include "ArithProfile.h"
30 #include "JITMathIC.h"
31
32 #if ENABLE(JIT)
33
34 namespace JSC {
35
36 JITMathICInlineResult JITSubGenerator::generateInline(CCallHelpers& jit, MathICGenerationState& state)
37 {
38     // We default to speculating int32.
39     ObservedType lhs = ObservedType().withInt32();
40     ObservedType rhs = ObservedType().withInt32();
41     if (m_arithProfile) {
42         lhs = m_arithProfile->lhsObservedType();
43         rhs = m_arithProfile->rhsObservedType();
44     }
45
46     if (lhs.isOnlyNonNumber() && rhs.isOnlyNonNumber())
47         return JITMathICInlineResult::DontGenerate;
48
49     if (lhs.isOnlyNumber() && rhs.isOnlyNumber()) {
50         if (!jit.supportsFloatingPoint())
51             return JITMathICInlineResult::DontGenerate;
52
53         if (!m_leftOperand.definitelyIsNumber())
54             state.slowPathJumps.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
55         if (!m_rightOperand.definitelyIsNumber())
56             state.slowPathJumps.append(jit.branchIfNotNumber(m_right, m_scratchGPR));
57         state.slowPathJumps.append(jit.branchIfInt32(m_left));
58         state.slowPathJumps.append(jit.branchIfInt32(m_right));
59         jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
60         jit.unboxDoubleNonDestructive(m_right, m_rightFPR, m_scratchGPR, m_scratchFPR);
61         jit.subDouble(m_rightFPR, m_leftFPR);
62         jit.boxDouble(m_leftFPR, m_result);
63
64         return JITMathICInlineResult::GeneratedFastPath;
65     }
66     if (lhs.isOnlyInt32() && rhs.isOnlyInt32()) {
67         ASSERT(!m_leftOperand.isConstInt32() || !m_rightOperand.isConstInt32());
68         state.slowPathJumps.append(jit.branchIfNotInt32(m_left));
69         state.slowPathJumps.append(jit.branchIfNotInt32(m_right));
70
71         jit.move(m_left.payloadGPR(), m_scratchGPR);
72         state.slowPathJumps.append(jit.branchSub32(CCallHelpers::Overflow, m_right.payloadGPR(), m_scratchGPR));
73
74         jit.boxInt32(m_scratchGPR, m_result);
75         return JITMathICInlineResult::GeneratedFastPath;
76     }
77
78     return JITMathICInlineResult::GenerateFullSnippet;
79 }
80
81 bool JITSubGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList& endJumpList, CCallHelpers::JumpList& slowPathJumpList, bool shouldEmitProfiling)
82 {
83     ASSERT(m_scratchGPR != InvalidGPRReg);
84     ASSERT(m_scratchGPR != m_left.payloadGPR());
85     ASSERT(m_scratchGPR != m_right.payloadGPR());
86 #if USE(JSVALUE32_64)
87     ASSERT(m_scratchGPR != m_left.tagGPR());
88     ASSERT(m_scratchGPR != m_right.tagGPR());
89     ASSERT(m_scratchFPR != InvalidFPRReg);
90 #endif
91
92     CCallHelpers::Jump leftNotInt = jit.branchIfNotInt32(m_left);
93     CCallHelpers::Jump rightNotInt = jit.branchIfNotInt32(m_right);
94
95     jit.move(m_left.payloadGPR(), m_scratchGPR);
96     slowPathJumpList.append(jit.branchSub32(CCallHelpers::Overflow, m_right.payloadGPR(), m_scratchGPR));
97
98     jit.boxInt32(m_scratchGPR, m_result);
99
100     endJumpList.append(jit.jump());
101
102     if (!jit.supportsFloatingPoint()) {
103         slowPathJumpList.append(leftNotInt);
104         slowPathJumpList.append(rightNotInt);
105         return true;
106     }
107
108     leftNotInt.link(&jit);
109     if (!m_leftOperand.definitelyIsNumber())
110         slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
111     if (!m_rightOperand.definitelyIsNumber())
112         slowPathJumpList.append(jit.branchIfNotNumber(m_right, m_scratchGPR));
113
114     jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
115     CCallHelpers::Jump rightIsDouble = jit.branchIfNotInt32(m_right);
116
117     jit.convertInt32ToDouble(m_right.payloadGPR(), m_rightFPR);
118     CCallHelpers::Jump rightWasInteger = jit.jump();
119
120     rightNotInt.link(&jit);
121     if (!m_rightOperand.definitelyIsNumber())
122         slowPathJumpList.append(jit.branchIfNotNumber(m_right, m_scratchGPR));
123
124     jit.convertInt32ToDouble(m_left.payloadGPR(), m_leftFPR);
125
126     rightIsDouble.link(&jit);
127     jit.unboxDoubleNonDestructive(m_right, m_rightFPR, m_scratchGPR, m_scratchFPR);
128
129     rightWasInteger.link(&jit);
130
131     jit.subDouble(m_rightFPR, m_leftFPR);
132     if (m_arithProfile && shouldEmitProfiling)
133         m_arithProfile->emitSetDouble(jit);
134
135     jit.boxDouble(m_leftFPR, m_result);
136
137     return true;
138 }
139
140 } // namespace JSC
141
142 #endif // ENABLE(JIT)