Chromium Code Reviews| Index: src/IceTargetLoweringMIPS32.cpp |
| diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp |
| index a2e82b266535a2149254aac634e52fbb1d6ef343..6fcb8d4383fafa0f8f2ae9191a919292d2c4fda8 100644 |
| --- a/src/IceTargetLoweringMIPS32.cpp |
| +++ b/src/IceTargetLoweringMIPS32.cpp |
| @@ -395,6 +395,7 @@ void TargetMIPS32::lowerArguments() { |
| // on patches. |
| // |
| unsigned NumGPRRegsUsed = 0; |
| + |
| // For each register argument, replace Arg in the argument list with the |
| // home register. Then generate an instruction in the prolog to copy the |
| // home register to the assigned location of Arg. |
| @@ -408,10 +409,13 @@ void TargetMIPS32::lowerArguments() { |
| UnimplementedError(getFlags()); |
| continue; |
| } |
| + |
| if (isFloatingType(Ty)) { |
| + assert(Ty = IceType_f32); |
|
Jim Stichnoth
2016/05/19 23:12:25
Is this really necessary, given the UnimplementedE
obucinac
2016/05/27 11:13:18
Done.
|
| UnimplementedError(getFlags()); |
| continue; |
| } |
| + |
| if (Ty == IceType_i64) { |
| if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG) |
| continue; |
| @@ -1276,6 +1280,12 @@ void TargetMIPS32::lowerRet(const InstRet *Instr) { |
| if (Instr->hasRetValue()) { |
| Operand *Src0 = Instr->getRetValue(); |
| switch (Src0->getType()) { |
| + case IceType_f32: { |
| + Operand *Src0F = legalize(Src0, Legal_Reg); |
| + Reg = makeReg(Src0F->getType(), RegMIPS32::Reg_V0); |
|
Jim Stichnoth
2016/05/19 23:12:25
Should this be Reg_F0 instead?
obucinac
2016/05/27 11:13:18
We need to rework this to o32 convention. Leaving
|
| + _mov(Reg, Src0F); |
| + break; |
| + } |
| case IceType_i1: |
| case IceType_i8: |
| case IceType_i16: |
| @@ -1403,7 +1413,9 @@ void TargetDataMIPS32::lowerJumpTables() { |
| Variable *TargetMIPS32::copyToReg(Operand *Src, RegNumT RegNum) { |
| Type Ty = Src->getType(); |
| Variable *Reg = makeReg(Ty, RegNum); |
| - if (isVectorType(Ty) || isFloatingType(Ty)) { |
| + if (isVectorType(Ty)) { |
| + UnimplementedError(getFlags()); |
| + } else if (isFloatingType(Ty)) { |
| UnimplementedError(getFlags()); |
| } else { |
| // Mov's Src operand can really only be the flexible second operand type |
| @@ -1431,6 +1443,34 @@ Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed, |
| Variable *Reg = makeReg(Ty, RegNum); |
| Context.insert<InstFakeDef>(Reg); |
| return Reg; |
| + } else if (auto *C32 = llvm::dyn_cast<ConstantFloat>(From)) { |
| + const float Value = C32->getValue(); |
| + // Check if the immediate will fit in a Flexible second operand, |
| + // if a Flexible second operand is allowed. We need to know the exact |
| + // value, so that rules out relocatable constants. |
| + // Also try the inverse and use MVN if possible. |
| + // Do a movw/movt to a register. |
| + Variable *Reg; |
| + if (RegNum.hasValue()) |
| + Reg = getPhysicalRegister(RegNum); |
|
Jim Stichnoth
2016/05/19 23:12:25
I'm very nervous about this use of getPhysicalRegi
obucinac
2016/05/27 11:13:18
We need to rework this to o32 convention. Leaving
|
| + else |
| + Reg = makeReg(Ty, RegNum); |
| + |
| + const uint32_t UIntValue = llvm::FloatToBits(Value); |
| + |
| + if (isInt<16>(int32_t(UIntValue))) { |
| + Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty); |
| + Context.insert<InstFakeDef>(Zero); |
| + _addiu(Reg, Zero, UIntValue); |
| + } else { |
| + uint32_t UpperBits = (UIntValue >> 16) & 0xFFFF; |
| + (void)UpperBits; |
|
Jim Stichnoth
2016/05/19 23:12:25
Remove this
obucinac
2016/05/27 11:13:18
Done.
|
| + uint32_t LowerBits = UIntValue & 0xFFFF; |
| + Variable *TReg = makeReg(Ty, RegNum); |
| + _lui(TReg, UpperBits); |
| + _ori(Reg, TReg, LowerBits); |
| + } |
| + return Reg; |
| } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { |
| const uint32_t Value = C32->getValue(); |
| // Check if the immediate will fit in a Flexible second operand, |