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_shared_LIR_x86_shared_h
8 #define jit_shared_LIR_x86_shared_h
10 namespace js {
11 namespace jit {
13 class LDivI : public LBinaryMath<1>
14 {
15 public:
16 LIR_HEADER(DivI)
18 LDivI(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp) {
19 setOperand(0, lhs);
20 setOperand(1, rhs);
21 setTemp(0, temp);
22 }
24 const char *extraName() const {
25 if (mir()->isTruncated()) {
26 if (mir()->canBeNegativeZero()) {
27 return mir()->canBeNegativeOverflow()
28 ? "Truncate_NegativeZero_NegativeOverflow"
29 : "Truncate_NegativeZero";
30 }
31 return mir()->canBeNegativeOverflow() ? "Truncate_NegativeOverflow" : "Truncate";
32 }
33 if (mir()->canBeNegativeZero())
34 return mir()->canBeNegativeOverflow() ? "NegativeZero_NegativeOverflow" : "NegativeZero";
35 return mir()->canBeNegativeOverflow() ? "NegativeOverflow" : nullptr;
36 }
38 const LDefinition *remainder() {
39 return getTemp(0);
40 }
41 MDiv *mir() const {
42 return mir_->toDiv();
43 }
44 };
46 // Signed division by a power-of-two constant.
47 class LDivPowTwoI : public LBinaryMath<0>
48 {
49 const int32_t shift_;
50 const bool negativeDivisor_;
52 public:
53 LIR_HEADER(DivPowTwoI)
55 LDivPowTwoI(const LAllocation &lhs, const LAllocation &lhsCopy, int32_t shift, bool negativeDivisor)
56 : shift_(shift), negativeDivisor_(negativeDivisor)
57 {
58 setOperand(0, lhs);
59 setOperand(1, lhsCopy);
60 }
62 const LAllocation *numerator() {
63 return getOperand(0);
64 }
65 const LAllocation *numeratorCopy() {
66 return getOperand(1);
67 }
68 int32_t shift() const {
69 return shift_;
70 }
71 bool negativeDivisor() const {
72 return negativeDivisor_;
73 }
74 MDiv *mir() const {
75 return mir_->toDiv();
76 }
77 };
79 class LDivOrModConstantI : public LInstructionHelper<1, 1, 1>
80 {
81 const int32_t denominator_;
83 public:
84 LIR_HEADER(DivOrModConstantI)
86 LDivOrModConstantI(const LAllocation &lhs, int32_t denominator, const LDefinition& temp)
87 : denominator_(denominator)
88 {
89 setOperand(0, lhs);
90 setTemp(0, temp);
91 }
93 const LAllocation *numerator() {
94 return getOperand(0);
95 }
96 int32_t denominator() const {
97 return denominator_;
98 }
99 MBinaryArithInstruction *mir() const {
100 JS_ASSERT(mir_->isDiv() || mir_->isMod());
101 return static_cast<MBinaryArithInstruction *>(mir_);
102 }
103 bool canBeNegativeDividend() const {
104 if (mir_->isMod())
105 return mir_->toMod()->canBeNegativeDividend();
106 return mir_->toDiv()->canBeNegativeDividend();
107 }
108 };
110 class LModI : public LBinaryMath<1>
111 {
112 public:
113 LIR_HEADER(ModI)
115 LModI(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp) {
116 setOperand(0, lhs);
117 setOperand(1, rhs);
118 setTemp(0, temp);
119 }
121 const char *extraName() const {
122 return mir()->isTruncated() ? "Truncated" : nullptr;
123 }
125 const LDefinition *remainder() {
126 return getDef(0);
127 }
128 MMod *mir() const {
129 return mir_->toMod();
130 }
131 };
133 // This class performs a simple x86 'div', yielding either a quotient or remainder depending on
134 // whether this instruction is defined to output eax (quotient) or edx (remainder).
135 class LUDivOrMod : public LBinaryMath<1>
136 {
137 public:
138 LIR_HEADER(UDivOrMod);
140 LUDivOrMod(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp) {
141 setOperand(0, lhs);
142 setOperand(1, rhs);
143 setTemp(0, temp);
144 }
146 const LDefinition *remainder() {
147 return getTemp(0);
148 }
150 const char *extraName() const {
151 return mir()->isTruncated() ? "Truncated" : nullptr;
152 }
154 MBinaryArithInstruction *mir() const {
155 JS_ASSERT(mir_->isDiv() || mir_->isMod());
156 return static_cast<MBinaryArithInstruction *>(mir_);
157 }
159 bool canBeDivideByZero() const {
160 if (mir_->isMod())
161 return mir_->toMod()->canBeDivideByZero();
162 return mir_->toDiv()->canBeDivideByZero();
163 }
164 };
166 class LModPowTwoI : public LInstructionHelper<1,1,0>
167 {
168 const int32_t shift_;
170 public:
171 LIR_HEADER(ModPowTwoI)
173 LModPowTwoI(const LAllocation &lhs, int32_t shift)
174 : shift_(shift)
175 {
176 setOperand(0, lhs);
177 }
179 int32_t shift() const {
180 return shift_;
181 }
182 const LDefinition *remainder() {
183 return getDef(0);
184 }
185 MMod *mir() const {
186 return mir_->toMod();
187 }
188 };
190 // Double raised to a half power.
191 class LPowHalfD : public LInstructionHelper<1, 1, 0>
192 {
193 public:
194 LIR_HEADER(PowHalfD)
195 LPowHalfD(const LAllocation &input) {
196 setOperand(0, input);
197 }
199 const LAllocation *input() {
200 return getOperand(0);
201 }
202 const LDefinition *output() {
203 return getDef(0);
204 }
205 MPowHalf *mir() const {
206 return mir_->toPowHalf();
207 }
208 };
210 // Takes a tableswitch with an integer to decide
211 class LTableSwitch : public LInstructionHelper<0, 1, 2>
212 {
213 public:
214 LIR_HEADER(TableSwitch)
216 LTableSwitch(const LAllocation &in, const LDefinition &inputCopy,
217 const LDefinition &jumpTablePointer, MTableSwitch *ins)
218 {
219 setOperand(0, in);
220 setTemp(0, inputCopy);
221 setTemp(1, jumpTablePointer);
222 setMir(ins);
223 }
225 MTableSwitch *mir() const {
226 return mir_->toTableSwitch();
227 }
229 const LAllocation *index() {
230 return getOperand(0);
231 }
232 const LDefinition *tempInt() {
233 return getTemp(0);
234 }
235 const LDefinition *tempPointer() {
236 return getTemp(1);
237 }
238 };
240 // Takes a tableswitch with a value to decide
241 class LTableSwitchV : public LInstructionHelper<0, BOX_PIECES, 3>
242 {
243 public:
244 LIR_HEADER(TableSwitchV)
246 LTableSwitchV(const LDefinition &inputCopy, const LDefinition &floatCopy,
247 const LDefinition &jumpTablePointer, MTableSwitch *ins)
248 {
249 setTemp(0, inputCopy);
250 setTemp(1, floatCopy);
251 setTemp(2, jumpTablePointer);
252 setMir(ins);
253 }
255 MTableSwitch *mir() const {
256 return mir_->toTableSwitch();
257 }
259 static const size_t InputValue = 0;
261 const LDefinition *tempInt() {
262 return getTemp(0);
263 }
264 const LDefinition *tempFloat() {
265 return getTemp(1);
266 }
267 const LDefinition *tempPointer() {
268 return getTemp(2);
269 }
270 };
272 class LGuardShape : public LInstructionHelper<0, 1, 0>
273 {
274 public:
275 LIR_HEADER(GuardShape)
277 LGuardShape(const LAllocation &in) {
278 setOperand(0, in);
279 }
280 const MGuardShape *mir() const {
281 return mir_->toGuardShape();
282 }
283 };
285 class LGuardObjectType : public LInstructionHelper<0, 1, 0>
286 {
287 public:
288 LIR_HEADER(GuardObjectType)
290 LGuardObjectType(const LAllocation &in) {
291 setOperand(0, in);
292 }
293 const MGuardObjectType *mir() const {
294 return mir_->toGuardObjectType();
295 }
296 };
298 class LInterruptCheck : public LInstructionHelper<0, 0, 0>
299 {
300 public:
301 LIR_HEADER(InterruptCheck)
302 };
304 class LMulI : public LBinaryMath<0, 1>
305 {
306 public:
307 LIR_HEADER(MulI)
309 LMulI(const LAllocation &lhs, const LAllocation &rhs, const LAllocation &lhsCopy) {
310 setOperand(0, lhs);
311 setOperand(1, rhs);
312 setOperand(2, lhsCopy);
313 }
315 const char *extraName() const {
316 return (mir()->mode() == MMul::Integer)
317 ? "Integer"
318 : (mir()->canBeNegativeZero() ? "CanBeNegativeZero" : nullptr);
319 }
321 MMul *mir() const {
322 return mir_->toMul();
323 }
324 const LAllocation *lhsCopy() {
325 return this->getOperand(2);
326 }
327 };
329 } // namespace jit
330 } // namespace js
332 #endif /* jit_shared_LIR_x86_shared_h */