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

Side by Side Diff: src/IceTargetLoweringX8664.cpp

Issue 1257643004: Subzero. Buildable, non-functional TargetLoweringX8664. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: git pull 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
« no previous file with comments | « src/IceTargetLoweringX8664.h ('k') | src/IceTargetLoweringX8664Traits.h » ('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/IceTargetLoweringX8664.cpp - lowering for x86-64 -------===// 1 //===- subzero/src/IceTargetLoweringX8664.cpp - x86-64 lowering -----------===//
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 /// Implements the Target Lowering for x86-64. 11 /// This file implements the TargetLoweringX8664 class, which
12 /// consists almost entirely of the lowering sequence for each
13 /// high-level instruction.
12 /// 14 ///
13 //===----------------------------------------------------------------------===// 15 //===----------------------------------------------------------------------===//
14 16
15 #include "IceDefs.h"
16 #include "IceTargetLoweringX8664.h" 17 #include "IceTargetLoweringX8664.h"
17 18
19 #include "IceTargetLoweringX8664Traits.h"
20 #include "IceTargetLoweringX86Base.h"
21
18 namespace Ice { 22 namespace Ice {
19 23
24 namespace X86Internal {
25 const MachineTraits<TargetX8664>::TableFcmpType
26 MachineTraits<TargetX8664>::TableFcmp[] = {
27 #define X(val, dflt, swapS, C1, C2, swapV, pred) \
28 { \
29 dflt, swapS, X8664::Traits::Cond::C1, X8664::Traits::Cond::C2, swapV, \
30 X8664::Traits::Cond::pred \
31 } \
32 ,
33 FCMPX8664_TABLE
34 #undef X
35 };
36
37 const size_t MachineTraits<TargetX8664>::TableFcmpSize =
38 llvm::array_lengthof(TableFcmp);
39
40 const MachineTraits<TargetX8664>::TableIcmp32Type
41 MachineTraits<TargetX8664>::TableIcmp32[] = {
42 #define X(val, C_32, C1_64, C2_64, C3_64) \
43 { X8664::Traits::Cond::C_32 } \
44 ,
45 ICMPX8664_TABLE
46 #undef X
47 };
48
49 const size_t MachineTraits<TargetX8664>::TableIcmp32Size =
50 llvm::array_lengthof(TableIcmp32);
51
52 const MachineTraits<TargetX8664>::TableIcmp64Type
53 MachineTraits<TargetX8664>::TableIcmp64[] = {
54 #define X(val, C_32, C1_64, C2_64, C3_64) \
55 { \
56 X8664::Traits::Cond::C1_64, X8664::Traits::Cond::C2_64, \
57 X8664::Traits::Cond::C3_64 \
58 } \
59 ,
60 ICMPX8664_TABLE
61 #undef X
62 };
63
64 const size_t MachineTraits<TargetX8664>::TableIcmp64Size =
65 llvm::array_lengthof(TableIcmp64);
66
67 const MachineTraits<TargetX8664>::TableTypeX8664AttributesType
68 MachineTraits<TargetX8664>::TableTypeX8664Attributes[] = {
69 #define X(tag, elementty, cvt, sdss, pack, width, fld) \
70 { elementty } \
71 ,
72 ICETYPEX8664_TABLE
73 #undef X
74 };
75
76 const size_t MachineTraits<TargetX8664>::TableTypeX8664AttributesSize =
77 llvm::array_lengthof(TableTypeX8664Attributes);
78
79 const uint32_t MachineTraits<TargetX8664>::X86_STACK_ALIGNMENT_BYTES = 16;
80 const char *MachineTraits<TargetX8664>::TargetName = "X8664";
81
82 } // end of namespace X86Internal
83
84 namespace {
85 template <typename T> struct PoolTypeConverter {};
86
87 template <> struct PoolTypeConverter<float> {
88 typedef uint32_t PrimitiveIntType;
89 typedef ConstantFloat IceType;
90 static const Type Ty = IceType_f32;
91 static const char *TypeName;
92 static const char *AsmTag;
93 static const char *PrintfString;
94 };
95 const char *PoolTypeConverter<float>::TypeName = "float";
96 const char *PoolTypeConverter<float>::AsmTag = ".long";
97 const char *PoolTypeConverter<float>::PrintfString = "0x%x";
98
99 template <> struct PoolTypeConverter<double> {
100 typedef uint64_t PrimitiveIntType;
101 typedef ConstantDouble IceType;
102 static const Type Ty = IceType_f64;
103 static const char *TypeName;
104 static const char *AsmTag;
105 static const char *PrintfString;
106 };
107 const char *PoolTypeConverter<double>::TypeName = "double";
108 const char *PoolTypeConverter<double>::AsmTag = ".quad";
109 const char *PoolTypeConverter<double>::PrintfString = "0x%llx";
110
111 // Add converter for int type constant pooling
112 template <> struct PoolTypeConverter<uint32_t> {
113 typedef uint32_t PrimitiveIntType;
114 typedef ConstantInteger32 IceType;
115 static const Type Ty = IceType_i32;
116 static const char *TypeName;
117 static const char *AsmTag;
118 static const char *PrintfString;
119 };
120 const char *PoolTypeConverter<uint32_t>::TypeName = "i32";
121 const char *PoolTypeConverter<uint32_t>::AsmTag = ".long";
122 const char *PoolTypeConverter<uint32_t>::PrintfString = "0x%x";
123
124 // Add converter for int type constant pooling
125 template <> struct PoolTypeConverter<uint16_t> {
126 typedef uint32_t PrimitiveIntType;
127 typedef ConstantInteger32 IceType;
128 static const Type Ty = IceType_i16;
129 static const char *TypeName;
130 static const char *AsmTag;
131 static const char *PrintfString;
132 };
133 const char *PoolTypeConverter<uint16_t>::TypeName = "i16";
134 const char *PoolTypeConverter<uint16_t>::AsmTag = ".short";
135 const char *PoolTypeConverter<uint16_t>::PrintfString = "0x%x";
136
137 // Add converter for int type constant pooling
138 template <> struct PoolTypeConverter<uint8_t> {
139 typedef uint32_t PrimitiveIntType;
140 typedef ConstantInteger32 IceType;
141 static const Type Ty = IceType_i8;
142 static const char *TypeName;
143 static const char *AsmTag;
144 static const char *PrintfString;
145 };
146 const char *PoolTypeConverter<uint8_t>::TypeName = "i8";
147 const char *PoolTypeConverter<uint8_t>::AsmTag = ".byte";
148 const char *PoolTypeConverter<uint8_t>::PrintfString = "0x%x";
149 } // end of anonymous namespace
150
151 template <typename T>
152 void TargetDataX8664::emitConstantPool(GlobalContext *Ctx) {
153 if (!BuildDefs::dump())
154 return;
155 Ostream &Str = Ctx->getStrEmit();
156 Type Ty = T::Ty;
157 SizeT Align = typeAlignInBytes(Ty);
158 ConstantList Pool = Ctx->getConstantPool(Ty);
159
160 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align
161 << "\n";
162 Str << "\t.align\t" << Align << "\n";
163
164 // If reorder-pooled-constants option is set to true, we need to shuffle the
165 // constant pool before emitting it.
166 if (Ctx->getFlags().shouldReorderPooledConstants())
167 RandomShuffle(Pool.begin(), Pool.end(), [Ctx](uint64_t N) {
168 return (uint32_t)Ctx->getRNG().next(N);
169 });
170
171 for (Constant *C : Pool) {
172 if (!C->getShouldBePooled())
173 continue;
174 typename T::IceType *Const = llvm::cast<typename T::IceType>(C);
175 typename T::IceType::PrimType Value = Const->getValue();
176 // Use memcpy() to copy bits from Value into RawValue in a way
177 // that avoids breaking strict-aliasing rules.
178 typename T::PrimitiveIntType RawValue;
179 memcpy(&RawValue, &Value, sizeof(Value));
180 char buf[30];
181 int CharsPrinted =
182 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue);
183 assert(CharsPrinted >= 0 &&
184 (size_t)CharsPrinted < llvm::array_lengthof(buf));
185 (void)CharsPrinted; // avoid warnings if asserts are disabled
186 Const->emitPoolLabel(Str);
187 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " "
188 << Value << "\n";
189 }
190 }
191
192 void TargetDataX8664::lowerConstants() {
193 if (Ctx->getFlags().getDisableTranslation())
194 return;
195 // No need to emit constants from the int pool since (for x86) they
196 // are embedded as immediates in the instructions, just emit float/double.
197 switch (Ctx->getFlags().getOutFileType()) {
198 case FT_Elf: {
199 ELFObjectWriter *Writer = Ctx->getObjectWriter();
200
201 Writer->writeConstantPool<ConstantInteger32>(IceType_i8);
202 Writer->writeConstantPool<ConstantInteger32>(IceType_i16);
203 Writer->writeConstantPool<ConstantInteger32>(IceType_i32);
204
205 Writer->writeConstantPool<ConstantFloat>(IceType_f32);
206 Writer->writeConstantPool<ConstantDouble>(IceType_f64);
207 } break;
208 case FT_Asm:
209 case FT_Iasm: {
210 OstreamLocker L(Ctx);
211
212 emitConstantPool<PoolTypeConverter<uint8_t>>(Ctx);
213 emitConstantPool<PoolTypeConverter<uint16_t>>(Ctx);
214 emitConstantPool<PoolTypeConverter<uint32_t>>(Ctx);
215
216 emitConstantPool<PoolTypeConverter<float>>(Ctx);
217 emitConstantPool<PoolTypeConverter<double>>(Ctx);
218 } break;
219 }
220 }
221
20 void TargetX8664::emitJumpTable(const Cfg *Func, 222 void TargetX8664::emitJumpTable(const Cfg *Func,
21 const InstJumpTable *JumpTable) const { 223 const InstJumpTable *JumpTable) const {
22 (void)Func; 224 if (!BuildDefs::dump())
23 (void)JumpTable; 225 return;
24 llvm::report_fatal_error("Not yet implemented"); 226 Ostream &Str = Ctx->getStrEmit();
25 } 227 IceString MangledName = Ctx->mangleName(Func->getFunctionName());
26 228 Str << "\t.section\t.rodata." << MangledName
27 TargetX8664 *TargetX8664::create(Cfg *) { 229 << "$jumptable,\"a\",@progbits\n";
28 llvm::report_fatal_error("Not yet implemented"); 230 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n";
29 } 231 Str << InstJumpTable::makeName(MangledName, JumpTable->getId()) << ":";
30 void TargetDataX8664::lowerGlobals(const VariableDeclarationList &, 232
31 const IceString &) { 233 // On X8664 ILP32 pointers are 32-bit hence the use of .long
32 llvm::report_fatal_error("Not yet implemented"); 234 for (SizeT I = 0; I < JumpTable->getNumTargets(); ++I)
33 } 235 Str << "\n\t.long\t" << JumpTable->getTarget(I)->getAsmName();
34 236 Str << "\n";
35 void TargetDataX8664::lowerConstants() {
36 llvm::report_fatal_error("Not yet implemented");
37 } 237 }
38 238
39 void TargetDataX8664::lowerJumpTables() { 239 void TargetDataX8664::lowerJumpTables() {
40 llvm::report_fatal_error("Not yet implemented"); 240 switch (Ctx->getFlags().getOutFileType()) {
41 } 241 case FT_Elf: {
242 ELFObjectWriter *Writer = Ctx->getObjectWriter();
243 for (const JumpTableData &JumpTable : *Ctx->getJumpTables())
244 // TODO(jpp): not 386.
245 Writer->writeJumpTable(JumpTable, llvm::ELF::R_386_32);
246 } break;
247 case FT_Asm:
248 // Already emitted from Cfg
249 break;
250 case FT_Iasm: {
251 if (!BuildDefs::dump())
252 return;
253 Ostream &Str = Ctx->getStrEmit();
254 for (const JumpTableData &JT : *Ctx->getJumpTables()) {
255 Str << "\t.section\t.rodata." << JT.getFunctionName()
256 << "$jumptable,\"a\",@progbits\n";
257 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n";
258 Str << InstJumpTable::makeName(JT.getFunctionName(), JT.getId()) << ":";
259
260 // On X8664 ILP32 pointers are 32-bit hence the use of .long
261 for (intptr_t TargetOffset : JT.getTargetOffsets())
262 Str << "\n\t.long\t" << JT.getFunctionName() << "+" << TargetOffset;
263 Str << "\n";
264 }
265 } break;
266 }
267 }
268
269 void TargetDataX8664::lowerGlobals(const VariableDeclarationList &Vars,
270 const IceString &SectionSuffix) {
271 switch (Ctx->getFlags().getOutFileType()) {
272 case FT_Elf: {
273 ELFObjectWriter *Writer = Ctx->getObjectWriter();
274 // TODO(jpp): not 386.
275 Writer->writeDataSection(Vars, llvm::ELF::R_386_32, SectionSuffix);
276 } break;
277 case FT_Asm:
278 case FT_Iasm: {
279 const IceString &TranslateOnly = Ctx->getFlags().getTranslateOnly();
280 OstreamLocker L(Ctx);
281 for (const VariableDeclaration *Var : Vars) {
282 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) {
283 emitGlobal(*Var, SectionSuffix);
284 }
285 }
286 } break;
287 }
288 }
289
290 // In some cases, there are x-macros tables for both high-level and
291 // low-level instructions/operands that use the same enum key value.
292 // The tables are kept separate to maintain a proper separation
293 // between abstraction layers. There is a risk that the tables could
294 // get out of sync if enum values are reordered or if entries are
295 // added or deleted. The following dummy namespaces use
296 // static_asserts to ensure everything is kept in sync.
297
298 namespace {
299 // Validate the enum values in FCMPX8664_TABLE.
300 namespace dummy1 {
301 // Define a temporary set of enum values based on low-level table
302 // entries.
303 enum _tmp_enum {
304 #define X(val, dflt, swapS, C1, C2, swapV, pred) _tmp_##val,
305 FCMPX8664_TABLE
306 #undef X
307 _num
308 };
309 // Define a set of constants based on high-level table entries.
310 #define X(tag, str) static const int _table1_##tag = InstFcmp::tag;
311 ICEINSTFCMP_TABLE
312 #undef X
313 // Define a set of constants based on low-level table entries, and
314 // ensure the table entry keys are consistent.
315 #define X(val, dflt, swapS, C1, C2, swapV, pred) \
316 static const int _table2_##val = _tmp_##val; \
317 static_assert( \
318 _table1_##val == _table2_##val, \
319 "Inconsistency between FCMPX8664_TABLE and ICEINSTFCMP_TABLE");
320 FCMPX8664_TABLE
321 #undef X
322 // Repeat the static asserts with respect to the high-level table
323 // entries in case the high-level table has extra entries.
324 #define X(tag, str) \
325 static_assert( \
326 _table1_##tag == _table2_##tag, \
327 "Inconsistency between FCMPX8664_TABLE and ICEINSTFCMP_TABLE");
328 ICEINSTFCMP_TABLE
329 #undef X
330 } // end of namespace dummy1
331
332 // Validate the enum values in ICMPX8664_TABLE.
333 namespace dummy2 {
334 // Define a temporary set of enum values based on low-level table
335 // entries.
336 enum _tmp_enum {
337 #define X(val, C_32, C1_64, C2_64, C3_64) _tmp_##val,
338 ICMPX8664_TABLE
339 #undef X
340 _num
341 };
342 // Define a set of constants based on high-level table entries.
343 #define X(tag, str) static const int _table1_##tag = InstIcmp::tag;
344 ICEINSTICMP_TABLE
345 #undef X
346 // Define a set of constants based on low-level table entries, and
347 // ensure the table entry keys are consistent.
348 #define X(val, C_32, C1_64, C2_64, C3_64) \
349 static const int _table2_##val = _tmp_##val; \
350 static_assert( \
351 _table1_##val == _table2_##val, \
352 "Inconsistency between ICMPX8664_TABLE and ICEINSTICMP_TABLE");
353 ICMPX8664_TABLE
354 #undef X
355 // Repeat the static asserts with respect to the high-level table
356 // entries in case the high-level table has extra entries.
357 #define X(tag, str) \
358 static_assert( \
359 _table1_##tag == _table2_##tag, \
360 "Inconsistency between ICMPX8664_TABLE and ICEINSTICMP_TABLE");
361 ICEINSTICMP_TABLE
362 #undef X
363 } // end of namespace dummy2
364
365 // Validate the enum values in ICETYPEX8664_TABLE.
366 namespace dummy3 {
367 // Define a temporary set of enum values based on low-level table
368 // entries.
369 enum _tmp_enum {
370 #define X(tag, elementty, cvt, sdss, pack, width, fld) _tmp_##tag,
371 ICETYPEX8664_TABLE
372 #undef X
373 _num
374 };
375 // Define a set of constants based on high-level table entries.
376 #define X(tag, sizeLog2, align, elts, elty, str) \
377 static const int _table1_##tag = tag;
378 ICETYPE_TABLE
379 #undef X
380 // Define a set of constants based on low-level table entries, and
381 // ensure the table entry keys are consistent.
382 #define X(tag, elementty, cvt, sdss, pack, width, fld) \
383 static const int _table2_##tag = _tmp_##tag; \
384 static_assert(_table1_##tag == _table2_##tag, \
385 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE");
386 ICETYPEX8664_TABLE
387 #undef X
388 // Repeat the static asserts with respect to the high-level table
389 // entries in case the high-level table has extra entries.
390 #define X(tag, sizeLog2, align, elts, elty, str) \
391 static_assert(_table1_##tag == _table2_##tag, \
392 "Inconsistency between ICETYPEX8664_TABLE and ICETYPE_TABLE");
393 ICETYPE_TABLE
394 #undef X
395 } // end of namespace dummy3
396 } // end of anonymous namespace
42 397
43 } // end of namespace Ice 398 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringX8664.h ('k') | src/IceTargetLoweringX8664Traits.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698