| 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Addps, | 138 Addps, |
| 140 Addss, | 139 Addss, |
| 141 And, | 140 And, |
| 142 Br, | 141 Br, |
| 143 Call, | 142 Call, |
| 144 Cdq, | 143 Cdq, |
| 144 Cmpxchg, |
| 145 Cmpxchg8b, |
| 145 Cvt, | 146 Cvt, |
| 146 Div, | 147 Div, |
| 147 Divps, | 148 Divps, |
| 148 Divss, | 149 Divss, |
| 149 Fld, | 150 Fld, |
| 150 Fstp, | 151 Fstp, |
| 151 Icmp, | 152 Icmp, |
| 152 Idiv, | 153 Idiv, |
| 153 Imul, | 154 Imul, |
| 154 Label, | 155 Label, |
| 155 Load, | 156 Load, |
| 156 Mfence, | 157 Mfence, |
| 157 Mov, | 158 Mov, |
| 158 Movp, | 159 Movp, |
| 159 Movq, | 160 Movq, |
| 160 Movsx, | 161 Movsx, |
| 161 Movzx, | 162 Movzx, |
| 162 Mul, | 163 Mul, |
| 163 Mulps, | 164 Mulps, |
| 164 Mulss, | 165 Mulss, |
| 166 Neg, |
| 165 Or, | 167 Or, |
| 166 Pop, | 168 Pop, |
| 167 Push, | 169 Push, |
| 168 Pxor, | 170 Pxor, |
| 169 Ret, | 171 Ret, |
| 170 Sar, | 172 Sar, |
| 171 Sbb, | 173 Sbb, |
| 172 Shl, | 174 Shl, |
| 173 Shld, | 175 Shld, |
| 174 Shr, | 176 Shr, |
| 175 Shrd, | 177 Shrd, |
| 176 Sqrtss, | 178 Sqrtss, |
| 177 Store, | 179 Store, |
| 178 StoreQ, | 180 StoreQ, |
| 179 Sub, | 181 Sub, |
| 180 Subps, | 182 Subps, |
| 181 Subss, | 183 Subss, |
| 182 Test, | 184 Test, |
| 183 Ucomiss, | 185 Ucomiss, |
| 184 UD2, | 186 UD2, |
| 185 Xadd, | 187 Xadd, |
| 188 Xchg, |
| 186 Xor | 189 Xor |
| 187 }; | 190 }; |
| 188 static const char *getWidthString(Type Ty); | 191 static const char *getWidthString(Type Ty); |
| 189 virtual void emit(const Cfg *Func) const = 0; | 192 virtual void emit(const Cfg *Func) const = 0; |
| 190 virtual void dump(const Cfg *Func) const; | 193 virtual void dump(const Cfg *Func) const; |
| 191 | 194 |
| 192 protected: | 195 protected: |
| 193 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest) | 196 InstX8632(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, Variable *Dest) |
| 194 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} | 197 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} |
| 195 virtual ~InstX8632() {} | 198 virtual ~InstX8632() {} |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 virtual void dump(const Cfg *Func) const; | 324 virtual void dump(const Cfg *Func) const; |
| 322 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } | 325 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } |
| 323 | 326 |
| 324 private: | 327 private: |
| 325 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); | 328 InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget); |
| 326 InstX8632Call(const InstX8632Call &) LLVM_DELETED_FUNCTION; | 329 InstX8632Call(const InstX8632Call &) LLVM_DELETED_FUNCTION; |
| 327 InstX8632Call &operator=(const InstX8632Call &) LLVM_DELETED_FUNCTION; | 330 InstX8632Call &operator=(const InstX8632Call &) LLVM_DELETED_FUNCTION; |
| 328 virtual ~InstX8632Call() {} | 331 virtual ~InstX8632Call() {} |
| 329 }; | 332 }; |
| 330 | 333 |
| 334 template <InstX8632::InstKindX8632 K> |
| 335 class InstX8632Unaryop : public InstX8632 { |
| 336 public: |
| 337 // Create an unary-op instruction like neg. |
| 338 // The source and dest are the same variable. |
| 339 static InstX8632Unaryop *create(Cfg *Func, Operand *SrcDest) { |
| 340 return new (Func->allocate<InstX8632Unaryop>()) |
| 341 InstX8632Unaryop(Func, SrcDest); |
| 342 } |
| 343 virtual void emit(const Cfg *Func) const { |
| 344 Ostream &Str = Func->getContext()->getStrEmit(); |
| 345 assert(getSrcSize() == 1); |
| 346 Str << "\t" << Opcode << "\t"; |
| 347 getSrc(0)->emit(Func); |
| 348 Str << "\n"; |
| 349 } |
| 350 virtual void dump(const Cfg *Func) const { |
| 351 Ostream &Str = Func->getContext()->getStrDump(); |
| 352 dumpDest(Func); |
| 353 Str << " = " << Opcode << "." << getDest()->getType() << " "; |
| 354 dumpSources(Func); |
| 355 } |
| 356 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
| 357 |
| 358 private: |
| 359 InstX8632Unaryop(Cfg *Func, Operand *SrcDest) |
| 360 : InstX8632(Func, K, 1, llvm::dyn_cast<Variable>(SrcDest)) { |
| 361 addSource(SrcDest); |
| 362 } |
| 363 InstX8632Unaryop(const InstX8632Unaryop &) LLVM_DELETED_FUNCTION; |
| 364 InstX8632Unaryop &operator=(const InstX8632Unaryop &) LLVM_DELETED_FUNCTION; |
| 365 virtual ~InstX8632Unaryop() {} |
| 366 static const char *Opcode; |
| 367 }; |
| 368 |
| 331 // See the definition of emitTwoAddress() for a description of | 369 // See the definition of emitTwoAddress() for a description of |
| 332 // ShiftHack. | 370 // ShiftHack. |
| 333 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, | 371 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, |
| 334 bool ShiftHack = false); | 372 bool ShiftHack = false); |
| 335 | 373 |
| 336 template <InstX8632::InstKindX8632 K, bool ShiftHack = false> | 374 template <InstX8632::InstKindX8632 K, bool ShiftHack = false> |
| 337 class InstX8632Binop : public InstX8632 { | 375 class InstX8632Binop : public InstX8632 { |
| 338 public: | 376 public: |
| 339 // Create an ordinary binary-op instruction like add or sub. | 377 // Create an ordinary binary-op instruction like add or sub. |
| 340 static InstX8632Binop *create(Cfg *Func, Variable *Dest, Operand *Source) { | 378 static InstX8632Binop *create(Cfg *Func, Variable *Dest, Operand *Source) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 addSource(Dest); | 431 addSource(Dest); |
| 394 addSource(Source1); | 432 addSource(Source1); |
| 395 addSource(Source2); | 433 addSource(Source2); |
| 396 } | 434 } |
| 397 InstX8632Ternop(const InstX8632Ternop &) LLVM_DELETED_FUNCTION; | 435 InstX8632Ternop(const InstX8632Ternop &) LLVM_DELETED_FUNCTION; |
| 398 InstX8632Ternop &operator=(const InstX8632Ternop &) LLVM_DELETED_FUNCTION; | 436 InstX8632Ternop &operator=(const InstX8632Ternop &) LLVM_DELETED_FUNCTION; |
| 399 virtual ~InstX8632Ternop() {} | 437 virtual ~InstX8632Ternop() {} |
| 400 static const char *Opcode; | 438 static const char *Opcode; |
| 401 }; | 439 }; |
| 402 | 440 |
| 441 typedef InstX8632Unaryop<InstX8632::Neg> InstX8632Neg; |
| 403 typedef InstX8632Binop<InstX8632::Add> InstX8632Add; | 442 typedef InstX8632Binop<InstX8632::Add> InstX8632Add; |
| 404 typedef InstX8632Binop<InstX8632::Addps> InstX8632Addps; | 443 typedef InstX8632Binop<InstX8632::Addps> InstX8632Addps; |
| 405 typedef InstX8632Binop<InstX8632::Adc> InstX8632Adc; | 444 typedef InstX8632Binop<InstX8632::Adc> InstX8632Adc; |
| 406 typedef InstX8632Binop<InstX8632::Addss> InstX8632Addss; | 445 typedef InstX8632Binop<InstX8632::Addss> InstX8632Addss; |
| 407 typedef InstX8632Binop<InstX8632::Sub> InstX8632Sub; | 446 typedef InstX8632Binop<InstX8632::Sub> InstX8632Sub; |
| 408 typedef InstX8632Binop<InstX8632::Subps> InstX8632Subps; | 447 typedef InstX8632Binop<InstX8632::Subps> InstX8632Subps; |
| 409 typedef InstX8632Binop<InstX8632::Subss> InstX8632Subss; | 448 typedef InstX8632Binop<InstX8632::Subss> InstX8632Subss; |
| 410 typedef InstX8632Binop<InstX8632::Sbb> InstX8632Sbb; | 449 typedef InstX8632Binop<InstX8632::Sbb> InstX8632Sbb; |
| 411 typedef InstX8632Binop<InstX8632::And> InstX8632And; | 450 typedef InstX8632Binop<InstX8632::And> InstX8632And; |
| 412 typedef InstX8632Binop<InstX8632::Or> InstX8632Or; | 451 typedef InstX8632Binop<InstX8632::Or> InstX8632Or; |
| 413 typedef InstX8632Binop<InstX8632::Xor> InstX8632Xor; | 452 typedef InstX8632Binop<InstX8632::Xor> InstX8632Xor; |
| 414 typedef InstX8632Binop<InstX8632::Pxor> InstX8632Pxor; | 453 typedef InstX8632Binop<InstX8632::Pxor> InstX8632Pxor; |
| 415 typedef InstX8632Binop<InstX8632::Imul> InstX8632Imul; | 454 typedef InstX8632Binop<InstX8632::Imul> InstX8632Imul; |
| 416 typedef InstX8632Binop<InstX8632::Mulps> InstX8632Mulps; | 455 typedef InstX8632Binop<InstX8632::Mulps> InstX8632Mulps; |
| 417 typedef InstX8632Binop<InstX8632::Mulss> InstX8632Mulss; | 456 typedef InstX8632Binop<InstX8632::Mulss> InstX8632Mulss; |
| 418 typedef InstX8632Binop<InstX8632::Divps> InstX8632Divps; | 457 typedef InstX8632Binop<InstX8632::Divps> InstX8632Divps; |
| 419 typedef InstX8632Binop<InstX8632::Divss> InstX8632Divss; | 458 typedef InstX8632Binop<InstX8632::Divss> InstX8632Divss; |
| 420 typedef InstX8632Binop<InstX8632::Shl, true> InstX8632Shl; | 459 typedef InstX8632Binop<InstX8632::Shl, true> InstX8632Shl; |
| 421 typedef InstX8632Binop<InstX8632::Shr, true> InstX8632Shr; | 460 typedef InstX8632Binop<InstX8632::Shr, true> InstX8632Shr; |
| 422 typedef InstX8632Binop<InstX8632::Sar, true> InstX8632Sar; | 461 typedef InstX8632Binop<InstX8632::Sar, true> InstX8632Sar; |
| 423 typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv; | 462 typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv; |
| 424 typedef InstX8632Ternop<InstX8632::Div> InstX8632Div; | 463 typedef InstX8632Ternop<InstX8632::Div> InstX8632Div; |
| 425 | 464 |
| 465 // Base class for a lockable x86-32 instruction (emits a locked prefix). |
| 466 class InstX8632Lockable : public InstX8632 { |
| 467 public: |
| 468 virtual void emit(const Cfg *Func) const = 0; |
| 469 virtual void dump(const Cfg *Func) const; |
| 470 |
| 471 protected: |
| 472 bool Locked; |
| 473 |
| 474 InstX8632Lockable(Cfg *Func, InstKindX8632 Kind, SizeT Maxsrcs, |
| 475 Variable *Dest, bool Locked) |
| 476 : InstX8632(Func, Kind, Maxsrcs, Dest), Locked(Locked) { |
| 477 // Assume that such instructions are used for Atomics and be careful |
| 478 // with optimizations. |
| 479 HasSideEffects = Locked; |
| 480 } |
| 481 |
| 482 private: |
| 483 InstX8632Lockable(const InstX8632Lockable &) LLVM_DELETED_FUNCTION; |
| 484 InstX8632Lockable &operator=(const InstX8632Lockable &) LLVM_DELETED_FUNCTION; |
| 485 }; |
| 486 |
| 426 // Mul instruction - unsigned multiply. | 487 // Mul instruction - unsigned multiply. |
| 427 class InstX8632Mul : public InstX8632 { | 488 class InstX8632Mul : public InstX8632 { |
| 428 public: | 489 public: |
| 429 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, | 490 static InstX8632Mul *create(Cfg *Func, Variable *Dest, Variable *Source1, |
| 430 Operand *Source2) { | 491 Operand *Source2) { |
| 431 return new (Func->allocate<InstX8632Mul>()) | 492 return new (Func->allocate<InstX8632Mul>()) |
| 432 InstX8632Mul(Func, Dest, Source1, Source2); | 493 InstX8632Mul(Func, Dest, Source1, Source2); |
| 433 } | 494 } |
| 434 virtual void emit(const Cfg *Func) const; | 495 virtual void emit(const Cfg *Func) const; |
| 435 virtual void dump(const Cfg *Func) const; | 496 virtual void dump(const Cfg *Func) const; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 virtual void dump(const Cfg *Func) const; | 556 virtual void dump(const Cfg *Func) const; |
| 496 static bool classof(const Inst *Inst) { return isClassof(Inst, Cdq); } | 557 static bool classof(const Inst *Inst) { return isClassof(Inst, Cdq); } |
| 497 | 558 |
| 498 private: | 559 private: |
| 499 InstX8632Cdq(Cfg *Func, Variable *Dest, Operand *Source); | 560 InstX8632Cdq(Cfg *Func, Variable *Dest, Operand *Source); |
| 500 InstX8632Cdq(const InstX8632Cdq &) LLVM_DELETED_FUNCTION; | 561 InstX8632Cdq(const InstX8632Cdq &) LLVM_DELETED_FUNCTION; |
| 501 InstX8632Cdq &operator=(const InstX8632Cdq &) LLVM_DELETED_FUNCTION; | 562 InstX8632Cdq &operator=(const InstX8632Cdq &) LLVM_DELETED_FUNCTION; |
| 502 virtual ~InstX8632Cdq() {} | 563 virtual ~InstX8632Cdq() {} |
| 503 }; | 564 }; |
| 504 | 565 |
| 566 // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest> |
| 567 // equals eax. If so, the ZF is set and <desired> is stored in <dest>. |
| 568 // If not, ZF is cleared and <dest> is copied to eax (or subregister). |
| 569 // <dest> can be a register or memory, while <desired> must be a register. |
| 570 // It is the user's responsiblity to mark eax with a FakeDef. |
| 571 class InstX8632Cmpxchg : public InstX8632Lockable { |
| 572 public: |
| 573 static InstX8632Cmpxchg *create(Cfg *Func, Operand *DestOrAddr, Variable *Eax, |
| 574 Variable *Desired, bool Locked) { |
| 575 return new (Func->allocate<InstX8632Cmpxchg>()) |
| 576 InstX8632Cmpxchg(Func, DestOrAddr, Eax, Desired, Locked); |
| 577 } |
| 578 virtual void emit(const Cfg *Func) const; |
| 579 virtual void dump(const Cfg *Func) const; |
| 580 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg); } |
| 581 |
| 582 private: |
| 583 InstX8632Cmpxchg(Cfg *Func, Operand *DestOrAddr, Variable *Eax, |
| 584 Variable *Desired, bool Locked); |
| 585 InstX8632Cmpxchg(const InstX8632Cmpxchg &) LLVM_DELETED_FUNCTION; |
| 586 InstX8632Cmpxchg &operator=(const InstX8632Cmpxchg &) LLVM_DELETED_FUNCTION; |
| 587 virtual ~InstX8632Cmpxchg() {} |
| 588 }; |
| 589 |
| 590 // Cmpxchg8b instruction - cmpxchg8b <m64> will compare if <m64> |
| 591 // equals edx:eax. If so, the ZF is set and ecx:ebx is stored in <m64>. |
| 592 // If not, ZF is cleared and <m64> is copied to edx:eax. |
| 593 // The caller is responsible for inserting FakeDefs to mark edx |
| 594 // and eax as modified. |
| 595 // <m64> must be a memory operand. |
| 596 class InstX8632Cmpxchg8b : public InstX8632Lockable { |
| 597 public: |
| 598 static InstX8632Cmpxchg8b *create(Cfg *Func, OperandX8632 *Dest, |
| 599 Variable *Edx, Variable *Eax, Variable *Ecx, |
| 600 Variable *Ebx, bool Locked) { |
| 601 return new (Func->allocate<InstX8632Cmpxchg8b>()) |
| 602 InstX8632Cmpxchg8b(Func, Dest, Edx, Eax, Ecx, Ebx, Locked); |
| 603 } |
| 604 virtual void emit(const Cfg *Func) const; |
| 605 virtual void dump(const Cfg *Func) const; |
| 606 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmpxchg8b); } |
| 607 |
| 608 private: |
| 609 InstX8632Cmpxchg8b(Cfg *Func, OperandX8632 *Dest, Variable *Edx, |
| 610 Variable *Eax, Variable *Ecx, Variable *Ebx, bool Locked); |
| 611 InstX8632Cmpxchg8b(const InstX8632Cmpxchg8b &) LLVM_DELETED_FUNCTION; |
| 612 InstX8632Cmpxchg8b & |
| 613 operator=(const InstX8632Cmpxchg8b &) LLVM_DELETED_FUNCTION; |
| 614 virtual ~InstX8632Cmpxchg8b() {} |
| 615 }; |
| 616 |
| 505 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} | 617 // Cvt instruction - wrapper for cvtsX2sY where X and Y are in {s,d,i} |
| 506 // as appropriate. s=float, d=double, i=int. X and Y are determined | 618 // as appropriate. s=float, d=double, i=int. X and Y are determined |
| 507 // from dest/src types. Sign and zero extension on the integer | 619 // from dest/src types. Sign and zero extension on the integer |
| 508 // operand needs to be done separately. | 620 // operand needs to be done separately. |
| 509 class InstX8632Cvt : public InstX8632 { | 621 class InstX8632Cvt : public InstX8632 { |
| 510 public: | 622 public: |
| 511 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source) { | 623 static InstX8632Cvt *create(Cfg *Func, Variable *Dest, Operand *Source) { |
| 512 return new (Func->allocate<InstX8632Cvt>()) | 624 return new (Func->allocate<InstX8632Cvt>()) |
| 513 InstX8632Cvt(Func, Dest, Source); | 625 InstX8632Cvt(Func, Dest, Source); |
| 514 } | 626 } |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 virtual ~InstX8632Sqrtss() {} | 966 virtual ~InstX8632Sqrtss() {} |
| 855 }; | 967 }; |
| 856 | 968 |
| 857 // Exchanging Add instruction. Exchanges the first operand (destination | 969 // Exchanging Add instruction. Exchanges the first operand (destination |
| 858 // operand) with the second operand (source operand), then loads the sum | 970 // operand) with the second operand (source operand), then loads the sum |
| 859 // of the two values into the destination operand. The destination may be | 971 // of the two values into the destination operand. The destination may be |
| 860 // a register or memory, while the source must be a register. | 972 // a register or memory, while the source must be a register. |
| 861 // | 973 // |
| 862 // Both the dest and source are updated. The caller should then insert a | 974 // Both the dest and source are updated. The caller should then insert a |
| 863 // FakeDef to reflect the second udpate. | 975 // FakeDef to reflect the second udpate. |
| 864 class InstX8632Xadd : public InstX8632 { | 976 class InstX8632Xadd : public InstX8632Lockable { |
| 865 public: | 977 public: |
| 866 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, | 978 static InstX8632Xadd *create(Cfg *Func, Operand *Dest, Variable *Source, |
| 867 bool Locked) { | 979 bool Locked) { |
| 868 return new (Func->allocate<InstX8632Xadd>()) | 980 return new (Func->allocate<InstX8632Xadd>()) |
| 869 InstX8632Xadd(Func, Dest, Source, Locked); | 981 InstX8632Xadd(Func, Dest, Source, Locked); |
| 870 } | 982 } |
| 871 virtual void emit(const Cfg *Func) const; | 983 virtual void emit(const Cfg *Func) const; |
| 872 virtual void dump(const Cfg *Func) const; | 984 virtual void dump(const Cfg *Func) const; |
| 873 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); } | 985 static bool classof(const Inst *Inst) { return isClassof(Inst, Xadd); } |
| 874 | 986 |
| 875 private: | 987 private: |
| 876 bool Locked; | |
| 877 | |
| 878 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); | 988 InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, bool Locked); |
| 879 InstX8632Xadd(const InstX8632Xadd &) LLVM_DELETED_FUNCTION; | 989 InstX8632Xadd(const InstX8632Xadd &) LLVM_DELETED_FUNCTION; |
| 880 InstX8632Xadd &operator=(const InstX8632Xadd &) LLVM_DELETED_FUNCTION; | 990 InstX8632Xadd &operator=(const InstX8632Xadd &) LLVM_DELETED_FUNCTION; |
| 881 virtual ~InstX8632Xadd() {} | 991 virtual ~InstX8632Xadd() {} |
| 882 }; | 992 }; |
| 883 | 993 |
| 994 // Exchange instruction. Exchanges the first operand (destination |
| 995 // operand) with the second operand (source operand). At least one of |
| 996 // the operands must be a register (and the other can be reg or mem). |
| 997 // Both the Dest and Source are updated. If there is a memory operand, |
| 998 // then the instruction is automatically "locked" without the need for |
| 999 // a lock prefix. |
| 1000 class InstX8632Xchg : public InstX8632 { |
| 1001 public: |
| 1002 static InstX8632Xchg *create(Cfg *Func, Operand *Dest, Variable *Source) { |
| 1003 return new (Func->allocate<InstX8632Xchg>()) |
| 1004 InstX8632Xchg(Func, Dest, Source); |
| 1005 } |
| 1006 virtual void emit(const Cfg *Func) const; |
| 1007 virtual void dump(const Cfg *Func) const; |
| 1008 static bool classof(const Inst *Inst) { return isClassof(Inst, Xchg); } |
| 1009 |
| 1010 private: |
| 1011 InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source); |
| 1012 InstX8632Xchg(const InstX8632Xchg &) LLVM_DELETED_FUNCTION; |
| 1013 InstX8632Xchg &operator=(const InstX8632Xchg &) LLVM_DELETED_FUNCTION; |
| 1014 virtual ~InstX8632Xchg() {} |
| 1015 }; |
| 1016 |
| 884 } // end of namespace Ice | 1017 } // end of namespace Ice |
| 885 | 1018 |
| 886 #endif // SUBZERO_SRC_ICEINSTX8632_H | 1019 #endif // SUBZERO_SRC_ICEINSTX8632_H |
| OLD | NEW |