diff options
| author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-07-15 15:35:52 +0000 |
|---|---|---|
| committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-07-15 15:35:52 +0000 |
| commit | bba0bf7d372ee33e5d383f6a15303eacd7f97ce5 (patch) | |
| tree | d7066a17314ed1cd900b9d86b41975144642648b /llvm/lib/Target | |
| parent | f7f2b816024dd6b43b860ad52445ac08330275b9 (diff) | |
| download | bcm5719-llvm-bba0bf7d372ee33e5d383f6a15303eacd7f97ce5.tar.gz bcm5719-llvm-bba0bf7d372ee33e5d383f6a15303eacd7f97ce5.zip | |
[Hexagon] Improve patterns with stack-based addressing
- Treat bitwise OR with a frame index as an ADD wherever possible, fold it
into addressing mode.
- Extend patterns for memops to allow memops with frame indexes as address
operands.
llvm-svn: 275569
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp | 20 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp | 26 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonInstrInfo.td | 64 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td | 566 | ||||
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonOperands.td | 70 |
5 files changed, 394 insertions, 352 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index e26374d3781..a6b8e7523ba 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -177,6 +177,7 @@ public: private: bool isValueExtension(const SDValue &Val, unsigned FromBits, SDValue &Src); + bool orIsAdd(const SDNode *N) const; bool isAlignedMemNode(const MemSDNode *N) const; }; // end HexagonDAGToDAGISel } // end anonymous namespace @@ -1517,6 +1518,25 @@ bool HexagonDAGToDAGISel::isValueExtension(const SDValue &Val, return false; } + +bool HexagonDAGToDAGISel::orIsAdd(const SDNode *N) const { + assert(N->getOpcode() == ISD::OR); + auto *C = dyn_cast<ConstantSDNode>(N->getOperand(1)); + assert(C); + + // Detect when "or" is used to add an offset to a stack object. + if (auto *FN = dyn_cast<FrameIndexSDNode>(N->getOperand(0))) { + MachineFrameInfo *MFI = MF->getFrameInfo(); + unsigned A = MFI->getObjectAlignment(FN->getIndex()); + assert(isPowerOf2_32(A)); + int32_t Off = C->getSExtValue(); + // If the alleged offset fits in the zero bits guaranteed by + // the alignment, then this or is really an add. + return (Off >= 0) && (((A-1) & Off) == unsigned(Off)); + } + return false; +} + bool HexagonDAGToDAGISel::isAlignedMemNode(const MemSDNode *N) const { return N->getAlignment() >= N->getMemoryVT().getStoreSize(); } diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp index 7cd32f9fb0c..72cffe20a01 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -2612,6 +2612,21 @@ bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset, case Hexagon::J2_loop0i: case Hexagon::J2_loop1i: return isUInt<10>(Offset); + + case Hexagon::S4_storeirb_io: + case Hexagon::S4_storeirbt_io: + case Hexagon::S4_storeirbf_io: + return isUInt<6>(Offset); + + case Hexagon::S4_storeirh_io: + case Hexagon::S4_storeirht_io: + case Hexagon::S4_storeirhf_io: + return isShiftedUInt<6,1>(Offset); + + case Hexagon::S4_storeiri_io: + case Hexagon::S4_storeirit_io: + case Hexagon::S4_storeirif_io: + return isShiftedUInt<6,2>(Offset); } if (Extend) @@ -2687,9 +2702,6 @@ bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset, case Hexagon::L2_ploadrubf_io: case Hexagon::S2_pstorerbt_io: case Hexagon::S2_pstorerbf_io: - case Hexagon::S4_storeirb_io: - case Hexagon::S4_storeirbt_io: - case Hexagon::S4_storeirbf_io: return isUInt<6>(Offset); case Hexagon::L2_ploadrht_io: @@ -2698,18 +2710,12 @@ bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset, case Hexagon::L2_ploadruhf_io: case Hexagon::S2_pstorerht_io: case Hexagon::S2_pstorerhf_io: - case Hexagon::S4_storeirh_io: - case Hexagon::S4_storeirht_io: - case Hexagon::S4_storeirhf_io: return isShiftedUInt<6,1>(Offset); case Hexagon::L2_ploadrit_io: case Hexagon::L2_ploadrif_io: case Hexagon::S2_pstorerit_io: case Hexagon::S2_pstorerif_io: - case Hexagon::S4_storeiri_io: - case Hexagon::S4_storeirit_io: - case Hexagon::S4_storeirif_io: return isShiftedUInt<6,2>(Offset); case Hexagon::L2_ploadrdt_io: @@ -3066,8 +3072,6 @@ bool HexagonInstrInfo::getBaseAndOffsetPosition(const MachineInstr *MI, unsigned &BasePos, unsigned &OffsetPos) const { // Deal with memops first. if (isMemOp(MI)) { - assert (MI->getOperand(0).isReg() && MI->getOperand(1).isImm() && - "Bad Memop."); BasePos = 0; OffsetPos = 1; } else if (MI->mayStore()) { diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td index 15a43eec408..10b4df8a5e8 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td @@ -32,6 +32,9 @@ def LoReg: OutPatFrag<(ops node:$Rs), def HiReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG (i64 $Rs), subreg_hireg)>; +def orisadd: PatFrag<(ops node:$Addr, node:$off), + (or node:$Addr, node:$off), [{ return orIsAdd(N); }]>; + // SDNode for converting immediate C to C-1. def DEC_CONST_SIGNED : SDNodeXForm<imm, [{ // Return the byte immediate const-1 as an SDNode. @@ -1787,6 +1790,8 @@ multiclass Loadx_pat<PatFrag Load, ValueType VT, PatLeaf ImmPred, def: Pat<(VT (Load AddrFI:$fi)), (VT (MI AddrFI:$fi, 0))>; def: Pat<(VT (Load (add (i32 AddrFI:$fi), ImmPred:$Off))), (VT (MI AddrFI:$fi, imm:$Off))>; + def: Pat<(VT (Load (orisadd (i32 AddrFI:$fi), ImmPred:$Off))), + (VT (MI AddrFI:$fi, imm:$Off))>; def: Pat<(VT (Load (add (i32 IntRegs:$Rs), ImmPred:$Off))), (VT (MI IntRegs:$Rs, imm:$Off))>; def: Pat<(VT (Load (i32 IntRegs:$Rs))), (VT (MI IntRegs:$Rs, 0))>; @@ -3540,14 +3545,20 @@ let addrMode = BaseImmOffset, InputType = "imm" in { // AddedComplexity) to the individual patterns. class Storex_fi_pat<PatFrag Store, PatFrag Value, InstHexagon MI> : Pat<(Store Value:$Rs, AddrFI:$fi), (MI AddrFI:$fi, 0, Value:$Rs)>; -class Storex_fi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred, - InstHexagon MI> - : Pat<(Store Value:$Rs, (add (i32 AddrFI:$fi), ImmPred:$Off)), - (MI AddrFI:$fi, imm:$Off, Value:$Rs)>; -class Storex_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred, - InstHexagon MI> - : Pat<(Store Value:$Rt, (add (i32 IntRegs:$Rs), ImmPred:$Off)), - (MI IntRegs:$Rs, imm:$Off, Value:$Rt)>; +multiclass Storex_fi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred, + InstHexagon MI> { + def: Pat<(Store Value:$Rs, (add (i32 AddrFI:$fi), ImmPred:$Off)), + (MI AddrFI:$fi, imm:$Off, Value:$Rs)>; + def: Pat<(Store Value:$Rs, (orisadd (i32 AddrFI:$fi), ImmPred:$Off)), + (MI AddrFI:$fi, imm:$Off, Value:$Rs)>; +} +multiclass Storex_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred, + InstHexagon MI> { + def: Pat<(Store Value:$Rt, (add (i32 IntRegs:$Rs), ImmPred:$Off)), + (MI IntRegs:$Rs, imm:$Off, Value:$Rt)>; + def: Pat<(Store Value:$Rt, (orisadd (i32 IntRegs:$Rs), ImmPred:$Off)), + (MI IntRegs:$Rs, imm:$Off, Value:$Rt)>; +} class Storex_simple_pat<PatFrag Store, PatFrag Value, InstHexagon MI> : Pat<(Store Value:$Rt, (i32 IntRegs:$Rs)), (MI IntRegs:$Rs, 0, Value:$Rt)>; @@ -3559,14 +3570,20 @@ class Storexm_fi_pat<PatFrag Store, PatFrag Value, PatFrag ValueMod, InstHexagon MI> : Pat<(Store Value:$Rs, AddrFI:$fi), (MI AddrFI:$fi, 0, (ValueMod Value:$Rs))>; -class Storexm_fi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred, - PatFrag ValueMod, InstHexagon MI> - : Pat<(Store Value:$Rs, (add (i32 AddrFI:$fi), ImmPred:$Off)), - (MI AddrFI:$fi, imm:$Off, (ValueMod Value:$Rs))>; -class Storexm_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred, - PatFrag ValueMod, InstHexagon MI> - : Pat<(Store Value:$Rt, (add (i32 IntRegs:$Rs), ImmPred:$Off)), - (MI IntRegs:$Rs, imm:$Off, (ValueMod Value:$Rt))>; +multiclass Storexm_fi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred, + PatFrag ValueMod, InstHexagon MI> { + def: Pat<(Store Value:$Rs, (add (i32 AddrFI:$fi), ImmPred:$Off)), + (MI AddrFI:$fi, imm:$Off, (ValueMod Value:$Rs))>; + def: Pat<(Store Value:$Rs, (orisadd (i32 AddrFI:$fi), ImmPred:$Off)), + (MI AddrFI:$fi, imm:$Off, (ValueMod Value:$Rs))>; +} +multiclass Storexm_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred, + PatFrag ValueMod, InstHexagon MI> { + def: Pat<(Store Value:$Rt, (add (i32 IntRegs:$Rs), ImmPred:$Off)), + (MI IntRegs:$Rs, imm:$Off, (ValueMod Value:$Rt))>; + def: Pat<(Store Value:$Rt, (orisadd (i32 IntRegs:$Rs), ImmPred:$Off)), + (MI IntRegs:$Rs, imm:$Off, (ValueMod Value:$Rt))>; +} class Storexm_simple_pat<PatFrag Store, PatFrag Value, PatFrag ValueMod, InstHexagon MI> : Pat<(Store Value:$Rt, (i32 IntRegs:$Rs)), @@ -3574,16 +3591,16 @@ class Storexm_simple_pat<PatFrag Store, PatFrag Value, PatFrag ValueMod, multiclass Storex_pat<PatFrag Store, PatFrag Value, PatLeaf ImmPred, InstHexagon MI> { - def: Storex_fi_pat <Store, Value, MI>; - def: Storex_fi_add_pat <Store, Value, ImmPred, MI>; - def: Storex_add_pat <Store, Value, ImmPred, MI>; + def: Storex_fi_pat <Store, Value, MI>; + defm: Storex_fi_add_pat <Store, Value, ImmPred, MI>; + defm: Storex_add_pat <Store, Value, ImmPred, MI>; } multiclass Storexm_pat<PatFrag Store, PatFrag Value, PatLeaf ImmPred, PatFrag ValueMod, InstHexagon MI> { - def: Storexm_fi_pat <Store, Value, ValueMod, MI>; - def: Storexm_fi_add_pat <Store, Value, ImmPred, ValueMod, MI>; - def: Storexm_add_pat <Store, Value, ImmPred, ValueMod, MI>; + def: Storexm_fi_pat <Store, Value, ValueMod, MI>; + defm: Storexm_fi_add_pat <Store, Value, ImmPred, ValueMod, MI>; + defm: Storexm_add_pat <Store, Value, ImmPred, ValueMod, MI>; } // Regular stores in the DAG have two operands: value and address. @@ -4503,6 +4520,9 @@ let isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1, (ins IntRegs:$Rs, IntRegs:$fi, s32Imm:$off), "">; } +def: Pat<(i32 (orisadd (i32 AddrFI:$Rs), s32ImmPred:$off)), + (i32 (TFR_FI (i32 AddrFI:$Rs), s32ImmPred:$off))>; + //===----------------------------------------------------------------------===// // CRUSER - Type. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td b/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td index a1895cf76d1..6b543a7473e 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td @@ -1188,17 +1188,52 @@ def ToImmByte : OutPatFrag<(ops node:$R), (IMM_BYTE $R)>; def ToImmHalf : OutPatFrag<(ops node:$R), (IMM_HALF $R)>; def ToImmWord : OutPatFrag<(ops node:$R), (IMM_WORD $R)>; +// Emit store-immediate, but only when the stored value will not be constant- +// extended. The reason for that is that there is no pass that can optimize +// constant extenders in store-immediate instructions. In some cases we can +// end up will a number of such stores, all of which store the same extended +// value (e.g. after unrolling a loop that initializes floating point array). + +// Predicates to determine if the 16-bit immediate is expressible as a sign- +// extended 8-bit immediate. Store-immediate-halfword will ignore any bits +// beyond 0..15, so we don't care what is in there. + +def i16in8ImmPred: PatLeaf<(i32 imm), [{ + int64_t v = (int16_t)N->getSExtValue(); + return v == (int64_t)(int8_t)v; +}]>; + +// Predicates to determine if the 32-bit immediate is expressible as a sign- +// extended 8-bit immediate. +def i32in8ImmPred: PatLeaf<(i32 imm), [{ + int64_t v = (int32_t)N->getSExtValue(); + return v == (int64_t)(int8_t)v; +}]>; + + let AddedComplexity = 40 in { - // Not using frameindex patterns for these stores, because the offset - // is not extendable. This could cause problems during removing the frame - // indices, since the offset with respect to R29/R30 may not fit in the - // u6 field. - def: Storexm_add_pat<truncstorei8, s32ImmPred, u6_0ImmPred, ToImmByte, - S4_storeirb_io>; - def: Storexm_add_pat<truncstorei16, s32ImmPred, u6_1ImmPred, ToImmHalf, - S4_storeirh_io>; - def: Storexm_add_pat<store, s32ImmPred, u6_2ImmPred, ToImmWord, - S4_storeiri_io>; + // Even though the offset is not extendable in the store-immediate, we + // can still generate the fi# in the base address. If the final offset + // is not valid for the instruction, we will replace it with a scratch + // register. +// def: Storexm_fi_pat <truncstorei8, s32ImmPred, ToImmByte, S4_storeirb_io>; +// def: Storexm_fi_pat <truncstorei16, i16in8ImmPred, ToImmHalf, +// S4_storeirh_io>; +// def: Storexm_fi_pat <store, i32in8ImmPred, ToImmWord, S4_storeiri_io>; + +// defm: Storexm_fi_add_pat <truncstorei8, s32ImmPred, u6_0ImmPred, ToImmByte, +// S4_storeirb_io>; +// defm: Storexm_fi_add_pat <truncstorei16, i16in8ImmPred, u6_1ImmPred, +// ToImmHalf, S4_storeirh_io>; +// defm: Storexm_fi_add_pat <store, i32in8ImmPred, u6_2ImmPred, ToImmWord, +// S4_storeiri_io>; + + defm: Storexm_add_pat<truncstorei8, s32ImmPred, u6_0ImmPred, ToImmByte, + S4_storeirb_io>; + defm: Storexm_add_pat<truncstorei16, i16in8ImmPred, u6_1ImmPred, ToImmHalf, + S4_storeirh_io>; + defm: Storexm_add_pat<store, i32in8ImmPred, u6_2ImmPred, ToImmWord, + S4_storeiri_io>; } def: Storexm_simple_pat<truncstorei8, s32ImmPred, ToImmByte, S4_storeirb_io>; @@ -2783,79 +2818,75 @@ def S4_lsli: SInst <(outs IntRegs:$Rd), (ins s6Imm:$s6, IntRegs:$Rt), //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// -// MEMOP: Word, Half, Byte +// MEMOP //===----------------------------------------------------------------------===// -def MEMOPIMM : SDNodeXForm<imm, [{ - // Call the transformation function XformM5ToU5Imm to get the negative - // immediate's positive counterpart. - int32_t imm = N->getSExtValue(); - return XformM5ToU5Imm(imm, SDLoc(N)); +def m5Imm8Pred : PatLeaf<(i32 imm), [{ + int32_t v = (int8_t)N->getSExtValue(); + return v >= -32 && v <= -1; }]>; -def MEMOPIMM_HALF : SDNodeXForm<imm, [{ - // -1 .. -31 represented as 65535..65515 - // assigning to a short restores our desired signed value. - // Call the transformation function XformM5ToU5Imm to get the negative - // immediate's positive counterpart. - int16_t imm = N->getSExtValue(); - return XformM5ToU5Imm(imm, SDLoc(N)); +def m5Imm16Pred : PatLeaf<(i32 imm), [{ + int32_t v = (int16_t)N->getSExtValue(); + return v >= -32 && v <= -1; }]>; -def MEMOPIMM_BYTE : SDNodeXForm<imm, [{ - // -1 .. -31 represented as 255..235 - // assigning to a char restores our desired signed value. - // Call the transformation function XformM5ToU5Imm to get the negative - // immediate's positive counterpart. - int8_t imm = N->getSExtValue(); - return XformM5ToU5Imm(imm, SDLoc(N)); +def Clr5Imm8Pred : PatLeaf<(i32 imm), [{ + uint32_t v = (uint8_t)~N->getZExtValue(); + return ImmIsSingleBit(v); }]>; -def SETMEMIMM : SDNodeXForm<imm, [{ - // Return the bit position we will set [0-31]. - // As an SDNode. - int32_t imm = N->getSExtValue(); +def Clr5Imm16Pred : PatLeaf<(i32 imm), [{ + uint32_t v = (uint16_t)~N->getZExtValue(); + return ImmIsSingleBit(v); +}]>; + +def Set5Imm8 : SDNodeXForm<imm, [{ + uint32_t imm = (uint8_t)N->getZExtValue(); return XformMskToBitPosU5Imm(imm, SDLoc(N)); }]>; -def CLRMEMIMM : SDNodeXForm<imm, [{ - // Return the bit position we will clear [0-31]. - // As an SDNode. - // we bit negate the value first - int32_t imm = ~(N->getSExtValue()); +def Set5Imm16 : SDNodeXForm<imm, [{ + uint32_t imm = (uint16_t)N->getZExtValue(); return XformMskToBitPosU5Imm(imm, SDLoc(N)); }]>; -def SETMEMIMM_SHORT : SDNodeXForm<imm, [{ - // Return the bit position we will set [0-15]. - // As an SDNode. - int16_t imm = N->getSExtValue(); - return XformMskToBitPosU4Imm(imm, SDLoc(N)); +def Set5Imm32 : SDNodeXForm<imm, [{ + uint32_t imm = (uint32_t)N->getZExtValue(); + return XformMskToBitPosU5Imm(imm, SDLoc(N)); }]>; -def CLRMEMIMM_SHORT : SDNodeXForm<imm, [{ - // Return the bit position we will clear [0-15]. - // As an SDNode. - // we bit negate the value first - int16_t imm = ~(N->getSExtValue()); - return XformMskToBitPosU4Imm(imm, SDLoc(N)); +def Clr5Imm8 : SDNodeXForm<imm, [{ + uint32_t imm = (uint8_t)~N->getZExtValue(); + return XformMskToBitPosU5Imm(imm, SDLoc(N)); }]>; -def SETMEMIMM_BYTE : SDNodeXForm<imm, [{ - // Return the bit position we will set [0-7]. - // As an SDNode. - int8_t imm = N->getSExtValue(); - return XformMskToBitPosU3Imm(imm, SDLoc(N)); +def Clr5Imm16 : SDNodeXForm<imm, [{ + uint32_t imm = (uint16_t)~N->getZExtValue(); + return XformMskToBitPosU5Imm(imm, SDLoc(N)); }]>; -def CLRMEMIMM_BYTE : SDNodeXForm<imm, [{ - // Return the bit position we will clear [0-7]. - // As an SDNode. - // we bit negate the value first - int8_t imm = ~(N->getSExtValue()); - return XformMskToBitPosU3Imm(imm, SDLoc(N)); +def Clr5Imm32 : SDNodeXForm<imm, [{ + int32_t imm = (int32_t)~N->getZExtValue(); + return XformMskToBitPosU5Imm(imm, SDLoc(N)); +}]>; + +def NegImm8 : SDNodeXForm<imm, [{ + int8_t V = N->getSExtValue(); + return CurDAG->getTargetConstant(-V, SDLoc(N), MVT::i32); +}]>; + +def NegImm16 : SDNodeXForm<imm, [{ + int16_t V = N->getSExtValue(); + return CurDAG->getTargetConstant(-V, SDLoc(N), MVT::i32); }]>; +def NegImm32 : SDNodeXForm<imm, [{ + return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N), MVT::i32); +}]>; + +def IdImm : SDNodeXForm<imm, [{ return SDValue(N, 0); }]>; + //===----------------------------------------------------------------------===// // Template class for MemOp instructions with the register value. //===----------------------------------------------------------------------===// @@ -2952,197 +2983,234 @@ let isExtendable = 1, opExtendable = 1, isExtentSigned = 0 in { defm memopw_io : MemOp_base <"memw", 0b10, u6_2Ext>; } -//===----------------------------------------------------------------------===// -// Multiclass to define 'Def Pats' for ALU operations on the memory -// Here value used for the ALU operation is an immediate value. -// mem[bh](Rs+#0) += #U5 -// mem[bh](Rs+#u6) += #U5 -//===----------------------------------------------------------------------===// - -multiclass MemOpi_u5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf ImmPred, - InstHexagon MI, SDNode OpNode> { - let AddedComplexity = 180 in - def: Pat<(stOp (OpNode (ldOp IntRegs:$addr), u5ImmPred:$addend), - IntRegs:$addr), - (MI IntRegs:$addr, 0, u5ImmPred:$addend)>; - - let AddedComplexity = 190 in - def: Pat<(stOp (OpNode (ldOp (add IntRegs:$base, ImmPred:$offset)), - u5ImmPred:$addend), - (add IntRegs:$base, ImmPred:$offset)), - (MI IntRegs:$base, ImmPred:$offset, u5ImmPred:$addend)>; -} - -multiclass MemOpi_u5ALUOp<PatFrag ldOp, PatFrag stOp, PatLeaf ImmPred, - InstHexagon addMI, InstHexagon subMI> { - defm: MemOpi_u5Pats<ldOp, stOp, ImmPred, addMI, add>; - defm: MemOpi_u5Pats<ldOp, stOp, ImmPred, subMI, sub>; -} - -multiclass MemOpi_u5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { - // Half Word - defm: MemOpi_u5ALUOp <ldOpHalf, truncstorei16, u31_1ImmPred, - L4_iadd_memoph_io, L4_isub_memoph_io>; - // Byte - defm: MemOpi_u5ALUOp <ldOpByte, truncstorei8, u32ImmPred, - L4_iadd_memopb_io, L4_isub_memopb_io>; -} - -let Predicates = [UseMEMOP] in { - defm: MemOpi_u5ExtType<zextloadi8, zextloadi16>; // zero extend - defm: MemOpi_u5ExtType<sextloadi8, sextloadi16>; // sign extend - defm: MemOpi_u5ExtType<extloadi8, extloadi16>; // any extend - - // Word - defm: MemOpi_u5ALUOp <load, store, u30_2ImmPred, L4_iadd_memopw_io, - L4_isub_memopw_io>; -} - -//===----------------------------------------------------------------------===// -// multiclass to define 'Def Pats' for ALU operations on the memory. -// Here value used for the ALU operation is a negative value. -// mem[bh](Rs+#0) += #m5 -// mem[bh](Rs+#u6) += #m5 -//===----------------------------------------------------------------------===// - -multiclass MemOpi_m5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf ImmPred, - PatLeaf immPred, SDNodeXForm xformFunc, - InstHexagon MI> { - let AddedComplexity = 190 in - def: Pat<(stOp (add (ldOp IntRegs:$addr), immPred:$subend), IntRegs:$addr), - (MI IntRegs:$addr, 0, (xformFunc immPred:$subend))>; - - let AddedComplexity = 195 in - def: Pat<(stOp (add (ldOp (add IntRegs:$base, ImmPred:$offset)), - immPred:$subend), - (add IntRegs:$base, ImmPred:$offset)), - (MI IntRegs:$base, ImmPred:$offset, (xformFunc immPred:$subend))>; -} - -multiclass MemOpi_m5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { - // Half Word - defm: MemOpi_m5Pats <ldOpHalf, truncstorei16, u31_1ImmPred, m5HImmPred, - MEMOPIMM_HALF, L4_isub_memoph_io>; - // Byte - defm: MemOpi_m5Pats <ldOpByte, truncstorei8, u32ImmPred, m5BImmPred, - MEMOPIMM_BYTE, L4_isub_memopb_io>; -} - -let Predicates = [UseMEMOP] in { - defm: MemOpi_m5ExtType<zextloadi8, zextloadi16>; // zero extend - defm: MemOpi_m5ExtType<sextloadi8, sextloadi16>; // sign extend - defm: MemOpi_m5ExtType<extloadi8, extloadi16>; // any extend - - // Word - defm: MemOpi_m5Pats <load, store, u30_2ImmPred, m5ImmPred, - MEMOPIMM, L4_isub_memopw_io>; -} - -//===----------------------------------------------------------------------===// -// Multiclass to define 'def Pats' for bit operations on the memory. -// mem[bhw](Rs+#0) = [clrbit|setbit](#U5) -// mem[bhw](Rs+#u6) = [clrbit|setbit](#U5) -//===----------------------------------------------------------------------===// - -multiclass MemOpi_bitPats <PatFrag ldOp, PatFrag stOp, PatLeaf immPred, - PatLeaf extPred, SDNodeXForm xformFunc, InstHexagon MI, - SDNode OpNode> { - - // mem[bhw](Rs+#u6:[012]) = [clrbit|setbit](#U5) - let AddedComplexity = 250 in - def: Pat<(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)), - immPred:$bitend), - (add IntRegs:$base, extPred:$offset)), - (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$bitend))>; - - // mem[bhw](Rs+#0) = [clrbit|setbit](#U5) - let AddedComplexity = 225 in - def: Pat<(stOp (OpNode (ldOp IntRegs:$addr), immPred:$bitend), IntRegs:$addr), - (MI IntRegs:$addr, 0, (xformFunc immPred:$bitend))>; -} - -multiclass MemOpi_bitExtType<PatFrag ldOpByte, PatFrag ldOpHalf> { - // Byte - clrbit - defm: MemOpi_bitPats<ldOpByte, truncstorei8, Clr3ImmPred, u32ImmPred, - CLRMEMIMM_BYTE, L4_iand_memopb_io, and>; - // Byte - setbit - defm: MemOpi_bitPats<ldOpByte, truncstorei8, Set3ImmPred, u32ImmPred, - SETMEMIMM_BYTE, L4_ior_memopb_io, or>; - // Half Word - clrbit - defm: MemOpi_bitPats<ldOpHalf, truncstorei16, Clr4ImmPred, u31_1ImmPred, - CLRMEMIMM_SHORT, L4_iand_memoph_io, and>; - // Half Word - setbit - defm: MemOpi_bitPats<ldOpHalf, truncstorei16, Set4ImmPred, u31_1ImmPred, - SETMEMIMM_SHORT, L4_ior_memoph_io, or>; -} - -let Predicates = [UseMEMOP] in { - // mem[bh](Rs+#0) = [clrbit|setbit](#U5) - // mem[bh](Rs+#u6:[01]) = [clrbit|setbit](#U5) - defm: MemOpi_bitExtType<zextloadi8, zextloadi16>; // zero extend - defm: MemOpi_bitExtType<sextloadi8, sextloadi16>; // sign extend - defm: MemOpi_bitExtType<extloadi8, extloadi16>; // any extend - - // memw(Rs+#0) = [clrbit|setbit](#U5) - // memw(Rs+#u6:2) = [clrbit|setbit](#U5) - defm: MemOpi_bitPats<load, store, Clr5ImmPred, u30_2ImmPred, CLRMEMIMM, - L4_iand_memopw_io, and>; - defm: MemOpi_bitPats<load, store, Set5ImmPred, u30_2ImmPred, SETMEMIMM, - L4_ior_memopw_io, or>; -} - -//===----------------------------------------------------------------------===// -// Multiclass to define 'def Pats' for ALU operations on the memory -// where addend is a register. -// mem[bhw](Rs+#0) [+-&|]= Rt -// mem[bhw](Rs+#U6:[012]) [+-&|]= Rt -//===----------------------------------------------------------------------===// - -multiclass MemOpr_Pats <PatFrag ldOp, PatFrag stOp, PatLeaf extPred, - InstHexagon MI, SDNode OpNode> { - let AddedComplexity = 141 in - // mem[bhw](Rs+#0) [+-&|]= Rt - def: Pat<(stOp (OpNode (ldOp IntRegs:$addr), (i32 IntRegs:$addend)), - IntRegs:$addr), - (MI IntRegs:$addr, 0, (i32 IntRegs:$addend))>; - // mem[bhw](Rs+#U6:[012]) [+-&|]= Rt - let AddedComplexity = 150 in - def: Pat<(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)), - (i32 IntRegs:$orend)), - (add IntRegs:$base, extPred:$offset)), - (MI IntRegs:$base, extPred:$offset, (i32 IntRegs:$orend))>; +multiclass Memopxr_simple_pat<PatFrag Load, PatFrag Store, SDNode Oper, + InstHexagon MI> { + // Addr: i32 + def: Pat<(Store (Oper (Load I32:$Rs), I32:$A), I32:$Rs), + (MI I32:$Rs, 0, I32:$A)>; + // Addr: fi + def: Pat<(Store (Oper (Load AddrFI:$Rs), I32:$A), AddrFI:$Rs), + (MI AddrFI:$Rs, 0, I32:$A)>; +} + +multiclass Memopxr_add_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred, + SDNode Oper, InstHexagon MI> { + // Addr: i32 + def: Pat<(Store (Oper (Load (add I32:$Rs, ImmPred:$Off)), I32:$A), + (add I32:$Rs, ImmPred:$Off)), + (MI I32:$Rs, imm:$Off, I32:$A)>; + def: Pat<(Store (Oper (Load (orisadd I32:$Rs, ImmPred:$Off)), I32:$A), + (orisadd I32:$Rs, ImmPred:$Off)), + (MI I32:$Rs, imm:$Off, I32:$A)>; + // Addr: fi + def: Pat<(Store (Oper (Load (add AddrFI:$Rs, ImmPred:$Off)), I32:$A), + (add AddrFI:$Rs, ImmPred:$Off)), + (MI AddrFI:$Rs, imm:$Off, I32:$A)>; + def: Pat<(Store (Oper (Load (orisadd AddrFI:$Rs, ImmPred:$Off)), I32:$A), + (orisadd AddrFI:$Rs, ImmPred:$Off)), + (MI AddrFI:$Rs, imm:$Off, I32:$A)>; +} + +multiclass Memopxr_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred, + SDNode Oper, InstHexagon MI> { + defm: Memopxr_simple_pat <Load, Store, Oper, MI>; + defm: Memopxr_add_pat <Load, Store, ImmPred, Oper, MI>; +} + +let AddedComplexity = 180 in { + // add reg + defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, add, + /*anyext*/ L4_add_memopb_io>; + defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, add, + /*sext*/ L4_add_memopb_io>; + defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, add, + /*zext*/ L4_add_memopb_io>; + defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, add, + /*anyext*/ L4_add_memoph_io>; + defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, add, + /*sext*/ L4_add_memoph_io>; + defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, add, + /*zext*/ L4_add_memoph_io>; + defm: Memopxr_pat<load, store, u6_2ImmPred, add, L4_add_memopw_io>; + + // sub reg + defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, sub, + /*anyext*/ L4_sub_memopb_io>; + defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub, + /*sext*/ L4_sub_memopb_io>; + defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub, + /*zext*/ L4_sub_memopb_io>; + defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, sub, + /*anyext*/ L4_sub_memoph_io>; + defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub, + /*sext*/ L4_sub_memoph_io>; + defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub, + /*zext*/ L4_sub_memoph_io>; + defm: Memopxr_pat<load, store, u6_2ImmPred, sub, L4_sub_memopw_io>; + + // and reg + defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, and, + /*anyext*/ L4_and_memopb_io>; + defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, and, + /*sext*/ L4_and_memopb_io>; + defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, and, + /*zext*/ L4_and_memopb_io>; + defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, and, + /*anyext*/ L4_and_memoph_io>; + defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, and, + /*sext*/ L4_and_memoph_io>; + defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, and, + /*zext*/ L4_and_memoph_io>; + defm: Memopxr_pat<load, store, u6_2ImmPred, and, L4_and_memopw_io>; + + // or reg + defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, or, + /*anyext*/ L4_or_memopb_io>; + defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, or, + /*sext*/ L4_or_memopb_io>; + defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, or, + /*zext*/ L4_or_memopb_io>; + defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, or, + /*anyext*/ L4_or_memoph_io>; + defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, or, + /*sext*/ L4_or_memoph_io>; + defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, or, + /*zext*/ L4_or_memoph_io>; + defm: Memopxr_pat<load, store, u6_2ImmPred, or, L4_or_memopw_io>; +} + + +multiclass Memopxi_simple_pat<PatFrag Load, PatFrag Store, SDNode Oper, + PatFrag Arg, SDNodeXForm ArgMod, + InstHexagon MI> { + // Addr: i32 + def: Pat<(Store (Oper (Load I32:$Rs), Arg:$A), I32:$Rs), + (MI I32:$Rs, 0, (ArgMod Arg:$A))>; + // Addr: fi + def: Pat<(Store (Oper (Load AddrFI:$Rs), Arg:$A), AddrFI:$Rs), + (MI AddrFI:$Rs, 0, (ArgMod Arg:$A))>; +} + +multiclass Memopxi_add_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred, + SDNode Oper, PatFrag Arg, SDNodeXForm ArgMod, + InstHexagon MI> { + // Addr: i32 + def: Pat<(Store (Oper (Load (add I32:$Rs, ImmPred:$Off)), Arg:$A), + (add I32:$Rs, ImmPred:$Off)), + (MI I32:$Rs, imm:$Off, (ArgMod Arg:$A))>; + def: Pat<(Store (Oper (Load (orisadd I32:$Rs, ImmPred:$Off)), Arg:$A), + (orisadd I32:$Rs, ImmPred:$Off)), + (MI I32:$Rs, imm:$Off, (ArgMod Arg:$A))>; + // Addr: fi + def: Pat<(Store (Oper (Load (add AddrFI:$Rs, ImmPred:$Off)), Arg:$A), + (add AddrFI:$Rs, ImmPred:$Off)), + (MI AddrFI:$Rs, imm:$Off, (ArgMod Arg:$A))>; + def: Pat<(Store (Oper (Load (orisadd AddrFI:$Rs, ImmPred:$Off)), Arg:$A), + (orisadd AddrFI:$Rs, ImmPred:$Off)), + (MI AddrFI:$Rs, imm:$Off, (ArgMod Arg:$A))>; +} + +multiclass Memopxi_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred, + SDNode Oper, PatFrag Arg, SDNodeXForm ArgMod, + InstHexagon MI> { + defm: Memopxi_simple_pat <Load, Store, Oper, Arg, ArgMod, MI>; + defm: Memopxi_add_pat <Load, Store, ImmPred, Oper, Arg, ArgMod, MI>; } -multiclass MemOPr_ALUOp<PatFrag ldOp, PatFrag stOp, PatLeaf extPred, - InstHexagon addMI, InstHexagon subMI, - InstHexagon andMI, InstHexagon orMI> { - defm: MemOpr_Pats <ldOp, stOp, extPred, addMI, add>; - defm: MemOpr_Pats <ldOp, stOp, extPred, subMI, sub>; - defm: MemOpr_Pats <ldOp, stOp, extPred, andMI, and>; - defm: MemOpr_Pats <ldOp, stOp, extPred, orMI, or>; -} - -multiclass MemOPr_ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { - // Half Word - defm: MemOPr_ALUOp <ldOpHalf, truncstorei16, u31_1ImmPred, - L4_add_memoph_io, L4_sub_memoph_io, - L4_and_memoph_io, L4_or_memoph_io>; - // Byte - defm: MemOPr_ALUOp <ldOpByte, truncstorei8, u32ImmPred, - L4_add_memopb_io, L4_sub_memopb_io, - L4_and_memopb_io, L4_or_memopb_io>; -} -// Define 'def Pats' for MemOps with register addend. -let Predicates = [UseMEMOP] in { - // Byte, Half Word - defm: MemOPr_ExtType<zextloadi8, zextloadi16>; // zero extend - defm: MemOPr_ExtType<sextloadi8, sextloadi16>; // sign extend - defm: MemOPr_ExtType<extloadi8, extloadi16>; // any extend - // Word - defm: MemOPr_ALUOp <load, store, u30_2ImmPred, L4_add_memopw_io, - L4_sub_memopw_io, L4_and_memopw_io, L4_or_memopw_io>; +let AddedComplexity = 200 in { + // add imm + defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, add, u5ImmPred, + /*anyext*/ IdImm, L4_iadd_memopb_io>; + defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, add, u5ImmPred, + /*sext*/ IdImm, L4_iadd_memopb_io>; + defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, add, u5ImmPred, + /*zext*/ IdImm, L4_iadd_memopb_io>; + defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5ImmPred, + /*anyext*/ IdImm, L4_iadd_memoph_io>; + defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5ImmPred, + /*sext*/ IdImm, L4_iadd_memoph_io>; + defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5ImmPred, + /*zext*/ IdImm, L4_iadd_memoph_io>; + defm: Memopxi_pat<load, store, u6_2ImmPred, add, u5ImmPred, IdImm, + L4_iadd_memopw_io>; + defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, sub, m5Imm8Pred, + /*anyext*/ NegImm8, L4_iadd_memopb_io>; + defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub, m5Imm8Pred, + /*sext*/ NegImm8, L4_iadd_memopb_io>; + defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub, m5Imm8Pred, + /*zext*/ NegImm8, L4_iadd_memopb_io>; + defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, sub, m5Imm16Pred, + /*anyext*/ NegImm16, L4_iadd_memoph_io>; + defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub, m5Imm16Pred, + /*sext*/ NegImm16, L4_iadd_memoph_io>; + defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub, m5Imm16Pred, + /*zext*/ NegImm16, L4_iadd_memoph_io>; + defm: Memopxi_pat<load, store, u6_2ImmPred, sub, m5ImmPred, NegImm32, + L4_iadd_memopw_io>; + + // sub imm + defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, sub, u5ImmPred, + /*anyext*/ IdImm, L4_isub_memopb_io>; + defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub, u5ImmPred, + /*sext*/ IdImm, L4_isub_memopb_io>; + defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub, u5ImmPred, + /*zext*/ IdImm, L4_isub_memopb_io>; + defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, sub, u5ImmPred, + /*anyext*/ IdImm, L4_isub_memoph_io>; + defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub, u5ImmPred, + /*sext*/ IdImm, L4_isub_memoph_io>; + defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub, u5ImmPred, + /*zext*/ IdImm, L4_isub_memoph_io>; + defm: Memopxi_pat<load, store, u6_2ImmPred, sub, u5ImmPred, IdImm, + L4_isub_memopw_io>; + defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, add, m5Imm8Pred, + /*anyext*/ NegImm8, L4_isub_memopb_io>; + defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, add, m5Imm8Pred, + /*sext*/ NegImm8, L4_isub_memopb_io>; + defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, add, m5Imm8Pred, + /*zext*/ NegImm8, L4_isub_memopb_io>; + defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, m5Imm16Pred, + /*anyext*/ NegImm16, L4_isub_memoph_io>; + defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, add, m5Imm16Pred, + /*sext*/ NegImm16, L4_isub_memoph_io>; + defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, add, m5Imm16Pred, + /*zext*/ NegImm16, L4_isub_memoph_io>; + defm: Memopxi_pat<load, store, u6_2ImmPred, add, m5ImmPred, NegImm32, + L4_isub_memopw_io>; + + // clrbit imm + defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, and, Clr5Imm8Pred, + /*anyext*/ Clr5Imm8, L4_iand_memopb_io>; + defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, and, Clr5Imm8Pred, + /*sext*/ Clr5Imm8, L4_iand_memopb_io>; + defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, and, Clr5Imm8Pred, + /*zext*/ Clr5Imm8, L4_iand_memopb_io>; + defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, and, Clr5Imm16Pred, + /*anyext*/ Clr5Imm16, L4_iand_memoph_io>; + defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, and, Clr5Imm16Pred, + /*sext*/ Clr5Imm16, L4_iand_memoph_io>; + defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, and, Clr5Imm16Pred, + /*zext*/ Clr5Imm16, L4_iand_memoph_io>; + defm: Memopxi_pat<load, store, u6_2ImmPred, and, Clr5ImmPred, Clr5Imm16, + L4_iand_memopw_io>; + + // setbit imm + defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, or, Set5ImmPred, + /*anyext*/ Set5Imm8, L4_ior_memopb_io>; + defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, or, Set5ImmPred, + /*sext*/ Set5Imm8, L4_ior_memopb_io>; + defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, or, Set5ImmPred, + /*zext*/ Set5Imm8, L4_ior_memopb_io>; + defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, or, Set5ImmPred, + /*anyext*/ Set5Imm16, L4_ior_memoph_io>; + defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, or, Set5ImmPred, + /*sext*/ Set5Imm16, L4_ior_memoph_io>; + defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, or, Set5ImmPred, + /*zext*/ Set5Imm16, L4_ior_memoph_io>; + defm: Memopxi_pat<load, store, u6_2ImmPred, or, Set5ImmPred, Set5Imm32, + L4_ior_memopw_io>; } //===----------------------------------------------------------------------===// @@ -3846,7 +3914,7 @@ let AddedComplexity = 30 in { // Indexed store word - global address. // memw(Rs+#u6:2)=#S8 let AddedComplexity = 100 in -def: Storex_add_pat<store, addrga, u6_2ImmPred, S4_storeiri_io>; +defm: Storex_add_pat<store, addrga, u6_2ImmPred, S4_storeiri_io>; // Load from a global address that has only one use in the current basic block. let AddedComplexity = 100 in { diff --git a/llvm/lib/Target/Hexagon/HexagonOperands.td b/llvm/lib/Target/Hexagon/HexagonOperands.td index 7224bb62c68..11092d2b92f 100644 --- a/llvm/lib/Target/Hexagon/HexagonOperands.td +++ b/llvm/lib/Target/Hexagon/HexagonOperands.td @@ -347,22 +347,6 @@ def u1ImmPred32 : PatLeaf<(i32 imm), [{ return isUInt<1>(v); }]>; -def m5BImmPred : PatLeaf<(i32 imm), [{ - // m5BImmPred predicate - True if the (char) number is in range -1 .. -31 - // and will fit in a 5 bit field when made positive, for use in memops. - // this is specific to the zero extending of a negative by CombineInstr - int8_t v = (int8_t)N->getSExtValue(); - return (-31 <= v && v <= -1); -}]>; - -def m5HImmPred : PatLeaf<(i32 imm), [{ - // m5HImmPred predicate - True if the (short) number is in range -1 .. -31 - // and will fit in a 5 bit field when made positive, for use in memops. - // this is specific to the zero extending of a negative by CombineInstr - int16_t v = (int16_t)N->getSExtValue(); - return (-31 <= v && v <= -1); -}]>; - def m5ImmPred : PatLeaf<(i32 imm), [{ // m5ImmPred predicate - True if the number is in range -1 .. -31 // and will fit in a 5 bit field when made positive, for use in memops. @@ -404,60 +388,6 @@ def Clr5ImmPred : PatLeaf<(i32 imm), [{ return ImmIsSingleBit(v); }]>; -def SetClr5ImmPred : PatLeaf<(i32 imm), [{ - // True if the immediate is in range 0..31. - int32_t v = (int32_t)N->getSExtValue(); - return (v >= 0 && v <= 31); -}]>; - -def Set4ImmPred : PatLeaf<(i32 imm), [{ - // Set4ImmPred predicate - True if the number is in the series of values: - // [ 2^0, 2^1, ... 2^15 ]. - // For use in setbit immediate. - uint16_t v = (int16_t)N->getSExtValue(); - // Constrain to 16 bits, and then check for single bit. - return ImmIsSingleBit(v); -}]>; - -def Clr4ImmPred : PatLeaf<(i32 imm), [{ - // Clr4ImmPred predicate - True if the number is in the series of - // bit negated values: - // [ 2^0, 2^1, ... 2^15 ]. - // For use in setbit and clrbit immediate. - uint16_t v = ~ (int16_t)N->getSExtValue(); - // Constrain to 16 bits, and then check for single bit. - return ImmIsSingleBit(v); -}]>; - -def SetClr4ImmPred : PatLeaf<(i32 imm), [{ - // True if the immediate is in the range 0..15. - int16_t v = (int16_t)N->getSExtValue(); - return (v >= 0 && v <= 15); -}]>; - -def Set3ImmPred : PatLeaf<(i32 imm), [{ - // True if the number is in the series of values: [ 2^0, 2^1, ... 2^7 ]. - // For use in setbit immediate. - uint8_t v = (int8_t)N->getSExtValue(); - // Constrain to 8 bits, and then check for single bit. - return ImmIsSingleBit(v); -}]>; - -def Clr3ImmPred : PatLeaf<(i32 imm), [{ - // True if the number is in the series of bit negated values: [ 2^0, 2^1, ... 2^7 ]. - // For use in setbit and clrbit immediate. - uint8_t v = ~ (int8_t)N->getSExtValue(); - // Constrain to 8 bits, and then check for single bit. - return ImmIsSingleBit(v); -}]>; - -def SetClr3ImmPred : PatLeaf<(i32 imm), [{ - // True if the immediate is in the range 0..7. - int8_t v = (int8_t)N->getSExtValue(); - return (v >= 0 && v <= 7); -}]>; - - // Extendable immediate operands. def f32ExtOperand : AsmOperandClass { let Name = "f32Ext"; } def s16ExtOperand : AsmOperandClass { let Name = "s16Ext"; } |

