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_LIR_arm_h
8 #define jit_arm_LIR_arm_h
10 namespace js {
11 namespace jit {
13 class LBox : public LInstructionHelper<2, 1, 0>
14 {
15 MIRType type_;
17 public:
18 LIR_HEADER(Box);
20 LBox(const LAllocation &in_payload, MIRType type)
21 : type_(type)
22 {
23 setOperand(0, in_payload);
24 }
26 MIRType type() const {
27 return type_;
28 }
29 const char *extraName() const {
30 return StringFromMIRType(type_);
31 }
32 };
34 class LBoxFloatingPoint : public LInstructionHelper<2, 1, 1>
35 {
36 MIRType type_;
38 public:
39 LIR_HEADER(BoxFloatingPoint);
41 LBoxFloatingPoint(const LAllocation &in, const LDefinition &temp, MIRType type)
42 : type_(type)
43 {
44 setOperand(0, in);
45 setTemp(0, temp);
46 }
48 MIRType type() const {
49 return type_;
50 }
51 const char *extraName() const {
52 return StringFromMIRType(type_);
53 }
54 };
56 class LUnbox : public LInstructionHelper<1, 2, 0>
57 {
58 public:
59 LIR_HEADER(Unbox);
61 MUnbox *mir() const {
62 return mir_->toUnbox();
63 }
64 const LAllocation *payload() {
65 return getOperand(0);
66 }
67 const LAllocation *type() {
68 return getOperand(1);
69 }
70 const char *extraName() const {
71 return StringFromMIRType(mir()->type());
72 }
73 };
75 class LUnboxFloatingPoint : public LInstructionHelper<1, 2, 0>
76 {
77 MIRType type_;
79 public:
80 LIR_HEADER(UnboxFloatingPoint);
82 static const size_t Input = 0;
84 LUnboxFloatingPoint(MIRType type)
85 : type_(type)
86 { }
88 MUnbox *mir() const {
89 return mir_->toUnbox();
90 }
92 MIRType type() const {
93 return type_;
94 }
95 const char *extraName() const {
96 return StringFromMIRType(type_);
97 }
98 };
100 // Convert a 32-bit unsigned integer to a double.
101 class LAsmJSUInt32ToDouble : public LInstructionHelper<1, 1, 0>
102 {
103 public:
104 LIR_HEADER(AsmJSUInt32ToDouble)
106 LAsmJSUInt32ToDouble(const LAllocation &input) {
107 setOperand(0, input);
108 }
109 };
111 // Convert a 32-bit unsigned integer to a float32.
112 class LAsmJSUInt32ToFloat32 : public LInstructionHelper<1, 1, 0>
113 {
114 public:
115 LIR_HEADER(AsmJSUInt32ToFloat32)
117 LAsmJSUInt32ToFloat32(const LAllocation &input) {
118 setOperand(0, input);
119 }
120 };
122 class LDivI : public LBinaryMath<1>
123 {
124 public:
125 LIR_HEADER(DivI);
127 LDivI(const LAllocation &lhs, const LAllocation &rhs,
128 const LDefinition &temp) {
129 setOperand(0, lhs);
130 setOperand(1, rhs);
131 setTemp(0, temp);
132 }
134 MDiv *mir() const {
135 return mir_->toDiv();
136 }
137 };
139 // LSoftDivI is a software divide for ARM cores that don't support a hardware
140 // divide instruction.
141 //
142 // It is implemented as a proper C function so it trashes r0, r1, r2 and r3.
143 // The call also trashes lr, and has the ability to trash ip. The function also
144 // takes two arguments (dividend in r0, divisor in r1). The LInstruction gets
145 // encoded such that the divisor and dividend are passed in their apropriate
146 // registers and end their life at the start of the instruction by the use of
147 // useFixedAtStart. The result is returned in r0 and the other three registers
148 // that can be trashed are marked as temps. For the time being, the link
149 // register is not marked as trashed because we never allocate to the link
150 // register. The FP registers are not trashed.
151 class LSoftDivI : public LBinaryMath<3>
152 {
153 public:
154 LIR_HEADER(SoftDivI);
156 LSoftDivI(const LAllocation &lhs, const LAllocation &rhs,
157 const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3) {
158 setOperand(0, lhs);
159 setOperand(1, rhs);
160 setTemp(0, temp1);
161 setTemp(1, temp2);
162 setTemp(2, temp3);
163 }
165 MDiv *mir() const {
166 return mir_->toDiv();
167 }
168 };
170 class LDivPowTwoI : public LInstructionHelper<1, 1, 0>
171 {
172 const int32_t shift_;
174 public:
175 LIR_HEADER(DivPowTwoI)
177 LDivPowTwoI(const LAllocation &lhs, int32_t shift)
178 : shift_(shift)
179 {
180 setOperand(0, lhs);
181 }
183 const LAllocation *numerator() {
184 return getOperand(0);
185 }
187 int32_t shift() {
188 return shift_;
189 }
191 MDiv *mir() const {
192 return mir_->toDiv();
193 }
194 };
196 class LModI : public LBinaryMath<1>
197 {
198 public:
199 LIR_HEADER(ModI);
201 LModI(const LAllocation &lhs, const LAllocation &rhs,
202 const LDefinition &callTemp)
203 {
204 setOperand(0, lhs);
205 setOperand(1, rhs);
206 setTemp(0, callTemp);
207 }
209 const LDefinition *callTemp() {
210 return getTemp(0);
211 }
213 MMod *mir() const {
214 return mir_->toMod();
215 }
216 };
218 class LSoftModI : public LBinaryMath<4>
219 {
220 public:
221 LIR_HEADER(SoftModI);
223 LSoftModI(const LAllocation &lhs, const LAllocation &rhs,
224 const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3,
225 const LDefinition &callTemp)
226 {
227 setOperand(0, lhs);
228 setOperand(1, rhs);
229 setTemp(0, temp1);
230 setTemp(1, temp2);
231 setTemp(2, temp3);
232 setTemp(3, callTemp);
233 }
235 const LDefinition *callTemp() {
236 return getTemp(3);
237 }
239 MMod *mir() const {
240 return mir_->toMod();
241 }
242 };
244 class LModPowTwoI : public LInstructionHelper<1, 1, 0>
245 {
246 const int32_t shift_;
248 public:
249 LIR_HEADER(ModPowTwoI);
250 int32_t shift()
251 {
252 return shift_;
253 }
255 LModPowTwoI(const LAllocation &lhs, int32_t shift)
256 : shift_(shift)
257 {
258 setOperand(0, lhs);
259 }
261 MMod *mir() const {
262 return mir_->toMod();
263 }
264 };
266 class LModMaskI : public LInstructionHelper<1, 1, 2>
267 {
268 const int32_t shift_;
270 public:
271 LIR_HEADER(ModMaskI);
273 LModMaskI(const LAllocation &lhs, const LDefinition &temp1, const LDefinition &temp2,
274 int32_t shift)
275 : shift_(shift)
276 {
277 setOperand(0, lhs);
278 setTemp(0, temp1);
279 setTemp(1, temp2);
280 }
282 int32_t shift() const {
283 return shift_;
284 }
286 MMod *mir() const {
287 return mir_->toMod();
288 }
289 };
291 class LPowHalfD : public LInstructionHelper<1, 1, 0>
292 {
293 public:
294 LIR_HEADER(PowHalfD);
295 LPowHalfD(const LAllocation &input) {
296 setOperand(0, input);
297 }
299 const LAllocation *input() {
300 return getOperand(0);
301 }
302 const LDefinition *output() {
303 return getDef(0);
304 }
305 };
307 // Takes a tableswitch with an integer to decide
308 class LTableSwitch : public LInstructionHelper<0, 1, 1>
309 {
310 public:
311 LIR_HEADER(TableSwitch);
313 LTableSwitch(const LAllocation &in, const LDefinition &inputCopy, MTableSwitch *ins) {
314 setOperand(0, in);
315 setTemp(0, inputCopy);
316 setMir(ins);
317 }
319 MTableSwitch *mir() const {
320 return mir_->toTableSwitch();
321 }
323 const LAllocation *index() {
324 return getOperand(0);
325 }
326 const LDefinition *tempInt() {
327 return getTemp(0);
328 }
329 // This is added to share the same CodeGenerator prefixes.
330 const LDefinition *tempPointer() {
331 return nullptr;
332 }
333 };
335 // Takes a tableswitch with an integer to decide
336 class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 2>
337 {
338 public:
339 LIR_HEADER(TableSwitchV);
341 LTableSwitchV(const LDefinition &inputCopy, const LDefinition &floatCopy,
342 MTableSwitch *ins)
343 {
344 setTemp(0, inputCopy);
345 setTemp(1, floatCopy);
346 setMir(ins);
347 }
349 MTableSwitch *mir() const {
350 return mir_->toTableSwitch();
351 }
353 static const size_t InputValue = 0;
355 const LDefinition *tempInt() {
356 return getTemp(0);
357 }
358 const LDefinition *tempFloat() {
359 return getTemp(1);
360 }
361 const LDefinition *tempPointer() {
362 return nullptr;
363 }
364 };
366 class LGuardShape : public LInstructionHelper<0, 1, 1>
367 {
368 public:
369 LIR_HEADER(GuardShape);
371 LGuardShape(const LAllocation &in, const LDefinition &temp) {
372 setOperand(0, in);
373 setTemp(0, temp);
374 }
375 const MGuardShape *mir() const {
376 return mir_->toGuardShape();
377 }
378 const LDefinition *tempInt() {
379 return getTemp(0);
380 }
381 };
383 class LGuardObjectType : public LInstructionHelper<0, 1, 1>
384 {
385 public:
386 LIR_HEADER(GuardObjectType);
388 LGuardObjectType(const LAllocation &in, const LDefinition &temp) {
389 setOperand(0, in);
390 setTemp(0, temp);
391 }
392 const MGuardObjectType *mir() const {
393 return mir_->toGuardObjectType();
394 }
395 const LDefinition *tempInt() {
396 return getTemp(0);
397 }
398 };
400 class LInterruptCheck : public LInstructionHelper<0, 0, 0>
401 {
402 public:
403 LIR_HEADER(InterruptCheck);
404 };
406 class LMulI : public LBinaryMath<0>
407 {
408 public:
409 LIR_HEADER(MulI);
411 MMul *mir() {
412 return mir_->toMul();
413 }
414 };
416 class LUDiv : public LBinaryMath<0>
417 {
418 public:
419 LIR_HEADER(UDiv);
421 MDiv *mir() {
422 return mir_->toDiv();
423 }
424 };
426 class LUMod : public LBinaryMath<0>
427 {
428 public:
429 LIR_HEADER(UMod);
431 MMod *mir() {
432 return mir_->toMod();
433 }
434 };
436 // This class performs a simple x86 'div', yielding either a quotient or remainder depending on
437 // whether this instruction is defined to output eax (quotient) or edx (remainder).
438 class LSoftUDivOrMod : public LBinaryMath<3>
439 {
440 public:
441 LIR_HEADER(SoftUDivOrMod);
443 LSoftUDivOrMod(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp1,
444 const LDefinition &temp2, const LDefinition &temp3) {
445 setOperand(0, lhs);
446 setOperand(1, rhs);
447 setTemp(0, temp1);
448 setTemp(1, temp2);
449 setTemp(2, temp3);
450 }
451 };
453 class LAsmJSLoadFuncPtr : public LInstructionHelper<1, 1, 1>
454 {
455 public:
456 LIR_HEADER(AsmJSLoadFuncPtr);
457 LAsmJSLoadFuncPtr(const LAllocation &index, const LDefinition &temp) {
458 setOperand(0, index);
459 setTemp(0, temp);
460 }
461 const MAsmJSLoadFuncPtr *mir() const {
462 return mir_->toAsmJSLoadFuncPtr();
463 }
464 const LAllocation *index() {
465 return getOperand(0);
466 }
467 const LDefinition *temp() {
468 return getTemp(0);
469 }
470 };
472 } // namespace jit
473 } // namespace js
475 #endif /* jit_arm_LIR_arm_h */