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