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

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2351583002: [SubZero] lower float and double constants for MIPS (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addressed review comments Created 4 years, 3 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 // 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 1467 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 Target->_mov(DstFPRLo, SrcGPRHi); 1478 Target->_mov(DstFPRLo, SrcGPRHi);
1479 Legalized = true; 1479 Legalized = true;
1480 } else { 1480 } else {
1481 Variable *SrcGPR = Target->makeReg(IceType_f32, SRegNum); 1481 Variable *SrcGPR = Target->makeReg(IceType_f32, SRegNum);
1482 Variable *DstFPR = Target->makeReg(IceType_i32, DRegNum); 1482 Variable *DstFPR = Target->makeReg(IceType_i32, DRegNum);
1483 Target->_mov(DstFPR, SrcGPR); 1483 Target->_mov(DstFPR, SrcGPR);
1484 Legalized = true; 1484 Legalized = true;
1485 } 1485 }
1486 } else { 1486 } else {
1487 // Dest is FPR and SrcR is GPR. Use mtc1. 1487 // Dest is FPR and SrcR is GPR. Use mtc1.
1488 if (typeWidthInBytes(SrcR->getType()) == 8) { 1488 if (typeWidthInBytes(Dest->getType()) == 8) {
1489 // Split it into two mtc1 instructions 1489 Variable *SrcGPRHi, *SrcGPRLo;
1490 Variable *SrcGPRHi = Target->makeReg( 1490 // SrcR could be $zero which is i32
1491 IceType_i32, RegMIPS32::get64PairFirstRegNum(SRegNum)); 1491 if (SRegNum == RegMIPS32::Reg_ZERO) {
1492 Variable *SrcGPRLo = Target->makeReg( 1492 SrcGPRHi = Target->makeReg(IceType_i32, SRegNum);
1493 IceType_i32, RegMIPS32::get64PairSecondRegNum(SRegNum)); 1493 SrcGPRLo = SrcGPRHi;
1494 } else {
1495 // Split it into two mtc1 instructions
1496 SrcGPRHi = Target->makeReg(
1497 IceType_i32, RegMIPS32::get64PairFirstRegNum(SRegNum));
1498 SrcGPRLo = Target->makeReg(
1499 IceType_i32, RegMIPS32::get64PairSecondRegNum(SRegNum));
1500 }
1494 Variable *DstFPRHi = Target->makeReg( 1501 Variable *DstFPRHi = Target->makeReg(
1495 IceType_f32, RegMIPS32::get64PairFirstRegNum(DRegNum)); 1502 IceType_f32, RegMIPS32::get64PairFirstRegNum(DRegNum));
1496 Variable *DstFPRLo = Target->makeReg( 1503 Variable *DstFPRLo = Target->makeReg(
1497 IceType_f32, RegMIPS32::get64PairSecondRegNum(DRegNum)); 1504 IceType_f32, RegMIPS32::get64PairSecondRegNum(DRegNum));
1498 Target->_mov(DstFPRHi, SrcGPRLo); 1505 Target->_mov(DstFPRHi, SrcGPRLo);
1499 Target->_mov(DstFPRLo, SrcGPRHi); 1506 Target->_mov(DstFPRLo, SrcGPRHi);
1500 Legalized = true; 1507 Legalized = true;
1501 } else { 1508 } else {
1502 Variable *SrcGPR = Target->makeReg(IceType_i32, SRegNum); 1509 Variable *SrcGPR = Target->makeReg(IceType_i32, SRegNum);
1503 Variable *DstFPR = Target->makeReg(IceType_f32, DRegNum); 1510 Variable *DstFPR = Target->makeReg(IceType_f32, DRegNum);
(...skipping 1910 matching lines...) Expand 10 before | Expand all | Expand 10 after
3414 OstreamLocker L(Ctx); 3421 OstreamLocker L(Ctx);
3415 for (const VariableDeclaration *Var : Vars) { 3422 for (const VariableDeclaration *Var : Vars) {
3416 if (getFlags().matchTranslateOnly(Var->getName(), 0)) { 3423 if (getFlags().matchTranslateOnly(Var->getName(), 0)) {
3417 emitGlobal(*Var, SectionSuffix); 3424 emitGlobal(*Var, SectionSuffix);
3418 } 3425 }
3419 } 3426 }
3420 } break; 3427 } break;
3421 } 3428 }
3422 } 3429 }
3423 3430
3431 namespace {
3432 template <typename T> struct ConstantPoolEmitterTraits;
3433
3434 static_assert(sizeof(uint64_t) == 8,
3435 "uint64_t is supposed to be 8 bytes wide.");
3436
3437 // TODO(jaydeep.patil): implement the following when implementing constant
3438 // randomization:
3439 // * template <> struct ConstantPoolEmitterTraits<uint8_t>
3440 // * template <> struct ConstantPoolEmitterTraits<uint16_t>
3441 // * template <> struct ConstantPoolEmitterTraits<uint32_t>
3442 template <> struct ConstantPoolEmitterTraits<float> {
3443 using ConstantType = ConstantFloat;
3444 static constexpr Type IceType = IceType_f32;
3445 // AsmTag and TypeName can't be constexpr because llvm::StringRef is unhappy
3446 // about them being constexpr.
3447 static const char AsmTag[];
3448 static const char TypeName[];
3449 static uint64_t bitcastToUint64(float Value) {
3450 static_assert(sizeof(Value) == sizeof(uint32_t),
3451 "Float should be 4 bytes.");
3452 const uint32_t IntValue = Utils::bitCopy<uint32_t>(Value);
3453 return static_cast<uint64_t>(IntValue);
3454 }
3455 };
3456 const char ConstantPoolEmitterTraits<float>::AsmTag[] = ".word";
3457 const char ConstantPoolEmitterTraits<float>::TypeName[] = "f32";
3458
3459 template <> struct ConstantPoolEmitterTraits<double> {
3460 using ConstantType = ConstantDouble;
3461 static constexpr Type IceType = IceType_f64;
3462 static const char AsmTag[];
3463 static const char TypeName[];
3464 static uint64_t bitcastToUint64(double Value) {
3465 static_assert(sizeof(double) == sizeof(uint64_t),
3466 "Double should be 8 bytes.");
3467 return Utils::bitCopy<uint64_t>(Value);
3468 }
3469 };
3470 const char ConstantPoolEmitterTraits<double>::AsmTag[] = ".quad";
3471 const char ConstantPoolEmitterTraits<double>::TypeName[] = "f64";
3472
3473 template <typename T>
3474 void emitConstant(
3475 Ostream &Str,
3476 const typename ConstantPoolEmitterTraits<T>::ConstantType *Const) {
3477 if (!BuildDefs::dump())
3478 return;
3479 using Traits = ConstantPoolEmitterTraits<T>;
3480 Str << Const->getLabelName();
3481 T Value = Const->getValue();
3482 Str << ":\n\t" << Traits::AsmTag << "\t0x";
3483 Str.write_hex(Traits::bitcastToUint64(Value));
3484 Str << "\t/* " << Traits::TypeName << " " << Value << " */\n";
3485 }
3486
3487 template <typename T> void emitConstantPool(GlobalContext *Ctx) {
3488 if (!BuildDefs::dump())
3489 return;
3490 using Traits = ConstantPoolEmitterTraits<T>;
3491 static constexpr size_t MinimumAlignment = 4;
3492 SizeT Align = std::max(MinimumAlignment, typeAlignInBytes(Traits::IceType));
3493 assert((Align % 4) == 0 && "Constants should be aligned");
3494 Ostream &Str = Ctx->getStrEmit();
3495 ConstantList Pool = Ctx->getConstantPool(Traits::IceType);
3496 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",%progbits," << Align
3497 << "\n"
3498 << "\t.align\t" << (Align == 4 ? 2 : 3) << "\n";
3499 if (getFlags().getReorderPooledConstants()) {
3500 // TODO(jaydeep.patil): add constant pooling.
3501 UnimplementedError(getFlags());
3502 }
3503 for (Constant *C : Pool) {
3504 if (!C->getShouldBePooled()) {
3505 continue;
3506 }
3507 emitConstant<T>(Str, llvm::dyn_cast<typename Traits::ConstantType>(C));
3508 }
3509 }
3510 } // end of anonymous namespace
3511
3424 void TargetDataMIPS32::lowerConstants() { 3512 void TargetDataMIPS32::lowerConstants() {
3425 if (getFlags().getDisableTranslation()) 3513 if (getFlags().getDisableTranslation())
3426 return; 3514 return;
3515 switch (getFlags().getOutFileType()) {
3516 case FT_Elf: {
3517 ELFObjectWriter *Writer = Ctx->getObjectWriter();
3518 Writer->writeConstantPool<ConstantFloat>(IceType_f32);
3519 Writer->writeConstantPool<ConstantDouble>(IceType_f64);
3520 } break;
3521 case FT_Asm:
3522 case FT_Iasm: {
3523 OstreamLocker _(Ctx);
3524 emitConstantPool<float>(Ctx);
3525 emitConstantPool<double>(Ctx);
3526 break;
3527 }
3528 }
3427 } 3529 }
3428 3530
3429 void TargetDataMIPS32::lowerJumpTables() { 3531 void TargetDataMIPS32::lowerJumpTables() {
3430 if (getFlags().getDisableTranslation()) 3532 if (getFlags().getDisableTranslation())
3431 return; 3533 return;
3432 } 3534 }
3433 3535
3434 // Helper for legalize() to emit the right code to lower an operand to a 3536 // Helper for legalize() to emit the right code to lower an operand to a
3435 // register of the appropriate type. 3537 // register of the appropriate type.
3436 Variable *TargetMIPS32::copyToReg(Operand *Src, RegNumT RegNum) { 3538 Variable *TargetMIPS32::copyToReg(Operand *Src, RegNumT RegNum) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
3538 Variable *TReg = makeReg(Ty, RegNum); 3640 Variable *TReg = makeReg(Ty, RegNum);
3539 if (LowerBits) { 3641 if (LowerBits) {
3540 _lui(TReg, Ctx->getConstantInt32(UpperBits)); 3642 _lui(TReg, Ctx->getConstantInt32(UpperBits));
3541 _ori(Reg, TReg, LowerBits); 3643 _ori(Reg, TReg, LowerBits);
3542 } else { 3644 } else {
3543 _lui(Reg, Ctx->getConstantInt32(UpperBits)); 3645 _lui(Reg, Ctx->getConstantInt32(UpperBits));
3544 } 3646 }
3545 } 3647 }
3546 return Reg; 3648 return Reg;
3547 } else if (isScalarFloatingType(Ty)) { 3649 } else if (isScalarFloatingType(Ty)) {
3548 // Load floats/doubles from literal pool.
3549 auto *CFrom = llvm::cast<Constant>(From); 3650 auto *CFrom = llvm::cast<Constant>(From);
3550 assert(CFrom->getShouldBePooled()); 3651 Variable *TReg = makeReg(Ty);
3551 Constant *Offset = Ctx->getConstantSym(0, CFrom->getLabelName()); 3652 if (!CFrom->getShouldBePooled()) {
3552 Variable *TReg1 = makeReg(getPointerType()); 3653 // Float/Double constant 0 is not pooled.
3553 Variable *TReg2 = makeReg(Ty); 3654 Context.insert<InstFakeDef>(TReg);
3554 Context.insert<InstFakeDef>(TReg2); 3655 _mov(TReg, getZero());
3555 _lui(TReg1, Offset, RO_Hi); 3656 } else {
3556 OperandMIPS32Mem *Addr = 3657 // Load floats/doubles from literal pool.
3557 OperandMIPS32Mem::create(Func, Ty, TReg1, Offset); 3658 Constant *Offset = Ctx->getConstantSym(0, CFrom->getLabelName());
3558 if (Ty == IceType_f32) 3659 Variable *TReg1 = makeReg(getPointerType());
3559 _lwc1(TReg2, Addr, RO_Lo); 3660 _lui(TReg1, Offset, RO_Hi);
3560 else 3661 OperandMIPS32Mem *Addr =
3561 _ldc1(TReg2, Addr, RO_Lo); 3662 OperandMIPS32Mem::create(Func, Ty, TReg1, Offset);
3562 return copyToReg(TReg2, RegNum); 3663 if (Ty == IceType_f32)
3664 _lwc1(TReg, Addr, RO_Lo);
3665 else
3666 _ldc1(TReg, Addr, RO_Lo);
3667 }
3668 return copyToReg(TReg, RegNum);
3563 } 3669 }
3564 } 3670 }
3565 3671
3566 if (auto *Var = llvm::dyn_cast<Variable>(From)) { 3672 if (auto *Var = llvm::dyn_cast<Variable>(From)) {
3567 if (Var->isRematerializable()) { 3673 if (Var->isRematerializable()) {
3568 if (Allowed & Legal_Rematerializable) { 3674 if (Allowed & Legal_Rematerializable) {
3569 return From; 3675 return From;
3570 } 3676 }
3571 3677
3572 Variable *T = makeReg(Var->getType(), RegNum); 3678 Variable *T = makeReg(Var->getType(), RegNum);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
3667 Str << "\t.set\t" 3773 Str << "\t.set\t"
3668 << "nomips16\n"; 3774 << "nomips16\n";
3669 } 3775 }
3670 3776
3671 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; 3777 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
3672 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; 3778 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
3673 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; 3779 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
3674 3780
3675 } // end of namespace MIPS32 3781 } // end of namespace MIPS32
3676 } // end of namespace Ice 3782 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698