Index: src/IceTargetLoweringMIPS32.cpp |
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp |
index cbfad693619260aa00cd2b05f75316550c1e97d7..15b4f9b72c1872f37607ac8efbbd24599030d7fa 100644 |
--- a/src/IceTargetLoweringMIPS32.cpp |
+++ b/src/IceTargetLoweringMIPS32.cpp |
@@ -905,20 +905,85 @@ void TargetMIPS32::lowerCall(const InstCall *Instr) { |
void TargetMIPS32::lowerCast(const InstCast *Instr) { |
InstCast::OpKind CastKind = Instr->getCastKind(); |
+ Variable *Dest = Instr->getDest(); |
+ const Type DestTy = Dest->getType(); |
+ Operand *Src0 = legalizeUndef(Instr->getSrc(0)); |
Jim Stichnoth
2016/05/05 15:32:37
Add this:
const Type Src0Ty = Src0->getType();
a
sagar.thakur
2016/05/06 13:04:06
Done.
|
+ 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 (Src0->getType() == IceType_i32) { |
+ _mov(DestLo, Src0R); |
+ } else if (Src0->getType() == IceType_i8) { |
+ _sll(T_Lo, Src0R, 24); |
Jim Stichnoth
2016/05/05 15:32:37
I strongly prefer to avoid magic constants like 24
sagar.thakur
2016/05/06 13:04:06
Done.
|
+ _sra(DestLo, T_Lo, 24); |
+ } else if (Src0->getType() == IceType_i16) { |
+ _sll(T_Lo, Src0R, 16); |
+ _sra(DestLo, T_Lo, 16); |
+ } |
+ _sra(DestHi, DestLo, 31); |
+ } else { |
+ Variable *Src0R = legalizeToReg(Src0); |
+ Variable *T = makeReg(DestTy); |
+ if (Src0->getType() == IceType_i8) { |
+ _sll(T, Src0R, 24); |
+ _sra(Dest, T, 24); |
+ } else if (Src0->getType() == IceType_i16) { |
+ _sll(T, Src0R, 16); |
+ _sra(Dest, T, 16); |
+ } |
+ } |
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 (Src0->getType()) { |
+ default: { assert(Src0->getType() != IceType_i64); } break; |
+ case IceType_i32: { |
+ _mov(DestLo, Src0R); |
+ } break; |
+ case IceType_i16: { |
+ _andi(DestLo, Src0R, 0xff); |
Jim Stichnoth
2016/05/05 15:32:37
Shouldn't the mask be 0xffff for i16 and 0xff for
sagar.thakur
2016/05/06 13:04:06
Done.
|
+ } break; |
+ case IceType_i8: { |
+ _andi(DestLo, Src0R, 0xffff); |
+ } break; |
+ } |
+ |
+ auto *Zero = getZero(); |
+ _addiu(DestHi, Zero, 0); |
+ } else { |
+ Variable *Src0R = legalizeToReg(Src0); |
+ Variable *T = makeReg(DestTy); |
+ if (Src0->getType() == IceType_i8) |
+ _andi(T, Src0R, 0xff); |
+ else if (Src0->getType() == IceType_i16) |
+ _andi(T, Src0R, 0xffff); |
+ _mov(Dest, T); |
+ } |
break; |
} |
case InstCast::Trunc: { |
- UnimplementedLoweringError(this, Instr); |
+ if (Src0->getType() == IceType_i64) |
+ Src0 = loOperand(Src0); |
+ Variable *Src0R = legalizeToReg(Src0); |
+ Variable *T = makeReg(DestTy); |
+ _mov(T, Src0R); |
+ _mov(Dest, T); |
break; |
} |
case InstCast::Fptrunc: |