mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-23 00:20:25 +00:00
Add numeric extend, trunctate to mips fast-isel
Summary: Add numeric extend, trunctate to mips fast-isel Reactivates D4827 Test Plan: fpext.ll loadstoreconv.ll Reviewers: dsanders Subscribers: mcrosier Differential Revision: http://reviews.llvm.org/D5251 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218681 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -78,6 +78,9 @@ private:
|
||||
bool SelectLoad(const Instruction *I);
|
||||
bool SelectRet(const Instruction *I);
|
||||
bool SelectStore(const Instruction *I);
|
||||
bool SelectIntExt(const Instruction *I);
|
||||
bool SelectTrunc(const Instruction *I);
|
||||
bool SelectFPExt(const Instruction *I);
|
||||
|
||||
bool isTypeLegal(Type *Ty, MVT &VT);
|
||||
bool isLoadTypeLegal(Type *Ty, MVT &VT);
|
||||
@@ -87,6 +90,16 @@ private:
|
||||
unsigned MaterializeInt(const Constant *C, MVT VT);
|
||||
unsigned Materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC);
|
||||
|
||||
bool EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg,
|
||||
bool IsZExt);
|
||||
|
||||
bool EmitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);
|
||||
|
||||
bool EmitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT, unsigned DestReg);
|
||||
bool EmitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,
|
||||
unsigned DestReg);
|
||||
bool EmitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,
|
||||
unsigned DestReg);
|
||||
// for some reason, this default is not generated by tablegen
|
||||
// so we explicitly generate it here.
|
||||
//
|
||||
@@ -242,6 +255,74 @@ bool MipsFastISel::EmitStore(MVT VT, unsigned SrcReg, Address &Addr,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MipsFastISel::EmitIntSExt32r1(MVT SrcVT, unsigned SrcReg, MVT DestVT,
|
||||
unsigned DestReg) {
|
||||
unsigned ShiftAmt;
|
||||
switch (SrcVT.SimpleTy) {
|
||||
default:
|
||||
return false;
|
||||
case MVT::i8:
|
||||
ShiftAmt = 24;
|
||||
break;
|
||||
case MVT::i16:
|
||||
ShiftAmt = 16;
|
||||
break;
|
||||
}
|
||||
unsigned TempReg = createResultReg(&Mips::GPR32RegClass);
|
||||
EmitInst(Mips::SLL, TempReg).addReg(SrcReg).addImm(ShiftAmt);
|
||||
EmitInst(Mips::SRA, DestReg).addReg(TempReg).addImm(ShiftAmt);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MipsFastISel::EmitIntSExt32r2(MVT SrcVT, unsigned SrcReg, MVT DestVT,
|
||||
unsigned DestReg) {
|
||||
switch (SrcVT.SimpleTy) {
|
||||
default:
|
||||
return false;
|
||||
case MVT::i8:
|
||||
EmitInst(Mips::SEB, DestReg).addReg(SrcReg);
|
||||
break;
|
||||
case MVT::i16:
|
||||
EmitInst(Mips::SEH, DestReg).addReg(SrcReg);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MipsFastISel::EmitIntExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
|
||||
unsigned DestReg, bool IsZExt) {
|
||||
if (IsZExt)
|
||||
return EmitIntZExt(SrcVT, SrcReg, DestVT, DestReg);
|
||||
return EmitIntSExt(SrcVT, SrcReg, DestVT, DestReg);
|
||||
}
|
||||
|
||||
bool MipsFastISel::EmitIntSExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
|
||||
unsigned DestReg) {
|
||||
if ((DestVT != MVT::i32) && (DestVT != MVT::i16))
|
||||
return false;
|
||||
if (Subtarget->hasMips32r2())
|
||||
return EmitIntSExt32r2(SrcVT, SrcReg, DestVT, DestReg);
|
||||
return EmitIntSExt32r1(SrcVT, SrcReg, DestVT, DestReg);
|
||||
}
|
||||
|
||||
bool MipsFastISel::EmitIntZExt(MVT SrcVT, unsigned SrcReg, MVT DestVT,
|
||||
unsigned DestReg) {
|
||||
switch (SrcVT.SimpleTy) {
|
||||
default:
|
||||
return false;
|
||||
case MVT::i1:
|
||||
EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(1);
|
||||
break;
|
||||
case MVT::i8:
|
||||
EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(0xff);
|
||||
break;
|
||||
case MVT::i16:
|
||||
EmitInst(Mips::ANDi, DestReg).addReg(SrcReg).addImm(0xffff);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MipsFastISel::SelectLoad(const Instruction *I) {
|
||||
// Atomic loads need special handling.
|
||||
if (cast<LoadInst>(I)->isAtomic())
|
||||
@@ -304,6 +385,79 @@ bool MipsFastISel::SelectRet(const Instruction *I) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Attempt to fast-select a floating-point extend instruction.
|
||||
bool MipsFastISel::SelectFPExt(const Instruction *I) {
|
||||
Value *Src = I->getOperand(0);
|
||||
EVT SrcVT = TLI.getValueType(Src->getType(), true);
|
||||
EVT DestVT = TLI.getValueType(I->getType(), true);
|
||||
|
||||
if (SrcVT != MVT::f32 || DestVT != MVT::f64)
|
||||
return false;
|
||||
|
||||
unsigned SrcReg =
|
||||
getRegForValue(Src); // his must be a 32 bit floating point register class
|
||||
// maybe we should handle this differently
|
||||
if (!SrcReg)
|
||||
return false;
|
||||
|
||||
unsigned DestReg = createResultReg(&Mips::AFGR64RegClass);
|
||||
EmitInst(Mips::CVT_D32_S, DestReg).addReg(SrcReg);
|
||||
updateValueMap(I, DestReg);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MipsFastISel::SelectIntExt(const Instruction *I) {
|
||||
Type *DestTy = I->getType();
|
||||
Value *Src = I->getOperand(0);
|
||||
Type *SrcTy = Src->getType();
|
||||
|
||||
bool isZExt = isa<ZExtInst>(I);
|
||||
unsigned SrcReg = getRegForValue(Src);
|
||||
if (!SrcReg)
|
||||
return false;
|
||||
|
||||
EVT SrcEVT, DestEVT;
|
||||
SrcEVT = TLI.getValueType(SrcTy, true);
|
||||
DestEVT = TLI.getValueType(DestTy, true);
|
||||
if (!SrcEVT.isSimple())
|
||||
return false;
|
||||
if (!DestEVT.isSimple())
|
||||
return false;
|
||||
|
||||
MVT SrcVT = SrcEVT.getSimpleVT();
|
||||
MVT DestVT = DestEVT.getSimpleVT();
|
||||
unsigned ResultReg = createResultReg(&Mips::GPR32RegClass);
|
||||
|
||||
if (!EmitIntExt(SrcVT, SrcReg, DestVT, ResultReg, isZExt))
|
||||
return false;
|
||||
updateValueMap(I, ResultReg);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MipsFastISel::SelectTrunc(const Instruction *I) {
|
||||
// The high bits for a type smaller than the register size are assumed to be
|
||||
// undefined.
|
||||
Value *Op = I->getOperand(0);
|
||||
|
||||
EVT SrcVT, DestVT;
|
||||
SrcVT = TLI.getValueType(Op->getType(), true);
|
||||
DestVT = TLI.getValueType(I->getType(), true);
|
||||
|
||||
if (SrcVT != MVT::i32 && SrcVT != MVT::i16 && SrcVT != MVT::i8)
|
||||
return false;
|
||||
if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1)
|
||||
return false;
|
||||
|
||||
unsigned SrcReg = getRegForValue(Op);
|
||||
if (!SrcReg)
|
||||
return false;
|
||||
|
||||
// Because the high bits are undefined, a truncate doesn't generate
|
||||
// any code.
|
||||
updateValueMap(I, SrcReg);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MipsFastISel::fastSelectInstruction(const Instruction *I) {
|
||||
if (!TargetSupported)
|
||||
return false;
|
||||
@@ -316,10 +470,16 @@ bool MipsFastISel::fastSelectInstruction(const Instruction *I) {
|
||||
return SelectStore(I);
|
||||
case Instruction::Ret:
|
||||
return SelectRet(I);
|
||||
case Instruction::Trunc:
|
||||
return SelectTrunc(I);
|
||||
case Instruction::ZExt:
|
||||
case Instruction::SExt:
|
||||
return SelectIntExt(I);
|
||||
case Instruction::FPExt:
|
||||
return SelectFPExt(I);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned MipsFastISel::MaterializeFP(const ConstantFP *CFP, MVT VT) {
|
||||
int64_t Imm = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
|
||||
@@ -352,13 +512,15 @@ unsigned MipsFastISel::MaterializeGV(const GlobalValue *GV, MVT VT) {
|
||||
// TLS not supported at this time.
|
||||
if (IsThreadLocal)
|
||||
return 0;
|
||||
EmitInst(Mips::LW, DestReg).addReg(MFI->getGlobalBaseReg()).addGlobalAddress(
|
||||
GV, 0, MipsII::MO_GOT);
|
||||
EmitInst(Mips::LW, DestReg)
|
||||
.addReg(MFI->getGlobalBaseReg())
|
||||
.addGlobalAddress(GV, 0, MipsII::MO_GOT);
|
||||
if ((GV->hasInternalLinkage() ||
|
||||
(GV->hasLocalLinkage() && !isa<Function>(GV)))) {
|
||||
unsigned TempReg = createResultReg(RC);
|
||||
EmitInst(Mips::ADDiu, TempReg).addReg(DestReg).addGlobalAddress(
|
||||
GV, 0, MipsII::MO_ABS_LO);
|
||||
EmitInst(Mips::ADDiu, TempReg)
|
||||
.addReg(DestReg)
|
||||
.addGlobalAddress(GV, 0, MipsII::MO_ABS_LO);
|
||||
DestReg = TempReg;
|
||||
}
|
||||
return DestReg;
|
||||
@@ -401,6 +563,7 @@ unsigned MipsFastISel::Materialize32BitInt(int64_t Imm,
|
||||
}
|
||||
return ResultReg;
|
||||
}
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
FastISel *Mips::createFastISel(FunctionLoweringInfo &funcInfo,
|
||||
|
||||
Reference in New Issue
Block a user