Chromium Code Reviews| 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 |
| (...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 555 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { | 555 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { |
| 556 SizeT j = CalleeSaves.size() - i - 1; | 556 SizeT j = CalleeSaves.size() - i - 1; |
| 557 if (j == Reg_ebp && IsEbpBasedFrame) | 557 if (j == Reg_ebp && IsEbpBasedFrame) |
| 558 continue; | 558 continue; |
| 559 if (CalleeSaves[j] && RegsUsed[j]) { | 559 if (CalleeSaves[j] && RegsUsed[j]) { |
| 560 _pop(getPhysicalRegister(j)); | 560 _pop(getPhysicalRegister(j)); |
| 561 } | 561 } |
| 562 } | 562 } |
| 563 } | 563 } |
| 564 | 564 |
| 565 void TargetX8632::emitConstants() const { | |
| 566 Ostream &Str = Ctx->getStrEmit(); | |
| 567 SizeT Align; | |
| 568 Type Ty; | |
| 569 ConstantList Pool; | |
| 570 | |
| 571 // Emit constants from the float pool. | |
| 572 Ty = IceType_f32; | |
| 573 Pool = Ctx->getConstantPool(Ty); | |
| 574 Align = typeAlignInBytes(Ty); | |
| 575 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align | |
| 576 << "\n"; | |
| 577 Str << "\t.align\t" << Align << "\n"; | |
| 578 for (ConstantList::const_iterator I = Pool.begin(), E = Pool.end(); I != E; | |
| 579 ++I) { | |
| 580 ConstantFloat *Const = llvm::cast<ConstantFloat>(*I); | |
| 581 float Value = Const->getValue(); | |
| 582 // Use memcpy() to copy bits from Value into RawValue in a way | |
| 583 // that avoids breaking strict-aliasing rules. | |
| 584 uint32_t RawValue; | |
| 585 memcpy(&RawValue, &Value, sizeof(Value)); | |
| 586 Str << "L$" << Ty << "$" << Const->getPoolEntryID() << ":\n"; | |
| 587 Str << "\t.long\t" << RawValue << "\t# float " << Value << "\n"; | |
|
JF
2014/05/22 21:39:47
Can you use hex format for .long? It would be more
Jim Stichnoth
2014/05/22 23:48:28
Done.
| |
| 588 } | |
| 589 | |
| 590 // Emit constants from the float pool. | |
| 591 Ty = IceType_f64; | |
| 592 Pool = Ctx->getConstantPool(Ty); | |
| 593 Align = typeAlignInBytes(Ty); | |
| 594 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align | |
| 595 << "\n"; | |
| 596 Str << "\t.align\t" << Align << "\n"; | |
| 597 for (ConstantList::const_iterator I = Pool.begin(), E = Pool.end(); I != E; | |
| 598 ++I) { | |
| 599 ConstantDouble *Const = llvm::cast<ConstantDouble>(*I); | |
| 600 double Value = Const->getValue(); | |
| 601 // Use memcpy() to copy bits from Value into RawValue in a way | |
| 602 // that avoids breaking strict-aliasing rules. | |
| 603 uint64_t RawValue; | |
| 604 memcpy(&RawValue, &Value, sizeof(Value)); | |
| 605 Str << "L$" << Ty << "$" << Const->getPoolEntryID() << ":\n"; | |
| 606 Str << "\t.quad\t" << RawValue << "\t# double " << Value << "\n"; | |
| 607 } | |
|
JF
2014/05/22 21:39:47
Those two functions are pretty much the same thing
Jim Stichnoth
2014/05/22 23:48:28
Done. Probably break-even in terms of LOC, but st
| |
| 608 | |
| 609 // No need to emit constants from the int pool since they are | |
| 610 // embedded as immediates in the instructions. | |
|
JF
2014/05/22 21:39:47
That won't always be true on ARM.
Jim Stichnoth
2014/05/22 23:48:28
Yes, but this is in a file with X86 in its name. :
| |
| 611 } | |
| 612 | |
| 565 void TargetX8632::split64(Variable *Var) { | 613 void TargetX8632::split64(Variable *Var) { |
| 566 switch (Var->getType()) { | 614 switch (Var->getType()) { |
| 567 default: | 615 default: |
| 568 return; | 616 return; |
| 569 case IceType_i64: | 617 case IceType_i64: |
| 570 // TODO: Only consider F64 if we need to push each half when | 618 // TODO: Only consider F64 if we need to push each half when |
| 571 // passing as an argument to a function call. Note that each half | 619 // passing as an argument to a function call. Note that each half |
| 572 // is still typed as I32. | 620 // is still typed as I32. |
| 573 case IceType_f64: | 621 case IceType_f64: |
| 574 break; | 622 break; |
| (...skipping 1296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1871 } | 1919 } |
| 1872 assert(AvailableTypedRegisters.any()); | 1920 assert(AvailableTypedRegisters.any()); |
| 1873 int32_t RegNum = AvailableTypedRegisters.find_first(); | 1921 int32_t RegNum = AvailableTypedRegisters.find_first(); |
| 1874 Var->setRegNum(RegNum); | 1922 Var->setRegNum(RegNum); |
| 1875 AvailableRegisters[RegNum] = false; | 1923 AvailableRegisters[RegNum] = false; |
| 1876 } | 1924 } |
| 1877 } | 1925 } |
| 1878 } | 1926 } |
| 1879 } | 1927 } |
| 1880 | 1928 |
| 1929 template <> void ConstantFloat::emit(const Cfg *Func) const { | |
| 1930 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1931 // It would be better to prefix with ".L$" instead of "L$", but | |
| 1932 // llvm-mc doesn't parse "dword ptr [.L$foo]". | |
| 1933 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; | |
| 1934 } | |
| 1935 | |
| 1936 template <> void ConstantDouble::emit(const Cfg *Func) const { | |
| 1937 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1938 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; | |
| 1939 } | |
| 1940 | |
| 1881 } // end of namespace Ice | 1941 } // end of namespace Ice |
| OLD | NEW |