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