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

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: Addresses comments; changes emitRex.* logic. 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
(Empty)
1 //===- subzero/src/IceTargetLoweringX8664Traits.h - x86-64 traits -*- C++ -*-=//
2 //
3 // The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This file declares the X8664 Target Lowering Traits.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #ifndef SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H
16 #define SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H
17
18 #include "IceAssembler.h"
19 #include "IceConditionCodesX8664.h"
20 #include "IceDefs.h"
21 #include "IceInst.h"
22 #include "IceInstX8664.def"
23 #include "IceOperand.h"
24 #include "IceRegistersX8664.h"
25 #include "IceTargetLowering.h"
26
27 namespace Ice {
28
29 class TargetX8664;
30
31 namespace X8664 {
32 class AssemblerX8664;
33 } // end of namespace X8664
34
35 namespace X86Internal {
36
37 template <class Machine> struct Insts;
38 template <class Machine> struct MachineTraits;
39
40 template <> struct MachineTraits<TargetX8664> {
41 //----------------------------------------------------------------------------
42 // ______ ______ __ __
43 // /\ __ \/\ ___\/\ "-./ \
44 // \ \ __ \ \___ \ \ \-./\ \
45 // \ \_\ \_\/\_____\ \_\ \ \_\
46 // \/_/\/_/\/_____/\/_/ \/_/
47 //
48 //----------------------------------------------------------------------------
49 static constexpr bool Is64Bit = true;
50 static constexpr bool HasPopa = false;
51 static constexpr bool HasPusha = false;
52 static constexpr bool UsesX87 = false;
53 static constexpr ::Ice::RegX8664::GPRRegister Last8BitGPR =
54 ::Ice::RegX8664::GPRRegister::Encoded_Reg_r15d;
55
56 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 };
57
58 using GPRRegister = ::Ice::RegX8664::GPRRegister;
59 using XmmRegister = ::Ice::RegX8664::XmmRegister;
60 using ByteRegister = ::Ice::RegX8664::ByteRegister;
61
62 using Cond = ::Ice::CondX8664;
63
64 using RegisterSet = ::Ice::RegX8664;
65 static const GPRRegister Encoded_Reg_Accumulator = RegX8664::Encoded_Reg_eax;
66 static const GPRRegister Encoded_Reg_Counter = RegX8664::Encoded_Reg_ecx;
67 static const FixupKind PcRelFixup = llvm::ELF::R_386_PC32; // TODO(jpp): ???
68
69 class Operand {
70 public:
71 enum RexBits {
72 RexNone = 0x00,
73 RexBase = 0x40,
74 RexW = RexBase | (1 << 3),
75 RexR = RexBase | (1 << 2),
76 RexX = RexBase | (1 << 1),
77 RexB = RexBase | (1 << 0),
78 };
79
80 Operand(const Operand &other)
81 : fixup_(other.fixup_), rex_(other.rex_), length_(other.length_) {
82 memmove(&encoding_[0], &other.encoding_[0], other.length_);
83 }
84
85 Operand &operator=(const Operand &other) {
86 length_ = other.length_;
87 fixup_ = other.fixup_;
88 rex_ = other.rex_;
89 memmove(&encoding_[0], &other.encoding_[0], other.length_);
90 return *this;
91 }
92
93 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
94
95 uint8_t rexX() const { return (rex_ & RexX) != RexX ? RexNone : RexX; }
96 uint8_t rexB() const { return (rex_ & RexB) != RexB ? RexNone : RexB; }
97
98 GPRRegister rm() const {
99 return static_cast<GPRRegister>((rexB() != 0 ? 0x08 : 0) |
100 (encoding_at(0) & 7));
101 }
102
103 ScaleFactor scale() const {
104 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
105 }
106
107 GPRRegister index() const {
108 return static_cast<GPRRegister>((rexX() != 0 ? 0x08 : 0) |
109 ((encoding_at(1) >> 3) & 7));
110 }
111
112 GPRRegister base() const {
113 return static_cast<GPRRegister>((rexB() != 0 ? 0x08 : 0) |
114 (encoding_at(1) & 7));
115 }
116
117 int8_t disp8() const {
118 assert(length_ >= 2);
119 return static_cast<int8_t>(encoding_[length_ - 1]);
120 }
121
122 int32_t disp32() const {
123 assert(length_ >= 5);
124 return bit_copy<int32_t>(encoding_[length_ - 4]);
125 }
126
127 AssemblerFixup *fixup() const { return fixup_; }
128
129 protected:
130 Operand() : fixup_(nullptr), length_(0) {} // Needed by subclass Address.
131
132 void SetModRM(int mod, GPRRegister rm) {
133 assert((mod & ~3) == 0);
134 encoding_[0] = (mod << 6) | (rm & 0x07);
135 rex_ = (rm & 0x08) ? RexB : RexNone;
136 length_ = 1;
137 }
138
139 void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) {
140 assert(length_ == 1);
141 assert((scale & ~3) == 0);
142 encoding_[1] = (scale << 6) | ((index & 0x07) << 3) | (base & 0x07);
143 rex_ =
144 ((base & 0x08) ? RexB : RexNone) | ((index & 0x08) ? RexX : RexNone);
145 length_ = 2;
146 }
147
148 void SetDisp8(int8_t disp) {
149 assert(length_ == 1 || length_ == 2);
150 encoding_[length_++] = static_cast<uint8_t>(disp);
151 }
152
153 void SetDisp32(int32_t disp) {
154 assert(length_ == 1 || length_ == 2);
155 intptr_t disp_size = sizeof(disp);
156 memmove(&encoding_[length_], &disp, disp_size);
157 length_ += disp_size;
158 }
159
160 void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; }
161
162 private:
163 AssemblerFixup *fixup_;
164 uint8_t rex_ = 0;
165 uint8_t encoding_[6];
166 uint8_t length_;
167
168 explicit Operand(GPRRegister reg) : fixup_(nullptr) { SetModRM(3, reg); }
169
170 /// Get the operand encoding byte at the given index.
171 uint8_t encoding_at(intptr_t index) const {
172 assert(index >= 0 && index < length_);
173 return encoding_[index];
174 }
175
176 /// Returns whether or not this operand is really the given register in
177 /// disguise. Used from the assembler to generate better encodings.
178 bool IsRegister(GPRRegister reg) const {
179 return ((encoding_[0] & 0xF8) ==
180 0xC0) // Addressing mode is register only.
181 &&
182 (rm() == reg); // Register codes match.
183 }
184
185 template <class> friend class AssemblerX86Base;
186 };
187
188 class Address : public Operand {
189 Address() = delete;
190
191 public:
192 Address(const Address &other) : Operand(other) {}
193
194 Address &operator=(const Address &other) {
195 Operand::operator=(other);
196 return *this;
197 }
198
199 Address(GPRRegister base, int32_t disp) {
200 if (disp == 0 && (base & 7) != RegX8664::Encoded_Reg_ebp) {
201 SetModRM(0, base);
202 if ((base & 7) == RegX8664::Encoded_Reg_esp)
203 SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, base);
204 } else if (Utils::IsInt(8, disp)) {
205 SetModRM(1, base);
206 if ((base & 7) == RegX8664::Encoded_Reg_esp)
207 SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, base);
208 SetDisp8(disp);
209 } else {
210 SetModRM(2, base);
211 if ((base & 7) == RegX8664::Encoded_Reg_esp)
212 SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, base);
213 SetDisp32(disp);
214 }
215 }
216
217 Address(GPRRegister index, ScaleFactor scale, int32_t disp) {
218 assert(index != RegX8664::Encoded_Reg_esp); // Illegal addressing mode.
219 SetModRM(0, RegX8664::Encoded_Reg_esp);
220 SetSIB(scale, index, RegX8664::Encoded_Reg_ebp);
221 SetDisp32(disp);
222 }
223
224 Address(GPRRegister base, GPRRegister index, ScaleFactor scale,
225 int32_t disp) {
226 assert(index != RegX8664::Encoded_Reg_esp); // Illegal addressing mode.
227 if (disp == 0 && (base & 7) != RegX8664::Encoded_Reg_ebp) {
228 SetModRM(0, RegX8664::Encoded_Reg_esp);
229 SetSIB(scale, index, base);
230 } else if (Utils::IsInt(8, disp)) {
231 SetModRM(1, RegX8664::Encoded_Reg_esp);
232 SetSIB(scale, index, base);
233 SetDisp8(disp);
234 } else {
235 SetModRM(2, RegX8664::Encoded_Reg_esp);
236 SetSIB(scale, index, base);
237 SetDisp32(disp);
238 }
239 }
240
241 // PcRelTag is a special tag for requesting rip-relative addressing in
242 // X86-64.
243 // TODO(jpp): this is bogus. remove.
244 enum AbsoluteTag { ABSOLUTE };
245
246 Address(AbsoluteTag, const uintptr_t Addr) {
247 SetModRM(0, RegX8664::Encoded_Reg_ebp);
248 SetDisp32(Addr);
249 }
250
251 // TODO(jpp): remove this.
252 static Address Absolute(const uintptr_t Addr) {
253 return Address(ABSOLUTE, Addr);
254 }
255
256 Address(AbsoluteTag, RelocOffsetT Offset, AssemblerFixup *Fixup) {
257 SetModRM(0, RegX8664::Encoded_Reg_ebp);
258 // Use the Offset in the displacement for now. If we decide to process
259 // fixups later, we'll need to patch up the emitted displacement.
260 SetDisp32(Offset);
261 SetFixup(Fixup);
262 }
263
264 // TODO(jpp): remove this.
265 static Address Absolute(RelocOffsetT Offset, AssemblerFixup *Fixup) {
266 return Address(ABSOLUTE, Offset, Fixup);
267 }
268
269 static Address ofConstPool(Assembler *Asm, const Constant *Imm) {
270 // TODO(jpp): ???
271 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Imm);
272 const RelocOffsetT Offset = 0;
273 return Address(ABSOLUTE, Offset, Fixup);
274 }
275 };
276
277 //----------------------------------------------------------------------------
278 // __ ______ __ __ ______ ______ __ __ __ ______
279 // /\ \ /\ __ \/\ \ _ \ \/\ ___\/\ == \/\ \/\ "-.\ \/\ ___\
280 // \ \ \___\ \ \/\ \ \ \/ ".\ \ \ __\\ \ __<\ \ \ \ \-. \ \ \__ \
281 // \ \_____\ \_____\ \__/".~\_\ \_____\ \_\ \_\ \_\ \_\\"\_\ \_____\
282 // \/_____/\/_____/\/_/ \/_/\/_____/\/_/ /_/\/_/\/_/ \/_/\/_____/
283 //
284 //----------------------------------------------------------------------------
285 using Assembler = X8664::AssemblerX8664;
286 };
287
288 } // end of namespace X86Internal
289
290 namespace X8664 {
291 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8664>;
292 } // end of namespace X8664
293
294 } // end of namespace Ice
295
296 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698