ARMInstrThumb.td revision 198892
1193323Sed//===- ARMInstrThumb.td - Thumb support for ARM ---------------------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file describes the Thumb instruction set. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed//===----------------------------------------------------------------------===// 15193323Sed// Thumb specific DAG Nodes. 16193323Sed// 17193323Sed 18193323Seddef ARMtcall : SDNode<"ARMISD::tCALL", SDT_ARMcall, 19193323Sed [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; 20193323Sed 21193323Seddef imm_neg_XFORM : SDNodeXForm<imm, [{ 22193323Sed return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32); 23193323Sed}]>; 24193323Seddef imm_comp_XFORM : SDNodeXForm<imm, [{ 25193323Sed return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32); 26193323Sed}]>; 27193323Sed 28193323Sed 29193323Sed/// imm0_7 predicate - True if the 32-bit immediate is in the range [0,7]. 30193323Seddef imm0_7 : PatLeaf<(i32 imm), [{ 31193323Sed return (uint32_t)N->getZExtValue() < 8; 32193323Sed}]>; 33193323Seddef imm0_7_neg : PatLeaf<(i32 imm), [{ 34193323Sed return (uint32_t)-N->getZExtValue() < 8; 35193323Sed}], imm_neg_XFORM>; 36193323Sed 37193323Seddef imm0_255 : PatLeaf<(i32 imm), [{ 38193323Sed return (uint32_t)N->getZExtValue() < 256; 39193323Sed}]>; 40193323Seddef imm0_255_comp : PatLeaf<(i32 imm), [{ 41193323Sed return ~((uint32_t)N->getZExtValue()) < 256; 42193323Sed}]>; 43193323Sed 44193323Seddef imm8_255 : PatLeaf<(i32 imm), [{ 45193323Sed return (uint32_t)N->getZExtValue() >= 8 && (uint32_t)N->getZExtValue() < 256; 46193323Sed}]>; 47193323Seddef imm8_255_neg : PatLeaf<(i32 imm), [{ 48193323Sed unsigned Val = -N->getZExtValue(); 49193323Sed return Val >= 8 && Val < 256; 50193323Sed}], imm_neg_XFORM>; 51193323Sed 52193323Sed// Break imm's up into two pieces: an immediate + a left shift. 53193323Sed// This uses thumb_immshifted to match and thumb_immshifted_val and 54193323Sed// thumb_immshifted_shamt to get the val/shift pieces. 55193323Seddef thumb_immshifted : PatLeaf<(imm), [{ 56193323Sed return ARM_AM::isThumbImmShiftedVal((unsigned)N->getZExtValue()); 57193323Sed}]>; 58193323Sed 59193323Seddef thumb_immshifted_val : SDNodeXForm<imm, [{ 60193323Sed unsigned V = ARM_AM::getThumbImmNonShiftedVal((unsigned)N->getZExtValue()); 61193323Sed return CurDAG->getTargetConstant(V, MVT::i32); 62193323Sed}]>; 63193323Sed 64193323Seddef thumb_immshifted_shamt : SDNodeXForm<imm, [{ 65193323Sed unsigned V = ARM_AM::getThumbImmValShift((unsigned)N->getZExtValue()); 66193323Sed return CurDAG->getTargetConstant(V, MVT::i32); 67193323Sed}]>; 68193323Sed 69193323Sed// Define Thumb specific addressing modes. 70193323Sed 71193323Sed// t_addrmode_rr := reg + reg 72193323Sed// 73193323Seddef t_addrmode_rr : Operand<i32>, 74193323Sed ComplexPattern<i32, 2, "SelectThumbAddrModeRR", []> { 75193323Sed let PrintMethod = "printThumbAddrModeRROperand"; 76193323Sed let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); 77193323Sed} 78193323Sed 79193323Sed// t_addrmode_s4 := reg + reg 80193323Sed// reg + imm5 * 4 81193323Sed// 82193323Seddef t_addrmode_s4 : Operand<i32>, 83193323Sed ComplexPattern<i32, 3, "SelectThumbAddrModeS4", []> { 84193323Sed let PrintMethod = "printThumbAddrModeS4Operand"; 85193323Sed let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 86193323Sed} 87193323Sed 88193323Sed// t_addrmode_s2 := reg + reg 89193323Sed// reg + imm5 * 2 90193323Sed// 91193323Seddef t_addrmode_s2 : Operand<i32>, 92193323Sed ComplexPattern<i32, 3, "SelectThumbAddrModeS2", []> { 93193323Sed let PrintMethod = "printThumbAddrModeS2Operand"; 94193323Sed let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 95193323Sed} 96193323Sed 97193323Sed// t_addrmode_s1 := reg + reg 98193323Sed// reg + imm5 99193323Sed// 100193323Seddef t_addrmode_s1 : Operand<i32>, 101193323Sed ComplexPattern<i32, 3, "SelectThumbAddrModeS1", []> { 102193323Sed let PrintMethod = "printThumbAddrModeS1Operand"; 103193323Sed let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 104193323Sed} 105193323Sed 106193323Sed// t_addrmode_sp := sp + imm8 * 4 107193323Sed// 108193323Seddef t_addrmode_sp : Operand<i32>, 109193323Sed ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> { 110193323Sed let PrintMethod = "printThumbAddrModeSPOperand"; 111193323Sed let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm); 112193323Sed} 113193323Sed 114193323Sed//===----------------------------------------------------------------------===// 115193323Sed// Miscellaneous Instructions. 116193323Sed// 117193323Sed 118193323Sedlet Defs = [SP], Uses = [SP] in { 119193323Seddef tADJCALLSTACKUP : 120198090SrdivackyPseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary, 121193323Sed "@ tADJCALLSTACKUP $amt1", 122198090Srdivacky [(ARMcallseq_end imm:$amt1, imm:$amt2)]>, Requires<[IsThumb1Only]>; 123193323Sed 124193323Seddef tADJCALLSTACKDOWN : 125198090SrdivackyPseudoInst<(outs), (ins i32imm:$amt), NoItinerary, 126193323Sed "@ tADJCALLSTACKDOWN $amt", 127198090Srdivacky [(ARMcallseq_start imm:$amt)]>, Requires<[IsThumb1Only]>; 128193323Sed} 129193323Sed 130198090Srdivacky// For both thumb1 and thumb2. 131193323Sedlet isNotDuplicable = 1 in 132198090Srdivackydef tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr, 133198892Srdivacky "\n$cp:\n\tadd\t$dst, pc", 134198090Srdivacky [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>; 135193323Sed 136195098Sed// PC relative add. 137198090Srdivackydef tADDrPCi : T1I<(outs tGPR:$dst), (ins i32imm:$rhs), IIC_iALUi, 138198892Srdivacky "add\t$dst, pc, $rhs * 4", []>; 139195098Sed 140195098Sed// ADD rd, sp, #imm8 141198090Srdivackydef tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, i32imm:$rhs), IIC_iALUi, 142198892Srdivacky "add\t$dst, $sp, $rhs * 4", []>; 143195098Sed 144195098Sed// ADD sp, sp, #imm7 145198090Srdivackydef tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALUi, 146198892Srdivacky "add\t$dst, $rhs * 4", []>; 147195098Sed 148198090Srdivacky// SUB sp, sp, #imm7 149198090Srdivackydef tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALUi, 150198892Srdivacky "sub\t$dst, $rhs * 4", []>; 151198090Srdivacky 152198090Srdivacky// ADD rm, sp 153198090Srdivackydef tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 154198892Srdivacky "add\t$dst, $rhs", []>; 155198090Srdivacky 156195098Sed// ADD sp, rm 157198090Srdivackydef tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 158198892Srdivacky "add\t$dst, $rhs", []>; 159195098Sed 160198090Srdivacky// Pseudo instruction that will expand into a tSUBspi + a copy. 161198892Srdivackylet usesCustomInserter = 1 in { // Expanded after instruction selection. 162198090Srdivackydef tSUBspi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), 163198892Srdivacky NoItinerary, "@ sub\t$dst, $rhs * 4", []>; 164198090Srdivacky 165198090Srdivackydef tADDspr_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 166198892Srdivacky NoItinerary, "@ add\t$dst, $rhs", []>; 167198090Srdivacky 168198090Srdivackylet Defs = [CPSR] in 169198090Srdivackydef tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), 170198892Srdivacky NoItinerary, "@ and\t$dst, $rhs", []>; 171198892Srdivacky} // usesCustomInserter 172198090Srdivacky 173193323Sed//===----------------------------------------------------------------------===// 174193323Sed// Control Flow Instructions. 175193323Sed// 176193323Sed 177198090Srdivackylet isReturn = 1, isTerminator = 1, isBarrier = 1 in { 178198892Srdivacky def tBX_RET : TI<(outs), (ins), IIC_Br, "bx\tlr", [(ARMretflag)]>; 179193323Sed // Alternative return instruction used by vararg functions. 180198892Srdivacky def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target", []>; 181193323Sed} 182193323Sed 183198892Srdivacky// Indirect branches 184198892Srdivackylet isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 185198892Srdivacky def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "mov\tpc, $dst", 186198892Srdivacky [(brind GPR:$dst)]>; 187198892Srdivacky} 188198892Srdivacky 189193323Sed// FIXME: remove when we have a way to marking a MI with these properties. 190198090Srdivackylet isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 191198090Srdivacky hasExtraDefRegAllocReq = 1 in 192198090Srdivackydef tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 193198892Srdivacky "pop${p}\t$wb", []>; 194193323Sed 195193323Sedlet isCall = 1, 196198090Srdivacky Defs = [R0, R1, R2, R3, R12, LR, 197198090Srdivacky D0, D1, D2, D3, D4, D5, D6, D7, 198198090Srdivacky D16, D17, D18, D19, D20, D21, D22, D23, 199198090Srdivacky D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 200198090Srdivacky // Also used for Thumb2 201198090Srdivacky def tBL : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 202198892Srdivacky "bl\t${func:call}", 203198090Srdivacky [(ARMtcall tglobaladdr:$func)]>, 204198090Srdivacky Requires<[IsThumb, IsNotDarwin]>; 205198090Srdivacky 206198090Srdivacky // ARMv5T and above, also used for Thumb2 207198090Srdivacky def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 208198892Srdivacky "blx\t${func:call}", 209198090Srdivacky [(ARMcall tglobaladdr:$func)]>, 210198090Srdivacky Requires<[IsThumb, HasV5T, IsNotDarwin]>; 211198090Srdivacky 212198090Srdivacky // Also used for Thumb2 213198090Srdivacky def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 214198892Srdivacky "blx\t$func", 215198090Srdivacky [(ARMtcall GPR:$func)]>, 216198090Srdivacky Requires<[IsThumb, HasV5T, IsNotDarwin]>; 217198090Srdivacky 218193323Sed // ARMv4T 219198090Srdivacky def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 220198892Srdivacky "mov\tlr, pc\n\tbx\t$func", 221198090Srdivacky [(ARMcall_nolink tGPR:$func)]>, 222198090Srdivacky Requires<[IsThumb1Only, IsNotDarwin]>; 223193323Sed} 224193323Sed 225198090Srdivacky// On Darwin R9 is call-clobbered. 226198090Srdivackylet isCall = 1, 227198090Srdivacky Defs = [R0, R1, R2, R3, R9, R12, LR, 228198090Srdivacky D0, D1, D2, D3, D4, D5, D6, D7, 229198090Srdivacky D16, D17, D18, D19, D20, D21, D22, D23, 230198090Srdivacky D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 231198090Srdivacky // Also used for Thumb2 232198090Srdivacky def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 233198892Srdivacky "bl\t${func:call}", 234198090Srdivacky [(ARMtcall tglobaladdr:$func)]>, 235198090Srdivacky Requires<[IsThumb, IsDarwin]>; 236198090Srdivacky 237198090Srdivacky // ARMv5T and above, also used for Thumb2 238198090Srdivacky def tBLXi_r9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 239198892Srdivacky "blx\t${func:call}", 240198090Srdivacky [(ARMcall tglobaladdr:$func)]>, 241198090Srdivacky Requires<[IsThumb, HasV5T, IsDarwin]>; 242198090Srdivacky 243198090Srdivacky // Also used for Thumb2 244198090Srdivacky def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 245198892Srdivacky "blx\t$func", 246198090Srdivacky [(ARMtcall GPR:$func)]>, 247198090Srdivacky Requires<[IsThumb, HasV5T, IsDarwin]>; 248198090Srdivacky 249198090Srdivacky // ARMv4T 250198090Srdivacky def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 251198892Srdivacky "mov\tlr, pc\n\tbx\t$func", 252198090Srdivacky [(ARMcall_nolink tGPR:$func)]>, 253198090Srdivacky Requires<[IsThumb1Only, IsDarwin]>; 254198090Srdivacky} 255198090Srdivacky 256193323Sedlet isBranch = 1, isTerminator = 1 in { 257193323Sed let isBarrier = 1 in { 258193323Sed let isPredicable = 1 in 259198090Srdivacky def tB : T1I<(outs), (ins brtarget:$target), IIC_Br, 260198892Srdivacky "b\t$target", [(br bb:$target)]>; 261193323Sed 262193323Sed // Far jump 263198090Srdivacky let Defs = [LR] in 264198090Srdivacky def tBfar : TIx2<(outs), (ins brtarget:$target), IIC_Br, 265198892Srdivacky "bl\t$target\t@ far jump",[]>; 266193323Sed 267195340Sed def tBR_JTr : T1JTI<(outs), 268195340Sed (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id), 269198892Srdivacky IIC_Br, "mov\tpc, $target\n\t.align\t2\n$jt", 270195340Sed [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>; 271193323Sed } 272193323Sed} 273193323Sed 274193323Sed// FIXME: should be able to write a pattern for ARMBrcond, but can't use 275193323Sed// a two-value operand where a dag node expects two operands. :( 276193323Sedlet isBranch = 1, isTerminator = 1 in 277198090Srdivacky def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br, 278198892Srdivacky "b$cc\t$target", 279193323Sed [/*(ARMbrcond bb:$target, imm:$cc)*/]>; 280193323Sed 281198892Srdivacky// Compare and branch on zero / non-zero 282198892Srdivackylet isBranch = 1, isTerminator = 1 in { 283198892Srdivacky def tCBZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br, 284198892Srdivacky "cbz\t$cmp, $target", []>; 285198892Srdivacky 286198892Srdivacky def tCBNZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br, 287198892Srdivacky "cbnz\t$cmp, $target", []>; 288198892Srdivacky} 289198892Srdivacky 290193323Sed//===----------------------------------------------------------------------===// 291193323Sed// Load Store Instructions. 292193323Sed// 293193323Sed 294193323Sedlet canFoldAsLoad = 1 in 295198090Srdivackydef tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, 296198892Srdivacky "ldr", "\t$dst, $addr", 297193323Sed [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>; 298193323Sed 299198090Srdivackydef tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr, 300198892Srdivacky "ldrb", "\t$dst, $addr", 301193323Sed [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; 302193323Sed 303198090Srdivackydef tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr, 304198892Srdivacky "ldrh", "\t$dst, $addr", 305193323Sed [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; 306193323Sed 307198090Srdivackylet AddedComplexity = 10 in 308198090Srdivackydef tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, 309198892Srdivacky "ldrsb", "\t$dst, $addr", 310193323Sed [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; 311193323Sed 312198090Srdivackylet AddedComplexity = 10 in 313198090Srdivackydef tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, 314198892Srdivacky "ldrsh", "\t$dst, $addr", 315193323Sed [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>; 316193323Sed 317193323Sedlet canFoldAsLoad = 1 in 318198090Srdivackydef tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, 319198892Srdivacky "ldr", "\t$dst, $addr", 320193323Sed [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>; 321193323Sed 322193323Sed// Special instruction for restore. It cannot clobber condition register 323193323Sed// when it's expanded by eliminateCallFramePseudoInstr(). 324193323Sedlet canFoldAsLoad = 1, mayLoad = 1 in 325198090Srdivackydef tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, 326198892Srdivacky "ldr", "\t$dst, $addr", []>; 327193323Sed 328193323Sed// Load tconstpool 329198892Srdivacky// FIXME: Use ldr.n to work around a Darwin assembler bug. 330193323Sedlet canFoldAsLoad = 1 in 331198090Srdivackydef tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, 332198892Srdivacky "ldr", ".n\t$dst, $addr", 333193323Sed [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; 334193323Sed 335193323Sed// Special LDR for loads from non-pc-relative constpools. 336193323Sedlet canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in 337198090Srdivackydef tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, 338198892Srdivacky "ldr", "\t$dst, $addr", []>; 339193323Sed 340198090Srdivackydef tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer, 341198892Srdivacky "str", "\t$src, $addr", 342193323Sed [(store tGPR:$src, t_addrmode_s4:$addr)]>; 343193323Sed 344198090Srdivackydef tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer, 345198892Srdivacky "strb", "\t$src, $addr", 346193323Sed [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; 347193323Sed 348198090Srdivackydef tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer, 349198892Srdivacky "strh", "\t$src, $addr", 350193323Sed [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; 351193323Sed 352198090Srdivackydef tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, 353198892Srdivacky "str", "\t$src, $addr", 354193323Sed [(store tGPR:$src, t_addrmode_sp:$addr)]>; 355193323Sed 356193323Sedlet mayStore = 1 in { 357193323Sed// Special instruction for spill. It cannot clobber condition register 358193323Sed// when it's expanded by eliminateCallFramePseudoInstr(). 359198090Srdivackydef tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, 360198892Srdivacky "str", "\t$src, $addr", []>; 361193323Sed} 362193323Sed 363193323Sed//===----------------------------------------------------------------------===// 364193323Sed// Load / store multiple Instructions. 365193323Sed// 366193323Sed 367198090Srdivacky// These requires base address to be written back or one of the loaded regs. 368198090Srdivackylet mayLoad = 1, hasExtraDefRegAllocReq = 1 in 369198090Srdivackydef tLDM : T1I<(outs), 370198090Srdivacky (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 371198090Srdivacky IIC_iLoadm, 372198892Srdivacky "ldm${addr:submode}${p}\t$addr, $wb", []>; 373193323Sed 374198090Srdivackylet mayStore = 1, hasExtraSrcRegAllocReq = 1 in 375198090Srdivackydef tSTM : T1I<(outs), 376198090Srdivacky (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 377198090Srdivacky IIC_iStorem, 378198892Srdivacky "stm${addr:submode}${p}\t$addr, $wb", []>; 379193323Sed 380198090Srdivackylet mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in 381198090Srdivackydef tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 382198892Srdivacky "pop${p}\t$wb", []>; 383193323Sed 384198090Srdivackylet mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in 385198090Srdivackydef tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 386198892Srdivacky "push${p}\t$wb", []>; 387198090Srdivacky 388193323Sed//===----------------------------------------------------------------------===// 389193323Sed// Arithmetic Instructions. 390193323Sed// 391193323Sed 392195098Sed// Add with carry register 393198090Srdivackylet isCommutable = 1, Uses = [CPSR] in 394198090Srdivackydef tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 395198892Srdivacky "adc", "\t$dst, $rhs", 396198090Srdivacky [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>; 397193323Sed 398195098Sed// Add immediate 399198090Srdivackydef tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 400198892Srdivacky "add", "\t$dst, $lhs, $rhs", 401198090Srdivacky [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>; 402193323Sed 403198090Srdivackydef tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 404198892Srdivacky "add", "\t$dst, $rhs", 405198090Srdivacky [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>; 406193323Sed 407195098Sed// Add register 408198090Srdivackylet isCommutable = 1 in 409198090Srdivackydef tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 410198892Srdivacky "add", "\t$dst, $lhs, $rhs", 411198090Srdivacky [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>; 412193323Sed 413194178Sedlet neverHasSideEffects = 1 in 414198090Srdivackydef tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 415198892Srdivacky "add", "\t$dst, $rhs", []>; 416193323Sed 417195098Sed// And register 418198090Srdivackylet isCommutable = 1 in 419198090Srdivackydef tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 420198892Srdivacky "and", "\t$dst, $rhs", 421198090Srdivacky [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>; 422193323Sed 423195098Sed// ASR immediate 424198090Srdivackydef tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 425198892Srdivacky "asr", "\t$dst, $lhs, $rhs", 426198090Srdivacky [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>; 427193323Sed 428195098Sed// ASR register 429198090Srdivackydef tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 430198892Srdivacky "asr", "\t$dst, $rhs", 431198090Srdivacky [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>; 432193323Sed 433195098Sed// BIC register 434198090Srdivackydef tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 435198892Srdivacky "bic", "\t$dst, $rhs", 436198090Srdivacky [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>; 437193323Sed 438195098Sed// CMN register 439195098Sedlet Defs = [CPSR] in { 440198090Srdivackydef tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 441198892Srdivacky "cmn", "\t$lhs, $rhs", 442198090Srdivacky [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>; 443198090Srdivackydef tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 444198892Srdivacky "cmn", "\t$lhs, $rhs", 445198090Srdivacky [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>; 446195098Sed} 447193323Sed 448195098Sed// CMP immediate 449195098Sedlet Defs = [CPSR] in { 450198090Srdivackydef tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, 451198892Srdivacky "cmp", "\t$lhs, $rhs", 452198090Srdivacky [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>; 453198090Srdivackydef tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, 454198892Srdivacky "cmp", "\t$lhs, $rhs", 455198090Srdivacky [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>; 456193323Sed 457195098Sed} 458195098Sed 459195098Sed// CMP register 460195098Sedlet Defs = [CPSR] in { 461198090Srdivackydef tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 462198892Srdivacky "cmp", "\t$lhs, $rhs", 463198090Srdivacky [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>; 464198090Srdivackydef tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 465198892Srdivacky "cmp", "\t$lhs, $rhs", 466198090Srdivacky [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>; 467198090Srdivacky 468198090Srdivackydef tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, 469198892Srdivacky "cmp", "\t$lhs, $rhs", []>; 470198090Srdivackydef tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, 471198892Srdivacky "cmp", "\t$lhs, $rhs", []>; 472195098Sed} 473193323Sed 474193323Sed 475195098Sed// XOR register 476198090Srdivackylet isCommutable = 1 in 477198090Srdivackydef tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 478198892Srdivacky "eor", "\t$dst, $rhs", 479198090Srdivacky [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>; 480193323Sed 481195098Sed// LSL immediate 482198090Srdivackydef tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 483198892Srdivacky "lsl", "\t$dst, $lhs, $rhs", 484198090Srdivacky [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>; 485193323Sed 486195098Sed// LSL register 487198090Srdivackydef tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 488198892Srdivacky "lsl", "\t$dst, $rhs", 489198090Srdivacky [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>; 490193323Sed 491195098Sed// LSR immediate 492198090Srdivackydef tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 493198892Srdivacky "lsr", "\t$dst, $lhs, $rhs", 494198090Srdivacky [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>; 495193323Sed 496195098Sed// LSR register 497198090Srdivackydef tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 498198892Srdivacky "lsr", "\t$dst, $rhs", 499198090Srdivacky [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>; 500193323Sed 501195098Sed// move register 502198090Srdivackydef tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iMOVi, 503198892Srdivacky "mov", "\t$dst, $src", 504198090Srdivacky [(set tGPR:$dst, imm0_255:$src)]>; 505193323Sed 506193323Sed// TODO: A7-73: MOV(2) - mov setting flag. 507193323Sed 508193323Sed 509194178Sedlet neverHasSideEffects = 1 in { 510198090Srdivacky// FIXME: Make this predicable. 511198090Srdivackydef tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 512198892Srdivacky "mov\t$dst, $src", []>; 513198090Srdivackylet Defs = [CPSR] in 514198090Srdivackydef tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 515198892Srdivacky "movs\t$dst, $src", []>; 516198090Srdivacky 517198090Srdivacky// FIXME: Make these predicable. 518198090Srdivackydef tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr, 519198892Srdivacky "mov\t$dst, $src", []>; 520198090Srdivackydef tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr, 521198892Srdivacky "mov\t$dst, $src", []>; 522198090Srdivackydef tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, 523198892Srdivacky "mov\t$dst, $src", []>; 524194178Sed} // neverHasSideEffects 525193323Sed 526195098Sed// multiply register 527198090Srdivackylet isCommutable = 1 in 528198090Srdivackydef tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMUL32, 529198892Srdivacky "mul", "\t$dst, $rhs", 530198090Srdivacky [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>; 531193323Sed 532195098Sed// move inverse register 533198090Srdivackydef tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 534198892Srdivacky "mvn", "\t$dst, $src", 535198090Srdivacky [(set tGPR:$dst, (not tGPR:$src))]>; 536193323Sed 537195098Sed// bitwise or register 538198090Srdivackylet isCommutable = 1 in 539198090Srdivackydef tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 540198892Srdivacky "orr", "\t$dst, $rhs", 541198090Srdivacky [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>; 542193323Sed 543195098Sed// swaps 544198090Srdivackydef tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 545198892Srdivacky "rev", "\t$dst, $src", 546198090Srdivacky [(set tGPR:$dst, (bswap tGPR:$src))]>, 547198090Srdivacky Requires<[IsThumb1Only, HasV6]>; 548193323Sed 549198090Srdivackydef tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 550198892Srdivacky "rev16", "\t$dst, $src", 551198090Srdivacky [(set tGPR:$dst, 552198090Srdivacky (or (and (srl tGPR:$src, (i32 8)), 0xFF), 553198090Srdivacky (or (and (shl tGPR:$src, (i32 8)), 0xFF00), 554198090Srdivacky (or (and (srl tGPR:$src, (i32 8)), 0xFF0000), 555198090Srdivacky (and (shl tGPR:$src, (i32 8)), 0xFF000000)))))]>, 556198090Srdivacky Requires<[IsThumb1Only, HasV6]>; 557193323Sed 558198090Srdivackydef tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 559198892Srdivacky "revsh", "\t$dst, $src", 560198090Srdivacky [(set tGPR:$dst, 561198090Srdivacky (sext_inreg 562198090Srdivacky (or (srl (and tGPR:$src, 0xFF00), (i32 8)), 563198090Srdivacky (shl tGPR:$src, (i32 8))), i16))]>, 564198090Srdivacky Requires<[IsThumb1Only, HasV6]>; 565193323Sed 566195098Sed// rotate right register 567198090Srdivackydef tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 568198892Srdivacky "ror", "\t$dst, $rhs", 569198090Srdivacky [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>; 570193323Sed 571198090Srdivacky// negate register 572198090Srdivackydef tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALUi, 573198892Srdivacky "rsb", "\t$dst, $src, #0", 574198090Srdivacky [(set tGPR:$dst, (ineg tGPR:$src))]>; 575198090Srdivacky 576195098Sed// Subtract with carry register 577198090Srdivackylet Uses = [CPSR] in 578198090Srdivackydef tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 579198892Srdivacky "sbc", "\t$dst, $rhs", 580198090Srdivacky [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>; 581193323Sed 582195098Sed// Subtract immediate 583198090Srdivackydef tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 584198892Srdivacky "sub", "\t$dst, $lhs, $rhs", 585198090Srdivacky [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>; 586193323Sed 587198090Srdivackydef tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 588198892Srdivacky "sub", "\t$dst, $rhs", 589198090Srdivacky [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>; 590193323Sed 591195098Sed// subtract register 592198090Srdivackydef tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 593198892Srdivacky "sub", "\t$dst, $lhs, $rhs", 594198090Srdivacky [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>; 595193323Sed 596195098Sed// TODO: A7-96: STMIA - store multiple. 597195098Sed 598195098Sed// sign-extend byte 599198090Srdivackydef tSXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 600198892Srdivacky "sxtb", "\t$dst, $src", 601198090Srdivacky [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>, 602198090Srdivacky Requires<[IsThumb1Only, HasV6]>; 603195098Sed 604195098Sed// sign-extend short 605198090Srdivackydef tSXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 606198892Srdivacky "sxth", "\t$dst, $src", 607198090Srdivacky [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, 608198090Srdivacky Requires<[IsThumb1Only, HasV6]>; 609193323Sed 610195098Sed// test 611195098Sedlet isCommutable = 1, Defs = [CPSR] in 612198090Srdivackydef tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 613198892Srdivacky "tst", "\t$lhs, $rhs", 614198090Srdivacky [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>; 615193323Sed 616195098Sed// zero-extend byte 617198090Srdivackydef tUXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 618198892Srdivacky "uxtb", "\t$dst, $src", 619198090Srdivacky [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, 620198090Srdivacky Requires<[IsThumb1Only, HasV6]>; 621195098Sed 622195098Sed// zero-extend short 623198090Srdivackydef tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 624198892Srdivacky "uxth", "\t$dst, $src", 625198090Srdivacky [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>, 626198090Srdivacky Requires<[IsThumb1Only, HasV6]>; 627193323Sed 628193323Sed 629193323Sed// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation. 630198892Srdivacky// Expanded after instruction selection into a branch sequence. 631198892Srdivackylet usesCustomInserter = 1 in // Expanded after instruction selection. 632198090Srdivacky def tMOVCCr_pseudo : 633193323Sed PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc), 634198090Srdivacky NoItinerary, "@ tMOVCCr $cc", 635198090Srdivacky [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>; 636193323Sed 637198090Srdivacky 638198090Srdivacky// 16-bit movcc in IT blocks for Thumb2. 639198090Srdivackydef tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr, 640198892Srdivacky "mov", "\t$dst, $rhs", []>; 641198090Srdivacky 642198090Srdivackydef tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iCMOVi, 643198892Srdivacky "mov", "\t$dst, $rhs", []>; 644198090Srdivacky 645193323Sed// tLEApcrel - Load a pc-relative address into a register without offending the 646193323Sed// assembler. 647198090Srdivackydef tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi, 648198892Srdivacky "adr$p\t$dst, #$label", []>; 649193323Sed 650198090Srdivackydef tLEApcrelJT : T1I<(outs tGPR:$dst), 651198090Srdivacky (ins i32imm:$label, nohash_imm:$id, pred:$p), 652198892Srdivacky IIC_iALUi, "adr$p\t$dst, #${label}_${id}", []>; 653193323Sed 654193323Sed//===----------------------------------------------------------------------===// 655193323Sed// TLS Instructions 656193323Sed// 657193323Sed 658193323Sed// __aeabi_read_tp preserves the registers r1-r3. 659193323Sedlet isCall = 1, 660193323Sed Defs = [R0, LR] in { 661198090Srdivacky def tTPsoft : TIx2<(outs), (ins), IIC_Br, 662198892Srdivacky "bl\t__aeabi_read_tp", 663193323Sed [(set R0, ARMthread_pointer)]>; 664193323Sed} 665193323Sed 666193323Sed//===----------------------------------------------------------------------===// 667193323Sed// Non-Instruction Patterns 668193323Sed// 669193323Sed 670198090Srdivacky// Add with carry 671198090Srdivackydef : T1Pat<(addc tGPR:$lhs, imm0_7:$rhs), 672198090Srdivacky (tADDi3 tGPR:$lhs, imm0_7:$rhs)>; 673198090Srdivackydef : T1Pat<(addc tGPR:$lhs, imm8_255:$rhs), 674198090Srdivacky (tADDi8 tGPR:$lhs, imm8_255:$rhs)>; 675198090Srdivackydef : T1Pat<(addc tGPR:$lhs, tGPR:$rhs), 676198090Srdivacky (tADDrr tGPR:$lhs, tGPR:$rhs)>; 677198090Srdivacky 678198090Srdivacky// Subtract with carry 679198090Srdivackydef : T1Pat<(addc tGPR:$lhs, imm0_7_neg:$rhs), 680198090Srdivacky (tSUBi3 tGPR:$lhs, imm0_7_neg:$rhs)>; 681198090Srdivackydef : T1Pat<(addc tGPR:$lhs, imm8_255_neg:$rhs), 682198090Srdivacky (tSUBi8 tGPR:$lhs, imm8_255_neg:$rhs)>; 683198090Srdivackydef : T1Pat<(subc tGPR:$lhs, tGPR:$rhs), 684198090Srdivacky (tSUBrr tGPR:$lhs, tGPR:$rhs)>; 685198090Srdivacky 686193323Sed// ConstantPool, GlobalAddress 687198090Srdivackydef : T1Pat<(ARMWrapper tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>; 688198090Srdivackydef : T1Pat<(ARMWrapper tconstpool :$dst), (tLEApcrel tconstpool :$dst)>; 689193323Sed 690193323Sed// JumpTable 691198090Srdivackydef : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), 692198090Srdivacky (tLEApcrelJT tjumptable:$dst, imm:$id)>; 693193323Sed 694193323Sed// Direct calls 695198090Srdivackydef : T1Pat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>, 696198090Srdivacky Requires<[IsThumb, IsNotDarwin]>; 697198090Srdivackydef : T1Pat<(ARMtcall texternalsym:$func), (tBLr9 texternalsym:$func)>, 698198090Srdivacky Requires<[IsThumb, IsDarwin]>; 699193323Sed 700198090Srdivackydef : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>, 701198090Srdivacky Requires<[IsThumb, HasV5T, IsNotDarwin]>; 702198090Srdivackydef : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi_r9 texternalsym:$func)>, 703198090Srdivacky Requires<[IsThumb, HasV5T, IsDarwin]>; 704198090Srdivacky 705193323Sed// Indirect calls to ARM routines 706198090Srdivackydef : Tv5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>, 707198090Srdivacky Requires<[IsThumb, HasV5T, IsNotDarwin]>; 708198090Srdivackydef : Tv5Pat<(ARMcall GPR:$dst), (tBLXr_r9 GPR:$dst)>, 709198090Srdivacky Requires<[IsThumb, HasV5T, IsDarwin]>; 710193323Sed 711193323Sed// zextload i1 -> zextload i8 712195340Seddef : T1Pat<(zextloadi1 t_addrmode_s1:$addr), 713195340Sed (tLDRB t_addrmode_s1:$addr)>; 714193323Sed 715193323Sed// extload -> zextload 716195340Seddef : T1Pat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 717195340Seddef : T1Pat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 718195340Seddef : T1Pat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>; 719193323Sed 720198090Srdivacky// If it's impossible to use [r,r] address mode for sextload, select to 721198090Srdivacky// ldr{b|h} + sxt{b|h} instead. 722198090Srdivackydef : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 723198090Srdivacky (tSXTB (tLDRB t_addrmode_s1:$addr))>, 724198090Srdivacky Requires<[IsThumb1Only, HasV6]>; 725198090Srdivackydef : T1Pat<(sextloadi16 t_addrmode_s2:$addr), 726198090Srdivacky (tSXTH (tLDRH t_addrmode_s2:$addr))>, 727198090Srdivacky Requires<[IsThumb1Only, HasV6]>; 728198090Srdivacky 729198090Srdivackydef : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 730198090Srdivacky (tASRri (tLSLri (tLDRB t_addrmode_s1:$addr), 24), 24)>; 731198090Srdivackydef : T1Pat<(sextloadi16 t_addrmode_s1:$addr), 732198090Srdivacky (tASRri (tLSLri (tLDRH t_addrmode_s1:$addr), 16), 16)>; 733198090Srdivacky 734193323Sed// Large immediate handling. 735193323Sed 736193323Sed// Two piece imms. 737195098Seddef : T1Pat<(i32 thumb_immshifted:$src), 738195098Sed (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)), 739195098Sed (thumb_immshifted_shamt imm:$src))>; 740193323Sed 741195098Seddef : T1Pat<(i32 imm0_255_comp:$src), 742195098Sed (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>; 743