OLD | NEW |
---|---|
1 // | 1 // |
2 // The Subzero Code Generator | 2 // The Subzero Code Generator |
3 // | 3 // |
4 // This file is distributed under the University of Illinois Open Source | 4 // This file is distributed under the University of Illinois Open Source |
5 // License. See LICENSE.TXT for details. | 5 // License. See LICENSE.TXT for details. |
6 // | 6 // |
7 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
8 /// | 8 /// |
9 /// \file | 9 /// \file |
10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost | 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost |
(...skipping 3403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3414 OstreamLocker L(Ctx); | 3414 OstreamLocker L(Ctx); |
3415 for (const VariableDeclaration *Var : Vars) { | 3415 for (const VariableDeclaration *Var : Vars) { |
3416 if (getFlags().matchTranslateOnly(Var->getName(), 0)) { | 3416 if (getFlags().matchTranslateOnly(Var->getName(), 0)) { |
3417 emitGlobal(*Var, SectionSuffix); | 3417 emitGlobal(*Var, SectionSuffix); |
3418 } | 3418 } |
3419 } | 3419 } |
3420 } break; | 3420 } break; |
3421 } | 3421 } |
3422 } | 3422 } |
3423 | 3423 |
3424 namespace { | |
3425 template <typename T> struct ConstantPoolEmitterTraits; | |
3426 | |
3427 static_assert(sizeof(uint64_t) == 8, | |
3428 "uint64_t is supposed to be 8 bytes wide."); | |
3429 | |
3430 // TODO(jaydeep.patil): implement the following when implementing constant | |
3431 // randomization: | |
3432 // * template <> struct ConstantPoolEmitterTraits<uint8_t> | |
3433 // * template <> struct ConstantPoolEmitterTraits<uint16_t> | |
3434 // * template <> struct ConstantPoolEmitterTraits<uint32_t> | |
3435 template <> struct ConstantPoolEmitterTraits<float> { | |
3436 using ConstantType = ConstantFloat; | |
3437 static constexpr Type IceType = IceType_f32; | |
3438 // AsmTag and TypeName can't be constexpr because llvm::StringRef is unhappy | |
3439 // about them being constexpr. | |
3440 static const char AsmTag[]; | |
3441 static const char TypeName[]; | |
3442 static uint64_t bitcastToUint64(float Value) { | |
3443 static_assert(sizeof(Value) == sizeof(uint32_t), | |
3444 "Float should be 4 bytes."); | |
3445 const uint32_t IntValue = Utils::bitCopy<uint32_t>(Value); | |
3446 return static_cast<uint64_t>(IntValue); | |
3447 } | |
3448 }; | |
3449 const char ConstantPoolEmitterTraits<float>::AsmTag[] = ".word"; | |
3450 const char ConstantPoolEmitterTraits<float>::TypeName[] = "f32"; | |
3451 | |
3452 template <> struct ConstantPoolEmitterTraits<double> { | |
3453 using ConstantType = ConstantDouble; | |
3454 static constexpr Type IceType = IceType_f64; | |
3455 static const char AsmTag[]; | |
3456 static const char TypeName[]; | |
3457 static uint64_t bitcastToUint64(double Value) { | |
3458 static_assert(sizeof(double) == sizeof(uint64_t), | |
3459 "Double should be 8 bytes."); | |
3460 return Utils::bitCopy<uint64_t>(Value); | |
3461 } | |
3462 }; | |
3463 const char ConstantPoolEmitterTraits<double>::AsmTag[] = ".word"; | |
Jim Stichnoth
2016/09/19 20:50:14
I was wondering about the use of ".word" for both
jaydeep.patil
2016/09/20 07:28:27
Done.
| |
3464 const char ConstantPoolEmitterTraits<double>::TypeName[] = "f64"; | |
3465 | |
3466 template <typename T> | |
3467 void emitConstant( | |
3468 Ostream &Str, | |
3469 const typename ConstantPoolEmitterTraits<T>::ConstantType *Const) { | |
3470 if (!BuildDefs::dump()) | |
3471 return; | |
3472 using Traits = ConstantPoolEmitterTraits<T>; | |
3473 Str << Const->getLabelName(); | |
3474 T Value = Const->getValue(); | |
3475 if (Traits::IceType == IceType_f64) { | |
3476 uint64_t BitValue = Traits::bitcastToUint64(Value); | |
3477 uint32_t BitValueHi = (BitValue >> 32) & 0xffffffff; | |
3478 uint32_t BitValueLo = BitValue & 0xffffffff; | |
3479 Str << ":\n\t" << Traits::AsmTag << "\t0x"; | |
3480 Str.write_hex(BitValueHi); | |
3481 Str << "\n\t" << Traits::AsmTag << "\t0x"; | |
3482 Str.write_hex(BitValueLo); | |
3483 } else { | |
3484 Str << ":\n\t" << Traits::AsmTag << "\t0x"; | |
3485 Str.write_hex(Traits::bitcastToUint64(Value)); | |
3486 } | |
3487 Str << "\t/* " << Traits::TypeName << " " << Value << " */\n"; | |
3488 } | |
3489 | |
3490 template <typename T> void emitConstantPool(GlobalContext *Ctx) { | |
3491 if (!BuildDefs::dump()) | |
3492 return; | |
3493 using Traits = ConstantPoolEmitterTraits<T>; | |
3494 static constexpr size_t MinimumAlignment = 4; | |
3495 SizeT Align = std::max(MinimumAlignment, typeAlignInBytes(Traits::IceType)); | |
3496 assert((Align % 4) == 0 && "Constants should be aligned"); | |
3497 Ostream &Str = Ctx->getStrEmit(); | |
3498 ConstantList Pool = Ctx->getConstantPool(Traits::IceType); | |
3499 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",%progbits," << Align | |
3500 << "\n" | |
3501 << "\t.align\t" << (Align == 4 ? 2 : 3) << "\n"; | |
3502 if (getFlags().getReorderPooledConstants()) { | |
3503 // TODO(jaydeep.patil): add constant pooling. | |
3504 UnimplementedError(getFlags()); | |
3505 } | |
3506 for (Constant *C : Pool) { | |
3507 if (!C->getShouldBePooled()) { | |
3508 continue; | |
3509 } | |
3510 emitConstant<T>(Str, llvm::dyn_cast<typename Traits::ConstantType>(C)); | |
3511 } | |
3512 } | |
3513 } // end of anonymous namespace | |
3514 | |
3424 void TargetDataMIPS32::lowerConstants() { | 3515 void TargetDataMIPS32::lowerConstants() { |
3425 if (getFlags().getDisableTranslation()) | 3516 if (getFlags().getDisableTranslation()) |
3426 return; | 3517 return; |
3518 switch (getFlags().getOutFileType()) { | |
3519 case FT_Elf: { | |
3520 ELFObjectWriter *Writer = Ctx->getObjectWriter(); | |
3521 Writer->writeConstantPool<ConstantFloat>(IceType_f32); | |
3522 Writer->writeConstantPool<ConstantDouble>(IceType_f64); | |
3523 } break; | |
3524 case FT_Asm: | |
3525 case FT_Iasm: { | |
3526 OstreamLocker _(Ctx); | |
3527 emitConstantPool<float>(Ctx); | |
3528 emitConstantPool<double>(Ctx); | |
3529 break; | |
3530 } | |
3531 } | |
3427 } | 3532 } |
3428 | 3533 |
3429 void TargetDataMIPS32::lowerJumpTables() { | 3534 void TargetDataMIPS32::lowerJumpTables() { |
3430 if (getFlags().getDisableTranslation()) | 3535 if (getFlags().getDisableTranslation()) |
3431 return; | 3536 return; |
3432 } | 3537 } |
3433 | 3538 |
3434 // Helper for legalize() to emit the right code to lower an operand to a | 3539 // Helper for legalize() to emit the right code to lower an operand to a |
3435 // register of the appropriate type. | 3540 // register of the appropriate type. |
3436 Variable *TargetMIPS32::copyToReg(Operand *Src, RegNumT RegNum) { | 3541 Variable *TargetMIPS32::copyToReg(Operand *Src, RegNumT RegNum) { |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3667 Str << "\t.set\t" | 3772 Str << "\t.set\t" |
3668 << "nomips16\n"; | 3773 << "nomips16\n"; |
3669 } | 3774 } |
3670 | 3775 |
3671 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 3776 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
3672 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 3777 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
3673 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 3778 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
3674 | 3779 |
3675 } // end of namespace MIPS32 | 3780 } // end of namespace MIPS32 |
3676 } // end of namespace Ice | 3781 } // end of namespace Ice |
OLD | NEW |