Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(168)

Side by Side Diff: src/IceTargetLoweringX8664Traits.h

Issue 1616103002: Subzero. X8664. Enables RIP-based addressing mode. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTargetLoweringX8664.cpp ('k') | unittest/AssemblerX8664/GPRArith.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX8664.cpp ('k') | unittest/AssemblerX8664/GPRArith.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698