Chromium Code Reviews| Index: src/IceTargetLoweringMIPS32.cpp |
| diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp |
| index cbfad693619260aa00cd2b05f75316550c1e97d7..79f02fbaefac2a5b395a0f1f37f3cd834e881a2b 100644 |
| --- a/src/IceTargetLoweringMIPS32.cpp |
| +++ b/src/IceTargetLoweringMIPS32.cpp |
| @@ -1,4 +1,3 @@ |
| -//===- subzero/src/IceTargetLoweringMIPS32.cpp - MIPS32 lowering ----------===// |
| // |
| // The Subzero Code Generator |
| // |
| @@ -905,20 +904,80 @@ 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)); |
| + const uint32_t Mask = (1 << (CHAR_BITS * typeWidthInBytes(Src0Ty))) - 1; |
| + |
| + 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 || Src0Ty == IceType_i16) { |
| + _sll(T_Lo, Src0R, ShiftAmount); |
| + _sra(DestLo, T_Lo, ShiftAmount); |
| + } |
| + _sra(DestHi, DestLo, INT32_BITS - 1); |
| + } else { |
| + Variable *Src0R = legalizeToReg(Src0); |
| + Variable *T = makeReg(DestTy); |
| + if (Src0Ty == IceType_i8 || Src0Ty == IceType_i16) { |
| + _sll(T, Src0R, ShiftAmount); |
| + _sra(Dest, T, ShiftAmount); |
| + } |
| + } |
| 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) { |
|
Jim Stichnoth
2016/05/09 18:41:27
It would probably be cleaner if all of the similar
|
| + default: { assert(Src0Ty != IceType_i64); } break; |
| + case IceType_i32: |
| + _mov(DestLo, Src0R); |
| + break; |
| + case IceType_i8: |
| + case IceType_i16: |
| + _andi(DestLo, Src0R, Mask); |
| + break; |
| + } |
| + |
| + auto *Zero = getZero(); |
| + _addiu(DestHi, Zero, 0); |
| + } else { |
| + Variable *Src0R = legalizeToReg(Src0); |
| + Variable *T = makeReg(DestTy); |
| + if (Src0Ty == IceType_i8 || Src0Ty == IceType_i16) |
| + _andi(T, Src0R, Mask); |
| + _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: |