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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 1616673004: Merge x86 data and header lowering (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Small syntactic commonality. 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
OLDNEW
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 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 /// \brief Implements the TargetLoweringX8632 class, which consists almost 11 /// \brief Implements the TargetLoweringX8632 class, which consists almost
12 /// entirely of the lowering sequence for each high-level instruction. 12 /// entirely of the lowering sequence for each high-level instruction.
13 /// 13 ///
14 //===----------------------------------------------------------------------===// 14 //===----------------------------------------------------------------------===//
15 15
16 #include "IceTargetLoweringX8632.h" 16 #include "IceTargetLoweringX8632.h"
17 17
18 #include "IceTargetLoweringX8632Traits.h" 18 #include "IceTargetLoweringX8632Traits.h"
19 19
20 namespace X8632 { 20 namespace X8632 {
21 std::unique_ptr<::Ice::TargetLowering> createTargetLowering(::Ice::Cfg *Func) { 21 std::unique_ptr<::Ice::TargetLowering> createTargetLowering(::Ice::Cfg *Func) {
22 return ::Ice::X8632::TargetX8632::create(Func); 22 return ::Ice::X8632::TargetX8632::create(Func);
23 } 23 }
24 24
25 std::unique_ptr<::Ice::TargetDataLowering> 25 std::unique_ptr<::Ice::TargetDataLowering>
26 createTargetDataLowering(::Ice::GlobalContext *Ctx) { 26 createTargetDataLowering(::Ice::GlobalContext *Ctx) {
27 return ::Ice::X8632::TargetDataX8632::create(Ctx); 27 return ::Ice::X8632::TargetDataX86<::Ice::X8632::TargetX8632Traits>::create(
28 Ctx);
28 } 29 }
29 30
30 std::unique_ptr<::Ice::TargetHeaderLowering> 31 std::unique_ptr<::Ice::TargetHeaderLowering>
31 createTargetHeaderLowering(::Ice::GlobalContext *Ctx) { 32 createTargetHeaderLowering(::Ice::GlobalContext *Ctx) {
32 return ::Ice::X8632::TargetHeaderX8632::create(Ctx); 33 return ::Ice::X8632::TargetHeaderX86::create(Ctx);
33 } 34 }
34 35
35 void staticInit(::Ice::GlobalContext *Ctx) { 36 void staticInit(::Ice::GlobalContext *Ctx) {
36 ::Ice::X8632::TargetX8632::staticInit(Ctx); 37 ::Ice::X8632::TargetX8632::staticInit(Ctx);
37 } 38 }
38 } // end of namespace X8632 39 } // end of namespace X8632
39 40
40 namespace Ice { 41 namespace Ice {
41 namespace X8632 { 42 namespace X8632 {
42 43
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 // bundle_lock 263 // bundle_lock
263 // and t, ~31 264 // and t, ~31
264 // jmp *t 265 // jmp *t
265 // bundle_unlock 266 // bundle_unlock
266 // FakeUse <original_ret_operand> 267 // FakeUse <original_ret_operand>
267 Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx); 268 Variable *T_ecx = makeReg(IceType_i32, Traits::RegisterSet::Reg_ecx);
268 _pop(T_ecx); 269 _pop(T_ecx);
269 lowerIndirectJump(T_ecx); 270 lowerIndirectJump(T_ecx);
270 } 271 }
271 272
272 void TargetX8632::emitJumpTable(const Cfg *Func,
273 const InstJumpTable *JumpTable) const {
274 if (!BuildDefs::dump())
275 return;
276 Ostream &Str = Ctx->getStrEmit();
277 const bool UseNonsfi = Ctx->getFlags().getUseNonsfi();
278 const IceString MangledName = Ctx->mangleName(Func->getFunctionName());
279 const IceString Prefix = UseNonsfi ? ".data.rel.ro." : ".rodata.";
280 Str << "\t.section\t" << Prefix << MangledName
281 << "$jumptable,\"a\",@progbits\n";
282 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n";
283 Str << InstJumpTable::makeName(MangledName, JumpTable->getId()) << ":";
284
285 // On X8632 pointers are 32-bit hence the use of .long
286 for (SizeT I = 0; I < JumpTable->getNumTargets(); ++I)
287 Str << "\n\t.long\t" << JumpTable->getTarget(I)->getAsmName();
288 Str << "\n";
289 }
290
291 TargetDataX8632::TargetDataX8632(GlobalContext *Ctx)
292 : TargetDataLowering(Ctx) {}
293
294 namespace {
295 template <typename T> struct PoolTypeConverter {};
296
297 template <> struct PoolTypeConverter<float> {
298 using PrimitiveIntType = uint32_t;
299 using IceType = ConstantFloat;
300 static const Type Ty = IceType_f32;
301 static const char *TypeName;
302 static const char *AsmTag;
303 static const char *PrintfString;
304 };
305 const char *PoolTypeConverter<float>::TypeName = "float";
306 const char *PoolTypeConverter<float>::AsmTag = ".long";
307 const char *PoolTypeConverter<float>::PrintfString = "0x%x";
308
309 template <> struct PoolTypeConverter<double> {
310 using PrimitiveIntType = uint64_t;
311 using IceType = ConstantDouble;
312 static const Type Ty = IceType_f64;
313 static const char *TypeName;
314 static const char *AsmTag;
315 static const char *PrintfString;
316 };
317 const char *PoolTypeConverter<double>::TypeName = "double";
318 const char *PoolTypeConverter<double>::AsmTag = ".quad";
319 const char *PoolTypeConverter<double>::PrintfString = "0x%llx";
320
321 // Add converter for int type constant pooling
322 template <> struct PoolTypeConverter<uint32_t> {
323 using PrimitiveIntType = uint32_t;
324 using IceType = ConstantInteger32;
325 static const Type Ty = IceType_i32;
326 static const char *TypeName;
327 static const char *AsmTag;
328 static const char *PrintfString;
329 };
330 const char *PoolTypeConverter<uint32_t>::TypeName = "i32";
331 const char *PoolTypeConverter<uint32_t>::AsmTag = ".long";
332 const char *PoolTypeConverter<uint32_t>::PrintfString = "0x%x";
333
334 // Add converter for int type constant pooling
335 template <> struct PoolTypeConverter<uint16_t> {
336 using PrimitiveIntType = uint32_t;
337 using IceType = ConstantInteger32;
338 static const Type Ty = IceType_i16;
339 static const char *TypeName;
340 static const char *AsmTag;
341 static const char *PrintfString;
342 };
343 const char *PoolTypeConverter<uint16_t>::TypeName = "i16";
344 const char *PoolTypeConverter<uint16_t>::AsmTag = ".short";
345 const char *PoolTypeConverter<uint16_t>::PrintfString = "0x%x";
346
347 // Add converter for int type constant pooling
348 template <> struct PoolTypeConverter<uint8_t> {
349 using PrimitiveIntType = uint32_t;
350 using IceType = ConstantInteger32;
351 static const Type Ty = IceType_i8;
352 static const char *TypeName;
353 static const char *AsmTag;
354 static const char *PrintfString;
355 };
356 const char *PoolTypeConverter<uint8_t>::TypeName = "i8";
357 const char *PoolTypeConverter<uint8_t>::AsmTag = ".byte";
358 const char *PoolTypeConverter<uint8_t>::PrintfString = "0x%x";
359 } // end of anonymous namespace
360
361 template <typename T>
362 void TargetDataX8632::emitConstantPool(GlobalContext *Ctx) {
363 if (!BuildDefs::dump())
364 return;
365 Ostream &Str = Ctx->getStrEmit();
366 Type Ty = T::Ty;
367 SizeT Align = typeAlignInBytes(Ty);
368 ConstantList Pool = Ctx->getConstantPool(Ty);
369
370 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align
371 << "\n";
372 Str << "\t.align\t" << Align << "\n";
373
374 // If reorder-pooled-constants option is set to true, we need to shuffle the
375 // constant pool before emitting it.
376 if (Ctx->getFlags().shouldReorderPooledConstants() && !Pool.empty()) {
377 // Use the constant's kind value as the salt for creating random number
378 // generator.
379 Operand::OperandKind K = (*Pool.begin())->getKind();
380
381 RandomNumberGenerator RNG(Ctx->getFlags().getRandomSeed(),
382 RPE_PooledConstantReordering, K);
383 RandomShuffle(Pool.begin(), Pool.end(),
384 [&RNG](uint64_t N) { return (uint32_t)RNG.next(N); });
385 }
386
387 for (Constant *C : Pool) {
388 if (!C->getShouldBePooled())
389 continue;
390 auto *Const = llvm::cast<typename T::IceType>(C);
391 typename T::IceType::PrimType Value = Const->getValue();
392 // Use memcpy() to copy bits from Value into RawValue in a way that avoids
393 // breaking strict-aliasing rules.
394 typename T::PrimitiveIntType RawValue;
395 memcpy(&RawValue, &Value, sizeof(Value));
396 char buf[30];
397 int CharsPrinted =
398 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue);
399 assert(CharsPrinted >= 0 &&
400 (size_t)CharsPrinted < llvm::array_lengthof(buf));
401 (void)CharsPrinted; // avoid warnings if asserts are disabled
402 Const->emitPoolLabel(Str, Ctx);
403 Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t/* " << T::TypeName << " "
404 << Value << " */\n";
405 }
406 }
407
408 void TargetDataX8632::lowerConstants() {
409 if (Ctx->getFlags().getDisableTranslation())
410 return;
411 // No need to emit constants from the int pool since (for x86) they are
412 // embedded as immediates in the instructions, just emit float/double.
413 switch (Ctx->getFlags().getOutFileType()) {
414 case FT_Elf: {
415 ELFObjectWriter *Writer = Ctx->getObjectWriter();
416
417 Writer->writeConstantPool<ConstantInteger32>(IceType_i8);
418 Writer->writeConstantPool<ConstantInteger32>(IceType_i16);
419 Writer->writeConstantPool<ConstantInteger32>(IceType_i32);
420
421 Writer->writeConstantPool<ConstantFloat>(IceType_f32);
422 Writer->writeConstantPool<ConstantDouble>(IceType_f64);
423 } break;
424 case FT_Asm:
425 case FT_Iasm: {
426 OstreamLocker L(Ctx);
427
428 emitConstantPool<PoolTypeConverter<uint8_t>>(Ctx);
429 emitConstantPool<PoolTypeConverter<uint16_t>>(Ctx);
430 emitConstantPool<PoolTypeConverter<uint32_t>>(Ctx);
431
432 emitConstantPool<PoolTypeConverter<float>>(Ctx);
433 emitConstantPool<PoolTypeConverter<double>>(Ctx);
434 } break;
435 }
436 }
437
438 void TargetDataX8632::lowerJumpTables() {
439 const bool IsPIC = Ctx->getFlags().getUseNonsfi();
440 switch (Ctx->getFlags().getOutFileType()) {
441 case FT_Elf: {
442 ELFObjectWriter *Writer = Ctx->getObjectWriter();
443 for (const JumpTableData &JT : Ctx->getJumpTables())
444 Writer->writeJumpTable(JT, TargetX8632::Traits::FK_Abs, IsPIC);
445 } break;
446 case FT_Asm:
447 // Already emitted from Cfg
448 break;
449 case FT_Iasm: {
450 if (!BuildDefs::dump())
451 return;
452 Ostream &Str = Ctx->getStrEmit();
453 const IceString Prefix = IsPIC ? ".data.rel.ro." : ".rodata.";
454 for (const JumpTableData &JT : Ctx->getJumpTables()) {
455 Str << "\t.section\t" << Prefix << JT.getFunctionName()
456 << "$jumptable,\"a\",@progbits\n";
457 Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n";
458 Str << InstJumpTable::makeName(JT.getFunctionName(), JT.getId()) << ":";
459
460 // On X8632 pointers are 32-bit hence the use of .long
461 for (intptr_t TargetOffset : JT.getTargetOffsets())
462 Str << "\n\t.long\t" << JT.getFunctionName() << "+" << TargetOffset;
463 Str << "\n";
464 }
465 } break;
466 }
467 }
468
469 void TargetDataX8632::lowerGlobals(const VariableDeclarationList &Vars,
470 const IceString &SectionSuffix) {
471 const bool IsPIC = Ctx->getFlags().getUseNonsfi();
472 switch (Ctx->getFlags().getOutFileType()) {
473 case FT_Elf: {
474 ELFObjectWriter *Writer = Ctx->getObjectWriter();
475 Writer->writeDataSection(Vars, TargetX8632::Traits::FK_Abs, SectionSuffix,
476 IsPIC);
477 } break;
478 case FT_Asm:
479 case FT_Iasm: {
480 const IceString &TranslateOnly = Ctx->getFlags().getTranslateOnly();
481 OstreamLocker L(Ctx);
482 for (const VariableDeclaration *Var : Vars) {
483 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) {
484 emitGlobal(*Var, SectionSuffix);
485 }
486 }
487 } break;
488 }
489 }
490
491 TargetHeaderX8632::TargetHeaderX8632(GlobalContext *Ctx)
492 : TargetHeaderLowering(Ctx) {}
493
494 // In some cases, there are x-macros tables for both high-level and low-level 273 // In some cases, there are x-macros tables for both high-level and low-level
495 // instructions/operands that use the same enum key value. The tables are kept 274 // instructions/operands that use the same enum key value. The tables are kept
496 // separate to maintain a proper separation between abstraction layers. There 275 // separate to maintain a proper separation between abstraction layers. There
497 // is a risk that the tables could get out of sync if enum values are reordered 276 // is a risk that the tables could get out of sync if enum values are reordered
498 // or if entries are added or deleted. The following dummy namespaces use 277 // or if entries are added or deleted. The following dummy namespaces use
499 // static_asserts to ensure everything is kept in sync. 278 // static_asserts to ensure everything is kept in sync.
500 279
501 namespace { 280 namespace {
502 // Validate the enum values in FCMPX8632_TABLE. 281 // Validate the enum values in FCMPX8632_TABLE.
503 namespace dummy1 { 282 namespace dummy1 {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 #define X(tag, sizeLog2, align, elts, elty, str) \ 369 #define X(tag, sizeLog2, align, elts, elty, str) \
591 static_assert(_table1_##tag == _table2_##tag, \ 370 static_assert(_table1_##tag == _table2_##tag, \
592 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); 371 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE");
593 ICETYPE_TABLE 372 ICETYPE_TABLE
594 #undef X 373 #undef X
595 } // end of namespace dummy3 374 } // end of namespace dummy3
596 } // end of anonymous namespace 375 } // end of anonymous namespace
597 376
598 } // end of namespace X8632 377 } // end of namespace X8632
599 } // end of namespace Ice 378 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698