Index: lib/Target/Mips/MipsFastISel.cpp =================================================================== --- lib/Target/Mips/MipsFastISel.cpp +++ lib/Target/Mips/MipsFastISel.cpp @@ -4,6 +4,7 @@ #include "llvm/CodeGen/FunctionLoweringInfo.h" #include "llvm/CodeGen/FastISel.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/Target/TargetInstrInfo.h" @@ -76,9 +77,10 @@ bool isTypeLegal(Type *Ty, MVT &VT); bool isLoadTypeLegal(Type *Ty, MVT &VT); - unsigned MaterializeFP(const ConstantFP *CFP, MVT VT); + unsigned MaterializeFP(const Constant *C, MVT VT); unsigned MaterializeGV(const GlobalValue *GV, MVT VT); unsigned MaterializeInt(const Constant *C, MVT VT); + unsigned Materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC); }; bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) { @@ -125,8 +127,8 @@ return 0; MVT VT = CEVT.getSimpleVT(); - if (const ConstantFP *CFP = dyn_cast(C)) - return MaterializeFP(CFP, VT); + if (isa(C)) + return MaterializeFP(C, VT); else if (const GlobalValue *GV = dyn_cast(C)) return MaterializeGV(GV, VT); else if (isa(C)) @@ -140,12 +142,23 @@ // // more cases will be handled here in following patches. // - if (VT != MVT::i32) + if (VT == MVT::i32) + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::SW)) + .addReg(SrcReg) + .addReg(Addr.Base.Reg) + .addImm(Addr.Offset); + else if (VT == MVT::f32) + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::SWC1)) + .addReg(SrcReg) + .addReg(Addr.Base.Reg) + .addImm(Addr.Offset); + else if (VT == MVT::f64) + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::SDC1)) + .addReg(SrcReg) + .addReg(Addr.Base.Reg) + .addImm(Addr.Offset); + else return false; - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::SW)) - .addReg(SrcReg) - .addReg(Addr.Base.Reg) - .addImm(Addr.Offset); return true; } @@ -205,7 +218,28 @@ } } -unsigned MipsFastISel::MaterializeFP(const ConstantFP *CFP, MVT VT) { +unsigned MipsFastISel::MaterializeFP(const Constant *C, MVT VT) { + const ConstantFP *CFP = cast(C); + int64_t Imm = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); + if (VT == MVT::f32) { + const TargetRegisterClass *RC = &Mips::FGR32RegClass; + unsigned DestReg = createResultReg(RC); + unsigned TempReg = Materialize32BitInt(Imm, &Mips::GPR32RegClass); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::MTC1), + DestReg).addReg(TempReg); + return DestReg; + } else if (VT == MVT::f64) { + const TargetRegisterClass *RC = &Mips::AFGR64RegClass; + unsigned DestReg = createResultReg(RC); + unsigned TempReg1 = Materialize32BitInt(Imm >> 32, &Mips::GPR32RegClass); + unsigned TempReg2 = + Materialize32BitInt(Imm & 0xFFFFFFFF, &Mips::GPR32RegClass); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(Mips::BuildPairF64), DestReg) + .addReg(TempReg2) + .addReg(TempReg1); + return DestReg; + } return 0; } @@ -226,20 +260,52 @@ return DestReg; } unsigned MipsFastISel::MaterializeInt(const Constant *C, MVT VT) { - if (VT != MVT::i32) + if (VT != MVT::i32 && VT != MVT::i16 && VT != MVT::i8 && VT != MVT::i1) return 0; const TargetRegisterClass *RC = &Mips::GPR32RegClass; - // If the constant is in range, use a load-immediate. const ConstantInt *CI = cast(C); - if (isInt<16>(CI->getSExtValue())) { + int64_t Imm; + if (CI->isNegative()) + Imm = CI->getSExtValue(); + else + Imm = CI->getZExtValue(); + return Materialize32BitInt(Imm, RC); +} + +unsigned MipsFastISel::Materialize32BitInt(int64_t Imm, + const TargetRegisterClass *RC) { + unsigned ResultReg = createResultReg(RC); + + if (isInt<16>(Imm)) { unsigned Opc = Mips::ADDiu; - unsigned ImmReg = createResultReg(RC); - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ImmReg) + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg) + .addReg(Mips::ZERO) + .addImm(Imm); + return ResultReg; + } else if (isUInt<16>(Imm)) { + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::ORi), + ResultReg) .addReg(Mips::ZERO) - .addImm(CI->getSExtValue()); - return ImmReg; + .addImm(Imm); + return ResultReg; } - return 0; + unsigned Lo = Imm & 0xFFFF; + unsigned Hi = (Imm >> 16) & 0xFFFF; + if (Lo) { + // Both Lo and Hi have nonzero bits. + unsigned TmpReg = createResultReg(RC); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::LUi), + TmpReg).addImm(Hi); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::ORi), + ResultReg) + .addReg(TmpReg) + .addImm(Lo); + + } else { + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::LUi), + ResultReg).addImm(Hi); + } + return ResultReg; } namespace llvm { Index: test/CodeGen/Mips/Fast-ISel/simplestorefp1.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/Fast-ISel/simplestorefp1.ll @@ -0,0 +1,39 @@ +; RUN: llc -march=mipsel -relocation-model=pic -O0 -mips-fast-isel -fast-isel-abort -mcpu=mips32r2 \ +; RUN: < %s | FileCheck %s + +@f = common global float 0.000000e+00, align 4 +@de = common global double 0.000000e+00, align 8 + +; Function Attrs: nounwind +define void @f1() #0 { +entry: + store float 0x3FFA76C8C0000000, float* @f, align 4 + ret void +; CHECK: .ent f1 +; CHECK: lui $[[REG1:[0-9]+]], 16339 +; CHECK: ori $[[REG2:[0-9]+]], $[[REG1]], 46662 +; CHECK: mtc1 $[[REG2]], $f[[REG3:[0-9]+]] +; CHECK: lw $[[REG4:[0-9]+]], %got(f)(${{[0-9]+}}) +; CHECK: swc1 $f[[REG3]], 0($[[REG4]]) +; CHECK: .end f1 + +} + +; Function Attrs: nounwind +define void @d1() #0 { +entry: + store double 1.234567e+00, double* @de, align 8 +; CHECK: .ent d1 +; CHECK: lui $[[REG1a:[0-9]+]], 16371 +; CHECK: ori $[[REG2a:[0-9]+]], $[[REG1a]], 49353 +; CHECK: lui $[[REG1b:[0-9]+]], 21403 +; CHECK: ori $[[REG2b:[0-9]+]], $[[REG1b]], 34951 +; CHECK: mtc1 $[[REG2b]], $f[[REG3b:[0-9]+]] +; CHECK: mtc1 $[[REG2a]], $f[[REG3a:[0-9]+]] +; CHECK: sdc1 $f[[REG3b]], 0(${{[0-9]+}}) +; CHECK: .end d1 + ret void +} + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + Index: test/CodeGen/Mips/Fast-ISel/simplestorei.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/Fast-ISel/simplestorei.ll @@ -0,0 +1,65 @@ +; RUN: llc -march=mipsel -relocation-model=pic -O0 -mips-fast-isel -fast-isel-abort -mcpu=mips32r2 \ +; RUN: < %s | FileCheck %s + +@ijk = external global i32 + +; Function Attrs: nounwind +define void @si2_1() #0 { +entry: + store i32 32767, i32* @ijk, align 4 +; CHECK: .ent si2_1 +; CHECK: addiu $[[REG1:[0-9]+]], $zero, 32767 +; CHECK: lw $[[REG2:[0-9]+]], %got(ijk)(${{[0-9]+}}) +; CHECK: sw $[[REG1]], 0($[[REG2]]) + + ret void +} + +; Function Attrs: nounwind +define void @si2_2() #0 { +entry: + store i32 -32768, i32* @ijk, align 4 +; CHECK: .ent si2_2 +; CHECK: addiu $[[REG1:[0-9]+]], $zero, -32768 +; CHECK: lw $[[REG2:[0-9]+]], %got(ijk)(${{[0-9]+}}) +; CHECK: sw $[[REG1]], 0($[[REG2]]) + ret void +} + +; Function Attrs: nounwind +define void @ui2_1() #0 { +entry: + store i32 65535, i32* @ijk, align 4 +; CHECK: .ent ui2_1 +; CHECK: ori $[[REG1:[0-9]+]], $zero, 65535 +; CHECK: lw $[[REG2:[0-9]+]], %got(ijk)(${{[0-9]+}}) +; CHECK: sw $[[REG1]], 0($[[REG2]]) + ret void +} + +; Function Attrs: nounwind +define void @ui4_1() #0 { +entry: + store i32 983040, i32* @ijk, align 4 +; CHECK: .ent ui4_1 +; CHECK: lui $[[REG1:[0-9]+]], 15 +; CHECK: lw $[[REG2:[0-9]+]], %got(ijk)(${{[0-9]+}}) +; CHECK: sw $[[REG1]], 0($[[REG2]]) + ret void +} + +; Function Attrs: nounwind +define void @ui4_2() #0 { +entry: + store i32 719566, i32* @ijk, align 4 +; CHECK: .ent ui4_2 +; CHECK: lui $[[REG1:[0-9]+]], 10 +; CHECK: ori $[[REG1]], $[[REG1]], 64206 +; CHECK: lw $[[REG2:[0-9]+]], %got(ijk)(${{[0-9]+}}) +; CHECK: sw $[[REG1]], 0($[[REG2]]) + ret void +} + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +