Index: src/IceTargetLoweringMIPS32.cpp |
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp |
index cbfad693619260aa00cd2b05f75316550c1e97d7..65bce3ffaf62b37adee4b8d818305448f85d3616 100644 |
--- a/src/IceTargetLoweringMIPS32.cpp |
+++ b/src/IceTargetLoweringMIPS32.cpp |
@@ -905,20 +905,98 @@ void TargetMIPS32::lowerCall(const InstCall *Instr) { |
void TargetMIPS32::lowerCast(const InstCast *Instr) { |
InstCast::OpKind CastKind = Instr->getCastKind(); |
+ Variable *Dest = Instr->getDest(); |
+ Operand *Src0 = legalizeUndef(Instr->getSrc(0)); |
+ const Type DestTy = Dest->getType(); |
+ const Type Src0Ty = Src0->getType(); |
+ const uint32_t ShiftAmount = |
+ INT32_BITS - (CHAR_BITS * typeWidthInBytes(Src0Ty)); |
+ ConstantInteger32 *ShiftConstant = |
+ llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(ShiftAmount)); |
+ const uint32_t Mask = (1 << (CHAR_BITS * typeWidthInBytes(Src0Ty))) - 1; |
+ ConstantInteger32 *MaskConstant = |
+ llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(Mask)); |
+ ConstantInteger32 *ShiftConstant31 = |
+ llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(31)); |
Jim Stichnoth
2016/05/06 19:55:10
Maybe INT32_BITS-1 ?
sagar.thakur
2016/05/09 11:03:40
Done.
|
+ ConstantInteger32 *Constant0 = |
+ llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32)); |
+ |
+ if (isVectorType(DestTy) || Src0->getType() == IceType_i1) { |
+ UnimplementedLoweringError(this, Instr); |
+ return; |
+ } |
switch (CastKind) { |
default: |
Func->setError("Cast type not supported"); |
return; |
case InstCast::Sext: { |
- UnimplementedLoweringError(this, Instr); |
+ if (DestTy == IceType_i64) { |
+ auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
+ auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
+ Variable *Src0R = legalizeToReg(Src0); |
+ Variable *T_Lo = I32Reg(); |
+ if (Src0Ty == IceType_i32) { |
+ _mov(DestLo, Src0R); |
+ } else if (Src0Ty == IceType_i8) { |
Jim Stichnoth
2016/05/06 19:55:09
Combine this and the next clause:
else if (Src0
sagar.thakur
2016/05/09 11:03:40
Done. Sorry I didn't notice that.
|
+ _sll(T_Lo, Src0R, ShiftConstant); |
+ _sra(DestLo, T_Lo, ShiftConstant); |
+ } else if (Src0Ty == IceType_i16) { |
+ _sll(T_Lo, Src0R, ShiftConstant); |
+ _sra(DestLo, T_Lo, ShiftConstant); |
+ } |
+ _sra(DestHi, DestLo, ShiftConstant31); |
+ } else { |
+ Variable *Src0R = legalizeToReg(Src0); |
+ Variable *T = makeReg(DestTy); |
+ if (Src0Ty == IceType_i8) { |
+ _sll(T, Src0R, ShiftConstant); |
+ _sra(Dest, T, ShiftConstant); |
+ } else if (Src0Ty == IceType_i16) { |
+ _sll(T, Src0R, ShiftConstant); |
+ _sra(Dest, T, ShiftConstant); |
+ } |
+ } |
break; |
} |
case InstCast::Zext: { |
- UnimplementedLoweringError(this, Instr); |
+ if (DestTy == IceType_i64) { |
+ auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
+ auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
+ Variable *Src0R = legalizeToReg(Src0); |
+ |
+ switch (Src0Ty) { |
+ default: { assert(Src0Ty != IceType_i64); } break; |
+ case IceType_i32: { |
+ _mov(DestLo, Src0R); |
+ } break; |
+ case IceType_i8: { |
+ _andi(DestLo, Src0R, MaskConstant); |
+ } break; |
+ case IceType_i16: { |
+ _andi(DestLo, Src0R, MaskConstant); |
+ } break; |
+ } |
+ |
+ auto *Zero = getZero(); |
+ _addiu(DestHi, Zero, Constant0); |
+ } else { |
+ Variable *Src0R = legalizeToReg(Src0); |
+ Variable *T = makeReg(DestTy); |
+ if (Src0Ty == IceType_i8) |
+ _andi(T, Src0R, MaskConstant); |
+ else if (Src0Ty == IceType_i16) |
+ _andi(T, Src0R, MaskConstant); |
+ _mov(Dest, T); |
+ } |
break; |
} |
case InstCast::Trunc: { |
- UnimplementedLoweringError(this, Instr); |
+ if (Src0Ty == IceType_i64) |
+ Src0 = loOperand(Src0); |
+ Variable *Src0R = legalizeToReg(Src0); |
+ Variable *T = makeReg(DestTy); |
+ _mov(T, Src0R); |
+ _mov(Dest, T); |
break; |
} |
case InstCast::Fptrunc: |
@@ -1381,7 +1459,7 @@ Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed, |
if (isInt<16>(int32_t(Value))) { |
Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty); |
Context.insert<InstFakeDef>(Zero); |
- _addiu(Reg, Zero, Value); |
+ _addiu(Reg, Zero, C32); |
} else { |
uint32_t UpperBits = (Value >> 16) & 0xFFFF; |
(void)UpperBits; |