Update FTL to support UntypedUse operands for op_sub.
[WebKit-https.git] / Source / JavaScriptCore / jit / JITSubGenerator.h
1 /*
2  * Copyright (C) 2015 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 JITSubGenerator_h
27 #define JITSubGenerator_h
28
29 #include "CCallHelpers.h"
30 #include "ResultType.h"
31 #include "ScratchRegisterAllocator.h"
32
33 namespace JSC {
34
35 class JITSubGenerator {
36 public:
37
38     JITSubGenerator(JSValueRegs result, JSValueRegs left, JSValueRegs right,
39         ResultType leftType, ResultType rightType, FPRReg leftFPR, FPRReg rightFPR,
40         GPRReg scratchGPR, FPRReg scratchFPR)
41         : m_result(result)
42         , m_left(left)
43         , m_right(right)
44         , m_leftType(leftType)
45         , m_rightType(rightType)
46         , m_leftFPR(leftFPR)
47         , m_rightFPR(rightFPR)
48         , m_scratchGPR(scratchGPR)
49         , m_scratchFPR(scratchFPR)
50     { }
51
52     void generateFastPath(CCallHelpers& jit)
53     {
54         ASSERT(m_scratchGPR != InvalidGPRReg);
55         ASSERT(m_scratchGPR != m_left.payloadGPR());
56         ASSERT(m_scratchGPR != m_right.payloadGPR());
57 #if USE(JSVALUE32_64)
58         ASSERT(m_scratchGPR != m_left.tagGPR());
59         ASSERT(m_scratchGPR != m_right.tagGPR());
60         ASSERT(m_scratchFPR != InvalidFPRReg);
61 #endif
62         CCallHelpers::Jump leftNotInt = jit.branchIfNotInt32(m_left);
63         CCallHelpers::Jump rightNotInt = jit.branchIfNotInt32(m_right);
64
65         jit.move(m_left.payloadGPR(), m_scratchGPR);
66         m_slowPathJumpList.append(
67             jit.branchSub32(CCallHelpers::Overflow, m_right.payloadGPR(), m_scratchGPR));
68
69         jit.boxInt32(m_scratchGPR, m_result);
70
71         m_endJumpList.append(jit.jump());
72
73         if (!jit.supportsFloatingPoint()) {
74             m_slowPathJumpList.append(leftNotInt);
75             m_slowPathJumpList.append(rightNotInt);
76             return;
77         }
78
79         leftNotInt.link(&jit);
80         if (!m_leftType.definitelyIsNumber())
81             m_slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
82         if (!m_rightType.definitelyIsNumber())
83             m_slowPathJumpList.append(jit.branchIfNotNumber(m_right, m_scratchGPR));
84
85         jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
86         CCallHelpers::Jump rightIsDouble = jit.branchIfNotInt32(m_right);
87
88         jit.convertInt32ToDouble(m_right.payloadGPR(), m_rightFPR);
89         CCallHelpers::Jump rightWasInteger = jit.jump();
90
91         rightNotInt.link(&jit);
92         if (!m_rightType.definitelyIsNumber())
93             m_slowPathJumpList.append(jit.branchIfNotNumber(m_right, m_scratchGPR));
94
95         jit.convertInt32ToDouble(m_left.payloadGPR(), m_leftFPR);
96
97         rightIsDouble.link(&jit);
98         jit.unboxDoubleNonDestructive(m_right, m_rightFPR, m_scratchGPR, m_scratchFPR);
99
100         rightWasInteger.link(&jit);
101
102         jit.subDouble(m_rightFPR, m_leftFPR);
103         jit.boxDouble(m_leftFPR, m_result);
104
105         m_endJumpList.append(jit.jump());
106     }
107
108     CCallHelpers::JumpList endJumpList() { return m_endJumpList; }
109     CCallHelpers::JumpList slowPathJumpList() { return m_slowPathJumpList; }
110
111 private:
112     JSValueRegs m_result;
113     JSValueRegs m_left;
114     JSValueRegs m_right;
115     ResultType m_leftType;
116     ResultType m_rightType;
117     FPRReg m_leftFPR;
118     FPRReg m_rightFPR;
119     GPRReg m_scratchGPR;
120     FPRReg m_scratchFPR;
121
122     CCallHelpers::JumpList m_endJumpList;
123     CCallHelpers::JumpList m_slowPathJumpList;
124 };
125
126 } // namespace JSC
127
128 #endif // JITSubGenerator_h