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 |