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