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, |