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

Side by Side Diff: src/IceTargetLoweringX8664Traits.h

Issue 1224173006: Adds the x86-64 assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: make format Created 5 years, 4 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
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698