Chromium Code Reviews| 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 |