Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceInstX8632.h - Low-level x86 instructions --*- C++ -*-===// | 1 //===- subzero/src/IceInstX8632.h - Low-level x86 instructions --*- C++ -*-===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file declares the InstX8632 and OperandX8632 classes and | 10 // This file declares the InstX8632 and OperandX8632 classes and |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 47 OperandX8632 &operator=(const OperandX8632 &) LLVM_DELETED_FUNCTION; | 47 OperandX8632 &operator=(const OperandX8632 &) LLVM_DELETED_FUNCTION; |
| 48 }; | 48 }; |
| 49 | 49 |
| 50 // OperandX8632Mem represents the m32 addressing mode, with optional | 50 // OperandX8632Mem represents the m32 addressing mode, with optional |
| 51 // base and index registers, a constant offset, and a fixed shift | 51 // base and index registers, a constant offset, and a fixed shift |
| 52 // value for the index register. | 52 // value for the index register. |
| 53 class OperandX8632Mem : public OperandX8632 { | 53 class OperandX8632Mem : public OperandX8632 { |
| 54 public: | 54 public: |
| 55 enum SegmentRegisters { | 55 enum SegmentRegisters { |
| 56 DefaultSegment = -1, | 56 DefaultSegment = -1, |
| 57 #define X(val, name) \ | 57 #define X(val, name) val, |
| 58 val, | 58 SEG_REGX8632_TABLE |
| 59 SEG_REGX8632_TABLE | |
| 60 #undef X | 59 #undef X |
| 61 SegReg_NUM | 60 SegReg_NUM |
| 62 }; | 61 }; |
| 63 static OperandX8632Mem *create(Cfg *Func, Type Ty, Variable *Base, | 62 static OperandX8632Mem *create(Cfg *Func, Type Ty, Variable *Base, |
| 64 Constant *Offset, Variable *Index = NULL, | 63 Constant *Offset, Variable *Index = NULL, |
| 65 uint16_t Shift = 0, | 64 uint16_t Shift = 0, |
| 66 SegmentRegisters SegmentReg = DefaultSegment) { | 65 SegmentRegisters SegmentReg = DefaultSegment) { |
| 67 return new (Func->allocate<OperandX8632Mem>()) | 66 return new (Func->allocate<OperandX8632Mem>()) |
| 68 OperandX8632Mem(Func, Ty, Base, Offset, Index, Shift, SegmentReg); | 67 OperandX8632Mem(Func, Ty, Base, Offset, Index, Shift, SegmentReg); |
| 69 } | 68 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 public: | 133 public: |
| 135 enum InstKindX8632 { | 134 enum InstKindX8632 { |
| 136 k__Start = Inst::Target, | 135 k__Start = Inst::Target, |
| 137 Adc, | 136 Adc, |
| 138 Add, | 137 Add, |
| 139 Addss, | 138 Addss, |
| 140 And, | 139 And, |
| 141 Br, | 140 Br, |
| 142 Call, | 141 Call, |
| 143 Cdq, | 142 Cdq, |
| 143 Cmpxchg, | |
| 144 Cmpxchg8b, | |
| 144 Cvt, | 145 Cvt, |
| 145 Div, | 146 Div, |
| 146 Divss, | 147 Divss, |
| 147 Fld, | 148 Fld, |
| 148 Fstp, | 149 Fstp, |
| 149 Icmp, | 150 Icmp, |
| 150 Idiv, | 151 Idiv, |
| 151 Imul, | 152 Imul, |
| 152 Label, | 153 Label, |
| 153 Load, | 154 Load, |
| 154 Mfence, | 155 Mfence, |
| 155 Mov, | 156 Mov, |
| 156 Movq, | 157 Movq, |
| 157 Movsx, | 158 Movsx, |
| 158 Movzx, | 159 Movzx, |
| 159 Mul, | 160 Mul, |
| 160 Mulss, | 161 Mulss, |
| 162 Neg, | |
| 161 Or, | 163 Or, |
| 162 Pop, | 164 Pop, |
| 163 Push, | 165 Push, |
| 164 Ret, | 166 Ret, |
| 165 Sar, | 167 Sar, |
| 166 Sbb, | 168 Sbb, |
| 167 Shl, | 169 Shl, |
| 168 Shld, | 170 Shld, |
| 169 Shr, | 171 Shr, |
| 170 Shrd, | 172 Shrd, |
| 171 Store, | 173 Store, |
| 172 StoreQ, | 174 StoreQ, |
| 173 Sub, | 175 Sub, |
| 174 Subss, | 176 Subss, |
| 175 Test, | 177 Test, |
| 176 Ucomiss, | 178 Ucomiss, |
| 177 UD2, | 179 UD2, |
| 178 Xadd, | 180 Xadd, |
| 181 Xchg, | |
| 179 Xor | 182 Xor |
| 180 }; | 183 }; |
| 181 static const char *getWidthString(Type Ty); | 184 static const char *getWidthString(Type Ty); |
| 182 virtual void emit(const Cfg *Func) const = 0; | 185 virtual void emit(const Cfg *Func) const = 0; |
| 183 virtual void dump(const Cfg *Func) const; | 186 virtual void dump(const Cfg *Func) const; |
| 184 | 187 |
| 185 protected: | 188 protected: |
| 186 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest) | 189 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest) |
| 187 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} | 190 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} |
| 188 virtual ~InstX8632() {} | 191 virtual ~InstX8632() {} |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 314 virtual void dump(const Cfg *Func) const; | 317 virtual void dump(const Cfg *Func) const; |
| 315 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } | 318 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } |
| 316 | 319 |
| 317 private: | 320 private: |
| 318 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); | 321 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); |
| 319 InstX8632Call(const InstX8632Call &) LLVM_DELETED_FUNCTION; | 322 InstX8632Call(const InstX8632Call &) LLVM_DELETED_FUNCTION; |
| 320 InstX8632Call &operator=(const InstX8632Call &) LLVM_DELETED_FUNCTION; | 323 InstX8632Call &operator=(const InstX8632Call &) LLVM_DELETED_FUNCTION; |
| 321 virtual ~InstX8632Call() {} | 324 virtual ~InstX8632Call() {} |
| 322 }; | 325 }; |
| 323 | 326 |
| 327 template <InstX8632::InstKindX8632 K> | |
| 328 class InstX8632Unaryop : public InstX8632 { | |
| 329 public: | |
| 330 // Create an unary-op instruction like neg. | |
| 331 // The source and dest are the same variable. | |
| 332 static InstX8632Unaryop *create(Cfg *Func, Variable *SrcDest) { | |
|
Jim Stichnoth
2014/07/08 04:50:19
An instruction like this is valid x86:
neg [eax+
jvoung (off chromium)
2014/07/08 18:14:07
Okay, I think I will try making it a more generic
jvoung (off chromium)
2014/07/09 17:07:55
Done.
Not sure about liveness either, but Dest wo
Jim Stichnoth
2014/07/09 18:14:28
Yes, that's also what I'd expect.
| |
| 333 return new (Func->allocate<InstX8632Unaryop>()) | |
| 334 InstX8632Unaryop(Func, SrcDest); | |
| 335 } | |
| 336 virtual void emit(const Cfg *Func) const { | |
| 337 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 338 assert(getSrcSize() == 1); | |
| 339 Str << "\t" << Opcode << "\t"; | |
| 340 getSrc(0)->emit(Func); | |
| 341 Str << "\n"; | |
| 342 } | |
| 343 virtual void dump(const Cfg *Func) const { | |
| 344 Ostream &Str = Func->getContext()->getStrDump(); | |
| 345 dumpDest(Func); | |
| 346 Str << " = " << Opcode << "." << getDest()->getType() << " "; | |
| 347 dumpSources(Func); | |
| 348 } | |
| 349 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | |
| 350 | |
| 351 private: | |
| 352 InstX8632Unaryop(Cfg *Func, Variable *SrcDest) | |
| 353 : InstX8632(Func, K, 1, SrcDest) { | |
| 354 addSource(SrcDest); | |
| 355 } | |
| 356 InstX8632Unaryop(const InstX8632Unaryop &) LLVM_DELETED_FUNCTION; | |
| 357 InstX8632Unaryop &operator=(const InstX8632Unaryop &) LLVM_DELETED_FUNCTION; | |
| 358 virtual ~InstX8632Unaryop() {} | |
| 359 static const char *Opcode; | |
| 360 }; | |
| 361 | |
| 324 // See the definition of emitTwoAddress() for a description of | 362 // See the definition of emitTwoAddress() for a description of |
| 325 // ShiftHack. | 363 // ShiftHack. |
| 326 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, | 364 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, |
| 327 bool ShiftHack = false); | 365 bool ShiftHack = false); |
| 328 | 366 |
| 329 template <InstX8632::InstKindX8632 K, bool ShiftHack = false> | 367 template <InstX8632::InstKindX8632 K, bool ShiftHack = false> |
| 330 class InstX8632Binop : public InstX8632 { | 368 class InstX8632Binop : public InstX8632 { |
| 331 public: | 369 public: |
| 332 // Create an ordinary binary-op instruction like add or sub. | 370 // Create an ordinary binary-op instruction like add or sub. |
| 333 static InstX8632Binop *create(Cfg *Func, Variable *Dest, Operand *Source) { | 371 static InstX8632Binop *create(Cfg *Func, Variable *Dest, Operand *Source) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 386 addSource(Dest); | 424 addSource(Dest); |
| 387 addSource(Source1); | 425 addSource(Source1); |
| 388 addSource(Source2); | 426 addSource(Source2); |
| 389 } | 427 } |
| 390 InstX8632Ternop(const InstX8632Ternop &) LLVM_DELETED_FUNCTION; | 428 InstX8632Ternop(const InstX8632Ternop &) LLVM_DELETED_FUNCTION; |
| 391 InstX8632Ternop &operator=(const InstX8632Ternop &) LLVM_DELETED_FUNCTION; | 429 InstX8632Ternop &operator=(const InstX8632Ternop &) LLVM_DELETED_FUNCTION; |
| 392 virtual ~InstX8632Ternop() {} | 430 virtual ~InstX8632Ternop() {} |
| 393 static const char *Opcode; | 431 static const char *Opcode; |
| 394 }; | 432 }; |
| 395 | 433 |
| 434 typedef InstX8632Unaryop<InstX8632::Neg> InstX8632Neg; | |
| 396 typedef InstX8632Binop<InstX8632::Add> InstX8632Add; | 435 typedef InstX8632Binop<InstX8632::Add> InstX8632Add; |
| 397 typedef InstX8632Binop<InstX8632::Adc> InstX8632Adc; | 436 typedef InstX8632Binop<InstX8632::Adc> InstX8632Adc; |
| 398 typedef InstX8632Binop<InstX8632::Addss> InstX8632Addss; | 437 typedef InstX8632Binop<InstX8632::Addss> InstX8632Addss; |
| 399 typedef InstX8632Binop<InstX8632::Sub> InstX8632Sub; | 438 typedef InstX8632Binop<InstX8632::Sub> InstX8632Sub; |
| 400 typedef InstX8632Binop<InstX8632::Subss> InstX8632Subss; | 439 typedef InstX8632Binop<InstX8632::Subss> InstX8632Subss; |
| 401 typedef InstX8632Binop<InstX8632::Sbb> InstX8632Sbb; | 440 typedef InstX8632Binop<InstX8632::Sbb> InstX8632Sbb; |
| 402 typedef InstX8632Binop<InstX8632::And> InstX8632And; | 441 typedef InstX8632Binop<InstX8632::And> InstX8632And; |
| 403 typedef InstX8632Binop<InstX8632::Or> InstX8632Or; | 442 typedef InstX8632Binop<InstX8632::Or> InstX8632Or; |
| 404 typedef InstX8632Binop<InstX8632::Xor> InstX8632Xor; | 443 typedef InstX8632Binop<InstX8632::Xor> InstX8632Xor; |
| 405 typedef InstX8632Binop<InstX8632::Imul> InstX8632Imul; | 444 typedef InstX8632Binop<InstX8632::Imul> InstX8632Imul; |
| 406 typedef InstX8632Binop<InstX8632::Mulss> InstX8632Mulss; | 445 typedef InstX8632Binop<InstX8632::Mulss> InstX8632Mulss; |
| 407 typedef InstX8632Binop<InstX8632::Divss> InstX8632Divss; | 446 typedef InstX8632Binop<InstX8632::Divss> InstX8632Divss; |
| 408 typedef InstX8632Binop<InstX8632::Shl, true> InstX8632Shl; | 447 typedef InstX8632Binop<InstX8632::Shl, true> InstX8632Shl; |
| 409 typedef InstX8632Binop<InstX8632::Shr, true> InstX8632Shr; | 448 typedef InstX8632Binop<InstX8632::Shr, true> InstX8632Shr; |
| 410 typedef InstX8632Binop<InstX8632::Sar, true> InstX8632Sar; | 449 typedef InstX8632Binop<InstX8632::Sar, true> InstX8632Sar; |
| 411 typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv; | 450 typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv; |
| 412 typedef InstX8632Ternop<InstX8632::Div> InstX8632Div; | 451 typedef InstX8632Ternop<InstX8632::Div> InstX8632Div; |
| 413 | 452 |
| 453 // Base class for a lockable x86-32 instruction (emits a locked prefix). | |
| 454 class InstX8632Lockable : public InstX8632 { | |
| 455 public: | |
| 456 virtual void emit(const Cfg *Func) const = 0; | |
| 457 virtual void dump(const Cfg *Func) const; | |
| 458 | |
| 459 protected: | |
| 460 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, | |
| 461 Variable *Dest, bool Locked) | |
| 462 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) { | |
| 463 // Assume that such instructions are used for Atomics and be careful | |
| 464 // with optimizations. | |
| 465 HasSideEffects = Locked; | |
| 466 } | |
| 467 bool Locked; | |
| 468 | |
| 469 private: | |
| 470 InstX8632Lockable(const InstX8632Lockable &) LLVM_DELETED_FUNCTION; | |
| 471 InstX8632Lockable &operator=(const InstX8632Lockable &) LLVM_DELETED_FUNCTION; | |
| 472 }; | |
| 473 | |
| 414 // Mul instruction - unsigned multiply. | 474 // Mul instruction - unsigned multiply. |
| 415 class InstX8632Mul : public InstX8632 { | 475 class InstX8632Mul : public InstX8632 { |
| 416 public: | 476 public: |
| 417 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, | 477 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, |
| 418 Operand *Source2) { | 478 Operand *Source2) { |
| 419 return new (Func->allocate<InstX8632Mul>()) | 479 return new (Func->allocate<InstX8632Mul>()) |
| 420 InstX8632Mul(Func, Dest, Source1, Source2); | 480 InstX8632Mul(Func, Dest, Source1, Source2); |
| 421 } | 481 } |
| 422 virtual void emit(const Cfg *Func) const; | 482 virtual void emit(const Cfg *Func) const; |
| 423 virtual void dump(const Cfg *Func) const; | 483 virtual void dump(const Cfg *Func) const; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 483 virtual void dump(const Cfg *Func) const; | 543 virtual void dump(const Cfg *Func) const; |
| 484 static bool classof(const Inst *Inst) { return isClassof(Inst, Cdq); } | 544 static bool classof(const Inst *Inst) { return isClassof(Inst, Cdq); } |
| 485 | 545 |
| 486 private: | 546 private: |
| 487 InstX8632Cdq(Cfg *Func, Variable *Dest, Operand *Source); | 547 InstX8632Cdq(Cfg *Func, Variable *Dest, Operand *Source); |
| 488 InstX8632Cdq(const InstX8632Cdq &) LLVM_DELETED_FUNCTION; | 548 InstX8632Cdq(const InstX8632Cdq &) LLVM_DELETED_FUNCTION; |
| 489 InstX8632Cdq &operator=(const InstX8632Cdq &) LLVM_DELETED_FUNCTION; | 549 InstX8632Cdq &operator=(const InstX8632Cdq &) LLVM_DELETED_FUNCTION; |
| 490 virtual ~InstX8632Cdq() {} | 550 virtual ~InstX8632Cdq() {} |
| 491 }; | 551 }; |
| 492 | 552 |
| 553 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> | |
| 554 // equals eax. If so, the ZF is set and <desired> is stored in <dest>. | |
| 555 // If not, ZF is cleared and <dest> is copied to eax (or subregister). | |
| 556 // The user is responsible for making a FakeDef to mark eax as | |
| 557 // possibly changed. | |
|
Jim Stichnoth
2014/07/08 04:50:19
Would it be simpler to swap the roles of Eax and D
jvoung (off chromium)
2014/07/08 18:14:07
I think this is similar to Xchg. See below?
jvoung (off chromium)
2014/07/09 17:07:55
Okay, this is slightly different from Xchg, in tha
Jim Stichnoth
2014/07/09 18:14:27
After more thought, I would go simple and just dis
| |
| 558 // <dest> can be a register or memory, while <desired> must be a register. | |
| 559 class InstX8632Cmpxchg : public InstX8632Lockable { | |
| 560 public: | |
| 561 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, | |
| 562 Variable *Desired, bool Locked) { | |
| 563 return new (Func->allocate<InstX8632Cmpxchg>()) | |
| 564 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); | |
| 565 } | |
| 566 virtual void emit(const Cfg *Func) const; | |
| 567 virtual void dump(const Cfg *Func) const; | |
| 568 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); } | |
| 569 | |
| 570 private: | |
| 571 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, | |
| 572 Variable *Desired, bool Locked); | |
| 573 InstX8632Cmpxchg(const InstX8632Cmpxchg &) LLVM_DELETED_FUNCTION; | |
| 574 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) LLVM_DELETED_FUNCTION; | |
| 575 virtual ~InstX8632Cmpxchg() {} | |
| 576 }; | |
| 577 | |
| 578 // Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> | |
| 579 // equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. | |
| 580 // If not, ZF is cleared and <m64> is copied to edx:eax. | |
| 581 // <m64> must be a memory operand. | |
|
Jim Stichnoth
2014/07/08 04:50:19
Document the user's responsibility to add appropri
jvoung (off chromium)
2014/07/09 17:07:55
Documented.
The other 64-bit integer instruction
Jim Stichnoth
2014/07/09 18:14:28
I was thinking of the 64-bit ret, but there may be
| |
| 582 class InstX8632Cmpxchg8b : public InstX8632Lockable { | |
| 583 public: | |
| 584 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632 *Dest, | |
| 585 Variable *Edx, Variable *Eax, Variable *Ecx, | |
| 586 Variable *Ebx, bool Locked) { | |
| 587 return new (Func->allocate<InstX8632Cmpxchg8b>()) | |
| 588 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); | |
| 589 } | |
| 590 virtual void emit(const Cfg *Func) const; | |
| 591 virtual void dump(const Cfg *Func) const; | |
| 592 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); } | |
| 593 | |
| 594 private: | |
| 595 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632 *Dest, Variable *Edx, | |
| 596 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked); | |
| 597 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) LLVM_DELETED_FUNCTION; | |
| 598 InstX8632Cmpxchg8b & | |
| 599 operator=(const InstX8632Cmpxchg8b &) LLVM_DELETED_FUNCTION; | |
| 600 virtual ~InstX8632Cmpxchg8b() {} | |
| 601 }; | |
| 602 | |
| 493 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} | 603 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} |
| 494 // as appropriate. s=float, d=double, i=int. X and Y are determined | 604 // as appropriate. s=float, d=double, i=int. X and Y are determined |
| 495 // from dest/src types. Sign and zero extension on the integer | 605 // from dest/src types. Sign and zero extension on the integer |
| 496 // operand needs to be done separately. | 606 // operand needs to be done separately. |
| 497 class InstX8632Cvt : public InstX8632 { | 607 class InstX8632Cvt : public InstX8632 { |
| 498 public: | 608 public: |
| 499 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source) { | 609 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source) { |
| 500 return new (Func->allocate<InstX8632Cvt>()) | 610 return new (Func->allocate<InstX8632Cvt>()) |
| 501 InstX8632Cvt(Func, Dest, Source); | 611 InstX8632Cvt(Func, Dest, Source); |
| 502 } | 612 } |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 804 virtual ~InstX8632Ret() {} | 914 virtual ~InstX8632Ret() {} |
| 805 }; | 915 }; |
| 806 | 916 |
| 807 // Exchanging Add instruction. Exchanges the first operand (destination | 917 // Exchanging Add instruction. Exchanges the first operand (destination |
| 808 // operand) with the second operand (source operand), then loads the sum | 918 // operand) with the second operand (source operand), then loads the sum |
| 809 // of the two values into the destination operand. The destination may be | 919 // of the two values into the destination operand. The destination may be |
| 810 // a register or memory, while the source must be a register. | 920 // a register or memory, while the source must be a register. |
| 811 // | 921 // |
| 812 // Both the dest and source are updated. The caller should then insert a | 922 // Both the dest and source are updated. The caller should then insert a |
| 813 // FakeDef to reflect the second udpate. | 923 // FakeDef to reflect the second udpate. |
| 814 class InstX8632Xadd : public InstX8632 { | 924 class InstX8632Xadd : public InstX8632Lockable { |
| 815 public: | 925 public: |
| 816 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, | 926 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, |
| 817 bool Locked) { | 927 bool Locked) { |
| 818 return new (Func->allocate<InstX8632Xadd>()) | 928 return new (Func->allocate<InstX8632Xadd>()) |
| 819 InstX8632Xadd(Func, Dest, Source, Locked); | 929 InstX8632Xadd(Func, Dest, Source, Locked); |
| 820 } | 930 } |
| 821 virtual void emit(const Cfg *Func) const; | 931 virtual void emit(const Cfg *Func) const; |
| 822 virtual void dump(const Cfg *Func) const; | 932 virtual void dump(const Cfg *Func) const; |
| 823 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); } | 933 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); } |
| 824 | 934 |
| 825 private: | 935 private: |
| 826 bool Locked; | |
| 827 | |
| 828 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); | 936 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); |
| 829 InstX8632Xadd(const InstX8632Xadd &) LLVM_DELETED_FUNCTION; | 937 InstX8632Xadd(const InstX8632Xadd &) LLVM_DELETED_FUNCTION; |
| 830 InstX8632Xadd &operator=(const InstX8632Xadd &) LLVM_DELETED_FUNCTION; | 938 InstX8632Xadd &operator=(const InstX8632Xadd &) LLVM_DELETED_FUNCTION; |
| 831 virtual ~InstX8632Xadd() {} | 939 virtual ~InstX8632Xadd() {} |
| 832 }; | 940 }; |
| 833 | 941 |
| 942 // Exchange instruction. Exchanges the first operand (destination | |
| 943 // operand) with the second operand (source operand). At least one of | |
| 944 // the operands must be a register (and the other can be reg or mem). | |
| 945 // Both the Dest and Source are updated. If there is a memory operand, | |
| 946 // then the instruction is automatically "locked" without the need for | |
| 947 // a lock prefix. | |
| 948 class InstX8632Xchg : public InstX8632 { | |
| 949 public: | |
| 950 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { | |
|
Jim Stichnoth
2014/07/08 04:50:19
Can we structure this so that Dest is the Variable
jvoung (off chromium)
2014/07/08 18:14:07
I think the motivation for this was to make it lik
Jim Stichnoth
2014/07/09 18:14:27
At least for now, I would just be conservative and
| |
| 951 return new (Func->allocate<InstX8632Xchg>()) | |
| 952 InstX8632Xchg(Func, Dest, Source); | |
| 953 } | |
| 954 virtual void emit(const Cfg *Func) const; | |
| 955 virtual void dump(const Cfg *Func) const; | |
| 956 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); } | |
| 957 | |
| 958 private: | |
| 959 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source); | |
| 960 InstX8632Xchg(const InstX8632Xchg &) LLVM_DELETED_FUNCTION; | |
| 961 InstX8632Xchg &operator=(const InstX8632Xchg &) LLVM_DELETED_FUNCTION; | |
| 962 virtual ~InstX8632Xchg() {} | |
| 963 }; | |
| 964 | |
| 834 } // end of namespace Ice | 965 } // end of namespace Ice |
| 835 | 966 |
| 836 #endif // SUBZERO_SRC_ICEINSTX8632_H | 967 #endif // SUBZERO_SRC_ICEINSTX8632_H |
| OLD | NEW |