ARMInstrThumb.td revision 202878
1//===- ARMInstrThumb.td - Thumb support for ARM ---------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file describes the Thumb instruction set. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// Thumb specific DAG Nodes. 16// 17 18def ARMtcall : SDNode<"ARMISD::tCALL", SDT_ARMcall, 19 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; 20 21def imm_neg_XFORM : SDNodeXForm<imm, [{ 22 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32); 23}]>; 24def imm_comp_XFORM : SDNodeXForm<imm, [{ 25 return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32); 26}]>; 27 28 29/// imm0_7 predicate - True if the 32-bit immediate is in the range [0,7]. 30def imm0_7 : PatLeaf<(i32 imm), [{ 31 return (uint32_t)N->getZExtValue() < 8; 32}]>; 33def imm0_7_neg : PatLeaf<(i32 imm), [{ 34 return (uint32_t)-N->getZExtValue() < 8; 35}], imm_neg_XFORM>; 36 37def imm0_255 : PatLeaf<(i32 imm), [{ 38 return (uint32_t)N->getZExtValue() < 256; 39}]>; 40def imm0_255_comp : PatLeaf<(i32 imm), [{ 41 return ~((uint32_t)N->getZExtValue()) < 256; 42}]>; 43 44def imm8_255 : PatLeaf<(i32 imm), [{ 45 return (uint32_t)N->getZExtValue() >= 8 && (uint32_t)N->getZExtValue() < 256; 46}]>; 47def imm8_255_neg : PatLeaf<(i32 imm), [{ 48 unsigned Val = -N->getZExtValue(); 49 return Val >= 8 && Val < 256; 50}], imm_neg_XFORM>; 51 52// Break imm's up into two pieces: an immediate + a left shift. 53// This uses thumb_immshifted to match and thumb_immshifted_val and 54// thumb_immshifted_shamt to get the val/shift pieces. 55def thumb_immshifted : PatLeaf<(imm), [{ 56 return ARM_AM::isThumbImmShiftedVal((unsigned)N->getZExtValue()); 57}]>; 58 59def thumb_immshifted_val : SDNodeXForm<imm, [{ 60 unsigned V = ARM_AM::getThumbImmNonShiftedVal((unsigned)N->getZExtValue()); 61 return CurDAG->getTargetConstant(V, MVT::i32); 62}]>; 63 64def thumb_immshifted_shamt : SDNodeXForm<imm, [{ 65 unsigned V = ARM_AM::getThumbImmValShift((unsigned)N->getZExtValue()); 66 return CurDAG->getTargetConstant(V, MVT::i32); 67}]>; 68 69// Scaled 4 immediate. 70def t_imm_s4 : Operand<i32> { 71 let PrintMethod = "printThumbS4ImmOperand"; 72} 73 74// Define Thumb specific addressing modes. 75 76// t_addrmode_rr := reg + reg 77// 78def t_addrmode_rr : Operand<i32>, 79 ComplexPattern<i32, 2, "SelectThumbAddrModeRR", []> { 80 let PrintMethod = "printThumbAddrModeRROperand"; 81 let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); 82} 83 84// t_addrmode_s4 := reg + reg 85// reg + imm5 * 4 86// 87def t_addrmode_s4 : Operand<i32>, 88 ComplexPattern<i32, 3, "SelectThumbAddrModeS4", []> { 89 let PrintMethod = "printThumbAddrModeS4Operand"; 90 let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 91} 92 93// t_addrmode_s2 := reg + reg 94// reg + imm5 * 2 95// 96def t_addrmode_s2 : Operand<i32>, 97 ComplexPattern<i32, 3, "SelectThumbAddrModeS2", []> { 98 let PrintMethod = "printThumbAddrModeS2Operand"; 99 let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 100} 101 102// t_addrmode_s1 := reg + reg 103// reg + imm5 104// 105def t_addrmode_s1 : Operand<i32>, 106 ComplexPattern<i32, 3, "SelectThumbAddrModeS1", []> { 107 let PrintMethod = "printThumbAddrModeS1Operand"; 108 let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 109} 110 111// t_addrmode_sp := sp + imm8 * 4 112// 113def t_addrmode_sp : Operand<i32>, 114 ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> { 115 let PrintMethod = "printThumbAddrModeSPOperand"; 116 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 117} 118 119//===----------------------------------------------------------------------===// 120// Miscellaneous Instructions. 121// 122 123let Defs = [SP], Uses = [SP] in { 124def tADJCALLSTACKUP : 125PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary, 126 "@ tADJCALLSTACKUP $amt1", 127 [(ARMcallseq_end imm:$amt1, imm:$amt2)]>, Requires<[IsThumb1Only]>; 128 129def tADJCALLSTACKDOWN : 130PseudoInst<(outs), (ins i32imm:$amt), NoItinerary, 131 "@ tADJCALLSTACKDOWN $amt", 132 [(ARMcallseq_start imm:$amt)]>, Requires<[IsThumb1Only]>; 133} 134 135// For both thumb1 and thumb2. 136let isNotDuplicable = 1 in 137def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr, 138 "\n$cp:\n\tadd\t$dst, pc", 139 [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>, 140 T1Special<{0,0,?,?}> { 141 let Inst{6-3} = 0b1111; // A8.6.6 Rm = pc 142} 143 144// PC relative add. 145def tADDrPCi : T1I<(outs tGPR:$dst), (ins t_imm_s4:$rhs), IIC_iALUi, 146 "add\t$dst, pc, $rhs", []>, 147 T1Encoding<{1,0,1,0,0,?}>; // A6.2 & A8.6.10 148 149// ADD rd, sp, #imm8 150def tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, t_imm_s4:$rhs), IIC_iALUi, 151 "add\t$dst, $sp, $rhs", []>, 152 T1Encoding<{1,0,1,0,1,?}>; // A6.2 & A8.6.8 153 154// ADD sp, sp, #imm7 155def tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), IIC_iALUi, 156 "add\t$dst, $rhs", []>, 157 T1Misc<{0,0,0,0,0,?,?}>; // A6.2.5 & A8.6.8 158 159// SUB sp, sp, #imm7 160def tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), IIC_iALUi, 161 "sub\t$dst, $rhs", []>, 162 T1Misc<{0,0,0,0,1,?,?}>; // A6.2.5 & A8.6.215 163 164// ADD rm, sp 165def tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 166 "add\t$dst, $rhs", []>, 167 T1Special<{0,0,?,?}> { 168 let Inst{6-3} = 0b1101; // A8.6.9 Encoding T1 169} 170 171// ADD sp, rm 172def tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 173 "add\t$dst, $rhs", []>, 174 T1Special<{0,0,?,?}> { 175 // A8.6.9 Encoding T2 176 let Inst{7} = 1; 177 let Inst{2-0} = 0b101; 178} 179 180// Pseudo instruction that will expand into a tSUBspi + a copy. 181let usesCustomInserter = 1 in { // Expanded after instruction selection. 182def tSUBspi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), 183 NoItinerary, "@ sub\t$dst, $rhs", []>; 184 185def tADDspr_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 186 NoItinerary, "@ add\t$dst, $rhs", []>; 187 188let Defs = [CPSR] in 189def tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), 190 NoItinerary, "@ and\t$dst, $rhs", []>; 191} // usesCustomInserter 192 193//===----------------------------------------------------------------------===// 194// Control Flow Instructions. 195// 196 197let isReturn = 1, isTerminator = 1, isBarrier = 1 in { 198 def tBX_RET : TI<(outs), (ins), IIC_Br, "bx\tlr", [(ARMretflag)]>, 199 T1Special<{1,1,0,?}> { // A6.2.3 & A8.6.25 200 let Inst{6-3} = 0b1110; // Rm = lr 201 } 202 // Alternative return instruction used by vararg functions. 203 def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target", []>, 204 T1Special<{1,1,0,?}>; // A6.2.3 & A8.6.25 205} 206 207// Indirect branches 208let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 209 def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "mov\tpc, $dst", 210 [(brind GPR:$dst)]>, 211 T1Special<{1,0,1,?}> { 212 // <Rd> = Inst{7:2-0} = pc 213 let Inst{2-0} = 0b111; 214 } 215} 216 217// FIXME: remove when we have a way to marking a MI with these properties. 218let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 219 hasExtraDefRegAllocReq = 1 in 220def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 221 "pop${p}\t$wb", []>, 222 T1Misc<{1,1,0,?,?,?,?}>; 223 224let isCall = 1, 225 Defs = [R0, R1, R2, R3, R12, LR, 226 D0, D1, D2, D3, D4, D5, D6, D7, 227 D16, D17, D18, D19, D20, D21, D22, D23, 228 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 229 // Also used for Thumb2 230 def tBL : TIx2<0b11110, 0b11, 1, 231 (outs), (ins i32imm:$func, variable_ops), IIC_Br, 232 "bl\t${func:call}", 233 [(ARMtcall tglobaladdr:$func)]>, 234 Requires<[IsThumb, IsNotDarwin]>; 235 236 // ARMv5T and above, also used for Thumb2 237 def tBLXi : TIx2<0b11110, 0b11, 0, 238 (outs), (ins i32imm:$func, variable_ops), IIC_Br, 239 "blx\t${func:call}", 240 [(ARMcall tglobaladdr:$func)]>, 241 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 242 243 // Also used for Thumb2 244 def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 245 "blx\t$func", 246 [(ARMtcall GPR:$func)]>, 247 Requires<[IsThumb, HasV5T, IsNotDarwin]>, 248 T1Special<{1,1,1,?}>; // A6.2.3 & A8.6.24; 249 250 // ARMv4T 251 def tBX : TIx2<{?,?,?,?,?}, {?,?}, ?, 252 (outs), (ins tGPR:$func, variable_ops), IIC_Br, 253 "mov\tlr, pc\n\tbx\t$func", 254 [(ARMcall_nolink tGPR:$func)]>, 255 Requires<[IsThumb1Only, IsNotDarwin]>; 256} 257 258// On Darwin R9 is call-clobbered. 259let isCall = 1, 260 Defs = [R0, R1, R2, R3, R9, R12, LR, 261 D0, D1, D2, D3, D4, D5, D6, D7, 262 D16, D17, D18, D19, D20, D21, D22, D23, 263 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 264 // Also used for Thumb2 265 def tBLr9 : TIx2<0b11110, 0b11, 1, 266 (outs), (ins i32imm:$func, variable_ops), IIC_Br, 267 "bl\t${func:call}", 268 [(ARMtcall tglobaladdr:$func)]>, 269 Requires<[IsThumb, IsDarwin]>; 270 271 // ARMv5T and above, also used for Thumb2 272 def tBLXi_r9 : TIx2<0b11110, 0b11, 0, 273 (outs), (ins i32imm:$func, variable_ops), IIC_Br, 274 "blx\t${func:call}", 275 [(ARMcall tglobaladdr:$func)]>, 276 Requires<[IsThumb, HasV5T, IsDarwin]>; 277 278 // Also used for Thumb2 279 def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 280 "blx\t$func", 281 [(ARMtcall GPR:$func)]>, 282 Requires<[IsThumb, HasV5T, IsDarwin]>, 283 T1Special<{1,1,1,?}>; // A6.2.3 & A8.6.24 284 285 // ARMv4T 286 def tBXr9 : TIx2<{?,?,?,?,?}, {?,?}, ?, 287 (outs), (ins tGPR:$func, variable_ops), IIC_Br, 288 "mov\tlr, pc\n\tbx\t$func", 289 [(ARMcall_nolink tGPR:$func)]>, 290 Requires<[IsThumb1Only, IsDarwin]>; 291} 292 293let isBranch = 1, isTerminator = 1 in { 294 let isBarrier = 1 in { 295 let isPredicable = 1 in 296 def tB : T1I<(outs), (ins brtarget:$target), IIC_Br, 297 "b\t$target", [(br bb:$target)]>, 298 T1Encoding<{1,1,1,0,0,?}>; 299 300 // Far jump 301 let Defs = [LR] in 302 def tBfar : TIx2<0b11110, 0b11, 1, (outs), (ins brtarget:$target), IIC_Br, 303 "bl\t$target\t@ far jump",[]>; 304 305 def tBR_JTr : T1JTI<(outs), 306 (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id), 307 IIC_Br, "mov\tpc, $target\n\t.align\t2\n$jt", 308 [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>, 309 Encoding16 { 310 let Inst{15-7} = 0b010001101; 311 let Inst{2-0} = 0b111; 312 } 313 } 314} 315 316// FIXME: should be able to write a pattern for ARMBrcond, but can't use 317// a two-value operand where a dag node expects two operands. :( 318let isBranch = 1, isTerminator = 1 in 319 def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br, 320 "b$cc\t$target", 321 [/*(ARMbrcond bb:$target, imm:$cc)*/]>, 322 T1Encoding<{1,1,0,1,?,?}>; 323 324// Compare and branch on zero / non-zero 325let isBranch = 1, isTerminator = 1 in { 326 def tCBZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br, 327 "cbz\t$cmp, $target", []>, 328 T1Misc<{0,0,?,1,?,?,?}>; 329 330 def tCBNZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br, 331 "cbnz\t$cmp, $target", []>, 332 T1Misc<{1,0,?,1,?,?,?}>; 333} 334 335//===----------------------------------------------------------------------===// 336// Load Store Instructions. 337// 338 339let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in 340def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, 341 "ldr", "\t$dst, $addr", 342 [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>, 343 T1LdSt<0b100>; 344def tLDRi: T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, 345 "ldr", "\t$dst, $addr", 346 []>, 347 T1LdSt4Imm<{1,?,?}>; 348 349def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr, 350 "ldrb", "\t$dst, $addr", 351 [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>, 352 T1LdSt<0b110>; 353def tLDRBi: T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr, 354 "ldrb", "\t$dst, $addr", 355 []>, 356 T1LdSt1Imm<{1,?,?}>; 357 358def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr, 359 "ldrh", "\t$dst, $addr", 360 [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>, 361 T1LdSt<0b101>; 362def tLDRHi: T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr, 363 "ldrh", "\t$dst, $addr", 364 []>, 365 T1LdSt2Imm<{1,?,?}>; 366 367let AddedComplexity = 10 in 368def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, 369 "ldrsb", "\t$dst, $addr", 370 [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>, 371 T1LdSt<0b011>; 372 373let AddedComplexity = 10 in 374def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, 375 "ldrsh", "\t$dst, $addr", 376 [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>, 377 T1LdSt<0b111>; 378 379let canFoldAsLoad = 1 in 380def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, 381 "ldr", "\t$dst, $addr", 382 [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>, 383 T1LdStSP<{1,?,?}>; 384 385// Special instruction for restore. It cannot clobber condition register 386// when it's expanded by eliminateCallFramePseudoInstr(). 387let canFoldAsLoad = 1, mayLoad = 1 in 388def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, 389 "ldr", "\t$dst, $addr", []>, 390 T1LdStSP<{1,?,?}>; 391 392// Load tconstpool 393// FIXME: Use ldr.n to work around a Darwin assembler bug. 394let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in 395def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, 396 "ldr", ".n\t$dst, $addr", 397 [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>, 398 T1Encoding<{0,1,0,0,1,?}>; // A6.2 & A8.6.59 399 400// Special LDR for loads from non-pc-relative constpools. 401let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1, 402 mayHaveSideEffects = 1 in 403def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, 404 "ldr", "\t$dst, $addr", []>, 405 T1LdStSP<{1,?,?}>; 406 407def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer, 408 "str", "\t$src, $addr", 409 [(store tGPR:$src, t_addrmode_s4:$addr)]>, 410 T1LdSt<0b000>; 411def tSTRi: T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer, 412 "str", "\t$src, $addr", 413 []>, 414 T1LdSt4Imm<{0,?,?}>; 415 416def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer, 417 "strb", "\t$src, $addr", 418 [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>, 419 T1LdSt<0b010>; 420def tSTRBi: T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer, 421 "strb", "\t$src, $addr", 422 []>, 423 T1LdSt1Imm<{0,?,?}>; 424 425def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer, 426 "strh", "\t$src, $addr", 427 [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>, 428 T1LdSt<0b001>; 429def tSTRHi: T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer, 430 "strh", "\t$src, $addr", 431 []>, 432 T1LdSt2Imm<{0,?,?}>; 433 434def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, 435 "str", "\t$src, $addr", 436 [(store tGPR:$src, t_addrmode_sp:$addr)]>, 437 T1LdStSP<{0,?,?}>; 438 439let mayStore = 1 in { 440// Special instruction for spill. It cannot clobber condition register 441// when it's expanded by eliminateCallFramePseudoInstr(). 442def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, 443 "str", "\t$src, $addr", []>, 444 T1LdStSP<{0,?,?}>; 445} 446 447//===----------------------------------------------------------------------===// 448// Load / store multiple Instructions. 449// 450 451// These requires base address to be written back or one of the loaded regs. 452let mayLoad = 1, hasExtraDefRegAllocReq = 1 in 453def tLDM : T1I<(outs), 454 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 455 IIC_iLoadm, 456 "ldm${addr:submode}${p}\t$addr, $wb", []>, 457 T1Encoding<{1,1,0,0,1,?}>; // A6.2 & A8.6.53 458 459let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 460def tSTM : T1I<(outs), 461 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 462 IIC_iStorem, 463 "stm${addr:submode}${p}\t$addr, $wb", []>, 464 T1Encoding<{1,1,0,0,0,?}>; // A6.2 & A8.6.189 465 466let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in 467def tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 468 "pop${p}\t$wb", []>, 469 T1Misc<{1,1,0,?,?,?,?}>; 470 471let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in 472def tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br, 473 "push${p}\t$wb", []>, 474 T1Misc<{0,1,0,?,?,?,?}>; 475 476//===----------------------------------------------------------------------===// 477// Arithmetic Instructions. 478// 479 480// Add with carry register 481let isCommutable = 1, Uses = [CPSR] in 482def tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 483 "adc", "\t$dst, $rhs", 484 [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>, 485 T1DataProcessing<0b0101>; 486 487// Add immediate 488def tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 489 "add", "\t$dst, $lhs, $rhs", 490 [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>, 491 T1General<0b01110>; 492 493def tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 494 "add", "\t$dst, $rhs", 495 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>, 496 T1General<{1,1,0,?,?}>; 497 498// Add register 499let isCommutable = 1 in 500def tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 501 "add", "\t$dst, $lhs, $rhs", 502 [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>, 503 T1General<0b01100>; 504 505let neverHasSideEffects = 1 in 506def tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 507 "add", "\t$dst, $rhs", []>, 508 T1Special<{0,0,?,?}>; 509 510// And register 511let isCommutable = 1 in 512def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 513 "and", "\t$dst, $rhs", 514 [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>, 515 T1DataProcessing<0b0000>; 516 517// ASR immediate 518def tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 519 "asr", "\t$dst, $lhs, $rhs", 520 [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>, 521 T1General<{0,1,0,?,?}>; 522 523// ASR register 524def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 525 "asr", "\t$dst, $rhs", 526 [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>, 527 T1DataProcessing<0b0100>; 528 529// BIC register 530def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 531 "bic", "\t$dst, $rhs", 532 [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>, 533 T1DataProcessing<0b1110>; 534 535// CMN register 536let Defs = [CPSR] in { 537//FIXME: Disable CMN, as CCodes are backwards from compare expectations 538// Compare-to-zero still works out, just not the relationals 539//def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 540// "cmn", "\t$lhs, $rhs", 541// [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>, 542// T1DataProcessing<0b1011>; 543def tCMNz : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 544 "cmn", "\t$lhs, $rhs", 545 [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>, 546 T1DataProcessing<0b1011>; 547} 548 549// CMP immediate 550let Defs = [CPSR] in { 551def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, 552 "cmp", "\t$lhs, $rhs", 553 [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>, 554 T1General<{1,0,1,?,?}>; 555def tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, 556 "cmp", "\t$lhs, $rhs", 557 [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>, 558 T1General<{1,0,1,?,?}>; 559} 560 561// CMP register 562let Defs = [CPSR] in { 563def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 564 "cmp", "\t$lhs, $rhs", 565 [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>, 566 T1DataProcessing<0b1010>; 567def tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 568 "cmp", "\t$lhs, $rhs", 569 [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>, 570 T1DataProcessing<0b1010>; 571 572def tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, 573 "cmp", "\t$lhs, $rhs", []>, 574 T1Special<{0,1,?,?}>; 575def tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, 576 "cmp", "\t$lhs, $rhs", []>, 577 T1Special<{0,1,?,?}>; 578} 579 580 581// XOR register 582let isCommutable = 1 in 583def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 584 "eor", "\t$dst, $rhs", 585 [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>, 586 T1DataProcessing<0b0001>; 587 588// LSL immediate 589def tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 590 "lsl", "\t$dst, $lhs, $rhs", 591 [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>, 592 T1General<{0,0,0,?,?}>; 593 594// LSL register 595def tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 596 "lsl", "\t$dst, $rhs", 597 [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>, 598 T1DataProcessing<0b0010>; 599 600// LSR immediate 601def tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 602 "lsr", "\t$dst, $lhs, $rhs", 603 [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>, 604 T1General<{0,0,1,?,?}>; 605 606// LSR register 607def tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 608 "lsr", "\t$dst, $rhs", 609 [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>, 610 T1DataProcessing<0b0011>; 611 612// move register 613def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iMOVi, 614 "mov", "\t$dst, $src", 615 [(set tGPR:$dst, imm0_255:$src)]>, 616 T1General<{1,0,0,?,?}>; 617 618// TODO: A7-73: MOV(2) - mov setting flag. 619 620 621let neverHasSideEffects = 1 in { 622// FIXME: Make this predicable. 623def tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 624 "mov\t$dst, $src", []>, 625 T1Special<0b1000>; 626let Defs = [CPSR] in 627def tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 628 "movs\t$dst, $src", []>, Encoding16 { 629 let Inst{15-6} = 0b0000000000; 630} 631 632// FIXME: Make these predicable. 633def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr, 634 "mov\t$dst, $src", []>, 635 T1Special<{1,0,0,?}>; 636def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr, 637 "mov\t$dst, $src", []>, 638 T1Special<{1,0,?,0}>; 639def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, 640 "mov\t$dst, $src", []>, 641 T1Special<{1,0,?,?}>; 642} // neverHasSideEffects 643 644// multiply register 645let isCommutable = 1 in 646def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMUL32, 647 "mul", "\t$dst, $rhs", 648 [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>, 649 T1DataProcessing<0b1101>; 650 651// move inverse register 652def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 653 "mvn", "\t$dst, $src", 654 [(set tGPR:$dst, (not tGPR:$src))]>, 655 T1DataProcessing<0b1111>; 656 657// bitwise or register 658let isCommutable = 1 in 659def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 660 "orr", "\t$dst, $rhs", 661 [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>, 662 T1DataProcessing<0b1100>; 663 664// swaps 665def tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 666 "rev", "\t$dst, $src", 667 [(set tGPR:$dst, (bswap tGPR:$src))]>, 668 Requires<[IsThumb1Only, HasV6]>, 669 T1Misc<{1,0,1,0,0,0,?}>; 670 671def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 672 "rev16", "\t$dst, $src", 673 [(set tGPR:$dst, 674 (or (and (srl tGPR:$src, (i32 8)), 0xFF), 675 (or (and (shl tGPR:$src, (i32 8)), 0xFF00), 676 (or (and (srl tGPR:$src, (i32 8)), 0xFF0000), 677 (and (shl tGPR:$src, (i32 8)), 0xFF000000)))))]>, 678 Requires<[IsThumb1Only, HasV6]>, 679 T1Misc<{1,0,1,0,0,1,?}>; 680 681def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 682 "revsh", "\t$dst, $src", 683 [(set tGPR:$dst, 684 (sext_inreg 685 (or (srl (and tGPR:$src, 0xFF00), (i32 8)), 686 (shl tGPR:$src, (i32 8))), i16))]>, 687 Requires<[IsThumb1Only, HasV6]>, 688 T1Misc<{1,0,1,0,1,1,?}>; 689 690// rotate right register 691def tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 692 "ror", "\t$dst, $rhs", 693 [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>, 694 T1DataProcessing<0b0111>; 695 696// negate register 697def tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALUi, 698 "rsb", "\t$dst, $src, #0", 699 [(set tGPR:$dst, (ineg tGPR:$src))]>, 700 T1DataProcessing<0b1001>; 701 702// Subtract with carry register 703let Uses = [CPSR] in 704def tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 705 "sbc", "\t$dst, $rhs", 706 [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>, 707 T1DataProcessing<0b0110>; 708 709// Subtract immediate 710def tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 711 "sub", "\t$dst, $lhs, $rhs", 712 [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>, 713 T1General<0b01111>; 714 715def tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 716 "sub", "\t$dst, $rhs", 717 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>, 718 T1General<{1,1,1,?,?}>; 719 720// subtract register 721def tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 722 "sub", "\t$dst, $lhs, $rhs", 723 [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>, 724 T1General<0b01101>; 725 726// TODO: A7-96: STMIA - store multiple. 727 728// sign-extend byte 729def tSXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 730 "sxtb", "\t$dst, $src", 731 [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>, 732 Requires<[IsThumb1Only, HasV6]>, 733 T1Misc<{0,0,1,0,0,1,?}>; 734 735// sign-extend short 736def tSXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 737 "sxth", "\t$dst, $src", 738 [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, 739 Requires<[IsThumb1Only, HasV6]>, 740 T1Misc<{0,0,1,0,0,0,?}>; 741 742// test 743let isCommutable = 1, Defs = [CPSR] in 744def tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 745 "tst", "\t$lhs, $rhs", 746 [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>, 747 T1DataProcessing<0b1000>; 748 749// zero-extend byte 750def tUXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 751 "uxtb", "\t$dst, $src", 752 [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, 753 Requires<[IsThumb1Only, HasV6]>, 754 T1Misc<{0,0,1,0,1,1,?}>; 755 756// zero-extend short 757def tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 758 "uxth", "\t$dst, $src", 759 [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>, 760 Requires<[IsThumb1Only, HasV6]>, 761 T1Misc<{0,0,1,0,1,0,?}>; 762 763 764// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation. 765// Expanded after instruction selection into a branch sequence. 766let usesCustomInserter = 1 in // Expanded after instruction selection. 767 def tMOVCCr_pseudo : 768 PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc), 769 NoItinerary, "@ tMOVCCr $cc", 770 [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>; 771 772 773// 16-bit movcc in IT blocks for Thumb2. 774def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr, 775 "mov", "\t$dst, $rhs", []>, 776 T1Special<{1,0,?,?}>; 777 778def tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iCMOVi, 779 "mov", "\t$dst, $rhs", []>, 780 T1General<{1,0,0,?,?}>; 781 782// tLEApcrel - Load a pc-relative address into a register without offending the 783// assembler. 784def tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi, 785 "adr$p\t$dst, #$label", []>, 786 T1Encoding<{1,0,1,0,0,?}>; // A6.2 & A8.6.10 787 788def tLEApcrelJT : T1I<(outs tGPR:$dst), 789 (ins i32imm:$label, nohash_imm:$id, pred:$p), 790 IIC_iALUi, "adr$p\t$dst, #${label}_${id}", []>, 791 T1Encoding<{1,0,1,0,0,?}>; // A6.2 & A8.6.10 792 793//===----------------------------------------------------------------------===// 794// TLS Instructions 795// 796 797// __aeabi_read_tp preserves the registers r1-r3. 798let isCall = 1, 799 Defs = [R0, LR] in { 800 def tTPsoft : TIx2<0b11110, 0b11, 1, (outs), (ins), IIC_Br, 801 "bl\t__aeabi_read_tp", 802 [(set R0, ARMthread_pointer)]>; 803} 804 805// SJLJ Exception handling intrinsics 806// eh_sjlj_setjmp() is an instruction sequence to store the return 807// address and save #0 in R0 for the non-longjmp case. 808// Since by its nature we may be coming from some other function to get 809// here, and we're using the stack frame for the containing function to 810// save/restore registers, we can't keep anything live in regs across 811// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 812// when we get here from a longjmp(). We force everthing out of registers 813// except for our own input by listing the relevant registers in Defs. By 814// doing so, we also cause the prologue/epilogue code to actively preserve 815// all of the callee-saved resgisters, which is exactly what we want. 816let Defs = 817 [ R0, R1, R2, R3, R4, R5, R6, R7, R12 ] in { 818 def tInt_eh_sjlj_setjmp : ThumbXI<(outs), (ins GPR:$src), 819 AddrModeNone, SizeSpecial, NoItinerary, 820 "mov\tr12, r1\t@ begin eh.setjmp\n" 821 "\tmov\tr1, sp\n" 822 "\tstr\tr1, [$src, #8]\n" 823 "\tadr\tr1, 0f\n" 824 "\tadds\tr1, #1\n" 825 "\tstr\tr1, [$src, #4]\n" 826 "\tmov\tr1, r12\n" 827 "\tmovs\tr0, #0\n" 828 "\tb\t1f\n" 829 ".align 2\n" 830 "0:\tmovs\tr0, #1\t@ end eh.setjmp\n" 831 "1:", "", 832 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>; 833} 834//===----------------------------------------------------------------------===// 835// Non-Instruction Patterns 836// 837 838// Add with carry 839def : T1Pat<(addc tGPR:$lhs, imm0_7:$rhs), 840 (tADDi3 tGPR:$lhs, imm0_7:$rhs)>; 841def : T1Pat<(addc tGPR:$lhs, imm8_255:$rhs), 842 (tADDi8 tGPR:$lhs, imm8_255:$rhs)>; 843def : T1Pat<(addc tGPR:$lhs, tGPR:$rhs), 844 (tADDrr tGPR:$lhs, tGPR:$rhs)>; 845 846// Subtract with carry 847def : T1Pat<(addc tGPR:$lhs, imm0_7_neg:$rhs), 848 (tSUBi3 tGPR:$lhs, imm0_7_neg:$rhs)>; 849def : T1Pat<(addc tGPR:$lhs, imm8_255_neg:$rhs), 850 (tSUBi8 tGPR:$lhs, imm8_255_neg:$rhs)>; 851def : T1Pat<(subc tGPR:$lhs, tGPR:$rhs), 852 (tSUBrr tGPR:$lhs, tGPR:$rhs)>; 853 854// ConstantPool, GlobalAddress 855def : T1Pat<(ARMWrapper tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>; 856def : T1Pat<(ARMWrapper tconstpool :$dst), (tLEApcrel tconstpool :$dst)>; 857 858// JumpTable 859def : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), 860 (tLEApcrelJT tjumptable:$dst, imm:$id)>; 861 862// Direct calls 863def : T1Pat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>, 864 Requires<[IsThumb, IsNotDarwin]>; 865def : T1Pat<(ARMtcall texternalsym:$func), (tBLr9 texternalsym:$func)>, 866 Requires<[IsThumb, IsDarwin]>; 867 868def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>, 869 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 870def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi_r9 texternalsym:$func)>, 871 Requires<[IsThumb, HasV5T, IsDarwin]>; 872 873// Indirect calls to ARM routines 874def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>, 875 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 876def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr_r9 GPR:$dst)>, 877 Requires<[IsThumb, HasV5T, IsDarwin]>; 878 879// zextload i1 -> zextload i8 880def : T1Pat<(zextloadi1 t_addrmode_s1:$addr), 881 (tLDRB t_addrmode_s1:$addr)>; 882 883// extload -> zextload 884def : T1Pat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 885def : T1Pat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 886def : T1Pat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>; 887 888// If it's impossible to use [r,r] address mode for sextload, select to 889// ldr{b|h} + sxt{b|h} instead. 890def : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 891 (tSXTB (tLDRB t_addrmode_s1:$addr))>, 892 Requires<[IsThumb1Only, HasV6]>; 893def : T1Pat<(sextloadi16 t_addrmode_s2:$addr), 894 (tSXTH (tLDRH t_addrmode_s2:$addr))>, 895 Requires<[IsThumb1Only, HasV6]>; 896 897def : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 898 (tASRri (tLSLri (tLDRB t_addrmode_s1:$addr), 24), 24)>; 899def : T1Pat<(sextloadi16 t_addrmode_s1:$addr), 900 (tASRri (tLSLri (tLDRH t_addrmode_s1:$addr), 16), 16)>; 901 902// Large immediate handling. 903 904// Two piece imms. 905def : T1Pat<(i32 thumb_immshifted:$src), 906 (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)), 907 (thumb_immshifted_shamt imm:$src))>; 908 909def : T1Pat<(i32 imm0_255_comp:$src), 910 (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>; 911 912// Pseudo instruction that combines ldr from constpool and add pc. This should 913// be expanded into two instructions late to allow if-conversion and 914// scheduling. 915let isReMaterializable = 1 in 916def tLDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp), 917 NoItinerary, "@ ldr.n\t$dst, $addr\n$cp:\n\tadd\t$dst, pc", 918 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)), 919 imm:$cp))]>, 920 Requires<[IsThumb1Only]>; 921