summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>2015-02-04 15:43:17 +0000
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>2015-02-04 15:43:17 +0000
commit5a1a780c2aa04bac5e5bb7220f74cb66fab70c15 (patch)
treedcc6465ddeb61117ae8d39ba87c25a88a465b917 /llvm/lib
parentfac2371be324d6a3aa0c9622f5147abbc707894e (diff)
downloadbcm5719-llvm-5a1a780c2aa04bac5e5bb7220f74cb66fab70c15.tar.gz
bcm5719-llvm-5a1a780c2aa04bac5e5bb7220f74cb66fab70c15.zip
[mips][microMIPS] Implement CodeGen support for SW16 and LW16 instructions
Differential Revision: http://reviews.llvm.org/D6581 llvm-svn: 228149
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Mips/MicroMipsInstrInfo.td13
-rw-r--r--llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp6
-rw-r--r--llvm/lib/Target/Mips/MipsISelDAGToDAG.h3
-rw-r--r--llvm/lib/Target/Mips/MipsInstrInfo.td8
-rw-r--r--llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp25
-rw-r--r--llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h3
6 files changed, 57 insertions, 1 deletions
diff --git a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
index e03cad30b41..eed21a44b55 100644
--- a/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMipsInstrInfo.td
@@ -1,4 +1,5 @@
def addrimm12 : ComplexPattern<iPTR, 2, "selectIntAddrMM", [frameindex]>;
+def addrimm4lsl2 : ComplexPattern<iPTR, 2, "selectIntAddrLSL2MM", [frameindex]>;
def simm4 : Operand<i32> {
let DecoderMethod = "DecodeSimm4";
@@ -65,7 +66,7 @@ def MicroMipsMemGPRMM16AsmOperand : AsmOperandClass {
class mem_mm_4_generic : Operand<i32> {
let PrintMethod = "printMemOperand";
- let MIOperandInfo = (ops ptr_rc, simm4);
+ let MIOperandInfo = (ops GPRMM16, simm4);
let OperandType = "OPERAND_MEMORY";
let ParserMatchClass = MicroMipsMemGPRMM16AsmOperand;
}
@@ -879,6 +880,16 @@ def : MipsPat<(srl GPRMM16:$src, immZExt2Shift:$imm),
def : MipsPat<(srl GPR32:$src, immZExt5:$imm),
(SRL_MM GPR32:$src, immZExt5:$imm)>;
+def : MipsPat<(store GPRMM16:$src, addrimm4lsl2:$addr),
+ (SW16_MM GPRMM16:$src, addrimm4lsl2:$addr)>;
+def : MipsPat<(store GPR32:$src, addr:$addr),
+ (SW_MM GPR32:$src, addr:$addr)>;
+
+def : MipsPat<(load addrimm4lsl2:$addr),
+ (LW16_MM addrimm4lsl2:$addr)>;
+def : MipsPat<(load addr:$addr),
+ (LW_MM addr:$addr)>;
+
//===----------------------------------------------------------------------===//
// MicroMips instruction aliases
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp
index 233bb0c8ef1..21fc8ce2d58 100644
--- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -95,6 +95,12 @@ bool MipsDAGToDAGISel::selectIntAddrMM(SDValue Addr, SDValue &Base,
return false;
}
+bool MipsDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base,
+ SDValue &Offset) const {
+ llvm_unreachable("Unimplemented function.");
+ return false;
+}
+
bool MipsDAGToDAGISel::selectIntAddrMSA(SDValue Addr, SDValue &Base,
SDValue &Offset) const {
llvm_unreachable("Unimplemented function.");
diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h
index 5378497c015..6b72877e9ee 100644
--- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.h
+++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.h
@@ -73,6 +73,9 @@ private:
virtual bool selectIntAddrMM(SDValue Addr, SDValue &Base,
SDValue &Offset) const;
+ virtual bool selectIntAddrLSL2MM(SDValue Addr, SDValue &Base,
+ SDValue &Offset) const;
+
/// Match addr+simm10 and addr
virtual bool selectIntAddrMSA(SDValue Addr, SDValue &Base,
SDValue &Offset) const;
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td
index ae2223a5855..38a1d03eb02 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.td
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.td
@@ -1192,11 +1192,15 @@ def LBu : Load<"lbu", GPR32Opnd, zextloadi8, II_LBU, addrDefault>, MMRel,
def LH : Load<"lh", GPR32Opnd, sextloadi16, II_LH, addrDefault>, MMRel,
LW_FM<0x21>;
def LHu : Load<"lhu", GPR32Opnd, zextloadi16, II_LHU>, MMRel, LW_FM<0x25>;
+let AdditionalPredicates = [NotInMicroMips] in {
def LW : Load<"lw", GPR32Opnd, load, II_LW, addrDefault>, MMRel,
LW_FM<0x23>;
+}
def SB : Store<"sb", GPR32Opnd, truncstorei8, II_SB>, MMRel, LW_FM<0x28>;
def SH : Store<"sh", GPR32Opnd, truncstorei16, II_SH>, MMRel, LW_FM<0x29>;
+let AdditionalPredicates = [NotInMicroMips] in {
def SW : Store<"sw", GPR32Opnd, store, II_SW>, MMRel, LW_FM<0x2b>;
+}
/// load/store left/right
let EncodingPredicates = []<Predicate>, // FIXME: Lack of HasStdEnc is probably a bug
@@ -1211,6 +1215,7 @@ def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, II_SWR>, LW_FM<0x2e>,
ISA_MIPS1_NOT_32R6_64R6;
}
+let AdditionalPredicates = [NotInMicroMips] in {
// COP2 Memory Instructions
def LWC2 : LW_FT2<"lwc2", COP2Opnd, NoItinerary, load>, LW_FM<0x32>,
ISA_MIPS1_NOT_32R6_64R6;
@@ -1230,6 +1235,7 @@ let DecoderNamespace = "COP3_" in {
def SDC3 : SW_FT3<"sdc3", COP3Opnd, NoItinerary, store>, LW_FM<0x3f>,
ISA_MIPS2;
}
+}
def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM, ISA_MIPS32;
def SYNCI : MMRel, SYNCI_FT<"synci">, SYNCI_FM, ISA_MIPS32R2;
@@ -1858,7 +1864,9 @@ def : MipsPat<(bswap GPR32:$rt), (ROTR (WSBH GPR32:$rt), 16)>;
let AddedComplexity = 40 in {
def : LoadRegImmPat<LBu, i32, zextloadi8>;
def : LoadRegImmPat<LH, i32, sextloadi16>;
+ let AdditionalPredicates = [NotInMicroMips] in {
def : LoadRegImmPat<LW, i32, load>;
+ }
}
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
index 075b067ea24..ae45bbdb708 100644
--- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
@@ -407,6 +407,31 @@ bool MipsSEDAGToDAGISel::selectIntAddrMM(SDValue Addr, SDValue &Base,
selectAddrDefault(Addr, Base, Offset);
}
+bool MipsSEDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base,
+ SDValue &Offset) const {
+ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 7)) {
+ if (dyn_cast<FrameIndexSDNode>(Base))
+ return false;
+ else {
+ ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Offset);
+ if (CN) {
+ unsigned CnstOff = CN->getZExtValue();
+ if (CnstOff == (CnstOff & 0x3c))
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ // For all other cases where "lw" would be selected, don't select "lw16"
+ // because it would result in additional instructions to prepare operands.
+ if (selectAddrRegImm(Addr, Base, Offset))
+ return false;
+
+ return selectAddrDefault(Addr, Base, Offset);
+}
+
bool MipsSEDAGToDAGISel::selectIntAddrMSA(SDValue Addr, SDValue &Base,
SDValue &Offset) const {
if (selectAddrRegImm10(Addr, Base, Offset))
diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h
index 2e11fa7282a..2d24eb43e30 100644
--- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h
+++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h
@@ -65,6 +65,9 @@ private:
bool selectIntAddrMM(SDValue Addr, SDValue &Base,
SDValue &Offset) const override;
+ bool selectIntAddrLSL2MM(SDValue Addr, SDValue &Base,
+ SDValue &Offset) const override;
+
bool selectIntAddrMSA(SDValue Addr, SDValue &Base,
SDValue &Offset) const override;
OpenPOWER on IntegriCloud