diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/Mips/MipsISelDAGToDAG.cpp | 11 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 13 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrFPU.td | 46 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrFormats.td | 20 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.td | 3 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSubtarget.h | 2 |
6 files changed, 91 insertions, 4 deletions
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index 281399e84e..f60a15e9e5 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -30,6 +30,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/SelectionDAGISel.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -91,7 +92,7 @@ private: SDNode *Select(SDNode *N); // Complex Pattern. - bool SelectAddr(SDValue N, SDValue &Base, SDValue &Offset); + bool SelectAddr(SDNode *Parent, SDValue N, SDValue &Base, SDValue &Offset); // getImm - Return a target constant with the specified value. inline SDValue getImm(const SDNode *Node, unsigned Imm) { @@ -197,7 +198,7 @@ SDNode *MipsDAGToDAGISel::getGlobalBaseReg() { /// ComplexPattern used on MipsInstrInfo /// Used on Mips Load/Store instructions bool MipsDAGToDAGISel:: -SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) { +SelectAddr(SDNode *Parent, SDValue Addr, SDValue &Base, SDValue &Offset) { EVT ValTy = Addr.getValueType(); // if Address is FI, get the TargetFrameIndex. @@ -256,6 +257,12 @@ SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) { return true; } } + + // If an indexed load/store can be emitted, return false. + if (const LSBaseSDNode* LS = dyn_cast<LSBaseSDNode>(Parent)) + if ((LS->getMemoryVT() == MVT::f32 || LS->getMemoryVT() == MVT::f64) && + Subtarget.hasMips32r2Or64()) + return false; } Base = Addr; diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 968a78b1f2..e0944c0167 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -261,7 +261,18 @@ MipsTargetLowering(MipsTargetMachine &TM) bool MipsTargetLowering::allowsUnalignedMemoryAccesses(EVT VT) const { MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy; - return SVT == MVT::i64 || SVT == MVT::i32 || SVT == MVT::i16; + + switch (SVT) { + case MVT::i64: + case MVT::i32: + case MVT::i16: + return true; + case MVT::f32: + case MVT::f64: + return Subtarget->hasMips32r2Or64(); + default: + return false; + } } EVT MipsTargetLowering::getSetCCResultType(EVT VT) const { diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index 055540b618..46fd278e8b 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -94,6 +94,24 @@ class FPStore<bits<6> op, string opstr, RegisterClass RC, Operand MemOpnd>: !strconcat(opstr, "\t$ft, $addr"), [(store RC:$ft, addr:$addr)], IIStore>; +// FP indexed load. +class FPIdxLoad<bits<6> funct, string opstr, RegisterClass DRC, + RegisterClass PRC, PatFrag FOp>: + FFMemIdx<funct, (outs DRC:$fd), (ins PRC:$base, PRC:$index), + !strconcat(opstr, "\t$fd, $index($base)"), + [(set DRC:$fd, (FOp (add PRC:$base, PRC:$index)))]> { + let fs = 0; +} + +// FP indexed store. +class FPIdxStore<bits<6> funct, string opstr, RegisterClass DRC, + RegisterClass PRC, PatFrag FOp>: + FFMemIdx<funct, (outs), (ins DRC:$fs, PRC:$base, PRC:$index), + !strconcat(opstr, "\t$fs, $index($base)"), + [(FOp DRC:$fs, (add PRC:$base, PRC:$index))]> { + let fd = 0; +} + // Instructions that convert an FP value to 32-bit fixed point. multiclass FFR1_W_M<bits<6> funct, string opstr> { def _S : FFR1<funct, 16, opstr, "w.s", FGR32, FGR32>; @@ -240,6 +258,34 @@ let Predicates = [NotN64, NotMips64] in { def SDC1 : FPStore<0x3d, "sdc1", AFGR64, mem>; } +// Indexed loads and stores. +let Predicates = [HasMips32r2Or64] in { + def LWXC1 : FPIdxLoad<0x0, "lwxc1", FGR32, CPURegs, load_a>; + def LUXC1 : FPIdxLoad<0x5, "luxc1", FGR32, CPURegs, load_u>; + def SWXC1 : FPIdxStore<0x8, "swxc1", FGR32, CPURegs, store_a>; + def SUXC1 : FPIdxStore<0xd, "suxc1", FGR32, CPURegs, store_u>; +} + +let Predicates = [HasMips32r2, NotMips64] in { + def LDXC1 : FPIdxLoad<0x1, "ldxc1", AFGR64, CPURegs, load_a>; + def SDXC1 : FPIdxStore<0x9, "sdxc1", AFGR64, CPURegs, store_a>; +} + +let Predicates = [HasMips64, NotN64] in { + def LDXC164 : FPIdxLoad<0x1, "ldxc1", FGR64, CPURegs, load_a>; + def SDXC164 : FPIdxStore<0x9, "sdxc1", FGR64, CPURegs, store_a>; +} + +// n64 +let Predicates = [IsN64] in { + def LWXC1_P8 : FPIdxLoad<0x0, "lwxc1", FGR32, CPU64Regs, load_a>; + def LUXC1_P8 : FPIdxLoad<0x5, "luxc1", FGR32, CPU64Regs, load_u>; + def LDXC164_P8 : FPIdxLoad<0x1, "ldxc1", FGR64, CPU64Regs, load_a>; + def SWXC1_P8 : FPIdxStore<0x8, "swxc1", FGR32, CPU64Regs, store_a>; + def SUXC1_P8 : FPIdxStore<0xd, "suxc1", FGR32, CPU64Regs, store_u>; + def SDXC164_P8 : FPIdxStore<0x9, "sdxc1", FGR64, CPU64Regs, store_a>; +} + /// Floating-point Aritmetic defm FADD : FFR2P_M<0x00, "add", fadd, 1>; defm FDIV : FFR2P_M<0x03, "div", fdiv>; diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td index 6bf8668fca..de744b7ef9 100644 --- a/lib/Target/Mips/MipsInstrFormats.td +++ b/lib/Target/Mips/MipsInstrFormats.td @@ -308,3 +308,23 @@ class FFMADDSUB<bits<3> funct, bits<3> fmt, dag outs, dag ins, string asmstr, let Inst{5-3} = funct; let Inst{2-0} = fmt; } + +// FP indexed load/store instructions. +class FFMemIdx<bits<6> _funct, dag outs, dag ins, string asmstr, + list<dag> pattern> : + MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmOther> +{ + bits<5> base; + bits<5> index; + bits<5> fs; + bits<5> fd; + bits<6> funct; + + let Opcode = 0x13; + + let Inst{25-21} = base; + let Inst{20-16} = index; + let Inst{15-11} = fs; + let Inst{10-6} = fd; + let Inst{5-0} = funct; +} diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 3d58030c02..7b3308b582 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -128,6 +128,7 @@ def HasCondMov : Predicate<"Subtarget.hasCondMov()">; def HasMips32 : Predicate<"Subtarget.hasMips32()">; def HasMips32r2 : Predicate<"Subtarget.hasMips32r2()">; def HasMips64 : Predicate<"Subtarget.hasMips64()">; +def HasMips32r2Or64 : Predicate<"Subtarget.hasMips32r2Or64()">; def NotMips64 : Predicate<"!Subtarget.hasMips64()">; def HasMips64r2 : Predicate<"Subtarget.hasMips64r2()">; def IsN64 : Predicate<"Subtarget.isABI_N64()">; @@ -231,7 +232,7 @@ def immZExt5 : ImmLeaf<i32, [{return Imm == (Imm & 0x1f);}]>; // Mips Address Mode! SDNode frameindex could possibily be a match // since load and store instructions from stack used it. -def addr : ComplexPattern<iPTR, 2, "SelectAddr", [frameindex], []>; +def addr : ComplexPattern<iPTR, 2, "SelectAddr", [frameindex], [SDNPWantParent]>; //===----------------------------------------------------------------------===// // Pattern fragment for load/store diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h index 0c6dc5264a..b501ade338 100644 --- a/lib/Target/Mips/MipsSubtarget.h +++ b/lib/Target/Mips/MipsSubtarget.h @@ -112,6 +112,8 @@ public: bool hasMips64() const { return MipsArchVersion >= Mips64; } bool hasMips64r2() const { return MipsArchVersion == Mips64r2; } + bool hasMips32r2Or64() const { return hasMips32r2() || hasMips64(); } + bool isLittle() const { return IsLittle; } bool isFP64bit() const { return IsFP64bit; } bool isGP64bit() const { return IsGP64bit; } |