js/src/jit/arm/LIR-arm.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial