OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX8664Traits.h - x86-64 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 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 public: | 82 public: |
83 enum RexBits { | 83 enum RexBits { |
84 RexNone = 0x00, | 84 RexNone = 0x00, |
85 RexBase = 0x40, | 85 RexBase = 0x40, |
86 RexW = RexBase | (1 << 3), | 86 RexW = RexBase | (1 << 3), |
87 RexR = RexBase | (1 << 2), | 87 RexR = RexBase | (1 << 2), |
88 RexX = RexBase | (1 << 1), | 88 RexX = RexBase | (1 << 1), |
89 RexB = RexBase | (1 << 0), | 89 RexB = RexBase | (1 << 0), |
90 }; | 90 }; |
91 | 91 |
92 Operand(const Operand &other) | 92 protected: |
93 : fixup_(other.fixup_), rex_(other.rex_), length_(other.length_) { | 93 // Needed by subclass Address. |
94 memmove(&encoding_[0], &other.encoding_[0], other.length_); | 94 Operand() = default; |
95 } | |
96 | 95 |
97 Operand &operator=(const Operand &other) { | 96 public: |
98 length_ = other.length_; | 97 Operand(const Operand &) = default; |
99 fixup_ = other.fixup_; | 98 Operand(Operand &&) = default; |
100 rex_ = other.rex_; | 99 Operand &operator=(const Operand &) = default; |
101 memmove(&encoding_[0], &other.encoding_[0], other.length_); | 100 Operand &operator=(Operand &&) = default; |
102 return *this; | |
103 } | |
104 | 101 |
105 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; } | 102 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; } |
106 | 103 |
107 uint8_t rexX() const { return (rex_ & RexX) != RexX ? RexNone : RexX; } | 104 uint8_t rexX() const { return (rex_ & RexX) != RexX ? RexNone : RexX; } |
108 uint8_t rexB() const { return (rex_ & RexB) != RexB ? RexNone : RexB; } | 105 uint8_t rexB() const { return (rex_ & RexB) != RexB ? RexNone : RexB; } |
109 | 106 |
110 GPRRegister rm() const { | 107 GPRRegister rm() const { |
111 return static_cast<GPRRegister>((rexB() != 0 ? 0x08 : 0) | | 108 return static_cast<GPRRegister>((rexB() != 0 ? 0x08 : 0) | |
112 (encoding_at(0) & 7)); | 109 (encoding_at(0) & 7)); |
113 } | 110 } |
(...skipping 10 matching lines...) Expand all Loading... |
124 GPRRegister base() const { | 121 GPRRegister base() const { |
125 return static_cast<GPRRegister>((rexB() != 0 ? 0x08 : 0) | | 122 return static_cast<GPRRegister>((rexB() != 0 ? 0x08 : 0) | |
126 (encoding_at(1) & 7)); | 123 (encoding_at(1) & 7)); |
127 } | 124 } |
128 | 125 |
129 int8_t disp8() const { | 126 int8_t disp8() const { |
130 assert(length_ >= 2); | 127 assert(length_ >= 2); |
131 return static_cast<int8_t>(encoding_[length_ - 1]); | 128 return static_cast<int8_t>(encoding_[length_ - 1]); |
132 } | 129 } |
133 | 130 |
134 int32_t disp32() const { | |
135 assert(length_ >= 5); | |
136 // TODO(stichnot): This method is not currently used. Delete it along | |
137 // with other unused methods, or use a safe version of bitCopy(). | |
138 llvm::report_fatal_error("Unexpected call to disp32()"); | |
139 // return Utils::bitCopy<int32_t>(encoding_[length_ - 4]); | |
140 } | |
141 | |
142 AssemblerFixup *fixup() const { return fixup_; } | 131 AssemblerFixup *fixup() const { return fixup_; } |
143 | 132 |
144 protected: | 133 protected: |
145 Operand() : fixup_(nullptr), length_(0) {} // Needed by subclass Address. | |
146 | |
147 void SetModRM(int mod, GPRRegister rm) { | 134 void SetModRM(int mod, GPRRegister rm) { |
148 assert((mod & ~3) == 0); | 135 assert((mod & ~3) == 0); |
149 encoding_[0] = (mod << 6) | (rm & 0x07); | 136 encoding_[0] = (mod << 6) | (rm & 0x07); |
150 rex_ = (rm & 0x08) ? RexB : RexNone; | 137 rex_ = (rm & 0x08) ? RexB : RexNone; |
151 length_ = 1; | 138 length_ = 1; |
152 } | 139 } |
153 | 140 |
154 void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) { | 141 void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) { |
155 assert(length_ == 1); | 142 assert(length_ == 1); |
156 assert((scale & ~3) == 0); | 143 assert((scale & ~3) == 0); |
(...skipping 11 matching lines...) Expand all Loading... |
168 void SetDisp32(int32_t disp) { | 155 void SetDisp32(int32_t disp) { |
169 assert(length_ == 1 || length_ == 2); | 156 assert(length_ == 1 || length_ == 2); |
170 intptr_t disp_size = sizeof(disp); | 157 intptr_t disp_size = sizeof(disp); |
171 memmove(&encoding_[length_], &disp, disp_size); | 158 memmove(&encoding_[length_], &disp, disp_size); |
172 length_ += disp_size; | 159 length_ += disp_size; |
173 } | 160 } |
174 | 161 |
175 void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; } | 162 void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; } |
176 | 163 |
177 private: | 164 private: |
178 AssemblerFixup *fixup_; | 165 AssemblerFixup *fixup_ = nullptr; |
179 uint8_t rex_ = 0; | 166 uint8_t rex_ = 0; |
180 uint8_t encoding_[6]; | 167 uint8_t encoding_[6]; |
181 uint8_t length_; | 168 uint8_t length_ = 0; |
182 | 169 |
183 explicit Operand(GPRRegister reg) : fixup_(nullptr) { SetModRM(3, reg); } | 170 explicit Operand(GPRRegister reg) : fixup_(nullptr) { SetModRM(3, reg); } |
184 | 171 |
185 /// Get the operand encoding byte at the given index. | 172 /// Get the operand encoding byte at the given index. |
186 uint8_t encoding_at(intptr_t index) const { | 173 uint8_t encoding_at(intptr_t index) const { |
187 assert(index >= 0 && index < length_); | 174 assert(index >= 0 && index < length_); |
188 return encoding_[index]; | 175 return encoding_[index]; |
189 } | 176 } |
190 | 177 |
191 /// Returns whether or not this operand is really the given register in | 178 /// Returns whether or not this operand is really the given register in |
192 /// disguise. Used from the assembler to generate better encodings. | 179 /// disguise. Used from the assembler to generate better encodings. |
193 bool IsRegister(GPRRegister reg) const { | 180 bool IsRegister(GPRRegister reg) const { |
194 return ((encoding_[0] & 0xF8) == | 181 return ((encoding_[0] & 0xF8) == |
195 0xC0) // Addressing mode is register only. | 182 0xC0) // Addressing mode is register only. |
196 && | 183 && |
197 (rm() == reg); // Register codes match. | 184 (rm() == reg); // Register codes match. |
198 } | 185 } |
199 | 186 |
200 friend class AssemblerX86Base<TargetX8664Traits>; | 187 friend class AssemblerX86Base<TargetX8664Traits>; |
201 }; | 188 }; |
202 | 189 |
203 class Address : public Operand { | 190 class Address : public Operand { |
204 Address() = delete; | 191 Address() = default; |
205 | 192 |
206 public: | 193 public: |
207 Address(const Address &other) : Operand(other) {} | 194 Address(const Address &) = default; |
208 | 195 Address(Address &&) = default; |
209 Address &operator=(const Address &other) { | 196 Address &operator=(const Address &) = default; |
210 Operand::operator=(other); | 197 Address &operator=(Address &&) = default; |
211 return *this; | |
212 } | |
213 | 198 |
214 Address(GPRRegister Base, int32_t Disp, AssemblerFixup *Fixup) { | 199 Address(GPRRegister Base, int32_t Disp, AssemblerFixup *Fixup) { |
215 if (Fixup == nullptr && Disp == 0 && | 200 if (Fixup == nullptr && Disp == 0 && |
216 (Base & 7) != RegX8664::Encoded_Reg_ebp) { | 201 (Base & 7) != RegX8664::Encoded_Reg_rbp) { |
217 SetModRM(0, Base); | 202 SetModRM(0, Base); |
218 if ((Base & 7) == RegX8664::Encoded_Reg_esp) | 203 if ((Base & 7) == RegX8664::Encoded_Reg_rsp) |
219 SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, Base); | 204 SetSIB(TIMES_1, RegX8664::Encoded_Reg_rsp, Base); |
220 } else if (Fixup == nullptr && Utils::IsInt(8, Disp)) { | 205 } else if (Fixup == nullptr && Utils::IsInt(8, Disp)) { |
221 SetModRM(1, Base); | 206 SetModRM(1, Base); |
222 if ((Base & 7) == RegX8664::Encoded_Reg_esp) | 207 if ((Base & 7) == RegX8664::Encoded_Reg_rsp) |
223 SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, Base); | 208 SetSIB(TIMES_1, RegX8664::Encoded_Reg_rsp, Base); |
224 SetDisp8(Disp); | 209 SetDisp8(Disp); |
225 } else { | 210 } else { |
226 SetModRM(2, Base); | 211 SetModRM(2, Base); |
227 if ((Base & 7) == RegX8664::Encoded_Reg_esp) | 212 if ((Base & 7) == RegX8664::Encoded_Reg_rsp) |
228 SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, Base); | 213 SetSIB(TIMES_1, RegX8664::Encoded_Reg_rsp, Base); |
229 SetDisp32(Disp); | 214 SetDisp32(Disp); |
230 if (Fixup) | 215 if (Fixup) |
231 SetFixup(Fixup); | 216 SetFixup(Fixup); |
232 } | 217 } |
233 } | 218 } |
234 | 219 |
235 Address(GPRRegister Index, ScaleFactor Scale, int32_t Disp, | 220 Address(GPRRegister Index, ScaleFactor Scale, int32_t Disp, |
236 AssemblerFixup *Fixup) { | 221 AssemblerFixup *Fixup) { |
237 assert(Index != RegX8664::Encoded_Reg_esp); // Illegal addressing mode. | 222 assert(Index != RegX8664::Encoded_Reg_rsp); // Illegal addressing mode. |
238 SetModRM(0, RegX8664::Encoded_Reg_esp); | 223 SetModRM(0, RegX8664::Encoded_Reg_rsp); |
239 SetSIB(Scale, Index, RegX8664::Encoded_Reg_ebp); | 224 SetSIB(Scale, Index, RegX8664::Encoded_Reg_rbp); |
240 SetDisp32(Disp); | 225 SetDisp32(Disp); |
241 if (Fixup) | 226 if (Fixup) |
242 SetFixup(Fixup); | 227 SetFixup(Fixup); |
243 } | 228 } |
244 | 229 |
245 Address(GPRRegister Base, GPRRegister Index, ScaleFactor Scale, | 230 Address(GPRRegister Base, GPRRegister Index, ScaleFactor Scale, |
246 int32_t Disp, AssemblerFixup *Fixup) { | 231 int32_t Disp, AssemblerFixup *Fixup) { |
247 assert(Index != RegX8664::Encoded_Reg_esp); // Illegal addressing mode. | 232 assert(Index != RegX8664::Encoded_Reg_rsp); // Illegal addressing mode. |
248 if (Fixup == nullptr && Disp == 0 && | 233 if (Fixup == nullptr && Disp == 0 && |
249 (Base & 7) != RegX8664::Encoded_Reg_ebp) { | 234 (Base & 7) != RegX8664::Encoded_Reg_rbp) { |
250 SetModRM(0, RegX8664::Encoded_Reg_esp); | 235 SetModRM(0, RegX8664::Encoded_Reg_rsp); |
251 SetSIB(Scale, Index, Base); | 236 SetSIB(Scale, Index, Base); |
252 } else if (Fixup == nullptr && Utils::IsInt(8, Disp)) { | 237 } else if (Fixup == nullptr && Utils::IsInt(8, Disp)) { |
253 SetModRM(1, RegX8664::Encoded_Reg_esp); | 238 SetModRM(1, RegX8664::Encoded_Reg_rsp); |
254 SetSIB(Scale, Index, Base); | 239 SetSIB(Scale, Index, Base); |
255 SetDisp8(Disp); | 240 SetDisp8(Disp); |
256 } else { | 241 } else { |
257 SetModRM(2, RegX8664::Encoded_Reg_esp); | 242 SetModRM(2, RegX8664::Encoded_Reg_rsp); |
258 SetSIB(Scale, Index, Base); | 243 SetSIB(Scale, Index, Base); |
259 SetDisp32(Disp); | 244 SetDisp32(Disp); |
260 if (Fixup) | 245 if (Fixup) |
261 SetFixup(Fixup); | 246 SetFixup(Fixup); |
262 } | 247 } |
263 } | 248 } |
264 | 249 |
265 /// Generate a RIP-relative address expression on x86-64. | 250 /// Generate a RIP-relative address expression on x86-64. |
266 Address(RelocOffsetT Offset, AssemblerFixup *Fixup) { | 251 static Address RipRelative(RelocOffsetT Offset, AssemblerFixup *Fixup) { |
267 SetModRM(0x0, RegX8664::Encoded_Reg_esp); | 252 assert(Fixup != nullptr); |
| 253 assert(Fixup->kind() == FK_PcRel); |
| 254 Address NewAddress; |
| 255 NewAddress.SetModRM(0x0, RegX8664::Encoded_Reg_rbp); |
268 | 256 |
269 static constexpr ScaleFactor Scale = TIMES_1; | |
270 SetSIB(Scale, RegX8664::Encoded_Reg_esp, RegX8664::Encoded_Reg_ebp); | |
271 // Use the Offset in the displacement for now. If we decide to process | 257 // Use the Offset in the displacement for now. If we decide to process |
272 // fixups later, we'll need to patch up the emitted displacement. | 258 // fixups later, we'll need to patch up the emitted displacement. |
273 SetDisp32(Offset); | 259 NewAddress.SetDisp32(Offset); |
274 if (Fixup) | 260 if (Fixup) |
275 SetFixup(Fixup); | 261 NewAddress.SetFixup(Fixup); |
| 262 |
| 263 return NewAddress; |
| 264 } |
| 265 |
| 266 /// Generate an absolute address. |
| 267 static Address Absolute(RelocOffsetT Addr) { |
| 268 Address NewAddress; |
| 269 NewAddress.SetModRM(0x0, RegX8664::Encoded_Reg_rsp); |
| 270 static constexpr ScaleFactor NoScale = TIMES_1; |
| 271 NewAddress.SetSIB(NoScale, RegX8664::Encoded_Reg_rsp, |
| 272 RegX8664::Encoded_Reg_rbp); |
| 273 NewAddress.SetDisp32(Addr); |
| 274 return NewAddress; |
276 } | 275 } |
277 | 276 |
278 static Address ofConstPool(Assembler *Asm, const Constant *Imm) { | 277 static Address ofConstPool(Assembler *Asm, const Constant *Imm) { |
279 // TODO(jpp): ??? | 278 // TODO(jpp): ??? |
280 AssemblerFixup *Fixup = Asm->createFixup(FK_Abs, Imm); | 279 AssemblerFixup *Fixup = Asm->createFixup(FK_Abs, Imm); |
281 const RelocOffsetT Offset = 4; | 280 const RelocOffsetT Offset = 4; |
282 return Address(Offset, Fixup); | 281 return Address::RipRelative(Offset, Fixup); |
283 } | 282 } |
284 }; | 283 }; |
285 | 284 |
286 //---------------------------------------------------------------------------- | 285 //---------------------------------------------------------------------------- |
287 // __ ______ __ __ ______ ______ __ __ __ ______ | 286 // __ ______ __ __ ______ ______ __ __ __ ______ |
288 // /\ \ /\ __ \/\ \ _ \ \/\ ___\/\ == \/\ \/\ "-.\ \/\ ___\ | 287 // /\ \ /\ __ \/\ \ _ \ \/\ ___\/\ == \/\ \/\ "-.\ \/\ ___\ |
289 // \ \ \___\ \ \/\ \ \ \/ ".\ \ \ __\\ \ __<\ \ \ \ \-. \ \ \__ \ | 288 // \ \ \___\ \ \/\ \ \ \/ ".\ \ \ __\\ \ __<\ \ \ \ \-. \ \ \__ \ |
290 // \ \_____\ \_____\ \__/".~\_\ \_____\ \_\ \_\ \_\ \_\\"\_\ \_____\ | 289 // \ \_____\ \_____\ \__/".~\_\ \_____\ \_\ \_\ \_\ \_\\"\_\ \_____\ |
291 // \/_____/\/_____/\/_/ \/_/\/_____/\/_/ /_/\/_/\/_/ \/_/\/_____/ | 290 // \/_____/\/_____/\/_/ \/_/\/_____/\/_/ /_/\/_/\/_/ \/_/\/_____/ |
292 // | 291 // |
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1046 const char *FldString; // s, l, or <blank> | 1045 const char *FldString; // s, l, or <blank> |
1047 } TypeAttributes[]; | 1046 } TypeAttributes[]; |
1048 }; | 1047 }; |
1049 | 1048 |
1050 using Traits = ::Ice::X8664::TargetX8664Traits; | 1049 using Traits = ::Ice::X8664::TargetX8664Traits; |
1051 } // end of namespace X8664 | 1050 } // end of namespace X8664 |
1052 | 1051 |
1053 } // end of namespace Ice | 1052 } // end of namespace Ice |
1054 | 1053 |
1055 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H | 1054 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H |
OLD | NEW |