|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * vim: set ts=8 sts=4 et sw=4 tw=99: |
|
3 * This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #ifndef jit_shared_CodeGenerator_x86_shared_h |
|
8 #define jit_shared_CodeGenerator_x86_shared_h |
|
9 |
|
10 #include "jit/shared/CodeGenerator-shared.h" |
|
11 |
|
12 namespace js { |
|
13 namespace jit { |
|
14 |
|
15 class OutOfLineBailout; |
|
16 class OutOfLineUndoALUOperation; |
|
17 class MulNegativeZeroCheck; |
|
18 class ModOverflowCheck; |
|
19 class ReturnZero; |
|
20 class OutOfLineTableSwitch; |
|
21 |
|
22 class CodeGeneratorX86Shared : public CodeGeneratorShared |
|
23 { |
|
24 friend class MoveResolverX86; |
|
25 |
|
26 CodeGeneratorX86Shared *thisFromCtor() { |
|
27 return this; |
|
28 } |
|
29 |
|
30 template <typename T> |
|
31 bool bailout(const T &t, LSnapshot *snapshot); |
|
32 |
|
33 protected: |
|
34 // Label for the common return path. |
|
35 NonAssertingLabel returnLabel_; |
|
36 NonAssertingLabel deoptLabel_; |
|
37 |
|
38 inline Operand ToOperand(const LAllocation &a) { |
|
39 if (a.isGeneralReg()) |
|
40 return Operand(a.toGeneralReg()->reg()); |
|
41 if (a.isFloatReg()) |
|
42 return Operand(a.toFloatReg()->reg()); |
|
43 return Operand(StackPointer, ToStackOffset(&a)); |
|
44 } |
|
45 inline Operand ToOperand(const LAllocation *a) { |
|
46 return ToOperand(*a); |
|
47 } |
|
48 inline Operand ToOperand(const LDefinition *def) { |
|
49 return ToOperand(def->output()); |
|
50 } |
|
51 |
|
52 MoveOperand toMoveOperand(const LAllocation *a) const; |
|
53 |
|
54 bool bailoutIf(Assembler::Condition condition, LSnapshot *snapshot); |
|
55 bool bailoutIf(Assembler::DoubleCondition condition, LSnapshot *snapshot); |
|
56 bool bailoutFrom(Label *label, LSnapshot *snapshot); |
|
57 bool bailout(LSnapshot *snapshot); |
|
58 |
|
59 template <typename T1, typename T2> |
|
60 bool bailoutCmpPtr(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot *snapshot) { |
|
61 masm.cmpPtr(lhs, rhs); |
|
62 return bailoutIf(c, snapshot); |
|
63 } |
|
64 bool bailoutTestPtr(Assembler::Condition c, Register lhs, Register rhs, LSnapshot *snapshot) { |
|
65 masm.testPtr(lhs, rhs); |
|
66 return bailoutIf(c, snapshot); |
|
67 } |
|
68 template <typename T1, typename T2> |
|
69 bool bailoutCmp32(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot *snapshot) { |
|
70 masm.cmp32(lhs, rhs); |
|
71 return bailoutIf(c, snapshot); |
|
72 } |
|
73 template <typename T1, typename T2> |
|
74 bool bailoutTest32(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot *snapshot) { |
|
75 masm.test32(lhs, rhs); |
|
76 return bailoutIf(c, snapshot); |
|
77 } |
|
78 |
|
79 protected: |
|
80 bool generatePrologue(); |
|
81 bool generateAsmJSPrologue(Label *stackOverflowLabe); |
|
82 bool generateEpilogue(); |
|
83 bool generateOutOfLineCode(); |
|
84 |
|
85 Operand createArrayElementOperand(Register elements, const LAllocation *index); |
|
86 |
|
87 void emitCompare(MCompare::CompareType type, const LAllocation *left, const LAllocation *right); |
|
88 |
|
89 // Emits a branch that directs control flow to the true block if |cond| is |
|
90 // true, and the false block if |cond| is false. |
|
91 void emitBranch(Assembler::Condition cond, MBasicBlock *ifTrue, MBasicBlock *ifFalse, |
|
92 Assembler::NaNCond ifNaN = Assembler::NaN_HandledByCond); |
|
93 void emitBranch(Assembler::DoubleCondition cond, MBasicBlock *ifTrue, MBasicBlock *ifFalse); |
|
94 |
|
95 void testNullEmitBranch(Assembler::Condition cond, const ValueOperand &value, |
|
96 MBasicBlock *ifTrue, MBasicBlock *ifFalse) |
|
97 { |
|
98 cond = masm.testNull(cond, value); |
|
99 emitBranch(cond, ifTrue, ifFalse); |
|
100 } |
|
101 void testUndefinedEmitBranch(Assembler::Condition cond, const ValueOperand &value, |
|
102 MBasicBlock *ifTrue, MBasicBlock *ifFalse) |
|
103 { |
|
104 cond = masm.testUndefined(cond, value); |
|
105 emitBranch(cond, ifTrue, ifFalse); |
|
106 } |
|
107 |
|
108 bool emitTableSwitchDispatch(MTableSwitch *mir, const Register &index, const Register &base); |
|
109 |
|
110 public: |
|
111 CodeGeneratorX86Shared(MIRGenerator *gen, LIRGraph *graph, MacroAssembler *masm); |
|
112 |
|
113 public: |
|
114 // Instruction visitors. |
|
115 virtual bool visitDouble(LDouble *ins); |
|
116 virtual bool visitFloat32(LFloat32 *ins); |
|
117 virtual bool visitMinMaxD(LMinMaxD *ins); |
|
118 virtual bool visitAbsD(LAbsD *ins); |
|
119 virtual bool visitAbsF(LAbsF *ins); |
|
120 virtual bool visitSqrtD(LSqrtD *ins); |
|
121 virtual bool visitSqrtF(LSqrtF *ins); |
|
122 virtual bool visitPowHalfD(LPowHalfD *ins); |
|
123 virtual bool visitAddI(LAddI *ins); |
|
124 virtual bool visitSubI(LSubI *ins); |
|
125 virtual bool visitMulI(LMulI *ins); |
|
126 virtual bool visitDivI(LDivI *ins); |
|
127 virtual bool visitDivPowTwoI(LDivPowTwoI *ins); |
|
128 virtual bool visitDivOrModConstantI(LDivOrModConstantI *ins); |
|
129 virtual bool visitModI(LModI *ins); |
|
130 virtual bool visitModPowTwoI(LModPowTwoI *ins); |
|
131 virtual bool visitBitNotI(LBitNotI *ins); |
|
132 virtual bool visitBitOpI(LBitOpI *ins); |
|
133 virtual bool visitShiftI(LShiftI *ins); |
|
134 virtual bool visitUrshD(LUrshD *ins); |
|
135 virtual bool visitTestIAndBranch(LTestIAndBranch *test); |
|
136 virtual bool visitTestDAndBranch(LTestDAndBranch *test); |
|
137 virtual bool visitTestFAndBranch(LTestFAndBranch *test); |
|
138 virtual bool visitCompare(LCompare *comp); |
|
139 virtual bool visitCompareAndBranch(LCompareAndBranch *comp); |
|
140 virtual bool visitCompareD(LCompareD *comp); |
|
141 virtual bool visitCompareDAndBranch(LCompareDAndBranch *comp); |
|
142 virtual bool visitCompareF(LCompareF *comp); |
|
143 virtual bool visitCompareFAndBranch(LCompareFAndBranch *comp); |
|
144 virtual bool visitBitAndAndBranch(LBitAndAndBranch *baab); |
|
145 virtual bool visitNotI(LNotI *comp); |
|
146 virtual bool visitNotD(LNotD *comp); |
|
147 virtual bool visitNotF(LNotF *comp); |
|
148 virtual bool visitMathD(LMathD *math); |
|
149 virtual bool visitMathF(LMathF *math); |
|
150 virtual bool visitFloor(LFloor *lir); |
|
151 virtual bool visitFloorF(LFloorF *lir); |
|
152 virtual bool visitRound(LRound *lir); |
|
153 virtual bool visitRoundF(LRoundF *lir); |
|
154 virtual bool visitGuardShape(LGuardShape *guard); |
|
155 virtual bool visitGuardObjectType(LGuardObjectType *guard); |
|
156 virtual bool visitGuardClass(LGuardClass *guard); |
|
157 virtual bool visitEffectiveAddress(LEffectiveAddress *ins); |
|
158 virtual bool visitUDivOrMod(LUDivOrMod *ins); |
|
159 virtual bool visitAsmJSPassStackArg(LAsmJSPassStackArg *ins); |
|
160 |
|
161 bool visitForkJoinGetSlice(LForkJoinGetSlice *ins); |
|
162 |
|
163 bool visitNegI(LNegI *lir); |
|
164 bool visitNegD(LNegD *lir); |
|
165 bool visitNegF(LNegF *lir); |
|
166 |
|
167 // Out of line visitors. |
|
168 bool visitOutOfLineBailout(OutOfLineBailout *ool); |
|
169 bool visitOutOfLineUndoALUOperation(OutOfLineUndoALUOperation *ool); |
|
170 bool visitMulNegativeZeroCheck(MulNegativeZeroCheck *ool); |
|
171 bool visitModOverflowCheck(ModOverflowCheck *ool); |
|
172 bool visitReturnZero(ReturnZero *ool); |
|
173 bool visitOutOfLineTableSwitch(OutOfLineTableSwitch *ool); |
|
174 bool generateInvalidateEpilogue(); |
|
175 }; |
|
176 |
|
177 // An out-of-line bailout thunk. |
|
178 class OutOfLineBailout : public OutOfLineCodeBase<CodeGeneratorX86Shared> |
|
179 { |
|
180 LSnapshot *snapshot_; |
|
181 |
|
182 public: |
|
183 OutOfLineBailout(LSnapshot *snapshot) |
|
184 : snapshot_(snapshot) |
|
185 { } |
|
186 |
|
187 bool accept(CodeGeneratorX86Shared *codegen); |
|
188 |
|
189 LSnapshot *snapshot() const { |
|
190 return snapshot_; |
|
191 } |
|
192 }; |
|
193 |
|
194 } // namespace jit |
|
195 } // namespace js |
|
196 |
|
197 #endif /* jit_shared_CodeGenerator_x86_shared_h */ |