Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceTargetLoweringX8632Traits.h - x86-32 traits -*- C++ -*-=// | 1 //===- subzero/src/IceTargetLoweringX8664Traits.h - x86-64 traits -*- 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 /// \file | 10 /// \file |
| 11 /// This file declares the X8632 Target Lowering Traits. | 11 /// This file declares the X8664 Target Lowering Traits. |
| 12 /// | 12 /// |
| 13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
| 14 | 14 |
| 15 #ifndef SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H | 15 #ifndef SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H |
| 16 #define SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H | 16 #define SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H |
| 17 | 17 |
| 18 #include "IceAssembler.h" | 18 #include "IceAssembler.h" |
| 19 #include "IceConditionCodesX8632.h" | 19 #include "IceConditionCodesX8664.h" |
| 20 #include "IceDefs.h" | 20 #include "IceDefs.h" |
| 21 #include "IceInst.h" | 21 #include "IceInst.h" |
| 22 #include "IceInstX8632.def" | 22 #include "IceInstX8664.def" |
| 23 #include "IceOperand.h" | 23 #include "IceOperand.h" |
| 24 #include "IceRegistersX8632.h" | 24 #include "IceRegistersX8664.h" |
| 25 #include "IceTargetLoweringX8632.def" | 25 #include "IceTargetLoweringX8664.def" |
| 26 #include "IceTargetLowering.h" | 26 #include "IceTargetLowering.h" |
| 27 | 27 |
| 28 namespace Ice { | 28 namespace Ice { |
| 29 | 29 |
| 30 class TargetX8632; | 30 class TargetX8664; |
| 31 | 31 |
| 32 namespace X8632 { | 32 namespace X8664 { |
| 33 class AssemblerX8632; | 33 class AssemblerX8664; |
| 34 } // end of namespace X8632 | 34 } // end of namespace X8664 |
| 35 | 35 |
| 36 namespace X86Internal { | 36 namespace X86Internal { |
| 37 | 37 |
| 38 template <class Machine> struct Insts; | 38 template <class Machine> struct Insts; |
| 39 template <class Machine> struct MachineTraits; | 39 template <class Machine> struct MachineTraits; |
| 40 template <class Machine> class TargetX86Base; | |
| 41 | 40 |
| 42 template <> struct MachineTraits<TargetX8632> { | 41 template <> struct MachineTraits<TargetX8664> { |
| 43 //---------------------------------------------------------------------------- | 42 //---------------------------------------------------------------------------- |
| 44 // ______ ______ __ __ | 43 // ______ ______ __ __ |
| 45 // /\ __ \/\ ___\/\ "-./ \ | 44 // /\ __ \/\ ___\/\ "-./ \ |
| 46 // \ \ __ \ \___ \ \ \-./\ \ | 45 // \ \ __ \ \___ \ \ \-./\ \ |
| 47 // \ \_\ \_\/\_____\ \_\ \ \_\ | 46 // \ \_\ \_\/\_____\ \_\ \ \_\ |
| 48 // \/_/\/_/\/_____/\/_/ \/_/ | 47 // \/_/\/_/\/_____/\/_/ \/_/ |
| 49 // | 48 // |
| 50 //---------------------------------------------------------------------------- | 49 //---------------------------------------------------------------------------- |
| 50 static constexpr bool Is64Bit = true; | |
| 51 static constexpr bool HasPopa = false; | |
| 52 static constexpr bool HasPusha = false; | |
| 53 static constexpr bool UsesX87 = false; | |
| 54 static constexpr ::Ice::RegX8664::GPRRegister Last8BitGPR = | |
| 55 ::Ice::RegX8664::GPRRegister::Encoded_Reg_r15d; | |
| 56 | |
| 51 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; | 57 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; |
| 52 | 58 |
| 53 using GPRRegister = ::Ice::RegX8632::GPRRegister; | 59 using GPRRegister = ::Ice::RegX8664::GPRRegister; |
| 54 using XmmRegister = ::Ice::RegX8632::XmmRegister; | 60 using XmmRegister = ::Ice::RegX8664::XmmRegister; |
| 55 using ByteRegister = ::Ice::RegX8632::ByteRegister; | 61 using ByteRegister = ::Ice::RegX8664::ByteRegister; |
| 56 using X87STRegister = ::Ice::RegX8632::X87STRegister; | |
| 57 | 62 |
| 58 using Cond = ::Ice::CondX86; | 63 using Cond = ::Ice::CondX8664; |
| 59 | 64 |
| 60 using RegisterSet = ::Ice::RegX8632; | 65 using RegisterSet = ::Ice::RegX8664; |
| 61 static const GPRRegister Encoded_Reg_Accumulator = RegX8632::Encoded_Reg_eax; | 66 static const GPRRegister Encoded_Reg_Accumulator = RegX8664::Encoded_Reg_eax; |
| 62 static const GPRRegister Encoded_Reg_Counter = RegX8632::Encoded_Reg_ecx; | 67 static const GPRRegister Encoded_Reg_Counter = RegX8664::Encoded_Reg_ecx; |
| 63 static const FixupKind PcRelFixup = llvm::ELF::R_386_PC32; | 68 static const FixupKind PcRelFixup = llvm::ELF::R_386_PC32; // TODO(jpp): ??? |
| 64 | 69 |
| 65 class Operand { | 70 class Operand { |
| 66 public: | 71 public: |
| 72 enum RexBits { | |
| 73 RexNone = 0x00, | |
| 74 RexBase = 0x40, | |
| 75 RexW = RexBase | (1 << 3), | |
| 76 RexR = RexBase | (1 << 2), | |
| 77 RexX = RexBase | (1 << 1), | |
| 78 RexB = RexBase | (1 << 0), | |
| 79 }; | |
| 80 | |
| 67 Operand(const Operand &other) | 81 Operand(const Operand &other) |
| 68 : fixup_(other.fixup_), length_(other.length_) { | 82 : fixup_(other.fixup_), rex_(other.rex_), length_(other.length_) { |
| 69 memmove(&encoding_[0], &other.encoding_[0], other.length_); | 83 memmove(&encoding_[0], &other.encoding_[0], other.length_); |
| 70 } | 84 } |
| 71 | 85 |
| 72 Operand &operator=(const Operand &other) { | 86 Operand &operator=(const Operand &other) { |
| 73 length_ = other.length_; | 87 length_ = other.length_; |
| 74 fixup_ = other.fixup_; | 88 fixup_ = other.fixup_; |
| 89 rex_ = other.rex_; | |
| 75 memmove(&encoding_[0], &other.encoding_[0], other.length_); | 90 memmove(&encoding_[0], &other.encoding_[0], other.length_); |
| 76 return *this; | 91 return *this; |
| 77 } | 92 } |
| 78 | 93 |
| 79 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; } | 94 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; } |
| 80 | 95 |
| 96 uint8_t rexX() const { return (rex_ & RexX) != RexX ? RexNone : RexX; } | |
| 97 uint8_t rexB() const { return (rex_ & RexB) != RexB ? RexNone : RexB; } | |
| 98 | |
| 81 GPRRegister rm() const { | 99 GPRRegister rm() const { |
| 82 return static_cast<GPRRegister>(encoding_at(0) & 7); | 100 return static_cast<GPRRegister>((rexB() != 0 ? 0x08 : 0) | |
| 101 (encoding_at(0) & 7)); | |
| 83 } | 102 } |
| 84 | 103 |
| 85 ScaleFactor scale() const { | 104 ScaleFactor scale() const { |
| 86 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3); | 105 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3); |
| 87 } | 106 } |
| 88 | 107 |
| 89 GPRRegister index() const { | 108 GPRRegister index() const { |
| 90 return static_cast<GPRRegister>((encoding_at(1) >> 3) & 7); | 109 return static_cast<GPRRegister>((rexX() != 0 ? 0x08 : 0) | |
| 110 ((encoding_at(1) >> 3) & 7)); | |
| 91 } | 111 } |
| 92 | 112 |
| 93 GPRRegister base() const { | 113 GPRRegister base() const { |
| 94 return static_cast<GPRRegister>(encoding_at(1) & 7); | 114 return static_cast<GPRRegister>((rexB() != 0 ? 0x08 : 0) | |
| 115 (encoding_at(1) & 7)); | |
| 95 } | 116 } |
| 96 | 117 |
| 97 int8_t disp8() const { | 118 int8_t disp8() const { |
| 98 assert(length_ >= 2); | 119 assert(length_ >= 2); |
| 99 return static_cast<int8_t>(encoding_[length_ - 1]); | 120 return static_cast<int8_t>(encoding_[length_ - 1]); |
| 100 } | 121 } |
| 101 | 122 |
| 102 int32_t disp32() const { | 123 int32_t disp32() const { |
| 103 assert(length_ >= 5); | 124 assert(length_ >= 5); |
| 104 return bit_copy<int32_t>(encoding_[length_ - 4]); | 125 return bit_copy<int32_t>(encoding_[length_ - 4]); |
| 105 } | 126 } |
| 106 | 127 |
| 107 AssemblerFixup *fixup() const { return fixup_; } | 128 AssemblerFixup *fixup() const { return fixup_; } |
| 108 | 129 |
| 109 protected: | 130 protected: |
| 110 Operand() : fixup_(nullptr), length_(0) {} // Needed by subclass Address. | 131 Operand() : fixup_(nullptr), length_(0) {} // Needed by subclass Address. |
| 111 | 132 |
| 112 void SetModRM(int mod, GPRRegister rm) { | 133 void SetModRM(int mod, GPRRegister rm) { |
| 113 assert((mod & ~3) == 0); | 134 assert((mod & ~3) == 0); |
| 114 encoding_[0] = (mod << 6) | rm; | 135 encoding_[0] = (mod << 6) | (rm & 0x07); |
| 136 rex_ = (rm & 0x08) ? RexB : RexNone; | |
| 115 length_ = 1; | 137 length_ = 1; |
| 116 } | 138 } |
| 117 | 139 |
| 118 void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) { | 140 void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) { |
| 119 assert(length_ == 1); | 141 assert(length_ == 1); |
| 120 assert((scale & ~3) == 0); | 142 assert((scale & ~3) == 0); |
| 121 encoding_[1] = (scale << 6) | (index << 3) | base; | 143 encoding_[1] = (scale << 6) | ((index & 0x07) << 3) | (base & 0x07); |
| 144 rex_ = | |
| 145 ((base & 0x08) ? RexB : RexNone) | ((index & 0x08) ? RexX : RexNone); | |
| 122 length_ = 2; | 146 length_ = 2; |
| 123 } | 147 } |
| 124 | 148 |
| 125 void SetDisp8(int8_t disp) { | 149 void SetDisp8(int8_t disp) { |
| 126 assert(length_ == 1 || length_ == 2); | 150 assert(length_ == 1 || length_ == 2); |
| 127 encoding_[length_++] = static_cast<uint8_t>(disp); | 151 encoding_[length_++] = static_cast<uint8_t>(disp); |
| 128 } | 152 } |
| 129 | 153 |
| 130 void SetDisp32(int32_t disp) { | 154 void SetDisp32(int32_t disp) { |
| 131 assert(length_ == 1 || length_ == 2); | 155 assert(length_ == 1 || length_ == 2); |
| 132 intptr_t disp_size = sizeof(disp); | 156 intptr_t disp_size = sizeof(disp); |
| 133 memmove(&encoding_[length_], &disp, disp_size); | 157 memmove(&encoding_[length_], &disp, disp_size); |
| 134 length_ += disp_size; | 158 length_ += disp_size; |
| 135 } | 159 } |
| 136 | 160 |
| 137 void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; } | 161 void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; } |
| 138 | 162 |
| 139 private: | 163 private: |
| 140 AssemblerFixup *fixup_; | 164 AssemblerFixup *fixup_; |
| 165 uint8_t rex_ = 0; | |
| 141 uint8_t encoding_[6]; | 166 uint8_t encoding_[6]; |
| 142 uint8_t length_; | 167 uint8_t length_; |
| 143 | 168 |
| 144 explicit Operand(GPRRegister reg) : fixup_(nullptr) { SetModRM(3, reg); } | 169 explicit Operand(GPRRegister reg) : fixup_(nullptr) { SetModRM(3, reg); } |
| 145 | 170 |
| 146 /// Get the operand encoding byte at the given index. | 171 /// Get the operand encoding byte at the given index. |
| 147 uint8_t encoding_at(intptr_t index) const { | 172 uint8_t encoding_at(intptr_t index) const { |
| 148 assert(index >= 0 && index < length_); | 173 assert(index >= 0 && index < length_); |
| 149 return encoding_[index]; | 174 return encoding_[index]; |
| 150 } | 175 } |
| 151 | 176 |
| 152 /// Returns whether or not this operand is really the given register in | 177 /// Returns whether or not this operand is really the given register in |
| 153 /// disguise. Used from the assembler to generate better encodings. | 178 /// disguise. Used from the assembler to generate better encodings. |
| 154 bool IsRegister(GPRRegister reg) const { | 179 bool IsRegister(GPRRegister reg) const { |
| 155 return ((encoding_[0] & 0xF8) == | 180 return ((encoding_[0] & 0xF8) == |
| 156 0xC0) // Addressing mode is register only. | 181 0xC0) // Addressing mode is register only. |
| 157 && | 182 && |
| 158 ((encoding_[0] & 0x07) == reg); // Register codes match. | 183 (rm() == reg); // Register codes match. |
| 159 } | 184 } |
| 160 | 185 |
| 161 template <class> friend class AssemblerX86Base; | 186 template <class> friend class AssemblerX86Base; |
| 162 }; | 187 }; |
| 163 | 188 |
| 164 class Address : public Operand { | 189 class Address : public Operand { |
| 165 Address() = delete; | 190 Address() = delete; |
| 166 | 191 |
| 167 public: | 192 public: |
| 168 Address(const Address &other) : Operand(other) {} | 193 Address(const Address &other) : Operand(other) {} |
| 169 | 194 |
| 170 Address &operator=(const Address &other) { | 195 Address &operator=(const Address &other) { |
| 171 Operand::operator=(other); | 196 Operand::operator=(other); |
| 172 return *this; | 197 return *this; |
| 173 } | 198 } |
| 174 | 199 |
| 175 Address(GPRRegister base, int32_t disp) { | 200 Address(GPRRegister base, int32_t disp) { |
| 176 if (disp == 0 && base != RegX8632::Encoded_Reg_ebp) { | 201 if (disp == 0 && (base & 7) != RegX8664::Encoded_Reg_ebp) { |
| 177 SetModRM(0, base); | 202 SetModRM(0, base); |
| 178 if (base == RegX8632::Encoded_Reg_esp) | 203 if ((base & 7) == RegX8664::Encoded_Reg_esp) |
| 179 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base); | 204 SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, base); |
| 180 } else if (Utils::IsInt(8, disp)) { | 205 } else if (Utils::IsInt(8, disp)) { |
| 181 SetModRM(1, base); | 206 SetModRM(1, base); |
| 182 if (base == RegX8632::Encoded_Reg_esp) | 207 if ((base & 7) == RegX8664::Encoded_Reg_esp) |
| 183 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base); | 208 SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, base); |
| 184 SetDisp8(disp); | 209 SetDisp8(disp); |
| 185 } else { | 210 } else { |
| 186 SetModRM(2, base); | 211 SetModRM(2, base); |
| 187 if (base == RegX8632::Encoded_Reg_esp) | 212 if ((base & 7) == RegX8664::Encoded_Reg_esp) |
| 188 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base); | 213 SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, base); |
| 189 SetDisp32(disp); | 214 SetDisp32(disp); |
| 190 } | 215 } |
| 191 } | 216 } |
| 192 | 217 |
| 193 Address(GPRRegister index, ScaleFactor scale, int32_t disp) { | 218 Address(GPRRegister index, ScaleFactor scale, int32_t disp) { |
| 194 assert(index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode. | 219 assert(index != RegX8664::Encoded_Reg_esp); // Illegal addressing mode. |
| 195 SetModRM(0, RegX8632::Encoded_Reg_esp); | 220 SetModRM(0, RegX8664::Encoded_Reg_esp); |
| 196 SetSIB(scale, index, RegX8632::Encoded_Reg_ebp); | 221 SetSIB(scale, index, RegX8664::Encoded_Reg_ebp); |
| 197 SetDisp32(disp); | 222 SetDisp32(disp); |
| 198 } | 223 } |
| 199 | 224 |
| 200 Address(GPRRegister base, GPRRegister index, ScaleFactor scale, | 225 Address(GPRRegister base, GPRRegister index, ScaleFactor scale, |
| 201 int32_t disp) { | 226 int32_t disp) { |
| 202 assert(index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode. | 227 assert(index != RegX8664::Encoded_Reg_esp); // Illegal addressing mode. |
| 203 if (disp == 0 && base != RegX8632::Encoded_Reg_ebp) { | 228 if (disp == 0 && (base & 7) != RegX8664::Encoded_Reg_ebp) { |
| 204 SetModRM(0, RegX8632::Encoded_Reg_esp); | 229 SetModRM(0, RegX8664::Encoded_Reg_esp); |
| 205 SetSIB(scale, index, base); | 230 SetSIB(scale, index, base); |
| 206 } else if (Utils::IsInt(8, disp)) { | 231 } else if (Utils::IsInt(8, disp)) { |
| 207 SetModRM(1, RegX8632::Encoded_Reg_esp); | 232 SetModRM(1, RegX8664::Encoded_Reg_esp); |
| 208 SetSIB(scale, index, base); | 233 SetSIB(scale, index, base); |
| 209 SetDisp8(disp); | 234 SetDisp8(disp); |
| 210 } else { | 235 } else { |
| 211 SetModRM(2, RegX8632::Encoded_Reg_esp); | 236 SetModRM(2, RegX8664::Encoded_Reg_esp); |
| 212 SetSIB(scale, index, base); | 237 SetSIB(scale, index, base); |
| 213 SetDisp32(disp); | 238 SetDisp32(disp); |
| 214 } | 239 } |
| 215 } | 240 } |
| 216 | 241 |
| 217 /// AbsoluteTag is a special tag used by clients to create an absolute | 242 // PcRelTag is a special tag for requesting rip-relative addressing in |
| 218 /// Address. | 243 // X86-64. |
| 244 // TODO(jpp): this is bogus. remove. | |
| 219 enum AbsoluteTag { ABSOLUTE }; | 245 enum AbsoluteTag { ABSOLUTE }; |
| 220 | 246 |
| 221 Address(AbsoluteTag, const uintptr_t Addr) { | 247 Address(AbsoluteTag, const uintptr_t Addr) { |
| 222 SetModRM(0, RegX8632::Encoded_Reg_ebp); | 248 SetModRM(0, RegX8664::Encoded_Reg_ebp); |
| 223 SetDisp32(Addr); | 249 SetDisp32(Addr); |
| 224 } | 250 } |
| 225 | 251 |
| 226 // TODO(jpp): remove this. | 252 // TODO(jpp): remove this. |
| 227 static Address Absolute(const uintptr_t Addr) { | 253 static Address Absolute(const uintptr_t Addr) { |
| 228 return Address(ABSOLUTE, Addr); | 254 return Address(ABSOLUTE, Addr); |
| 229 } | 255 } |
| 230 | 256 |
| 231 Address(AbsoluteTag, RelocOffsetT Offset, AssemblerFixup *Fixup) { | 257 Address(AbsoluteTag, RelocOffsetT Offset, AssemblerFixup *Fixup) { |
| 232 SetModRM(0, RegX8632::Encoded_Reg_ebp); | 258 SetModRM(0, RegX8664::Encoded_Reg_ebp); |
| 233 // Use the Offset in the displacement for now. If we decide to process | 259 // Use the Offset in the displacement for now. If we decide to process |
| 234 // fixups later, we'll need to patch up the emitted displacement. | 260 // fixups later, we'll need to patch up the emitted displacement. |
| 235 SetDisp32(Offset); | 261 SetDisp32(Offset); |
| 236 SetFixup(Fixup); | 262 SetFixup(Fixup); |
| 237 } | 263 } |
| 238 | 264 |
| 239 // TODO(jpp): remove this. | 265 // TODO(jpp): remove this. |
| 240 static Address Absolute(RelocOffsetT Offset, AssemblerFixup *Fixup) { | 266 static Address Absolute(RelocOffsetT Offset, AssemblerFixup *Fixup) { |
| 241 return Address(ABSOLUTE, Offset, Fixup); | 267 return Address(ABSOLUTE, Offset, Fixup); |
| 242 } | 268 } |
| 243 | 269 |
| 244 static Address ofConstPool(Assembler *Asm, const Constant *Imm) { | 270 static Address ofConstPool(Assembler *Asm, const Constant *Imm) { |
| 271 // TODO(jpp): ??? | |
| 245 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Imm); | 272 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Imm); |
| 246 const RelocOffsetT Offset = 0; | 273 const RelocOffsetT Offset = 0; |
| 247 return Address(ABSOLUTE, Offset, Fixup); | 274 return Address(ABSOLUTE, Offset, Fixup); |
| 248 } | 275 } |
| 249 }; | 276 }; |
| 250 | 277 |
| 278 #if 0 | |
|
Jim Stichnoth
2015/07/26 15:31:11
Why keep the "#if 0" commented-out code around?
John
2015/07/27 20:35:58
Because it would make my life a little bit easier
| |
| 279 // The Traits for lowering/insts for x86-64 are very similar to the ones for x 86-32, so these are kept here. | |
|
Jim Stichnoth
2015/07/26 15:31:11
80-col
John
2015/07/27 20:35:58
Done.
| |
| 251 //---------------------------------------------------------------------------- | 280 //---------------------------------------------------------------------------- |
| 252 // __ ______ __ __ ______ ______ __ __ __ ______ | 281 // __ ______ __ __ ______ ______ __ __ __ ______ |
| 253 // /\ \ /\ __ \/\ \ _ \ \/\ ___\/\ == \/\ \/\ "-.\ \/\ ___\ | 282 // /\ \ /\ __ \/\ \ _ \ \/\ ___\/\ == \/\ \/\ "-.\ \/\ ___\ |
| 254 // \ \ \___\ \ \/\ \ \ \/ ".\ \ \ __\\ \ __<\ \ \ \ \-. \ \ \__ \ | 283 // \ \ \___\ \ \/\ \ \ \/ ".\ \ \ __\\ \ __<\ \ \ \ \-. \ \ \__ \ |
| 255 // \ \_____\ \_____\ \__/".~\_\ \_____\ \_\ \_\ \_\ \_\\"\_\ \_____\ | 284 // \ \_____\ \_____\ \__/".~\_\ \_____\ \_\ \_\ \_\ \_\\"\_\ \_____\ |
| 256 // \/_____/\/_____/\/_/ \/_/\/_____/\/_/ /_/\/_/\/_/ \/_/\/_____/ | 285 // \/_____/\/_____/\/_/ \/_/\/_____/\/_/ /_/\/_/\/_/ \/_/\/_____/ |
| 257 // | 286 // |
| 258 //---------------------------------------------------------------------------- | 287 //---------------------------------------------------------------------------- |
| 259 enum InstructionSet { | 288 enum InstructionSet { |
| 260 Begin, | 289 Begin, |
| 261 // SSE2 is the PNaCl baseline instruction set. | 290 // SSE2 is the PNaCl baseline instruction set. |
| 262 SSE2 = Begin, | 291 SSE2 = Begin, |
| 263 SSE4_1, | 292 SSE4_1, |
| 264 End | 293 End |
| 265 }; | 294 }; |
| 266 | 295 |
| 267 static const char *TargetName; | 296 static const char *TargetName; |
| 268 | 297 |
| 269 static IceString getRegName(SizeT RegNum, Type Ty) { | 298 static IceString getRegName(SizeT RegNum, Type Ty) { |
| 270 assert(RegNum < RegisterSet::Reg_NUM); | 299 assert(RegNum < RegisterSet::Reg_NUM); |
| 271 static const char *RegNames8[] = { | 300 static const char *RegNames8[] = { |
| 272 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ | 301 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
| 273 frameptr, isI8, isInt, isFP) \ | 302 frameptr, isI8, isInt, isFP) \ |
| 274 name8, | 303 name8, |
| 275 REGX8632_TABLE | 304 REGX8664_TABLE |
| 276 #undef X | 305 #undef X |
| 277 }; | 306 }; |
| 278 | 307 |
| 279 static const char *RegNames16[] = { | 308 static const char *RegNames16[] = { |
| 280 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ | 309 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
| 281 frameptr, isI8, isInt, isFP) \ | 310 frameptr, isI8, isInt, isFP) \ |
| 282 name16, | 311 name16, |
| 283 REGX8632_TABLE | 312 REGX8664_TABLE |
| 284 #undef X | 313 #undef X |
| 285 }; | 314 }; |
| 286 | 315 |
| 287 static const char *RegNames[] = { | 316 static const char *RegNames[] = { |
| 288 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ | 317 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
| 289 frameptr, isI8, isInt, isFP) \ | 318 frameptr, isI8, isInt, isFP) \ |
| 290 name, | 319 name, |
| 291 REGX8632_TABLE | 320 REGX8664_TABLE |
| 292 #undef X | 321 #undef X |
| 293 }; | 322 }; |
| 294 | 323 |
| 295 switch (Ty) { | 324 switch (Ty) { |
| 296 case IceType_i1: | 325 case IceType_i1: |
| 297 case IceType_i8: | 326 case IceType_i8: |
| 298 return RegNames8[RegNum]; | 327 return RegNames8[RegNum]; |
| 299 case IceType_i16: | 328 case IceType_i16: |
| 300 return RegNames16[RegNum]; | 329 return RegNames16[RegNum]; |
| 301 default: | 330 default: |
| 302 return RegNames[RegNum]; | 331 return RegNames[RegNum]; |
| 303 } | 332 } |
| 304 } | 333 } |
| 305 | 334 |
| 306 static void initRegisterSet(llvm::SmallBitVector *IntegerRegisters, | 335 static void initRegisterSet(llvm::SmallBitVector *IntegerRegisters, |
| 307 llvm::SmallBitVector *IntegerRegistersI8, | 336 llvm::SmallBitVector *IntegerRegistersI8, |
| 308 llvm::SmallBitVector *FloatRegisters, | 337 llvm::SmallBitVector *FloatRegisters, |
| 309 llvm::SmallBitVector *VectorRegisters, | 338 llvm::SmallBitVector *VectorRegisters, |
| 310 llvm::SmallBitVector *ScratchRegs) { | 339 llvm::SmallBitVector *ScratchRegs) { |
| 311 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ | 340 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
| 312 frameptr, isI8, isInt, isFP) \ | 341 frameptr, isI8, isInt, isFP) \ |
| 313 (*IntegerRegisters)[RegisterSet::val] = isInt; \ | 342 (*IntegerRegisters)[RegisterSet::val] = isInt; \ |
| 314 (*IntegerRegistersI8)[RegisterSet::val] = isI8; \ | 343 (*IntegerRegistersI8)[RegisterSet::val] = isI8; \ |
| 315 (*FloatRegisters)[RegisterSet::val] = isFP; \ | 344 (*FloatRegisters)[RegisterSet::val] = isFP; \ |
| 316 (*VectorRegisters)[RegisterSet::val] = isFP; \ | 345 (*VectorRegisters)[RegisterSet::val] = isFP; \ |
| 317 (*ScratchRegs)[RegisterSet::val] = scratch; | 346 (*ScratchRegs)[RegisterSet::val] = scratch; |
| 318 REGX8632_TABLE; | 347 REGX8664_TABLE; |
| 319 #undef X | 348 #undef X |
| 320 } | 349 } |
| 321 | 350 |
| 322 static llvm::SmallBitVector | 351 static llvm::SmallBitVector |
| 323 getRegisterSet(TargetLowering::RegSetMask Include, | 352 getRegisterSet(TargetLowering::RegSetMask Include, |
| 324 TargetLowering::RegSetMask Exclude) { | 353 TargetLowering::RegSetMask Exclude) { |
| 325 llvm::SmallBitVector Registers(RegisterSet::Reg_NUM); | 354 llvm::SmallBitVector Registers(RegisterSet::Reg_NUM); |
| 326 | 355 |
| 327 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ | 356 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
| 328 frameptr, isI8, isInt, isFP) \ | 357 frameptr, isI8, isInt, isFP) \ |
| 329 if (scratch && (Include & ::Ice::TargetLowering::RegSet_CallerSave)) \ | 358 if (scratch && (Include & ::Ice::TargetLowering::RegSet_CallerSave)) \ |
| 330 Registers[RegisterSet::val] = true; \ | 359 Registers[RegisterSet::val] = true; \ |
| 331 if (preserved && (Include & ::Ice::TargetLowering::RegSet_CalleeSave)) \ | 360 if (preserved && (Include & ::Ice::TargetLowering::RegSet_CalleeSave)) \ |
| 332 Registers[RegisterSet::val] = true; \ | 361 Registers[RegisterSet::val] = true; \ |
| 333 if (stackptr && (Include & ::Ice::TargetLowering::RegSet_StackPointer)) \ | 362 if (stackptr && (Include & ::Ice::TargetLowering::RegSet_StackPointer)) \ |
| 334 Registers[RegisterSet::val] = true; \ | 363 Registers[RegisterSet::val] = true; \ |
| 335 if (frameptr && (Include & ::Ice::TargetLowering::RegSet_FramePointer)) \ | 364 if (frameptr && (Include & ::Ice::TargetLowering::RegSet_FramePointer)) \ |
| 336 Registers[RegisterSet::val] = true; \ | 365 Registers[RegisterSet::val] = true; \ |
| 337 if (scratch && (Exclude & ::Ice::TargetLowering::RegSet_CallerSave)) \ | 366 if (scratch && (Exclude & ::Ice::TargetLowering::RegSet_CallerSave)) \ |
| 338 Registers[RegisterSet::val] = false; \ | 367 Registers[RegisterSet::val] = false; \ |
| 339 if (preserved && (Exclude & ::Ice::TargetLowering::RegSet_CalleeSave)) \ | 368 if (preserved && (Exclude & ::Ice::TargetLowering::RegSet_CalleeSave)) \ |
| 340 Registers[RegisterSet::val] = false; \ | 369 Registers[RegisterSet::val] = false; \ |
| 341 if (stackptr && (Exclude & ::Ice::TargetLowering::RegSet_StackPointer)) \ | 370 if (stackptr && (Exclude & ::Ice::TargetLowering::RegSet_StackPointer)) \ |
| 342 Registers[RegisterSet::val] = false; \ | 371 Registers[RegisterSet::val] = false; \ |
| 343 if (frameptr && (Exclude & ::Ice::TargetLowering::RegSet_FramePointer)) \ | 372 if (frameptr && (Exclude & ::Ice::TargetLowering::RegSet_FramePointer)) \ |
| 344 Registers[RegisterSet::val] = false; | 373 Registers[RegisterSet::val] = false; |
| 345 | 374 |
| 346 REGX8632_TABLE | 375 REGX8664_TABLE |
| 347 | 376 |
| 348 #undef X | 377 #undef X |
| 349 | 378 |
| 350 return Registers; | 379 return Registers; |
| 351 } | 380 } |
| 352 | 381 |
| 353 static void | 382 static void |
| 354 makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func, | 383 makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func, |
| 355 llvm::SmallVectorImpl<int32_t> &Permutation, | 384 llvm::SmallVectorImpl<int32_t> &Permutation, |
| 356 const llvm::SmallBitVector &ExcludeRegisters) { | 385 const llvm::SmallBitVector &ExcludeRegisters) { |
| 357 // TODO(stichnot): Declaring Permutation this way loses type/size | 386 // TODO(stichnot): Declaring Permutation this way loses type/size |
| 358 // information. Fix this in conjunction with the caller-side TODO. | 387 // information. Fix this in conjunction with the caller-side TODO. |
| 359 assert(Permutation.size() >= RegisterSet::Reg_NUM); | 388 assert(Permutation.size() >= RegisterSet::Reg_NUM); |
| 360 // Expected upper bound on the number of registers in a single equivalence | 389 // Expected upper bound on the number of registers in a single equivalence |
| 361 // class. For x86-32, this would comprise the 8 XMM registers. This is for | 390 // class. For x86-64, this would comprise the 8 XMM registers. This is for |
| 362 // performance, not correctness. | 391 // performance, not correctness. |
| 363 static const unsigned MaxEquivalenceClassSize = 8; | 392 static const unsigned MaxEquivalenceClassSize = 8; |
| 364 typedef llvm::SmallVector<int32_t, MaxEquivalenceClassSize> RegisterList; | 393 typedef llvm::SmallVector<int32_t, MaxEquivalenceClassSize> RegisterList; |
| 365 typedef std::map<uint32_t, RegisterList> EquivalenceClassMap; | 394 typedef std::map<uint32_t, RegisterList> EquivalenceClassMap; |
| 366 EquivalenceClassMap EquivalenceClasses; | 395 EquivalenceClassMap EquivalenceClasses; |
| 367 SizeT NumShuffled = 0, NumPreserved = 0; | 396 SizeT NumShuffled = 0, NumPreserved = 0; |
| 368 | 397 |
| 369 // Build up the equivalence classes of registers by looking at the register | 398 // Build up the equivalence classes of registers by looking at the register |
| 370 // properties as well as whether the registers should be explicitly excluded | 399 // properties as well as whether the registers should be explicitly excluded |
| 371 // from shuffling. | 400 // from shuffling. |
| 372 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ | 401 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
| 373 frameptr, isI8, isInt, isFP) \ | 402 frameptr, isI8, isInt, isFP) \ |
| 374 if (ExcludeRegisters[RegisterSet::val]) { \ | 403 if (ExcludeRegisters[RegisterSet::val]) { \ |
| 375 /* val stays the same in the resulting permutation. */ \ | 404 /* val stays the same in the resulting permutation. */ \ |
| 376 Permutation[RegisterSet::val] = RegisterSet::val; \ | 405 Permutation[RegisterSet::val] = RegisterSet::val; \ |
| 377 ++NumPreserved; \ | 406 ++NumPreserved; \ |
| 378 } else { \ | 407 } else { \ |
| 379 const uint32_t Index = (scratch << 0) | (preserved << 1) | (isI8 << 2) | \ | 408 const uint32_t Index = (scratch << 0) | (preserved << 1) | (isI8 << 2) | \ |
| 380 (isInt << 3) | (isFP << 4); \ | 409 (isInt << 3) | (isFP << 4); \ |
| 381 /* val is assigned to an equivalence class based on its properties. */ \ | 410 /* val is assigned to an equivalence class based on its properties. */ \ |
| 382 EquivalenceClasses[Index].push_back(RegisterSet::val); \ | 411 EquivalenceClasses[Index].push_back(RegisterSet::val); \ |
| 383 } | 412 } |
| 384 REGX8632_TABLE | 413 REGX8664_TABLE |
| 385 #undef X | 414 #undef X |
| 386 | 415 |
| 387 RandomNumberGeneratorWrapper RNG(Ctx->getRNG()); | 416 RandomNumberGeneratorWrapper RNG(Ctx->getRNG()); |
| 388 | 417 |
| 389 // Shuffle the resulting equivalence classes. | 418 // Shuffle the resulting equivalence classes. |
| 390 for (auto I : EquivalenceClasses) { | 419 for (auto I : EquivalenceClasses) { |
| 391 const RegisterList &List = I.second; | 420 const RegisterList &List = I.second; |
| 392 RegisterList Shuffled(List); | 421 RegisterList Shuffled(List); |
| 393 RandomShuffle(Shuffled.begin(), Shuffled.end(), RNG); | 422 RandomShuffle(Shuffled.begin(), Shuffled.end(), RNG); |
| 394 for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) { | 423 for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 415 } | 444 } |
| 416 Str << "}\n"; | 445 Str << "}\n"; |
| 417 } | 446 } |
| 418 } | 447 } |
| 419 } | 448 } |
| 420 | 449 |
| 421 /// The maximum number of arguments to pass in XMM registers | 450 /// The maximum number of arguments to pass in XMM registers |
| 422 static const uint32_t X86_MAX_XMM_ARGS = 4; | 451 static const uint32_t X86_MAX_XMM_ARGS = 4; |
| 423 /// The number of bits in a byte | 452 /// The number of bits in a byte |
| 424 static const uint32_t X86_CHAR_BIT = 8; | 453 static const uint32_t X86_CHAR_BIT = 8; |
| 425 /// Stack alignment. This is defined in IceTargetLoweringX8632.cpp because it | 454 /// Stack alignment. This is defined in IceTargetLoweringX8664.cpp because it |
| 426 /// is used as an argument to std::max(), and the default std::less<T> has an | 455 /// is used as an argument to std::max(), and the default std::less<T> has an |
| 427 /// operator(T const&, T const&) which requires this member to have an | 456 /// operator(T const&, T const&) which requires this member to have an |
| 428 /// address. | 457 /// address. |
| 429 static const uint32_t X86_STACK_ALIGNMENT_BYTES; | 458 static const uint32_t X86_STACK_ALIGNMENT_BYTES; |
| 430 /// Size of the return address on the stack | 459 /// Size of the return address on the stack |
| 431 static const uint32_t X86_RET_IP_SIZE_BYTES = 4; | 460 static const uint32_t X86_RET_IP_SIZE_BYTES = 4; |
| 432 /// The number of different NOP instructions | 461 /// The number of different NOP instructions |
| 433 static const uint32_t X86_NUM_NOP_VARIANTS = 5; | 462 static const uint32_t X86_NUM_NOP_VARIANTS = 5; |
| 434 | 463 |
| 435 /// Value is in bytes. Return Value adjusted to the next highest multiple | 464 /// Value is in bytes. Return Value adjusted to the next highest multiple |
| 436 /// of the stack alignment. | 465 /// of the stack alignment. |
| 437 static uint32_t applyStackAlignment(uint32_t Value) { | 466 static uint32_t applyStackAlignment(uint32_t Value) { |
| 438 return Utils::applyAlignment(Value, X86_STACK_ALIGNMENT_BYTES); | 467 return Utils::applyAlignment(Value, X86_STACK_ALIGNMENT_BYTES); |
| 439 } | 468 } |
| 440 | 469 |
| 441 /// Return the type which the elements of the vector have in the X86 | 470 /// Return the type which the elements of the vector have in the X86 |
| 442 /// representation of the vector. | 471 /// representation of the vector. |
| 443 static Type getInVectorElementType(Type Ty) { | 472 static Type getInVectorElementType(Type Ty) { |
| 444 assert(isVectorType(Ty)); | 473 assert(isVectorType(Ty)); |
| 445 size_t Index = static_cast<size_t>(Ty); | 474 size_t Index = static_cast<size_t>(Ty); |
| 446 (void)Index; | 475 (void)Index; |
| 447 assert(Index < TableTypeX8632AttributesSize); | 476 assert(Index < TableTypeX8664AttributesSize); |
| 448 return TableTypeX8632Attributes[Ty].InVectorElementType; | 477 return TableTypeX8664Attributes[Ty].InVectorElementType; |
| 449 } | 478 } |
| 450 | 479 |
| 451 // Note: The following data structures are defined in | 480 // Note: The following data structures are defined in |
| 452 // IceTargetLoweringX8632.cpp. | 481 // IceTargetLoweringX8664.cpp. |
| 453 | 482 |
| 454 /// The following table summarizes the logic for lowering the fcmp | 483 /// The following table summarizes the logic for lowering the fcmp |
| 455 /// instruction. There is one table entry for each of the 16 conditions. | 484 /// instruction. There is one table entry for each of the 16 conditions. |
| 456 /// | 485 /// |
| 457 /// The first four columns describe the case when the operands are floating | 486 /// The first four columns describe the case when the operands are floating |
| 458 /// point scalar values. A comment in lowerFcmp() describes the lowering | 487 /// point scalar values. A comment in lowerFcmp() describes the lowering |
| 459 /// template. In the most general case, there is a compare followed by two | 488 /// template. In the most general case, there is a compare followed by two |
| 460 /// conditional branches, because some fcmp conditions don't map to a single | 489 /// conditional branches, because some fcmp conditions don't map to a single |
| 461 /// x86 conditional branch. However, in many cases it is possible to swap the | 490 /// x86 conditional branch. However, in many cases it is possible to swap the |
| 462 /// operands in the comparison and have a single conditional branch. Since | 491 /// operands in the comparison and have a single conditional branch. Since |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 497 } TableIcmp64[]; | 526 } TableIcmp64[]; |
| 498 static const size_t TableIcmp64Size; | 527 static const size_t TableIcmp64Size; |
| 499 /// @} | 528 /// @} |
| 500 | 529 |
| 501 static Cond::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) { | 530 static Cond::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) { |
| 502 size_t Index = static_cast<size_t>(Cond); | 531 size_t Index = static_cast<size_t>(Cond); |
| 503 assert(Index < TableIcmp32Size); | 532 assert(Index < TableIcmp32Size); |
| 504 return TableIcmp32[Index].Mapping; | 533 return TableIcmp32[Index].Mapping; |
| 505 } | 534 } |
| 506 | 535 |
| 507 static const struct TableTypeX8632AttributesType { | 536 static const struct TableTypeX8664AttributesType { |
| 508 Type InVectorElementType; | 537 Type InVectorElementType; |
| 509 } TableTypeX8632Attributes[]; | 538 } TableTypeX8664Attributes[]; |
| 510 static const size_t TableTypeX8632AttributesSize; | 539 static const size_t TableTypeX8664AttributesSize; |
| 511 | 540 |
| 512 //---------------------------------------------------------------------------- | 541 //---------------------------------------------------------------------------- |
| 513 // __ __ __ ______ ______ | 542 // __ __ __ ______ ______ |
| 514 // /\ \/\ "-.\ \/\ ___\/\__ _\ | 543 // /\ \/\ "-.\ \/\ ___\/\__ _\ |
| 515 // \ \ \ \ \-. \ \___ \/_/\ \/ | 544 // \ \ \ \ \-. \ \___ \/_/\ \/ |
| 516 // \ \_\ \_\\"\_\/\_____\ \ \_\ | 545 // \ \_\ \_\\"\_\/\_____\ \ \_\ |
| 517 // \/_/\/_/ \/_/\/_____/ \/_/ | 546 // \/_/\/_/ \/_/\/_____/ \/_/ |
| 518 // | 547 // |
| 519 //---------------------------------------------------------------------------- | 548 //---------------------------------------------------------------------------- |
| 520 using Insts = ::Ice::X86Internal::Insts<TargetX8632>; | 549 using Insts = ::Ice::X86Internal::Insts<TargetX8664>; |
| 521 | 550 |
| 522 using TargetLowering = ::Ice::X86Internal::TargetX86Base<TargetX8632>; | 551 using TargetLowering = TargetX8664; |
| 523 using Assembler = X8632::AssemblerX8632; | 552 #endif // 0 |
| 524 | 553 |
| 554 using Assembler = X8664::AssemblerX8664; | |
| 555 | |
| 556 #if 0 | |
| 525 /// X86Operand extends the Operand hierarchy. Its subclasses are | 557 /// X86Operand extends the Operand hierarchy. Its subclasses are |
| 526 /// X86OperandMem and VariableSplit. | 558 /// X86OperandMem and VariableSplit. |
| 527 class X86Operand : public ::Ice::Operand { | 559 class X86Operand : public ::Ice::Operand { |
| 528 X86Operand() = delete; | 560 X86Operand() = delete; |
| 529 X86Operand(const X86Operand &) = delete; | 561 X86Operand(const X86Operand &) = delete; |
| 530 X86Operand &operator=(const X86Operand &) = delete; | 562 X86Operand &operator=(const X86Operand &) = delete; |
| 531 | 563 |
| 532 public: | 564 public: |
| 533 enum OperandKindX8632 { k__Start = ::Ice::Operand::kTarget, kMem, kSplit }; | 565 enum OperandKindX8664 { k__Start = ::Ice::Operand::kTarget, kMem, kSplit }; |
| 534 using ::Ice::Operand::dump; | 566 using ::Ice::Operand::dump; |
| 535 | 567 |
| 536 void dump(const Cfg *, Ostream &Str) const override; | 568 void dump(const Cfg *, Ostream &Str) const override; |
| 537 | 569 |
| 538 protected: | 570 protected: |
| 539 X86Operand(OperandKindX8632 Kind, Type Ty) | 571 X86Operand(OperandKindX8664 Kind, Type Ty) |
| 540 : Operand(static_cast<::Ice::Operand::OperandKind>(Kind), Ty) {} | 572 : Operand(static_cast<::Ice::Operand::OperandKind>(Kind), Ty) {} |
| 541 }; | 573 }; |
| 542 | 574 |
| 543 /// X86OperandMem represents the m32 addressing mode, with optional base and | 575 /// X86OperandMem represents the m32 addressing mode, with optional base and |
| 544 /// index registers, a constant offset, and a fixed shift value for the index | 576 /// index registers, a constant offset, and a fixed shift value for the index |
| 545 /// register. | 577 /// register. |
| 546 class X86OperandMem : public X86Operand { | 578 class X86OperandMem : public X86Operand { |
| 547 X86OperandMem() = delete; | 579 X86OperandMem() = delete; |
| 548 X86OperandMem(const X86OperandMem &) = delete; | 580 X86OperandMem(const X86OperandMem &) = delete; |
| 549 X86OperandMem &operator=(const X86OperandMem &) = delete; | 581 X86OperandMem &operator=(const X86OperandMem &) = delete; |
| 550 | 582 |
| 551 public: | 583 public: |
| 552 enum SegmentRegisters { | 584 enum SegmentRegisters { |
| 553 DefaultSegment = -1, | 585 DefaultSegment = -1, |
| 554 #define X(val, name, prefix) val, | 586 #define X(val, name, prefix) val, |
| 555 SEG_REGX8632_TABLE | 587 SEG_REGX8664_TABLE |
| 556 #undef X | 588 #undef X |
| 557 SegReg_NUM | 589 SegReg_NUM |
| 558 }; | 590 }; |
| 559 static X86OperandMem *create(Cfg *Func, Type Ty, Variable *Base, | 591 static X86OperandMem *create(Cfg *Func, Type Ty, Variable *Base, |
| 560 Constant *Offset, Variable *Index = nullptr, | 592 Constant *Offset, Variable *Index = nullptr, |
| 561 uint16_t Shift = 0, | 593 uint16_t Shift = 0, |
| 562 SegmentRegisters SegmentReg = DefaultSegment) { | 594 SegmentRegisters SegmentReg = DefaultSegment) { |
| 563 return new (Func->allocate<X86OperandMem>()) | 595 return new (Func->allocate<X86OperandMem>()) |
| 564 X86OperandMem(Func, Ty, Base, Offset, Index, Shift, SegmentReg); | 596 X86OperandMem(Func, Ty, Base, Offset, Index, Shift, SegmentReg); |
| 565 } | 597 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 662 void setLinkedTo(Variable *Var) { LinkedTo = Var; } | 694 void setLinkedTo(Variable *Var) { LinkedTo = Var; } |
| 663 Variable *getLinkedTo() const { return LinkedTo; } | 695 Variable *getLinkedTo() const { return LinkedTo; } |
| 664 // Inherit dump() and emit() from Variable. | 696 // Inherit dump() and emit() from Variable. |
| 665 | 697 |
| 666 private: | 698 private: |
| 667 SpillVariable(Type Ty, SizeT Index) | 699 SpillVariable(Type Ty, SizeT Index) |
| 668 : Variable(SpillVariableKind, Ty, Index), LinkedTo(nullptr) {} | 700 : Variable(SpillVariableKind, Ty, Index), LinkedTo(nullptr) {} |
| 669 Variable *LinkedTo; | 701 Variable *LinkedTo; |
| 670 }; | 702 }; |
| 671 | 703 |
| 672 // Note: The following data structures are defined in IceInstX8632.cpp. | 704 // Note: The following data structures are defined in IceInstX8664.cpp. |
| 673 | 705 |
| 674 static const struct InstBrAttributesType { | 706 static const struct InstBrAttributesType { |
| 675 Cond::BrCond Opposite; | 707 Cond::BrCond Opposite; |
| 676 const char *DisplayString; | 708 const char *DisplayString; |
| 677 const char *EmitString; | 709 const char *EmitString; |
| 678 } InstBrAttributes[]; | 710 } InstBrAttributes[]; |
| 679 | 711 |
| 680 static const struct InstCmppsAttributesType { | 712 static const struct InstCmppsAttributesType { |
| 681 const char *EmitString; | 713 const char *EmitString; |
| 682 } InstCmppsAttributes[]; | 714 } InstCmppsAttributes[]; |
| 683 | 715 |
| 684 static const struct TypeAttributesType { | 716 static const struct TypeAttributesType { |
| 685 const char *CvtString; // i (integer), s (single FP), d (double FP) | 717 const char *CvtString; // i (integer), s (single FP), d (double FP) |
| 686 const char *SdSsString; // ss, sd, or <blank> | 718 const char *SdSsString; // ss, sd, or <blank> |
| 687 const char *PackString; // b, w, d, or <blank> | 719 const char *PackString; // b, w, d, or <blank> |
| 688 const char *WidthString; // b, w, l, q, or <blank> | 720 const char *WidthString; // b, w, l, q, or <blank> |
| 689 const char *FldString; // s, l, or <blank> | 721 const char *FldString; // s, l, or <blank> |
| 690 } TypeAttributes[]; | 722 } TypeAttributes[]; |
| 691 | 723 |
| 692 static const char *InstSegmentRegNames[]; | 724 static const char *InstSegmentRegNames[]; |
| 693 | 725 |
| 694 static uint8_t InstSegmentPrefixes[]; | 726 static uint8_t InstSegmentPrefixes[]; |
| 727 #endif // 0 | |
| 695 }; | 728 }; |
| 696 | 729 |
| 697 } // end of namespace X86Internal | 730 } // end of namespace X86Internal |
| 698 | 731 |
| 699 namespace X8632 { | 732 namespace X8664 { |
| 700 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8632>; | 733 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8664>; |
| 701 } // end of namespace X8632 | 734 } // end of namespace X8664 |
| 702 | 735 |
| 703 } // end of namespace Ice | 736 } // end of namespace Ice |
| 704 | 737 |
| 705 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H | 738 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H |
| OLD | NEW |