Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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/. */
7 #ifndef jit_arm_CodeGenerator_arm_h
8 #define jit_arm_CodeGenerator_arm_h
10 #include "jit/arm/Assembler-arm.h"
11 #include "jit/shared/CodeGenerator-shared.h"
13 namespace js {
14 namespace jit {
16 class OutOfLineBailout;
17 class OutOfLineTableSwitch;
19 class CodeGeneratorARM : public CodeGeneratorShared
20 {
21 friend class MoveResolverARM;
23 CodeGeneratorARM *thisFromCtor() {return this;}
25 protected:
26 // Label for the common return path.
27 NonAssertingLabel returnLabel_;
28 NonAssertingLabel deoptLabel_;
29 // ugh. this is not going to be pretty to move over.
30 // stack slotted variables are not useful on arm.
31 // it looks like this will need to return one of two types.
32 inline Operand ToOperand(const LAllocation &a) {
33 if (a.isGeneralReg())
34 return Operand(a.toGeneralReg()->reg());
35 if (a.isFloatReg())
36 return Operand(a.toFloatReg()->reg());
37 return Operand(StackPointer, ToStackOffset(&a));
38 }
39 inline Operand ToOperand(const LAllocation *a) {
40 return ToOperand(*a);
41 }
42 inline Operand ToOperand(const LDefinition *def) {
43 return ToOperand(def->output());
44 }
46 MoveOperand toMoveOperand(const LAllocation *a) const;
48 bool bailoutIf(Assembler::Condition condition, LSnapshot *snapshot);
49 bool bailoutFrom(Label *label, LSnapshot *snapshot);
50 bool bailout(LSnapshot *snapshot);
52 template <typename T1, typename T2>
53 bool bailoutCmpPtr(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot *snapshot) {
54 masm.cmpPtr(lhs, rhs);
55 return bailoutIf(c, snapshot);
56 }
57 bool bailoutTestPtr(Assembler::Condition c, Register lhs, Register rhs, LSnapshot *snapshot) {
58 masm.testPtr(lhs, rhs);
59 return bailoutIf(c, snapshot);
60 }
61 template <typename T1, typename T2>
62 bool bailoutCmp32(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot *snapshot) {
63 masm.cmp32(lhs, rhs);
64 return bailoutIf(c, snapshot);
65 }
66 template <typename T1, typename T2>
67 bool bailoutTest32(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot *snapshot) {
68 masm.test32(lhs, rhs);
69 return bailoutIf(c, snapshot);
70 }
72 protected:
73 bool generatePrologue();
74 bool generateAsmJSPrologue(Label *stackOverflowLabel);
75 bool generateEpilogue();
76 bool generateOutOfLineCode();
78 void emitRoundDouble(const FloatRegister &src, const Register &dest, Label *fail);
80 // Emits a branch that directs control flow to the true block if |cond| is
81 // true, and the false block if |cond| is false.
82 void emitBranch(Assembler::Condition cond, MBasicBlock *ifTrue, MBasicBlock *ifFalse);
84 void testNullEmitBranch(Assembler::Condition cond, const ValueOperand &value,
85 MBasicBlock *ifTrue, MBasicBlock *ifFalse)
86 {
87 cond = masm.testNull(cond, value);
88 emitBranch(cond, ifTrue, ifFalse);
89 }
90 void testUndefinedEmitBranch(Assembler::Condition cond, const ValueOperand &value,
91 MBasicBlock *ifTrue, MBasicBlock *ifFalse)
92 {
93 cond = masm.testUndefined(cond, value);
94 emitBranch(cond, ifTrue, ifFalse);
95 }
97 bool emitTableSwitchDispatch(MTableSwitch *mir, const Register &index, const Register &base);
99 public:
100 // Instruction visitors.
101 virtual bool visitMinMaxD(LMinMaxD *ins);
102 virtual bool visitAbsD(LAbsD *ins);
103 virtual bool visitAbsF(LAbsF *ins);
104 virtual bool visitSqrtD(LSqrtD *ins);
105 virtual bool visitSqrtF(LSqrtF *ins);
106 virtual bool visitAddI(LAddI *ins);
107 virtual bool visitSubI(LSubI *ins);
108 virtual bool visitBitNotI(LBitNotI *ins);
109 virtual bool visitBitOpI(LBitOpI *ins);
111 virtual bool visitMulI(LMulI *ins);
113 virtual bool visitDivI(LDivI *ins);
114 virtual bool visitSoftDivI(LSoftDivI *ins);
115 virtual bool visitDivPowTwoI(LDivPowTwoI *ins);
116 virtual bool visitModI(LModI *ins);
117 virtual bool visitSoftModI(LSoftModI *ins);
118 virtual bool visitModPowTwoI(LModPowTwoI *ins);
119 virtual bool visitModMaskI(LModMaskI *ins);
120 virtual bool visitPowHalfD(LPowHalfD *ins);
121 virtual bool visitShiftI(LShiftI *ins);
122 virtual bool visitUrshD(LUrshD *ins);
124 virtual bool visitTestIAndBranch(LTestIAndBranch *test);
125 virtual bool visitCompare(LCompare *comp);
126 virtual bool visitCompareAndBranch(LCompareAndBranch *comp);
127 virtual bool visitTestDAndBranch(LTestDAndBranch *test);
128 virtual bool visitTestFAndBranch(LTestFAndBranch *test);
129 virtual bool visitCompareD(LCompareD *comp);
130 virtual bool visitCompareF(LCompareF *comp);
131 virtual bool visitCompareDAndBranch(LCompareDAndBranch *comp);
132 virtual bool visitCompareFAndBranch(LCompareFAndBranch *comp);
133 virtual bool visitCompareB(LCompareB *lir);
134 virtual bool visitCompareBAndBranch(LCompareBAndBranch *lir);
135 virtual bool visitCompareV(LCompareV *lir);
136 virtual bool visitCompareVAndBranch(LCompareVAndBranch *lir);
137 virtual bool visitBitAndAndBranch(LBitAndAndBranch *baab);
138 virtual bool visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble *lir);
139 virtual bool visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32 *lir);
140 virtual bool visitNotI(LNotI *ins);
141 virtual bool visitNotD(LNotD *ins);
142 virtual bool visitNotF(LNotF *ins);
144 virtual bool visitMathD(LMathD *math);
145 virtual bool visitMathF(LMathF *math);
146 virtual bool visitFloor(LFloor *lir);
147 virtual bool visitFloorF(LFloorF *lir);
148 virtual bool visitRound(LRound *lir);
149 virtual bool visitRoundF(LRoundF *lir);
150 virtual bool visitTruncateDToInt32(LTruncateDToInt32 *ins);
151 virtual bool visitTruncateFToInt32(LTruncateFToInt32 *ins);
153 // Out of line visitors.
154 bool visitOutOfLineBailout(OutOfLineBailout *ool);
155 bool visitOutOfLineTableSwitch(OutOfLineTableSwitch *ool);
157 protected:
158 ValueOperand ToValue(LInstruction *ins, size_t pos);
159 ValueOperand ToOutValue(LInstruction *ins);
160 ValueOperand ToTempValue(LInstruction *ins, size_t pos);
162 // Functions for LTestVAndBranch.
163 Register splitTagForTest(const ValueOperand &value);
165 void storeElementTyped(const LAllocation *value, MIRType valueType, MIRType elementType,
166 const Register &elements, const LAllocation *index);
168 bool divICommon(MDiv *mir, Register lhs, Register rhs, Register output, LSnapshot *snapshot,
169 Label &done);
170 bool modICommon(MMod *mir, Register lhs, Register rhs, Register output, LSnapshot *snapshot,
171 Label &done);
173 public:
174 CodeGeneratorARM(MIRGenerator *gen, LIRGraph *graph, MacroAssembler *masm);
176 public:
177 bool visitBox(LBox *box);
178 bool visitBoxFloatingPoint(LBoxFloatingPoint *box);
179 bool visitUnbox(LUnbox *unbox);
180 bool visitValue(LValue *value);
181 bool visitDouble(LDouble *ins);
182 bool visitFloat32(LFloat32 *ins);
184 bool visitLoadSlotV(LLoadSlotV *load);
185 bool visitLoadSlotT(LLoadSlotT *load);
186 bool visitStoreSlotT(LStoreSlotT *load);
188 bool visitLoadElementT(LLoadElementT *load);
190 bool visitGuardShape(LGuardShape *guard);
191 bool visitGuardObjectType(LGuardObjectType *guard);
192 bool visitGuardClass(LGuardClass *guard);
193 bool visitImplicitThis(LImplicitThis *lir);
195 bool visitInterruptCheck(LInterruptCheck *lir);
197 bool visitNegI(LNegI *lir);
198 bool visitNegD(LNegD *lir);
199 bool visitNegF(LNegF *lir);
200 bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins);
201 bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins);
202 bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins);
203 bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins);
204 bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins);
205 bool visitAsmJSStoreGlobalVar(LAsmJSStoreGlobalVar *ins);
206 bool visitAsmJSLoadFuncPtr(LAsmJSLoadFuncPtr *ins);
207 bool visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins);
208 bool visitAsmJSPassStackArg(LAsmJSPassStackArg *ins);
210 bool visitForkJoinGetSlice(LForkJoinGetSlice *ins);
212 bool generateInvalidateEpilogue();
213 protected:
214 void postAsmJSCall(LAsmJSCall *lir) {
215 if (!useHardFpABI() && lir->mir()->callee().which() == MAsmJSCall::Callee::Builtin) {
216 switch (lir->mir()->type()) {
217 case MIRType_Double:
218 masm.ma_vxfer(r0, r1, d0);
219 break;
220 case MIRType_Float32:
221 masm.as_vxfer(r0, InvalidReg, VFPRegister(d0).singleOverlay(),
222 Assembler::CoreToFloat);
223 break;
224 default:
225 break;
226 }
227 }
228 }
230 bool visitEffectiveAddress(LEffectiveAddress *ins);
231 bool visitUDiv(LUDiv *ins);
232 bool visitUMod(LUMod *ins);
233 bool visitSoftUDivOrMod(LSoftUDivOrMod *ins);
234 };
236 typedef CodeGeneratorARM CodeGeneratorSpecific;
238 // An out-of-line bailout thunk.
239 class OutOfLineBailout : public OutOfLineCodeBase<CodeGeneratorARM>
240 {
241 protected: // Silence Clang warning.
242 LSnapshot *snapshot_;
243 uint32_t frameSize_;
245 public:
246 OutOfLineBailout(LSnapshot *snapshot, uint32_t frameSize)
247 : snapshot_(snapshot),
248 frameSize_(frameSize)
249 { }
251 bool accept(CodeGeneratorARM *codegen);
253 LSnapshot *snapshot() const {
254 return snapshot_;
255 }
256 };
258 } // namespace jit
259 } // namespace js
261 #endif /* jit_arm_CodeGenerator_arm_h */