From: Zoran Jovanovic Date: Wed, 4 Feb 2015 15:43:17 +0000 (+0000) Subject: [mips][microMIPS] Implement CodeGen support for SW16 and LW16 instructions X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8dc0ae66069d3de8d2fdb630028115af054aa2d0;p=oota-llvm.git [mips][microMIPS] Implement CodeGen support for SW16 and LW16 instructions Differential Revision: http://reviews.llvm.org/D6581 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228149 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index e03cad30b41..eed21a44b55 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -1,4 +1,5 @@ def addrimm12 : ComplexPattern; +def addrimm4lsl2 : ComplexPattern; def simm4 : Operand { let DecoderMethod = "DecodeSimm4"; @@ -65,7 +66,7 @@ def MicroMipsMemGPRMM16AsmOperand : AsmOperandClass { class mem_mm_4_generic : Operand { 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/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index 233bb0c8ef1..21fc8ce2d58 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/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/lib/Target/Mips/MipsISelDAGToDAG.h b/lib/Target/Mips/MipsISelDAGToDAG.h index 5378497c015..6b72877e9ee 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.h +++ b/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/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index ae2223a5855..38a1d03eb02 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/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 = [], // 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; def : LoadRegImmPat; + let AdditionalPredicates = [NotInMicroMips] in { def : LoadRegImmPat; + } } //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/lib/Target/Mips/MipsSEISelDAGToDAG.cpp index 075b067ea24..ae45bbdb708 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ b/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(Base)) + return false; + else { + ConstantSDNode *CN = dyn_cast(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/lib/Target/Mips/MipsSEISelDAGToDAG.h b/lib/Target/Mips/MipsSEISelDAGToDAG.h index 2e11fa7282a..2d24eb43e30 100644 --- a/lib/Target/Mips/MipsSEISelDAGToDAG.h +++ b/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; diff --git a/test/CodeGen/Mips/longbranch.ll b/test/CodeGen/Mips/longbranch.ll index ad0235eb0af..821ced8e7b8 100644 --- a/test/CodeGen/Mips/longbranch.ll +++ b/test/CodeGen/Mips/longbranch.ll @@ -124,7 +124,7 @@ end: ; MICROMIPS: $[[BB0]]: ; MICROMIPS: lw $[[R1:[0-9]+]], %got(x)($[[GP]]) ; MICROMIPS: li16 $[[R2:[0-9]+]], 1 -; MICROMIPS: sw $[[R2]], 0($[[R1]]) +; MICROMIPS: sw16 $[[R2]], 0($[[R1]]) ; MICROMIPS: $[[BB2]]: ; MICROMIPS: jr $ra ; MICROMIPS: nop diff --git a/test/CodeGen/Mips/micromips-sw-lw-16.ll b/test/CodeGen/Mips/micromips-sw-lw-16.ll new file mode 100644 index 00000000000..bc095546ceb --- /dev/null +++ b/test/CodeGen/Mips/micromips-sw-lw-16.ll @@ -0,0 +1,27 @@ +; RUN: llc %s -march=mipsel -mattr=micromips -filetype=asm \ +; RUN: -relocation-model=pic -O3 -o - | FileCheck %s + +; Function Attrs: noinline nounwind +define void @bar(i32* %p) #0 { +entry: + %p.addr = alloca i32*, align 4 + store i32* %p, i32** %p.addr, align 4 + %0 = load i32** %p.addr, align 4 + %1 = load i32* %0, align 4 + %add = add nsw i32 7, %1 + %2 = load i32** %p.addr, align 4 + store i32 %add, i32* %2, align 4 + %3 = load i32** %p.addr, align 4 + %add.ptr = getelementptr inbounds i32* %3, i32 1 + %4 = load i32* %add.ptr, align 4 + %add1 = add nsw i32 7, %4 + %5 = load i32** %p.addr, align 4 + %add.ptr2 = getelementptr inbounds i32* %5, i32 1 + store i32 %add1, i32* %add.ptr2, align 4 + ret void +} + +; CHECK: lw16 ${{[0-9]+}}, 0($4) +; CHECK: sw16 ${{[0-9]+}}, 0($4) +; CHECK: lw16 ${{[0-9]+}}, 4(${{[0-9]+}}) +; CHECK: sw16 ${{[0-9]+}}, 4(${{[0-9]+}})