ARMInstrThumb.td revision 199511
1249259Sdim//===- ARMInstrThumb.td - Thumb support for ARM ---------------------------===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file describes the Thumb instruction set. 11249259Sdim// 12249259Sdim//===----------------------------------------------------------------------===// 13249259Sdim 14249259Sdim//===----------------------------------------------------------------------===// 15249259Sdim// Thumb specific DAG Nodes. 16249259Sdim// 17276479Sdim 18276479Sdimdef ARMtcall : SDNode<"ARMISD::tCALL", SDT_ARMcall, 19249259Sdim [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; 20249259Sdim 21249259Sdimdef imm_neg_XFORM : SDNodeXForm<imm, [{ 22249259Sdim return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32); 23249259Sdim}]>; 24249259Sdimdef imm_comp_XFORM : SDNodeXForm<imm, [{ 25249259Sdim return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32); 26249259Sdim}]>; 27249259Sdim 28249259Sdim 29249259Sdim/// imm0_7 predicate - True if the 32-bit immediate is in the range [0,7]. 30249259Sdimdef imm0_7 : PatLeaf<(i32 imm), [{ 31249259Sdim return (uint32_t)N->getZExtValue() < 8; 32249259Sdim}]>; 33249259Sdimdef imm0_7_neg : PatLeaf<(i32 imm), [{ 34249259Sdim return (uint32_t)-N->getZExtValue() < 8; 35249259Sdim}], imm_neg_XFORM>; 36249259Sdim 37249259Sdimdef imm0_255 : PatLeaf<(i32 imm), [{ 38249259Sdim return (uint32_t)N->getZExtValue() < 256; 39249259Sdim}]>; 40249259Sdimdef imm0_255_comp : PatLeaf<(i32 imm), [{ 41249259Sdim return ~((uint32_t)N->getZExtValue()) < 256; 42249259Sdim}]>; 43249259Sdim 44249259Sdimdef imm8_255 : PatLeaf<(i32 imm), [{ 45249259Sdim return (uint32_t)N->getZExtValue() >= 8 && (uint32_t)N->getZExtValue() < 256; 46249259Sdim}]>; 47249259Sdimdef imm8_255_neg : PatLeaf<(i32 imm), [{ 48249259Sdim unsigned Val = -N->getZExtValue(); 49249259Sdim return Val >= 8 && Val < 256; 50249259Sdim}], imm_neg_XFORM>; 51249259Sdim 52249259Sdim// Break imm's up into two pieces: an immediate + a left shift. 53249259Sdim// This uses thumb_immshifted to match and thumb_immshifted_val and 54249259Sdim// thumb_immshifted_shamt to get the val/shift pieces. 55249259Sdimdef thumb_immshifted : PatLeaf<(imm), [{ 56249259Sdim return ARM_AM::isThumbImmShiftedVal((unsigned)N->getZExtValue()); 57249259Sdim}]>; 58249259Sdim 59249259Sdimdef thumb_immshifted_val : SDNodeXForm<imm, [{ 60249259Sdim unsigned V = ARM_AM::getThumbImmNonShiftedVal((unsigned)N->getZExtValue()); 61249259Sdim return CurDAG->getTargetConstant(V, MVT::i32); 62249259Sdim}]>; 63249259Sdim 64249259Sdimdef thumb_immshifted_shamt : SDNodeXForm<imm, [{ 65296417Sdim unsigned V = ARM_AM::getThumbImmValShift((unsigned)N->getZExtValue()); 66296417Sdim return CurDAG->getTargetConstant(V, MVT::i32); 67296417Sdim}]>; 68296417Sdim 69249259Sdim// Scaled 4 immediate. 70249259Sdimdef t_imm_s4 : Operand<i32> { 71249259Sdim let PrintMethod = "printThumbS4ImmOperand"; 72249259Sdim} 73249259Sdim 74276479Sdim// Define Thumb specific addressing modes. 75249259Sdim 76249259Sdim// t_addrmode_rr := reg + reg 77249259Sdim// 78249259Sdimdef t_addrmode_rr : Operand<i32>, 79249259Sdim ComplexPattern<i32, 2, "SelectThumbAddrModeRR", []> { 80249259Sdim let PrintMethod = "printThumbAddrModeRROperand"; 81249259Sdim let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); 82276479Sdim} 83249259Sdim 84249259Sdim// t_addrmode_s4 := reg + reg 85249259Sdim// reg + imm5 * 4 86249259Sdim// 87249259Sdimdef t_addrmode_s4 : Operand<i32>, 88249259Sdim ComplexPattern<i32, 3, "SelectThumbAddrModeS4", []> { 89249259Sdim let PrintMethod = "printThumbAddrModeS4Operand"; 90296417Sdim let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 91296417Sdim} 92249259Sdim 93288943Sdim// t_addrmode_s2 := reg + reg 94288943Sdim// reg + imm5 * 2 95288943Sdim// 96249259Sdimdef t_addrmode_s2 : Operand<i32>, 97249259Sdim ComplexPattern<i32, 3, "SelectThumbAddrModeS2", []> { 98249259Sdim let PrintMethod = "printThumbAddrModeS2Operand"; 99249259Sdim let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 100249259Sdim} 101249259Sdim 102249259Sdim// t_addrmode_s1 := reg + reg 103249259Sdim// reg + imm5 104249259Sdim// 105249259Sdimdef t_addrmode_s1 : Operand<i32>, 106249259Sdim ComplexPattern<i32, 3, "SelectThumbAddrModeS1", []> { 107249259Sdim let PrintMethod = "printThumbAddrModeS1Operand"; 108249259Sdim let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 109249259Sdim} 110249259Sdim 111249259Sdim// t_addrmode_sp := sp + imm8 * 4 112249259Sdim// 113249259Sdimdef t_addrmode_sp : Operand<i32>, 114249259Sdim ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> { 115276479Sdim let PrintMethod = "printThumbAddrModeSPOperand"; 116288943Sdim let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm); 117249259Sdim} 118249259Sdim 119249259Sdim//===----------------------------------------------------------------------===// 120249259Sdim// Miscellaneous Instructions. 121249259Sdim// 122249259Sdim 123249259Sdimlet Defs = [SP], Uses = [SP] in { 124249259Sdimdef tADJCALLSTACKUP : 125249259SdimPseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary, 126249259Sdim "@ tADJCALLSTACKUP $amt1", 127249259Sdim [(ARMcallseq_end imm:$amt1, imm:$amt2)]>, Requires<[IsThumb1Only]>; 128249259Sdim 129249259Sdimdef tADJCALLSTACKDOWN : 130249259SdimPseudoInst<(outs), (ins i32imm:$amt), NoItinerary, 131249259Sdim "@ tADJCALLSTACKDOWN $amt", 132249259Sdim [(ARMcallseq_start imm:$amt)]>, Requires<[IsThumb1Only]>; 133249259Sdim} 134249259Sdim 135249259Sdim// For both thumb1 and thumb2. 136249259Sdimlet isNotDuplicable = 1 in 137288943Sdimdef tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr, 138249259Sdim "\n$cp:\n\tadd\t$dst, pc", 139249259Sdim [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>; 140249259Sdim 141249259Sdim// PC relative add. 142249259Sdimdef tADDrPCi : T1I<(outs tGPR:$dst), (ins t_imm_s4:$rhs), IIC_iALUi, 143249259Sdim "add\t$dst, pc, $rhs", []>; 144249259Sdim 145249259Sdim// ADD rd, sp, #imm8 146249259Sdimdef tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, t_imm_s4:$rhs), IIC_iALUi, 147249259Sdim "add\t$dst, $sp, $rhs", []>; 148276479Sdim 149249259Sdim// ADD sp, sp, #imm7 150249259Sdimdef tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), IIC_iALUi, 151249259Sdim "add\t$dst, $rhs", []>; 152249259Sdim 153249259Sdim// SUB sp, sp, #imm7 154249259Sdimdef tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), IIC_iALUi, 155249259Sdim "sub\t$dst, $rhs", []>; 156249259Sdim 157249259Sdim// ADD rm, sp 158249259Sdimdef tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 159249259Sdim "add\t$dst, $rhs", []>; 160249259Sdim 161288943Sdim// ADD sp, rm 162288943Sdimdef tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 163288943Sdim "add\t$dst, $rhs", []>; 164288943Sdim 165249259Sdim// Pseudo instruction that will expand into a tSUBspi + a copy. 166249259Sdimlet usesCustomInserter = 1 in { // Expanded after instruction selection. 167288943Sdimdef tSUBspi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), 168288943Sdim NoItinerary, "@ sub\t$dst, $rhs", []>; 169288943Sdim 170288943Sdimdef tADDspr_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 171249259Sdim NoItinerary, "@ add\t$dst, $rhs", []>; 172249259Sdim 173249259Sdimlet Defs = [CPSR] in 174288943Sdimdef tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), 175288943Sdim NoItinerary, "@ and\t$dst, $rhs", []>; 176288943Sdim} // usesCustomInserter 177288943Sdim 178288943Sdim//===----------------------------------------------------------------------===// 179288943Sdim// Control Flow Instructions. 180249259Sdim// 181249259Sdim 182249259Sdimlet isReturn = 1, isTerminator = 1, isBarrier = 1 in { 183249259Sdim def tBX_RET : TI<(outs), (ins), IIC_Br, "bx\tlr", [(ARMretflag)]>; 184249259Sdim // Alternative return instruction used by vararg functions. 185249259Sdim def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target", []>; 186288943Sdim} 187249259Sdim 188249259Sdim// Indirect branches 189288943Sdimlet isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 190249259Sdim def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "mov\tpc, $dst", 191249259Sdim [(brind GPR:$dst)]>; 192288943Sdim} 193249259Sdim 194249259Sdim// FIXME: remove when we have a way to marking a MI with these properties. 195288943Sdimlet isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 196249259Sdim hasExtraDefRegAllocReq = 1 in 197249259Sdimdef tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 198288943Sdim "pop${p}\t$wb", []>; 199249259Sdim 200288943Sdimlet isCall = 1, 201288943Sdim Defs = [R0, R1, R2, R3, R12, LR, 202249259Sdim D0, D1, D2, D3, D4, D5, D6, D7, 203249259Sdim D16, D17, D18, D19, D20, D21, D22, D23, 204249259Sdim D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 205249259Sdim // Also used for Thumb2 206249259Sdim def tBL : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 207249259Sdim "bl\t${func:call}", 208249259Sdim [(ARMtcall tglobaladdr:$func)]>, 209249259Sdim Requires<[IsThumb, IsNotDarwin]>; 210249259Sdim 211288943Sdim // ARMv5T and above, also used for Thumb2 212288943Sdim def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 213249259Sdim "blx\t${func:call}", 214249259Sdim [(ARMcall tglobaladdr:$func)]>, 215276479Sdim Requires<[IsThumb, HasV5T, IsNotDarwin]>; 216249259Sdim 217249259Sdim // Also used for Thumb2 218249259Sdim def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 219288943Sdim "blx\t$func", 220288943Sdim [(ARMtcall GPR:$func)]>, 221249259Sdim Requires<[IsThumb, HasV5T, IsNotDarwin]>; 222249259Sdim 223249259Sdim // ARMv4T 224249259Sdim def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 225249259Sdim "mov\tlr, pc\n\tbx\t$func", 226249259Sdim [(ARMcall_nolink tGPR:$func)]>, 227249259Sdim Requires<[IsThumb1Only, IsNotDarwin]>; 228249259Sdim} 229249259Sdim 230288943Sdim// On Darwin R9 is call-clobbered. 231296417Sdimlet isCall = 1, 232288943Sdim Defs = [R0, R1, R2, R3, R9, R12, LR, 233296417Sdim D0, D1, D2, D3, D4, D5, D6, D7, 234296417Sdim D16, D17, D18, D19, D20, D21, D22, D23, 235249259Sdim D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 236249259Sdim // Also used for Thumb2 237249259Sdim def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 238249259Sdim "bl\t${func:call}", 239249259Sdim [(ARMtcall tglobaladdr:$func)]>, 240249259Sdim Requires<[IsThumb, IsDarwin]>; 241249259Sdim 242249259Sdim // ARMv5T and above, also used for Thumb2 243249259Sdim def tBLXi_r9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 244249259Sdim "blx\t${func:call}", 245249259Sdim [(ARMcall tglobaladdr:$func)]>, 246249259Sdim Requires<[IsThumb, HasV5T, IsDarwin]>; 247249259Sdim 248249259Sdim // Also used for Thumb2 249296417Sdim def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 250296417Sdim "blx\t$func", 251296417Sdim [(ARMtcall GPR:$func)]>, 252296417Sdim Requires<[IsThumb, HasV5T, IsDarwin]>; 253296417Sdim 254249259Sdim // ARMv4T 255249259Sdim def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 256249259Sdim "mov\tlr, pc\n\tbx\t$func", 257249259Sdim [(ARMcall_nolink tGPR:$func)]>, 258288943Sdim Requires<[IsThumb1Only, IsDarwin]>; 259288943Sdim} 260288943Sdim 261249259Sdimlet isBranch = 1, isTerminator = 1 in { 262249259Sdim let isBarrier = 1 in { 263249259Sdim let isPredicable = 1 in 264249259Sdim def tB : T1I<(outs), (ins brtarget:$target), IIC_Br, 265249259Sdim "b\t$target", [(br bb:$target)]>; 266249259Sdim 267249259Sdim // Far jump 268249259Sdim let Defs = [LR] in 269249259Sdim def tBfar : TIx2<(outs), (ins brtarget:$target), IIC_Br, 270249259Sdim "bl\t$target\t@ far jump",[]>; 271249259Sdim 272249259Sdim def tBR_JTr : T1JTI<(outs), 273249259Sdim (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id), 274249259Sdim IIC_Br, "mov\tpc, $target\n\t.align\t2\n$jt", 275249259Sdim [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>; 276249259Sdim } 277249259Sdim} 278249259Sdim 279249259Sdim// FIXME: should be able to write a pattern for ARMBrcond, but can't use 280249259Sdim// a two-value operand where a dag node expects two operands. :( 281249259Sdimlet isBranch = 1, isTerminator = 1 in 282249259Sdim def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br, 283249259Sdim "b$cc\t$target", 284249259Sdim [/*(ARMbrcond bb:$target, imm:$cc)*/]>; 285249259Sdim 286249259Sdim// Compare and branch on zero / non-zero 287249259Sdimlet isBranch = 1, isTerminator = 1 in { 288249259Sdim def tCBZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br, 289288943Sdim "cbz\t$cmp, $target", []>; 290288943Sdim 291288943Sdim def tCBNZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br, 292288943Sdim "cbnz\t$cmp, $target", []>; 293276479Sdim} 294249259Sdim 295296417Sdim//===----------------------------------------------------------------------===// 296249259Sdim// Load Store Instructions. 297296417Sdim// 298296417Sdim 299249259Sdimlet canFoldAsLoad = 1 in 300249259Sdimdef tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, 301249259Sdim "ldr", "\t$dst, $addr", 302296417Sdim [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>; 303296417Sdim 304296417Sdimdef tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr, 305296417Sdim "ldrb", "\t$dst, $addr", 306296417Sdim [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; 307296417Sdim 308296417Sdimdef tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr, 309296417Sdim "ldrh", "\t$dst, $addr", 310296417Sdim [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; 311296417Sdim 312296417Sdimlet AddedComplexity = 10 in 313296417Sdimdef tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, 314296417Sdim "ldrsb", "\t$dst, $addr", 315249259Sdim [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; 316249259Sdim 317249259Sdimlet AddedComplexity = 10 in 318249259Sdimdef tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, 319249259Sdim "ldrsh", "\t$dst, $addr", 320249259Sdim [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>; 321288943Sdim 322288943Sdimlet canFoldAsLoad = 1 in 323288943Sdimdef tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, 324288943Sdim "ldr", "\t$dst, $addr", 325288943Sdim [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>; 326288943Sdim 327249259Sdim// Special instruction for restore. It cannot clobber condition register 328249259Sdim// when it's expanded by eliminateCallFramePseudoInstr(). 329249259Sdimlet canFoldAsLoad = 1, mayLoad = 1 in 330249259Sdimdef tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, 331249259Sdim "ldr", "\t$dst, $addr", []>; 332249259Sdim 333249259Sdim// Load tconstpool 334249259Sdim// FIXME: Use ldr.n to work around a Darwin assembler bug. 335249259Sdimlet canFoldAsLoad = 1 in 336288943Sdimdef tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, 337288943Sdim "ldr", ".n\t$dst, $addr", 338288943Sdim [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; 339288943Sdim 340249259Sdim// Special LDR for loads from non-pc-relative constpools. 341249259Sdimlet canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in 342288943Sdimdef tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, 343288943Sdim "ldr", "\t$dst, $addr", []>; 344288943Sdim 345288943Sdimdef tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer, 346288943Sdim "str", "\t$src, $addr", 347288943Sdim [(store tGPR:$src, t_addrmode_s4:$addr)]>; 348249259Sdim 349296417Sdimdef tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer, 350296417Sdim "strb", "\t$src, $addr", 351249259Sdim [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; 352249259Sdim 353249259Sdimdef tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer, 354249259Sdim "strh", "\t$src, $addr", 355249259Sdim [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; 356249259Sdim 357249259Sdimdef tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, 358296417Sdim "str", "\t$src, $addr", 359296417Sdim [(store tGPR:$src, t_addrmode_sp:$addr)]>; 360296417Sdim 361296417Sdimlet mayStore = 1 in { 362296417Sdim// Special instruction for spill. It cannot clobber condition register 363296417Sdim// when it's expanded by eliminateCallFramePseudoInstr(). 364296417Sdimdef tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, 365296417Sdim "str", "\t$src, $addr", []>; 366296417Sdim} 367296417Sdim 368296417Sdim//===----------------------------------------------------------------------===// 369296417Sdim// Load / store multiple Instructions. 370296417Sdim// 371296417Sdim 372296417Sdim// These requires base address to be written back or one of the loaded regs. 373296417Sdimlet mayLoad = 1, hasExtraDefRegAllocReq = 1 in 374296417Sdimdef tLDM : T1I<(outs), 375296417Sdim (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 376296417Sdim IIC_iLoadm, 377249259Sdim "ldm${addr:submode}${p}\t$addr, $wb", []>; 378249259Sdim 379280031Sdimlet mayStore = 1, hasExtraSrcRegAllocReq = 1 in 380280031Sdimdef tSTM : T1I<(outs), 381280031Sdim (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 382249259Sdim IIC_iStorem, 383249259Sdim "stm${addr:submode}${p}\t$addr, $wb", []>; 384249259Sdim 385249259Sdimlet mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in 386249259Sdimdef tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 387249259Sdim "pop${p}\t$wb", []>; 388249259Sdim 389249259Sdimlet mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in 390249259Sdimdef tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 391249259Sdim "push${p}\t$wb", []>; 392249259Sdim 393249259Sdim//===----------------------------------------------------------------------===// 394249259Sdim// Arithmetic Instructions. 395249259Sdim// 396249259Sdim 397249259Sdim// Add with carry register 398249259Sdimlet isCommutable = 1, Uses = [CPSR] in 399249259Sdimdef tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 400249259Sdim "adc", "\t$dst, $rhs", 401249259Sdim [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>; 402249259Sdim 403249259Sdim// Add immediate 404249259Sdimdef tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 405249259Sdim "add", "\t$dst, $lhs, $rhs", 406249259Sdim [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>; 407249259Sdim 408249259Sdimdef tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 409249259Sdim "add", "\t$dst, $rhs", 410249259Sdim [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>; 411249259Sdim 412249259Sdim// Add register 413249259Sdimlet isCommutable = 1 in 414249259Sdimdef tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 415249259Sdim "add", "\t$dst, $lhs, $rhs", 416249259Sdim [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>; 417249259Sdim 418249259Sdimlet neverHasSideEffects = 1 in 419249259Sdimdef tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 420249259Sdim "add", "\t$dst, $rhs", []>; 421249259Sdim 422249259Sdim// And register 423249259Sdimlet isCommutable = 1 in 424249259Sdimdef tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 425249259Sdim "and", "\t$dst, $rhs", 426249259Sdim [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>; 427249259Sdim 428249259Sdim// ASR immediate 429249259Sdimdef tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 430249259Sdim "asr", "\t$dst, $lhs, $rhs", 431249259Sdim [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>; 432249259Sdim 433249259Sdim// ASR register 434280031Sdimdef tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 435249259Sdim "asr", "\t$dst, $rhs", 436276479Sdim [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>; 437276479Sdim 438249259Sdim// BIC register 439249259Sdimdef tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 440249259Sdim "bic", "\t$dst, $rhs", 441249259Sdim [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>; 442249259Sdim 443249259Sdim// CMN register 444249259Sdimlet Defs = [CPSR] in { 445249259Sdimdef tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 446249259Sdim "cmn", "\t$lhs, $rhs", 447249259Sdim [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>; 448249259Sdimdef tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 449249259Sdim "cmn", "\t$lhs, $rhs", 450249259Sdim [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>; 451249259Sdim} 452249259Sdim 453249259Sdim// CMP immediate 454249259Sdimlet Defs = [CPSR] in { 455249259Sdimdef tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, 456249259Sdim "cmp", "\t$lhs, $rhs", 457249259Sdim [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>; 458249259Sdimdef tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, 459249259Sdim "cmp", "\t$lhs, $rhs", 460249259Sdim [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>; 461249259Sdim 462249259Sdim} 463249259Sdim 464249259Sdim// CMP register 465249259Sdimlet Defs = [CPSR] in { 466249259Sdimdef tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 467249259Sdim "cmp", "\t$lhs, $rhs", 468249259Sdim [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>; 469249259Sdimdef tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 470249259Sdim "cmp", "\t$lhs, $rhs", 471249259Sdim [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>; 472249259Sdim 473249259Sdimdef tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, 474276479Sdim "cmp", "\t$lhs, $rhs", []>; 475249259Sdimdef tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, 476249259Sdim "cmp", "\t$lhs, $rhs", []>; 477249259Sdim} 478249259Sdim 479249259Sdim 480249259Sdim// XOR register 481249259Sdimlet isCommutable = 1 in 482249259Sdimdef tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 483249259Sdim "eor", "\t$dst, $rhs", 484249259Sdim [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>; 485249259Sdim 486249259Sdim// LSL immediate 487249259Sdimdef tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 488249259Sdim "lsl", "\t$dst, $lhs, $rhs", 489249259Sdim [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>; 490276479Sdim 491249259Sdim// LSL register 492249259Sdimdef tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 493249259Sdim "lsl", "\t$dst, $rhs", 494249259Sdim [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>; 495249259Sdim 496249259Sdim// LSR immediate 497249259Sdimdef tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 498249259Sdim "lsr", "\t$dst, $lhs, $rhs", 499249259Sdim [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>; 500249259Sdim 501249259Sdim// LSR register 502249259Sdimdef tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 503249259Sdim "lsr", "\t$dst, $rhs", 504249259Sdim [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>; 505249259Sdim 506249259Sdim// move register 507280031Sdimdef tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iMOVi, 508276479Sdim "mov", "\t$dst, $src", 509249259Sdim [(set tGPR:$dst, imm0_255:$src)]>; 510249259Sdim 511249259Sdim// TODO: A7-73: MOV(2) - mov setting flag. 512249259Sdim 513249259Sdim 514249259Sdimlet neverHasSideEffects = 1 in { 515249259Sdim// FIXME: Make this predicable. 516249259Sdimdef tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 517249259Sdim "mov\t$dst, $src", []>; 518249259Sdimlet Defs = [CPSR] in 519249259Sdimdef tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 520249259Sdim "movs\t$dst, $src", []>; 521249259Sdim 522249259Sdim// FIXME: Make these predicable. 523249259Sdimdef tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr, 524249259Sdim "mov\t$dst, $src", []>; 525249259Sdimdef tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr, 526249259Sdim "mov\t$dst, $src", []>; 527249259Sdimdef tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, 528276479Sdim "mov\t$dst, $src", []>; 529249259Sdim} // neverHasSideEffects 530249259Sdim 531249259Sdim// multiply register 532249259Sdimlet isCommutable = 1 in 533249259Sdimdef tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMUL32, 534249259Sdim "mul", "\t$dst, $rhs", 535276479Sdim [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>; 536249259Sdim 537249259Sdim// move inverse register 538249259Sdimdef tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 539249259Sdim "mvn", "\t$dst, $src", 540249259Sdim [(set tGPR:$dst, (not tGPR:$src))]>; 541249259Sdim 542249259Sdim// bitwise or register 543249259Sdimlet isCommutable = 1 in 544288943Sdimdef tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 545288943Sdim "orr", "\t$dst, $rhs", 546296417Sdim [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>; 547288943Sdim 548288943Sdim// swaps 549288943Sdimdef tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 550296417Sdim "rev", "\t$dst, $src", 551296417Sdim [(set tGPR:$dst, (bswap tGPR:$src))]>, 552249259Sdim Requires<[IsThumb1Only, HasV6]>; 553249259Sdim 554249259Sdimdef tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 555249259Sdim "rev16", "\t$dst, $src", 556249259Sdim [(set tGPR:$dst, 557249259Sdim (or (and (srl tGPR:$src, (i32 8)), 0xFF), 558249259Sdim (or (and (shl tGPR:$src, (i32 8)), 0xFF00), 559249259Sdim (or (and (srl tGPR:$src, (i32 8)), 0xFF0000), 560249259Sdim (and (shl tGPR:$src, (i32 8)), 0xFF000000)))))]>, 561249259Sdim Requires<[IsThumb1Only, HasV6]>; 562249259Sdim 563249259Sdimdef tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 564249259Sdim "revsh", "\t$dst, $src", 565249259Sdim [(set tGPR:$dst, 566249259Sdim (sext_inreg 567249259Sdim (or (srl (and tGPR:$src, 0xFF00), (i32 8)), 568296417Sdim (shl tGPR:$src, (i32 8))), i16))]>, 569296417Sdim Requires<[IsThumb1Only, HasV6]>; 570296417Sdim 571296417Sdim// rotate right register 572296417Sdimdef tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 573249259Sdim "ror", "\t$dst, $rhs", 574249259Sdim [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>; 575249259Sdim 576249259Sdim// negate register 577288943Sdimdef tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALUi, 578288943Sdim "rsb", "\t$dst, $src, #0", 579288943Sdim [(set tGPR:$dst, (ineg tGPR:$src))]>; 580288943Sdim 581288943Sdim// Subtract with carry register 582249259Sdimlet Uses = [CPSR] in 583249259Sdimdef tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 584296417Sdim "sbc", "\t$dst, $rhs", 585296417Sdim [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>; 586249259Sdim 587249259Sdim// Subtract immediate 588249259Sdimdef tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 589296417Sdim "sub", "\t$dst, $lhs, $rhs", 590296417Sdim [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>; 591296417Sdim 592296417Sdimdef tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 593296417Sdim "sub", "\t$dst, $rhs", 594296417Sdim [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>; 595296417Sdim 596296417Sdim// subtract register 597296417Sdimdef tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 598296417Sdim "sub", "\t$dst, $lhs, $rhs", 599296417Sdim [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>; 600296417Sdim 601296417Sdim// TODO: A7-96: STMIA - store multiple. 602249259Sdim 603249259Sdim// sign-extend byte 604249259Sdimdef tSXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 605249259Sdim "sxtb", "\t$dst, $src", 606249259Sdim [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>, 607249259Sdim Requires<[IsThumb1Only, HasV6]>; 608249259Sdim 609249259Sdim// sign-extend short 610249259Sdimdef tSXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 611249259Sdim "sxth", "\t$dst, $src", 612296417Sdim [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, 613296417Sdim Requires<[IsThumb1Only, HasV6]>; 614249259Sdim 615249259Sdim// test 616249259Sdimlet isCommutable = 1, Defs = [CPSR] in 617249259Sdimdef tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 618249259Sdim "tst", "\t$lhs, $rhs", 619249259Sdim [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>; 620249259Sdim 621249259Sdim// zero-extend byte 622296417Sdimdef tUXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 623296417Sdim "uxtb", "\t$dst, $src", 624296417Sdim [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, 625296417Sdim Requires<[IsThumb1Only, HasV6]>; 626296417Sdim 627296417Sdim// zero-extend short 628296417Sdimdef tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 629296417Sdim "uxth", "\t$dst, $src", 630296417Sdim [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>, 631296417Sdim Requires<[IsThumb1Only, HasV6]>; 632296417Sdim 633296417Sdim 634296417Sdim// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation. 635296417Sdim// Expanded after instruction selection into a branch sequence. 636296417Sdimlet usesCustomInserter = 1 in // Expanded after instruction selection. 637296417Sdim def tMOVCCr_pseudo : 638296417Sdim PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc), 639296417Sdim NoItinerary, "@ tMOVCCr $cc", 640249259Sdim [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>; 641249259Sdim 642249259Sdim 643249259Sdim// 16-bit movcc in IT blocks for Thumb2. 644249259Sdimdef tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr, 645249259Sdim "mov", "\t$dst, $rhs", []>; 646249259Sdim 647249259Sdimdef tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iCMOVi, 648249259Sdim "mov", "\t$dst, $rhs", []>; 649249259Sdim 650249259Sdim// tLEApcrel - Load a pc-relative address into a register without offending the 651249259Sdim// assembler. 652249259Sdimdef tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi, 653249259Sdim "adr$p\t$dst, #$label", []>; 654288943Sdim 655288943Sdimdef tLEApcrelJT : T1I<(outs tGPR:$dst), 656288943Sdim (ins i32imm:$label, nohash_imm:$id, pred:$p), 657288943Sdim IIC_iALUi, "adr$p\t$dst, #${label}_${id}", []>; 658288943Sdim 659288943Sdim//===----------------------------------------------------------------------===// 660288943Sdim// TLS Instructions 661288943Sdim// 662288943Sdim 663288943Sdim// __aeabi_read_tp preserves the registers r1-r3. 664288943Sdimlet isCall = 1, 665288943Sdim Defs = [R0, LR] in { 666249259Sdim def tTPsoft : TIx2<(outs), (ins), IIC_Br, 667249259Sdim "bl\t__aeabi_read_tp", 668249259Sdim [(set R0, ARMthread_pointer)]>; 669249259Sdim} 670249259Sdim 671249259Sdim//===----------------------------------------------------------------------===// 672249259Sdim// Non-Instruction Patterns 673249259Sdim// 674249259Sdim 675249259Sdim// Add with carry 676249259Sdimdef : T1Pat<(addc tGPR:$lhs, imm0_7:$rhs), 677249259Sdim (tADDi3 tGPR:$lhs, imm0_7:$rhs)>; 678249259Sdimdef : T1Pat<(addc tGPR:$lhs, imm8_255:$rhs), 679249259Sdim (tADDi8 tGPR:$lhs, imm8_255:$rhs)>; 680249259Sdimdef : T1Pat<(addc tGPR:$lhs, tGPR:$rhs), 681249259Sdim (tADDrr tGPR:$lhs, tGPR:$rhs)>; 682249259Sdim 683249259Sdim// Subtract with carry 684249259Sdimdef : T1Pat<(addc tGPR:$lhs, imm0_7_neg:$rhs), 685249259Sdim (tSUBi3 tGPR:$lhs, imm0_7_neg:$rhs)>; 686249259Sdimdef : T1Pat<(addc tGPR:$lhs, imm8_255_neg:$rhs), 687249259Sdim (tSUBi8 tGPR:$lhs, imm8_255_neg:$rhs)>; 688249259Sdimdef : T1Pat<(subc tGPR:$lhs, tGPR:$rhs), 689249259Sdim (tSUBrr tGPR:$lhs, tGPR:$rhs)>; 690249259Sdim 691249259Sdim// ConstantPool, GlobalAddress 692249259Sdimdef : T1Pat<(ARMWrapper tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>; 693249259Sdimdef : T1Pat<(ARMWrapper tconstpool :$dst), (tLEApcrel tconstpool :$dst)>; 694249259Sdim 695249259Sdim// JumpTable 696249259Sdimdef : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), 697249259Sdim (tLEApcrelJT tjumptable:$dst, imm:$id)>; 698249259Sdim 699249259Sdim// Direct calls 700249259Sdimdef : T1Pat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>, 701249259Sdim Requires<[IsThumb, IsNotDarwin]>; 702249259Sdimdef : T1Pat<(ARMtcall texternalsym:$func), (tBLr9 texternalsym:$func)>, 703249259Sdim Requires<[IsThumb, IsDarwin]>; 704249259Sdim 705249259Sdimdef : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>, 706249259Sdim Requires<[IsThumb, HasV5T, IsNotDarwin]>; 707249259Sdimdef : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi_r9 texternalsym:$func)>, 708249259Sdim Requires<[IsThumb, HasV5T, IsDarwin]>; 709249259Sdim 710249259Sdim// Indirect calls to ARM routines 711249259Sdimdef : Tv5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>, 712249259Sdim Requires<[IsThumb, HasV5T, IsNotDarwin]>; 713249259Sdimdef : Tv5Pat<(ARMcall GPR:$dst), (tBLXr_r9 GPR:$dst)>, 714249259Sdim Requires<[IsThumb, HasV5T, IsDarwin]>; 715249259Sdim 716249259Sdim// zextload i1 -> zextload i8 717249259Sdimdef : T1Pat<(zextloadi1 t_addrmode_s1:$addr), 718249259Sdim (tLDRB t_addrmode_s1:$addr)>; 719249259Sdim 720249259Sdim// extload -> zextload 721249259Sdimdef : T1Pat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 722249259Sdimdef : T1Pat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 723249259Sdimdef : T1Pat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>; 724249259Sdim 725249259Sdim// If it's impossible to use [r,r] address mode for sextload, select to 726249259Sdim// ldr{b|h} + sxt{b|h} instead. 727249259Sdimdef : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 728249259Sdim (tSXTB (tLDRB t_addrmode_s1:$addr))>, 729249259Sdim Requires<[IsThumb1Only, HasV6]>; 730249259Sdimdef : T1Pat<(sextloadi16 t_addrmode_s2:$addr), 731249259Sdim (tSXTH (tLDRH t_addrmode_s2:$addr))>, 732249259Sdim Requires<[IsThumb1Only, HasV6]>; 733249259Sdim 734249259Sdimdef : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 735249259Sdim (tASRri (tLSLri (tLDRB t_addrmode_s1:$addr), 24), 24)>; 736249259Sdimdef : T1Pat<(sextloadi16 t_addrmode_s1:$addr), 737249259Sdim (tASRri (tLSLri (tLDRH t_addrmode_s1:$addr), 16), 16)>; 738249259Sdim 739249259Sdim// Large immediate handling. 740249259Sdim 741249259Sdim// Two piece imms. 742249259Sdimdef : T1Pat<(i32 thumb_immshifted:$src), 743249259Sdim (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)), 744249259Sdim (thumb_immshifted_shamt imm:$src))>; 745249259Sdim 746249259Sdimdef : T1Pat<(i32 imm0_255_comp:$src), 747249259Sdim (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>; 748249259Sdim 749249259Sdim// Pseudo instruction that combines ldr from constpool and add pc. This should 750249259Sdim// be expanded into two instructions late to allow if-conversion and 751249259Sdim// scheduling. 752249259Sdimlet isReMaterializable = 1 in 753249259Sdimdef tLDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp), 754249259Sdim NoItinerary, "@ ldr.n\t$dst, $addr\n$cp:\n\tadd\t$dst, pc", 755296417Sdim [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)), 756296417Sdim imm:$cp))]>, 757296417Sdim Requires<[IsThumb1Only]>; 758296417Sdim