OLD | NEW |
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 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
11 // consists almost entirely of the lowering sequence for each | 11 // consists almost entirely of the lowering sequence for each |
12 // high-level instruction. It also implements | 12 // high-level instruction. It also implements |
13 // TargetX8632Fast::postLower() which does the simplest possible | 13 // TargetX8632Fast::postLower() which does the simplest possible |
14 // register allocation for the "fast" target. | 14 // register allocation for the "fast" target. |
15 // | 15 // |
16 //===----------------------------------------------------------------------===// | 16 //===----------------------------------------------------------------------===// |
17 | 17 |
18 #include "llvm/ADT/DenseMap.h" | 18 #include "llvm/ADT/DenseMap.h" |
19 #include "llvm/Support/CommandLine.h" | 19 #include "llvm/Support/CommandLine.h" |
20 #include "llvm/Support/MathExtras.h" | 20 #include "llvm/Support/MathExtras.h" |
21 | 21 |
22 #include "IceCfg.h" | 22 #include "IceCfg.h" |
23 #include "IceCfgNode.h" | 23 #include "IceCfgNode.h" |
24 #include "IceClFlags.h" | 24 #include "IceClFlags.h" |
25 #include "IceDefs.h" | 25 #include "IceDefs.h" |
| 26 #include "IceGlobalInits.h" |
26 #include "IceInstX8632.h" | 27 #include "IceInstX8632.h" |
27 #include "IceOperand.h" | 28 #include "IceOperand.h" |
28 #include "IceRegistersX8632.h" | 29 #include "IceRegistersX8632.h" |
29 #include "IceTargetLoweringX8632.def" | 30 #include "IceTargetLoweringX8632.def" |
30 #include "IceTargetLoweringX8632.h" | 31 #include "IceTargetLoweringX8632.h" |
31 #include "IceUtils.h" | 32 #include "IceUtils.h" |
32 | 33 |
33 namespace Ice { | 34 namespace Ice { |
34 | 35 |
35 namespace { | 36 namespace { |
(...skipping 4390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4426 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; | 4427 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; |
4427 } | 4428 } |
4428 | 4429 |
4429 void ConstantUndef::emit(GlobalContext *) const { | 4430 void ConstantUndef::emit(GlobalContext *) const { |
4430 llvm_unreachable("undef value encountered by emitter."); | 4431 llvm_unreachable("undef value encountered by emitter."); |
4431 } | 4432 } |
4432 | 4433 |
4433 TargetGlobalInitX8632::TargetGlobalInitX8632(GlobalContext *Ctx) | 4434 TargetGlobalInitX8632::TargetGlobalInitX8632(GlobalContext *Ctx) |
4434 : TargetGlobalInitLowering(Ctx) {} | 4435 : TargetGlobalInitLowering(Ctx) {} |
4435 | 4436 |
4436 namespace { | 4437 void TargetGlobalInitX8632::lower(const GlobalAddress &Global, |
4437 char hexdigit(unsigned X) { return X < 10 ? '0' + X : 'A' + X - 10; } | 4438 bool DisableTranslation) { |
4438 } | |
4439 | |
4440 void TargetGlobalInitX8632::lower(const IceString &Name, SizeT Align, | |
4441 bool IsInternal, bool IsConst, | |
4442 bool IsZeroInitializer, SizeT Size, | |
4443 const char *Data, bool DisableTranslation) { | |
4444 if (Ctx->isVerbose()) { | 4439 if (Ctx->isVerbose()) { |
4445 // TODO: Consider moving the dump output into the driver to be | 4440 Global.dump(Ctx->getStrDump()); |
4446 // reused for all targets. | |
4447 Ostream &Str = Ctx->getStrDump(); | |
4448 Str << "@" << Name << " = " << (IsInternal ? "internal" : "external"); | |
4449 Str << (IsConst ? " constant" : " global"); | |
4450 Str << " [" << Size << " x i8] "; | |
4451 if (IsZeroInitializer) { | |
4452 Str << "zeroinitializer"; | |
4453 } else { | |
4454 Str << "c\""; | |
4455 // Code taken from PrintEscapedString() in AsmWriter.cpp. Keep | |
4456 // the strings in the same format as the .ll file for practical | |
4457 // diffing. | |
4458 for (uint64_t i = 0; i < Size; ++i) { | |
4459 unsigned char C = Data[i]; | |
4460 if (isprint(C) && C != '\\' && C != '"') | |
4461 Str << C; | |
4462 else | |
4463 Str << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F); | |
4464 } | |
4465 Str << "\""; | |
4466 } | |
4467 Str << ", align " << Align << "\n"; | |
4468 } | 4441 } |
4469 | 4442 |
4470 if (DisableTranslation) | 4443 if (DisableTranslation) |
4471 return; | 4444 return; |
4472 | 4445 |
4473 Ostream &Str = Ctx->getStrEmit(); | 4446 Ostream &Str = Ctx->getStrEmit(); |
4474 // constant: | 4447 // constant: |
4475 // .section .rodata,"a",@progbits | 4448 // .section .rodata,"a",@progbits |
4476 // .align ALIGN | 4449 // .align ALIGN |
4477 // .byte ... | 4450 // .byte ... |
4478 // .size NAME, SIZE | 4451 // .size NAME, SIZE |
4479 | 4452 |
4480 // non-constant: | 4453 // non-constant: |
4481 // .data | 4454 // .data |
4482 // .align ALIGN | 4455 // .align ALIGN |
4483 // .byte ... | 4456 // .byte ... |
4484 // .size NAME, SIZE | 4457 // .size NAME, SIZE |
4485 | 4458 |
4486 // zeroinitializer (constant): | 4459 // zeroinitializer (constant): |
4487 // (.section or .data as above) | 4460 // (.section or .data as above) |
4488 // .align ALIGN | 4461 // .align ALIGN |
4489 // .zero SIZE | 4462 // .zero SIZE |
4490 // .size NAME, SIZE | 4463 // .size NAME, SIZE |
4491 | 4464 |
4492 // zeroinitializer (non-constant): | 4465 // zeroinitializer (non-constant): |
4493 // (.section or .data as above) | 4466 // (.section or .data as above) |
4494 // .local NAME | 4467 // .local NAME |
4495 // .comm NAME, SIZE, ALIGN | 4468 // .comm NAME, SIZE, ALIGN |
4496 | 4469 |
4497 IceString MangledName = Ctx->mangleName(Name); | 4470 // TODO(kschimpf): Don't mangle name if external and uninitialized. This |
| 4471 // will allow us to cross test relocations for references to external |
| 4472 // global variables. |
| 4473 |
| 4474 IceString MangledName = Ctx->mangleName(Global.getName()); |
4498 // Start a new section. | 4475 // Start a new section. |
4499 if (IsConst) { | 4476 if (Ctx->getFlags().DataSections) { |
| 4477 Str << "\t.section\t.rodata." << MangledName << ",\"a\",@progbits\n"; |
| 4478 } else if (Global.getIsConstant()) { |
4500 Str << "\t.section\t.rodata,\"a\",@progbits\n"; | 4479 Str << "\t.section\t.rodata,\"a\",@progbits\n"; |
4501 } else { | 4480 } else { |
4502 Str << "\t.type\t" << MangledName << ",@object\n"; | 4481 Str << "\t.type\t" << MangledName << ",@object\n"; |
4503 Str << "\t.data\n"; | 4482 Str << "\t.data\n"; |
4504 } | 4483 } |
4505 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName | 4484 |
4506 << "\n"; | 4485 Str << "\t" << (Global.getIsInternal() ? ".local" : ".global") << "\t" |
4507 if (IsZeroInitializer) { | 4486 << MangledName << "\n"; |
4508 if (IsConst) { | 4487 |
4509 Str << "\t.align\t" << Align << "\n"; | 4488 const GlobalAddress::InitializerListType &Initializers = |
4510 Str << MangledName << ":\n"; | 4489 Global.getInitializers(); |
4511 Str << "\t.zero\t" << Size << "\n"; | 4490 |
4512 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4491 // Note: Handle zero initializations specially when lowering, since |
4513 } else { | 4492 // we may be able to reduce object size. |
4514 // TODO(stichnot): Put the appropriate non-constant | 4493 GlobalAddress::ZeroInitializer *SimpleZeroInit = nullptr; |
4515 // zeroinitializers in a .bss section to reduce object size. | 4494 if (Initializers.size() == 1) { |
4516 Str << "\t.comm\t" << MangledName << ", " << Size << ", " << Align | 4495 GlobalAddress::Initializer *Init = Initializers[0]; |
4517 << "\n"; | 4496 if (const auto ZeroInit = |
| 4497 llvm::dyn_cast<GlobalAddress::ZeroInitializer>(Init)) { |
| 4498 SimpleZeroInit = ZeroInit; |
4518 } | 4499 } |
| 4500 } |
| 4501 |
| 4502 if (SimpleZeroInit && !Global.getIsConstant()) { |
| 4503 // TODO(stichnot): Put the appropriate non-constant |
| 4504 // zeroinitializers in a .bss section to reduce object size. |
| 4505 Str << "\t.comm\t" << MangledName << ", " << Global.getNumBytes() << ", " |
| 4506 << Global.getAlignment() << "\n"; |
| 4507 // } |
4519 } else { | 4508 } else { |
4520 Str << "\t.align\t" << Align << "\n"; | 4509 Str << "\t.align\t" << Global.getAlignment() << "\n"; |
4521 Str << MangledName << ":\n"; | 4510 Str << MangledName << ":\n"; |
4522 for (SizeT i = 0; i < Size; ++i) { | 4511 for (GlobalAddress::Initializer *Init : Initializers) { |
4523 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 4512 switch (Init->getKind()) { |
| 4513 case GlobalAddress::Initializer::DataInitializerKind: { |
| 4514 const auto Data = |
| 4515 llvm::cast<GlobalAddress::DataInitializer>(Init)->getContents(); |
| 4516 for (SizeT i = 0; i < Init->getNumBytes(); ++i) { |
| 4517 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
| 4518 } |
| 4519 break; |
| 4520 } |
| 4521 case GlobalAddress::Initializer::ZeroInitializerKind: |
| 4522 Str << "\t.zero\t" << Init->getNumBytes() << "\n"; |
| 4523 break; |
| 4524 case GlobalAddress::Initializer::RelocInitializerKind: { |
| 4525 const auto Reloc = llvm::cast<GlobalAddress::RelocInitializer>(Init); |
| 4526 Str << "\t.long\t"; |
| 4527 // TODO(kschimpf): Once the representation of a relocation has |
| 4528 // been modified to reference the corresponding global |
| 4529 // address, modify to not mangle the name if the global is |
| 4530 // external and uninitialized. This will allow us to better |
| 4531 // test cross test relocations. |
| 4532 Str << Ctx->mangleName(Reloc->getName()); |
| 4533 if (GlobalAddress::RelocOffsetType Offset = Reloc->getOffset()) { |
| 4534 Str << " + " << Offset; |
| 4535 } |
| 4536 Str << "\n"; |
| 4537 break; |
| 4538 } |
| 4539 default: { |
| 4540 std::string Buffer; |
| 4541 llvm::raw_string_ostream StrBuf(Buffer); |
| 4542 StrBuf << "Unable to lower initializer: "; |
| 4543 Init->dump(StrBuf); |
| 4544 llvm::report_fatal_error(StrBuf.str()); |
| 4545 break; |
| 4546 } |
| 4547 } |
4524 } | 4548 } |
4525 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4549 Str << "\t.size\t" << MangledName << ", " << Global.getNumBytes() << "\n"; |
4526 } | 4550 } |
4527 } | 4551 } |
4528 | 4552 |
4529 } // end of namespace Ice | 4553 } // end of namespace Ice |
OLD | NEW |