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" @@ -12,6 +13,7 @@ #include "MipsISelLowering.h" #include "MipsMachineFunction.h" #include "MipsSubtarget.h" +#include "MipsTargetMachine.h" using namespace llvm; @@ -36,11 +38,11 @@ /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can /// make the right decision when generating code for different targets. - const MipsSubtarget *Subtarget; Module &M; const TargetMachine &TM; const TargetInstrInfo &TII; const TargetLowering &TLI; + const MipsSubtarget &Subtarget; MipsFunctionInfo *MFI; // Convenience variables to avoid some queries. @@ -54,12 +56,12 @@ : FastISel(funcInfo, libInfo), M(const_cast(*funcInfo.Fn->getParent())), TM(funcInfo.MF->getTarget()), TII(*TM.getInstrInfo()), - TLI(*TM.getTargetLowering()) { - Subtarget = &TM.getSubtarget(); + TLI(*TM.getTargetLowering()), + Subtarget(TM.getSubtarget()) { MFI = funcInfo.MF->getInfo(); Context = &funcInfo.Fn->getContext(); - TargetSupported = ((Subtarget->getRelocationModel() == Reloc::PIC_) && - (Subtarget->hasMips32r2() && (Subtarget->isABI_O32()))); + TargetSupported = ((Subtarget.getRelocationModel() == Reloc::PIC_) && + (Subtarget.hasMips32r2() && (Subtarget.isABI_O32()))); } bool TargetSelectInstruction(const Instruction *I) override; @@ -80,6 +82,26 @@ unsigned MaterializeGV(const GlobalValue *GV, MVT VT); unsigned MaterializeInt(const Constant *C, MVT VT); unsigned Materialize32BitInt(int64_t Imm, const TargetRegisterClass *RC); + + unsigned FastEmitInst_riir(uint64_t inst, const TargetRegisterClass *RC, + unsigned Op0, bool Op0IsKill, uint64_t imm1, + uint64_t imm2, unsigned Op3, bool Op3IsKill) { + return 0; + } + + MachineInstrBuilder EmitInst(unsigned Opc) { + return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc)); + } + + MachineInstrBuilder EmitInst(unsigned Opc, unsigned DstReg) { + return BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), DstReg); + } + + MachineInstrBuilder EmitInstStore(unsigned Opc, unsigned SrcReg, unsigned MemReg , int64_t MemOffset) { + return EmitInst(Opc).addReg(SrcReg).addReg(MemReg).addImm(MemOffset); + } + +#include "MipsGenFastISel.inc" }; bool MipsFastISel::isTypeLegal(Type *Ty, MVT &VT) { @@ -141,12 +163,14 @@ // // more cases will be handled here in following patches. // - if (VT != MVT::i32) + if (VT == MVT::i32) + EmitInstStore(Mips::SW, SrcReg, Addr.Base.Reg, Addr.Offset); + else if (VT == MVT::f32) + EmitInstStore(Mips::SWC1, SrcReg, Addr.Base.Reg, Addr.Offset); + else if (VT == MVT::f64) + EmitInstStore(Mips::SDC1, SrcReg, Addr.Base.Reg, 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; } @@ -186,8 +210,7 @@ if (Ret->getNumOperands() > 0) { return false; } - unsigned RetOpc = Mips::RetRA; - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(RetOpc)); + EmitInst(Mips::RetRA); return true; } @@ -207,6 +230,22 @@ } unsigned MipsFastISel::MaterializeFP(const ConstantFP *CFP, MVT VT) { + 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); + EmitInst(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); + EmitInst(Mips::BuildPairF64, DestReg).addReg(TempReg2).addReg(TempReg1); + return DestReg; + } return 0; } @@ -221,8 +260,7 @@ // TLS not supported at this time. if (IsThreadLocal) return 0; - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::LW), DestReg) - .addReg(MFI->getGlobalBaseReg()) + EmitInst(Mips::LW, DestReg).addReg(MFI->getGlobalBaseReg()) .addGlobalAddress(GV, 0, MipsII::MO_GOT); return DestReg; } @@ -245,15 +283,10 @@ if (isInt<16>(Imm)) { unsigned Opc = Mips::ADDiu; - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg) - .addReg(Mips::ZERO) - .addImm(Imm); + EmitInst(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(Imm); + EmitInst(Mips::ORi, ResultReg).addReg(Mips::ZERO).addImm(Imm); return ResultReg; } unsigned Lo = Imm & 0xFFFF; @@ -261,16 +294,11 @@ 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); + EmitInst(Mips::LUi, TmpReg).addImm(Hi); + EmitInst(Mips::ORi, ResultReg).addReg(TmpReg).addImm(Lo); } else { - BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Mips::LUi), - ResultReg).addImm(Hi); + EmitInst(Mips::LUi, ResultReg).addImm(Hi); } return ResultReg; } 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" } +