| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 // | 4 // |
| 5 // Modified by the Subzero authors. | 5 // Modified by the Subzero authors. |
| 6 // | 6 // |
| 7 //===- subzero/src/assembler_ia32.h - Assembler for x86-32 ----------------===// | 7 //===- subzero/src/assembler_ia32.h - Assembler for x86-32 ----------------===// |
| 8 // | 8 // |
| 9 // The Subzero Code Generator | 9 // The Subzero Code Generator |
| 10 // | 10 // |
| 11 // This file is distributed under the University of Illinois Open Source | 11 // This file is distributed under the University of Illinois Open Source |
| 12 // License. See LICENSE.TXT for details. | 12 // License. See LICENSE.TXT for details. |
| 13 // | 13 // |
| 14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
| 15 // | 15 // |
| 16 // This file implements the Assembler class for x86-32. | 16 // This file implements the Assembler class for x86-32. |
| 17 // | 17 // |
| 18 //===----------------------------------------------------------------------===// | 18 //===----------------------------------------------------------------------===// |
| 19 | 19 |
| 20 #ifndef SUBZERO_SRC_ASSEMBLER_IA32_H_ | 20 #ifndef SUBZERO_SRC_ASSEMBLER_IA32_H_ |
| 21 #define SUBZERO_SRC_ASSEMBLER_IA32_H_ | 21 #define SUBZERO_SRC_ASSEMBLER_IA32_H_ |
| 22 | 22 |
| 23 #include "IceDefs.h" | |
| 24 #include "IceConditionCodesX8632.h" | 23 #include "IceConditionCodesX8632.h" |
| 24 #include "IceOperand.h" |
| 25 #include "IceRegistersX8632.h" | 25 #include "IceRegistersX8632.h" |
| 26 #include "IceTypes.h" | 26 #include "IceTypes.h" |
| 27 #include "IceUtils.h" | 27 #include "IceUtils.h" |
| 28 | 28 |
| 29 #include "assembler.h" | 29 #include "assembler.h" |
| 30 | 30 |
| 31 namespace Ice { | 31 namespace Ice { |
| 32 | 32 |
| 33 class Assembler; | 33 class Assembler; |
| 34 class ConstantRelocatable; | |
| 35 | 34 |
| 36 using RegX8632::GPRRegister; | 35 using RegX8632::GPRRegister; |
| 37 using RegX8632::XmmRegister; | 36 using RegX8632::XmmRegister; |
| 38 using RegX8632::ByteRegister; | 37 using RegX8632::ByteRegister; |
| 39 using RegX8632::X87STRegister; | 38 using RegX8632::X87STRegister; |
| 40 | 39 |
| 41 namespace x86 { | 40 namespace x86 { |
| 42 | 41 |
| 43 const int MAX_NOP_SIZE = 8; | 42 const int MAX_NOP_SIZE = 8; |
| 44 | 43 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 60 | 59 |
| 61 private: | 60 private: |
| 62 DisplacementRelocation(FixupKind Kind, const ConstantRelocatable *Sym) | 61 DisplacementRelocation(FixupKind Kind, const ConstantRelocatable *Sym) |
| 63 : AssemblerFixup(Kind, Sym) {} | 62 : AssemblerFixup(Kind, Sym) {} |
| 64 DisplacementRelocation(const DisplacementRelocation &) = delete; | 63 DisplacementRelocation(const DisplacementRelocation &) = delete; |
| 65 DisplacementRelocation &operator=(const DisplacementRelocation &) = delete; | 64 DisplacementRelocation &operator=(const DisplacementRelocation &) = delete; |
| 66 }; | 65 }; |
| 67 | 66 |
| 68 class Immediate { | 67 class Immediate { |
| 69 public: | 68 public: |
| 70 explicit Immediate(int32_t value) : value_(value) {} | 69 explicit Immediate(int32_t value) : value_(value), fixup_(NULL) {} |
| 71 | 70 |
| 72 Immediate(const Immediate &other) : value_(other.value_) {} | 71 explicit Immediate(const Immediate &other) |
| 72 : value_(other.value_), |
| 73 fixup_(other.fixup_) { |
| 74 } |
| 75 |
| 76 explicit Immediate(AssemblerFixup *fixup) |
| 77 : value_(fixup->value()->getOffset()), fixup_(fixup) { |
| 78 // Use the Offset in the "value" for now. If the symbol is part of |
| 79 // ".bss", then the relocation's symbol will be plain ".bss" and |
| 80 // the value will need to be adjusted further to be sym's |
| 81 // bss offset + Offset. |
| 82 } |
| 73 | 83 |
| 74 int32_t value() const { return value_; } | 84 int32_t value() const { return value_; } |
| 85 AssemblerFixup *fixup() const { return fixup_; } |
| 75 | 86 |
| 76 bool is_int8() const { return Utils::IsInt(8, value_); } | 87 bool is_int8() const { |
| 77 bool is_uint8() const { return Utils::IsUint(8, value_); } | 88 // We currently only allow 32-bit fixups, and they usually have value = 0, |
| 78 bool is_uint16() const { return Utils::IsUint(16, value_); } | 89 // so if fixup_ != NULL, it shouldn't be classified as int8/16. |
| 90 return fixup_ == NULL && Utils::IsInt(8, value_); |
| 91 } |
| 92 bool is_uint8() const { |
| 93 return fixup_ == NULL && Utils::IsUint(8, value_); |
| 94 } |
| 95 bool is_uint16() const { |
| 96 return fixup_ == NULL && Utils::IsUint(16, value_); |
| 97 } |
| 79 | 98 |
| 80 private: | 99 private: |
| 81 const int32_t value_; | 100 const int32_t value_; |
| 101 AssemblerFixup *fixup_; |
| 82 }; | 102 }; |
| 83 | 103 |
| 84 class Operand { | 104 class Operand { |
| 85 public: | 105 public: |
| 86 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; } | 106 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; } |
| 87 | 107 |
| 88 GPRRegister rm() const { | 108 GPRRegister rm() const { |
| 89 return static_cast<GPRRegister>(encoding_at(0) & 7); | 109 return static_cast<GPRRegister>(encoding_at(0) & 7); |
| 90 } | 110 } |
| 91 | 111 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 } | 241 } |
| 222 } | 242 } |
| 223 | 243 |
| 224 Address(const Address &other) : Operand(other) {} | 244 Address(const Address &other) : Operand(other) {} |
| 225 | 245 |
| 226 Address &operator=(const Address &other) { | 246 Address &operator=(const Address &other) { |
| 227 Operand::operator=(other); | 247 Operand::operator=(other); |
| 228 return *this; | 248 return *this; |
| 229 } | 249 } |
| 230 | 250 |
| 231 static Address Absolute(const uintptr_t addr, AssemblerFixup *fixup) { | 251 static Address Absolute(const uintptr_t addr) { |
| 232 Address result; | 252 Address result; |
| 233 result.SetModRM(0, RegX8632::Encoded_Reg_ebp); | 253 result.SetModRM(0, RegX8632::Encoded_Reg_ebp); |
| 234 result.SetDisp32(addr); | 254 result.SetDisp32(addr); |
| 255 return result; |
| 256 } |
| 257 |
| 258 static Address Absolute(AssemblerFixup *fixup) { |
| 259 Address result; |
| 260 result.SetModRM(0, RegX8632::Encoded_Reg_ebp); |
| 261 // Use the Offset in the displacement for now. If the symbol is part of |
| 262 // ".bss", then the relocation's symbol will be plain .bss and the |
| 263 // displacement will need to be adjusted further to be sym's |
| 264 // bss offset + Offset. |
| 265 result.SetDisp32(fixup->value()->getOffset()); |
| 235 result.SetFixup(fixup); | 266 result.SetFixup(fixup); |
| 236 return result; | 267 return result; |
| 237 } | 268 } |
| 238 | 269 |
| 239 static Address ofConstPool(GlobalContext *Ctx, Assembler *Asm, | 270 static Address ofConstPool(GlobalContext *Ctx, Assembler *Asm, |
| 240 const Constant *Imm); | 271 const Constant *Imm); |
| 241 | 272 |
| 242 private: | 273 private: |
| 243 Address() {} // Needed by Address::Absolute. | 274 Address() {} // Needed by Address::Absolute. |
| 244 }; | 275 }; |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 void pushl(GPRRegister reg); | 451 void pushl(GPRRegister reg); |
| 421 | 452 |
| 422 void popl(GPRRegister reg); | 453 void popl(GPRRegister reg); |
| 423 void popl(const Address &address); | 454 void popl(const Address &address); |
| 424 | 455 |
| 425 void pushal(); | 456 void pushal(); |
| 426 void popal(); | 457 void popal(); |
| 427 | 458 |
| 428 void setcc(CondX86::BrCond condition, ByteRegister dst); | 459 void setcc(CondX86::BrCond condition, ByteRegister dst); |
| 429 | 460 |
| 430 void movl(GPRRegister dst, const Immediate &src); | 461 void mov(Type Ty, GPRRegister dst, const Immediate &src); |
| 431 void movl(GPRRegister dst, GPRRegister src); | 462 void mov(Type Ty, GPRRegister dst, GPRRegister src); |
| 432 | 463 |
| 433 void movl(GPRRegister dst, const Address &src); | 464 void mov(Type Ty, GPRRegister dst, const Address &src); |
| 434 void movl(const Address &dst, GPRRegister src); | 465 void mov(Type Ty, const Address &dst, GPRRegister src); |
| 435 void movl(const Address &dst, const Immediate &imm); | 466 void mov(Type Ty, const Address &dst, const Immediate &imm); |
| 436 | 467 |
| 437 void movzxb(GPRRegister dst, ByteRegister src); | 468 void movzxb(GPRRegister dst, ByteRegister src); |
| 438 void movzxb(GPRRegister dst, const Address &src); | 469 void movzxb(GPRRegister dst, const Address &src); |
| 439 void movsxb(GPRRegister dst, ByteRegister src); | 470 void movsxb(GPRRegister dst, ByteRegister src); |
| 440 void movsxb(GPRRegister dst, const Address &src); | 471 void movsxb(GPRRegister dst, const Address &src); |
| 441 | 472 |
| 442 void movb(ByteRegister dst, const Address &src); | |
| 443 void movb(const Address &dst, ByteRegister src); | |
| 444 void movb(const Address &dst, const Immediate &imm); | |
| 445 | |
| 446 void movzxw(GPRRegister dst, GPRRegister src); | 473 void movzxw(GPRRegister dst, GPRRegister src); |
| 447 void movzxw(GPRRegister dst, const Address &src); | 474 void movzxw(GPRRegister dst, const Address &src); |
| 448 void movsxw(GPRRegister dst, GPRRegister src); | 475 void movsxw(GPRRegister dst, GPRRegister src); |
| 449 void movsxw(GPRRegister dst, const Address &src); | 476 void movsxw(GPRRegister dst, const Address &src); |
| 450 void movw(GPRRegister dst, const Address &src); | |
| 451 void movw(const Address &dst, GPRRegister src); | |
| 452 | 477 |
| 453 void lea(Type Ty, GPRRegister dst, const Address &src); | 478 void lea(Type Ty, GPRRegister dst, const Address &src); |
| 454 | 479 |
| 455 void cmov(CondX86::BrCond cond, GPRRegister dst, GPRRegister src); | 480 void cmov(CondX86::BrCond cond, GPRRegister dst, GPRRegister src); |
| 456 | 481 |
| 457 void rep_movsb(); | 482 void rep_movsb(); |
| 458 | 483 |
| 459 void movss(Type Ty, XmmRegister dst, const Address &src); | 484 void movss(Type Ty, XmmRegister dst, const Address &src); |
| 460 void movss(Type Ty, const Address &dst, XmmRegister src); | 485 void movss(Type Ty, const Address &dst, XmmRegister src); |
| 461 void movss(Type Ty, XmmRegister dst, XmmRegister src); | 486 void movss(Type Ty, XmmRegister dst, XmmRegister src); |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 void cmpxchg(Type Ty, const Address &address, GPRRegister reg); | 757 void cmpxchg(Type Ty, const Address &address, GPRRegister reg); |
| 733 void cmpxchg8b(const Address &address); | 758 void cmpxchg8b(const Address &address); |
| 734 void xadd(Type Ty, const Address &address, GPRRegister reg); | 759 void xadd(Type Ty, const Address &address, GPRRegister reg); |
| 735 void xchg(Type Ty, const Address &address, GPRRegister reg); | 760 void xchg(Type Ty, const Address &address, GPRRegister reg); |
| 736 | 761 |
| 737 void LockCmpxchg(Type Ty, const Address &address, GPRRegister reg) { | 762 void LockCmpxchg(Type Ty, const Address &address, GPRRegister reg) { |
| 738 lock(); | 763 lock(); |
| 739 cmpxchg(Ty, address, reg); | 764 cmpxchg(Ty, address, reg); |
| 740 } | 765 } |
| 741 | 766 |
| 767 void EmitSegmentOverride(uint8_t prefix) { EmitUint8(prefix); } |
| 768 |
| 742 intptr_t PreferredLoopAlignment() { return 16; } | 769 intptr_t PreferredLoopAlignment() { return 16; } |
| 743 void Align(intptr_t alignment, intptr_t offset); | 770 void Align(intptr_t alignment, intptr_t offset); |
| 744 void Bind(Label *label); | 771 void Bind(Label *label); |
| 745 | 772 |
| 746 intptr_t CodeSize() const { return buffer_.Size(); } | 773 intptr_t CodeSize() const { return buffer_.Size(); } |
| 747 | 774 |
| 748 void FinalizeInstructions(const MemoryRegion ®ion) { | 775 void FinalizeInstructions(const MemoryRegion ®ion) { |
| 749 buffer_.FinalizeInstructions(region); | 776 buffer_.FinalizeInstructions(region); |
| 750 } | 777 } |
| 751 | 778 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 inline void AssemblerX86::EmitFixup(AssemblerFixup *fixup) { | 836 inline void AssemblerX86::EmitFixup(AssemblerFixup *fixup) { |
| 810 buffer_.EmitFixup(fixup); | 837 buffer_.EmitFixup(fixup); |
| 811 } | 838 } |
| 812 | 839 |
| 813 inline void AssemblerX86::EmitOperandSizeOverride() { EmitUint8(0x66); } | 840 inline void AssemblerX86::EmitOperandSizeOverride() { EmitUint8(0x66); } |
| 814 | 841 |
| 815 } // end of namespace x86 | 842 } // end of namespace x86 |
| 816 } // end of namespace Ice | 843 } // end of namespace Ice |
| 817 | 844 |
| 818 #endif // SUBZERO_SRC_ASSEMBLER_IA32_H_ | 845 #endif // SUBZERO_SRC_ASSEMBLER_IA32_H_ |
| OLD | NEW |