ARMInstrThumb.td revision 210299
168349Sobrien//===- ARMInstrThumb.td - Thumb support for ARM ---------------------------===// 268349Sobrien// 368349Sobrien// The LLVM Compiler Infrastructure 468349Sobrien// 568349Sobrien// This file is distributed under the University of Illinois Open Source 668349Sobrien// License. See LICENSE.TXT for details. 768349Sobrien// 8186690Sobrien//===----------------------------------------------------------------------===// 9191736Sobrien// 1068349Sobrien// This file describes the Thumb instruction set. 11186690Sobrien// 12186690Sobrien//===----------------------------------------------------------------------===// 13186690Sobrien 14186690Sobrien//===----------------------------------------------------------------------===// 15186690Sobrien// Thumb specific DAG Nodes. 16186690Sobrien// 1768349Sobrien 1868349Sobriendef ARMtcall : SDNode<"ARMISD::tCALL", SDT_ARMcall, 19186690Sobrien [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, 20191736Sobrien SDNPVariadic]>; 2168349Sobrien 22186690Sobriendef imm_neg_XFORM : SDNodeXForm<imm, [{ 23186690Sobrien return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32); 24186690Sobrien}]>; 25186690Sobriendef imm_comp_XFORM : SDNodeXForm<imm, [{ 26186690Sobrien return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32); 27186690Sobrien}]>; 2868349Sobrien 2968349Sobrien 3068349Sobrien/// imm0_7 predicate - True if the 32-bit immediate is in the range [0,7]. 3168349Sobriendef imm0_7 : PatLeaf<(i32 imm), [{ 3268349Sobrien return (uint32_t)N->getZExtValue() < 8; 3368349Sobrien}]>; 3468349Sobriendef imm0_7_neg : PatLeaf<(i32 imm), [{ 3568349Sobrien return (uint32_t)-N->getZExtValue() < 8; 3668349Sobrien}], imm_neg_XFORM>; 3768349Sobrien 3868349Sobriendef imm0_255 : PatLeaf<(i32 imm), [{ 3968349Sobrien return (uint32_t)N->getZExtValue() < 256; 40186690Sobrien}]>; 41186690Sobriendef imm0_255_comp : PatLeaf<(i32 imm), [{ 42186690Sobrien return ~((uint32_t)N->getZExtValue()) < 256; 43186690Sobrien}]>; 4468349Sobrien 45186690Sobriendef imm8_255 : PatLeaf<(i32 imm), [{ 46186690Sobrien return (uint32_t)N->getZExtValue() >= 8 && (uint32_t)N->getZExtValue() < 256; 4768349Sobrien}]>; 4868349Sobriendef imm8_255_neg : PatLeaf<(i32 imm), [{ 4968349Sobrien unsigned Val = -N->getZExtValue(); 5068349Sobrien return Val >= 8 && Val < 256; 5168349Sobrien}], imm_neg_XFORM>; 5268349Sobrien 5368349Sobrien// Break imm's up into two pieces: an immediate + a left shift. 5468349Sobrien// This uses thumb_immshifted to match and thumb_immshifted_val and 5568349Sobrien// thumb_immshifted_shamt to get the val/shift pieces. 5668349Sobriendef thumb_immshifted : PatLeaf<(imm), [{ 5768349Sobrien return ARM_AM::isThumbImmShiftedVal((unsigned)N->getZExtValue()); 5868349Sobrien}]>; 5968349Sobrien 6068349Sobriendef thumb_immshifted_val : SDNodeXForm<imm, [{ 6168349Sobrien unsigned V = ARM_AM::getThumbImmNonShiftedVal((unsigned)N->getZExtValue()); 6268349Sobrien return CurDAG->getTargetConstant(V, MVT::i32); 6368349Sobrien}]>; 6468349Sobrien 6568349Sobriendef thumb_immshifted_shamt : SDNodeXForm<imm, [{ 6668349Sobrien unsigned V = ARM_AM::getThumbImmValShift((unsigned)N->getZExtValue()); 6768349Sobrien return CurDAG->getTargetConstant(V, MVT::i32); 6868349Sobrien}]>; 6968349Sobrien 7068349Sobrien// Scaled 4 immediate. 7168349Sobriendef t_imm_s4 : Operand<i32> { 7268349Sobrien let PrintMethod = "printThumbS4ImmOperand"; 7368349Sobrien} 7468349Sobrien 7568349Sobrien// Define Thumb specific addressing modes. 7668349Sobrien 7768349Sobrien// t_addrmode_rr := reg + reg 7868349Sobrien// 7968349Sobriendef t_addrmode_rr : Operand<i32>, 8068349Sobrien ComplexPattern<i32, 2, "SelectThumbAddrModeRR", []> { 8168349Sobrien let PrintMethod = "printThumbAddrModeRROperand"; 8268349Sobrien let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); 8368349Sobrien} 8468349Sobrien 8568349Sobrien// t_addrmode_s4 := reg + reg 8668349Sobrien// reg + imm5 * 4 8768349Sobrien// 8868349Sobriendef t_addrmode_s4 : Operand<i32>, 8968349Sobrien ComplexPattern<i32, 3, "SelectThumbAddrModeS4", []> { 9068349Sobrien let PrintMethod = "printThumbAddrModeS4Operand"; 9168349Sobrien let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 9268349Sobrien} 9368349Sobrien 9468349Sobrien// t_addrmode_s2 := reg + reg 95133359Sobrien// reg + imm5 * 2 9668349Sobrien// 9768349Sobriendef t_addrmode_s2 : Operand<i32>, 98103373Sobrien ComplexPattern<i32, 3, "SelectThumbAddrModeS2", []> { 99103373Sobrien let PrintMethod = "printThumbAddrModeS2Operand"; 100103373Sobrien let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 101103373Sobrien} 102133359Sobrien 103133359Sobrien// t_addrmode_s1 := reg + reg 104133359Sobrien// reg + imm5 105133359Sobrien// 106133359Sobriendef t_addrmode_s1 : Operand<i32>, 107133359Sobrien ComplexPattern<i32, 3, "SelectThumbAddrModeS1", []> { 108133359Sobrien let PrintMethod = "printThumbAddrModeS1Operand"; 109133359Sobrien let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 110133359Sobrien} 111133359Sobrien 112133359Sobrien// t_addrmode_sp := sp + imm8 * 4 113133359Sobrien// 114133359Sobriendef t_addrmode_sp : Operand<i32>, 115133359Sobrien ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> { 116133359Sobrien let PrintMethod = "printThumbAddrModeSPOperand"; 117133359Sobrien let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 118133359Sobrien} 119133359Sobrien 120133359Sobrien//===----------------------------------------------------------------------===// 121133359Sobrien// Miscellaneous Instructions. 122133359Sobrien// 123133359Sobrien 124133359Sobrien// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE 125133359Sobrien// from removing one half of the matched pairs. That breaks PEI, which assumes 126159764Sobrien// these will always be in pairs, and asserts if it finds otherwise. Better way? 127159764Sobrienlet Defs = [SP], Uses = [SP], hasSideEffects = 1 in { 128159764Sobriendef tADJCALLSTACKUP : 129159764SobrienPseudoInst<(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 224def tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, t_imm_s4:$rhs), IIC_iALUi, 225 "add\t$dst, $sp, $rhs", []>, 226 T1Encoding<{1,0,1,0,1,?}>; // A6.2 & A8.6.8 227 228// ADD sp, sp, #imm7 229def tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), IIC_iALUi, 230 "add\t$dst, $rhs", []>, 231 T1Misc<{0,0,0,0,0,?,?}>; // A6.2.5 & A8.6.8 232 233// SUB sp, sp, #imm7 234def tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), IIC_iALUi, 235 "sub\t$dst, $rhs", []>, 236 T1Misc<{0,0,0,0,1,?,?}>; // A6.2.5 & A8.6.215 237 238// ADD rm, sp 239def tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 240 "add\t$dst, $rhs", []>, 241 T1Special<{0,0,?,?}> { 242 let Inst{6-3} = 0b1101; // A8.6.9 Encoding T1 243} 244 245// ADD sp, rm 246def tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 247 "add\t$dst, $rhs", []>, 248 T1Special<{0,0,?,?}> { 249 // A8.6.9 Encoding T2 250 let Inst{7} = 1; 251 let Inst{2-0} = 0b101; 252} 253 254// Pseudo instruction that will expand into a tSUBspi + a copy. 255let usesCustomInserter = 1 in { // Expanded after instruction selection. 256def tSUBspi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), 257 NoItinerary, "${:comment} sub\t$dst, $rhs", []>; 258 259def tADDspr_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 260 NoItinerary, "${:comment} add\t$dst, $rhs", []>; 261 262let Defs = [CPSR] in 263def tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), 264 NoItinerary, "${:comment} and\t$dst, $rhs", []>; 265} // usesCustomInserter 266 267//===----------------------------------------------------------------------===// 268// Control Flow Instructions. 269// 270 271let isReturn = 1, isTerminator = 1, isBarrier = 1 in { 272 def tBX_RET : TI<(outs), (ins), IIC_Br, "bx\tlr", [(ARMretflag)]>, 273 T1Special<{1,1,0,?}> { // A6.2.3 & A8.6.25 274 let Inst{6-3} = 0b1110; // Rm = lr 275 } 276 // Alternative return instruction used by vararg functions. 277 def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target",[]>, 278 T1Special<{1,1,0,?}>; // A6.2.3 & A8.6.25 279} 280 281// Indirect branches 282let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 283 def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "mov\tpc, $dst", 284 [(brind GPR:$dst)]>, 285 T1Special<{1,0,1,?}> { 286 // <Rd> = Inst{7:2-0} = pc 287 let Inst{2-0} = 0b111; 288 } 289} 290 291// FIXME: remove when we have a way to marking a MI with these properties. 292let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 293 hasExtraDefRegAllocReq = 1 in 294def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$dsts, variable_ops), IIC_Br, 295 "pop${p}\t$dsts", []>, 296 T1Misc<{1,1,0,?,?,?,?}>; 297 298let isCall = 1, 299 Defs = [R0, R1, R2, R3, R12, LR, 300 D0, D1, D2, D3, D4, D5, D6, D7, 301 D16, D17, D18, D19, D20, D21, D22, D23, 302 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 303 // Also used for Thumb2 304 def tBL : TIx2<0b11110, 0b11, 1, 305 (outs), (ins i32imm:$func, variable_ops), IIC_Br, 306 "bl\t${func:call}", 307 [(ARMtcall tglobaladdr:$func)]>, 308 Requires<[IsThumb, IsNotDarwin]>; 309 310 // ARMv5T and above, also used for Thumb2 311 def tBLXi : TIx2<0b11110, 0b11, 0, 312 (outs), (ins i32imm:$func, variable_ops), IIC_Br, 313 "blx\t${func:call}", 314 [(ARMcall tglobaladdr:$func)]>, 315 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 316 317 // Also used for Thumb2 318 def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 319 "blx\t$func", 320 [(ARMtcall GPR:$func)]>, 321 Requires<[IsThumb, HasV5T, IsNotDarwin]>, 322 T1Special<{1,1,1,?}>; // A6.2.3 & A8.6.24; 323 324 // ARMv4T 325 def tBX : TIx2<{?,?,?,?,?}, {?,?}, ?, 326 (outs), (ins tGPR:$func, variable_ops), IIC_Br, 327 "mov\tlr, pc\n\tbx\t$func", 328 [(ARMcall_nolink tGPR:$func)]>, 329 Requires<[IsThumb1Only, IsNotDarwin]>; 330} 331 332// On Darwin R9 is call-clobbered. 333let isCall = 1, 334 Defs = [R0, R1, R2, R3, R9, R12, LR, 335 D0, D1, D2, D3, D4, D5, D6, D7, 336 D16, D17, D18, D19, D20, D21, D22, D23, 337 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 338 // Also used for Thumb2 339 def tBLr9 : TIx2<0b11110, 0b11, 1, 340 (outs), (ins i32imm:$func, variable_ops), IIC_Br, 341 "bl\t${func:call}", 342 [(ARMtcall tglobaladdr:$func)]>, 343 Requires<[IsThumb, IsDarwin]>; 344 345 // ARMv5T and above, also used for Thumb2 346 def tBLXi_r9 : TIx2<0b11110, 0b11, 0, 347 (outs), (ins i32imm:$func, variable_ops), IIC_Br, 348 "blx\t${func:call}", 349 [(ARMcall tglobaladdr:$func)]>, 350 Requires<[IsThumb, HasV5T, IsDarwin]>; 351 352 // Also used for Thumb2 353 def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 354 "blx\t$func", 355 [(ARMtcall GPR:$func)]>, 356 Requires<[IsThumb, HasV5T, IsDarwin]>, 357 T1Special<{1,1,1,?}>; // A6.2.3 & A8.6.24 358 359 // ARMv4T 360 def tBXr9 : TIx2<{?,?,?,?,?}, {?,?}, ?, 361 (outs), (ins tGPR:$func, variable_ops), IIC_Br, 362 "mov\tlr, pc\n\tbx\t$func", 363 [(ARMcall_nolink tGPR:$func)]>, 364 Requires<[IsThumb1Only, IsDarwin]>; 365} 366 367let isBranch = 1, isTerminator = 1 in { 368 let isBarrier = 1 in { 369 let isPredicable = 1 in 370 def tB : T1I<(outs), (ins brtarget:$target), IIC_Br, 371 "b\t$target", [(br bb:$target)]>, 372 T1Encoding<{1,1,1,0,0,?}>; 373 374 // Far jump 375 let Defs = [LR] in 376 def tBfar : TIx2<0b11110, 0b11, 1, (outs), (ins brtarget:$target), IIC_Br, 377 "bl\t$target\t${:comment} far jump",[]>; 378 379 def tBR_JTr : T1JTI<(outs), 380 (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id), 381 IIC_Br, "mov\tpc, $target\n\t.align\t2\n$jt", 382 [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>, 383 Encoding16 { 384 let Inst{15-7} = 0b010001101; 385 let Inst{2-0} = 0b111; 386 } 387 } 388} 389 390// FIXME: should be able to write a pattern for ARMBrcond, but can't use 391// a two-value operand where a dag node expects two operands. :( 392let isBranch = 1, isTerminator = 1 in 393 def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br, 394 "b$cc\t$target", 395 [/*(ARMbrcond bb:$target, imm:$cc)*/]>, 396 T1Encoding<{1,1,0,1,?,?}>; 397 398// Compare and branch on zero / non-zero 399let isBranch = 1, isTerminator = 1 in { 400 def tCBZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br, 401 "cbz\t$cmp, $target", []>, 402 T1Misc<{0,0,?,1,?,?,?}>; 403 404 def tCBNZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br, 405 "cbnz\t$cmp, $target", []>, 406 T1Misc<{1,0,?,1,?,?,?}>; 407} 408 409// A8.6.218 Supervisor Call (Software Interrupt) -- for disassembly only 410// A8.6.16 B: Encoding T1 411// If Inst{11-8} == 0b1111 then SEE SVC 412let isCall = 1 in { 413def tSVC : T1pI<(outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc", []>, 414 Encoding16 { 415 let Inst{15-12} = 0b1101; 416 let Inst{11-8} = 0b1111; 417} 418} 419 420// A8.6.16 B: Encoding T1 421// If Inst{11-8} == 0b1110 then UNDEFINED 422// FIXME: Temporary emitted as raw bytes until this pseudo-op will be added to 423// binutils 424let isBarrier = 1, isTerminator = 1 in 425def tTRAP : TI<(outs), (ins), IIC_Br, 426 ".short 0xdefe ${:comment} trap", [(trap)]>, Encoding16 { 427 let Inst{15-12} = 0b1101; 428 let Inst{11-8} = 0b1110; 429} 430 431//===----------------------------------------------------------------------===// 432// Load Store Instructions. 433// 434 435let canFoldAsLoad = 1, isReMaterializable = 1 in 436def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, 437 "ldr", "\t$dst, $addr", 438 [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>, 439 T1LdSt<0b100>; 440def tLDRi: T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr, 441 "ldr", "\t$dst, $addr", 442 []>, 443 T1LdSt4Imm<{1,?,?}>; 444 445def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr, 446 "ldrb", "\t$dst, $addr", 447 [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>, 448 T1LdSt<0b110>; 449def tLDRBi: T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr, 450 "ldrb", "\t$dst, $addr", 451 []>, 452 T1LdSt1Imm<{1,?,?}>; 453 454def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr, 455 "ldrh", "\t$dst, $addr", 456 [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>, 457 T1LdSt<0b101>; 458def tLDRHi: T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr, 459 "ldrh", "\t$dst, $addr", 460 []>, 461 T1LdSt2Imm<{1,?,?}>; 462 463let AddedComplexity = 10 in 464def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, 465 "ldrsb", "\t$dst, $addr", 466 [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>, 467 T1LdSt<0b011>; 468 469let AddedComplexity = 10 in 470def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr, 471 "ldrsh", "\t$dst, $addr", 472 [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>, 473 T1LdSt<0b111>; 474 475let canFoldAsLoad = 1 in 476def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, 477 "ldr", "\t$dst, $addr", 478 [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>, 479 T1LdStSP<{1,?,?}>; 480 481// Special instruction for restore. It cannot clobber condition register 482// when it's expanded by eliminateCallFramePseudoInstr(). 483let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1 in 484def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi, 485 "ldr", "\t$dst, $addr", []>, 486 T1LdStSP<{1,?,?}>; 487 488// Load tconstpool 489// FIXME: Use ldr.n to work around a Darwin assembler bug. 490let canFoldAsLoad = 1, isReMaterializable = 1 in 491def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, 492 "ldr", ".n\t$dst, $addr", 493 [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>, 494 T1Encoding<{0,1,0,0,1,?}>; // A6.2 & A8.6.59 495 496// Special LDR for loads from non-pc-relative constpools. 497let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1, 498 isReMaterializable = 1 in 499def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi, 500 "ldr", "\t$dst, $addr", []>, 501 T1LdStSP<{1,?,?}>; 502 503def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer, 504 "str", "\t$src, $addr", 505 [(store tGPR:$src, t_addrmode_s4:$addr)]>, 506 T1LdSt<0b000>; 507def tSTRi: T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer, 508 "str", "\t$src, $addr", 509 []>, 510 T1LdSt4Imm<{0,?,?}>; 511 512def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer, 513 "strb", "\t$src, $addr", 514 [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>, 515 T1LdSt<0b010>; 516def tSTRBi: T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer, 517 "strb", "\t$src, $addr", 518 []>, 519 T1LdSt1Imm<{0,?,?}>; 520 521def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer, 522 "strh", "\t$src, $addr", 523 [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>, 524 T1LdSt<0b001>; 525def tSTRHi: T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer, 526 "strh", "\t$src, $addr", 527 []>, 528 T1LdSt2Imm<{0,?,?}>; 529 530def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, 531 "str", "\t$src, $addr", 532 [(store tGPR:$src, t_addrmode_sp:$addr)]>, 533 T1LdStSP<{0,?,?}>; 534 535let mayStore = 1, neverHasSideEffects = 1 in { 536// Special instruction for spill. It cannot clobber condition register 537// when it's expanded by eliminateCallFramePseudoInstr(). 538def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei, 539 "str", "\t$src, $addr", []>, 540 T1LdStSP<{0,?,?}>; 541} 542 543//===----------------------------------------------------------------------===// 544// Load / store multiple Instructions. 545// 546 547// These requires base address to be written back or one of the loaded regs. 548let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in { 549def tLDM : T1I<(outs), 550 (ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops), 551 IIC_iLoadm, 552 "ldm${addr:submode}${p}\t$addr, $dsts", []>, 553 T1Encoding<{1,1,0,0,1,?}>; // A6.2 & A8.6.53 554 555def tLDM_UPD : T1It<(outs tGPR:$wb), 556 (ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops), 557 IIC_iLoadm, 558 "ldm${addr:submode}${p}\t$addr!, $dsts", 559 "$addr.addr = $wb", []>, 560 T1Encoding<{1,1,0,0,1,?}>; // A6.2 & A8.6.53 561} // mayLoad, neverHasSideEffects = 1, hasExtraDefRegAllocReq 562 563let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in 564def tSTM_UPD : T1It<(outs tGPR:$wb), 565 (ins addrmode4:$addr, pred:$p, reglist:$srcs, variable_ops), 566 IIC_iStorem, 567 "stm${addr:submode}${p}\t$addr!, $srcs", 568 "$addr.addr = $wb", []>, 569 T1Encoding<{1,1,0,0,0,?}>; // A6.2 & A8.6.189 570 571let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in 572def tPOP : T1I<(outs), (ins pred:$p, reglist:$dsts, variable_ops), IIC_Br, 573 "pop${p}\t$dsts", []>, 574 T1Misc<{1,1,0,?,?,?,?}>; 575 576let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in 577def tPUSH : T1I<(outs), (ins pred:$p, reglist:$srcs, variable_ops), IIC_Br, 578 "push${p}\t$srcs", []>, 579 T1Misc<{0,1,0,?,?,?,?}>; 580 581//===----------------------------------------------------------------------===// 582// Arithmetic Instructions. 583// 584 585// Add with carry register 586let isCommutable = 1, Uses = [CPSR] in 587def tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 588 "adc", "\t$dst, $rhs", 589 [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>, 590 T1DataProcessing<0b0101>; 591 592// Add immediate 593def tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 594 "add", "\t$dst, $lhs, $rhs", 595 [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>, 596 T1General<0b01110>; 597 598def tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 599 "add", "\t$dst, $rhs", 600 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>, 601 T1General<{1,1,0,?,?}>; 602 603// Add register 604let isCommutable = 1 in 605def tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 606 "add", "\t$dst, $lhs, $rhs", 607 [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>, 608 T1General<0b01100>; 609 610let neverHasSideEffects = 1 in 611def tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 612 "add", "\t$dst, $rhs", []>, 613 T1Special<{0,0,?,?}>; 614 615// And register 616let isCommutable = 1 in 617def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 618 "and", "\t$dst, $rhs", 619 [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>, 620 T1DataProcessing<0b0000>; 621 622// ASR immediate 623def tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 624 "asr", "\t$dst, $lhs, $rhs", 625 [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>, 626 T1General<{0,1,0,?,?}>; 627 628// ASR register 629def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 630 "asr", "\t$dst, $rhs", 631 [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>, 632 T1DataProcessing<0b0100>; 633 634// BIC register 635def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 636 "bic", "\t$dst, $rhs", 637 [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>, 638 T1DataProcessing<0b1110>; 639 640// CMN register 641let Defs = [CPSR] in { 642//FIXME: Disable CMN, as CCodes are backwards from compare expectations 643// Compare-to-zero still works out, just not the relationals 644//def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 645// "cmn", "\t$lhs, $rhs", 646// [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>, 647// T1DataProcessing<0b1011>; 648def tCMNz : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 649 "cmn", "\t$lhs, $rhs", 650 [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>, 651 T1DataProcessing<0b1011>; 652} 653 654// CMP immediate 655let Defs = [CPSR] in { 656def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, 657 "cmp", "\t$lhs, $rhs", 658 [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>, 659 T1General<{1,0,1,?,?}>; 660def tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi, 661 "cmp", "\t$lhs, $rhs", 662 [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>, 663 T1General<{1,0,1,?,?}>; 664} 665 666// CMP register 667let Defs = [CPSR] in { 668def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 669 "cmp", "\t$lhs, $rhs", 670 [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>, 671 T1DataProcessing<0b1010>; 672def tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 673 "cmp", "\t$lhs, $rhs", 674 [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>, 675 T1DataProcessing<0b1010>; 676 677def tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, 678 "cmp", "\t$lhs, $rhs", []>, 679 T1Special<{0,1,?,?}>; 680def tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, 681 "cmp", "\t$lhs, $rhs", []>, 682 T1Special<{0,1,?,?}>; 683} 684 685 686// XOR register 687let isCommutable = 1 in 688def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 689 "eor", "\t$dst, $rhs", 690 [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>, 691 T1DataProcessing<0b0001>; 692 693// LSL immediate 694def tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 695 "lsl", "\t$dst, $lhs, $rhs", 696 [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>, 697 T1General<{0,0,0,?,?}>; 698 699// LSL register 700def tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 701 "lsl", "\t$dst, $rhs", 702 [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>, 703 T1DataProcessing<0b0010>; 704 705// LSR immediate 706def tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi, 707 "lsr", "\t$dst, $lhs, $rhs", 708 [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>, 709 T1General<{0,0,1,?,?}>; 710 711// LSR register 712def tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 713 "lsr", "\t$dst, $rhs", 714 [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>, 715 T1DataProcessing<0b0011>; 716 717// move register 718def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iMOVi, 719 "mov", "\t$dst, $src", 720 [(set tGPR:$dst, imm0_255:$src)]>, 721 T1General<{1,0,0,?,?}>; 722 723// TODO: A7-73: MOV(2) - mov setting flag. 724 725 726let neverHasSideEffects = 1 in { 727// FIXME: Make this predicable. 728def tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 729 "mov\t$dst, $src", []>, 730 T1Special<0b1000>; 731let Defs = [CPSR] in 732def tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 733 "movs\t$dst, $src", []>, Encoding16 { 734 let Inst{15-6} = 0b0000000000; 735} 736 737// FIXME: Make these predicable. 738def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr, 739 "mov\t$dst, $src", []>, 740 T1Special<{1,0,0,?}>; 741def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr, 742 "mov\t$dst, $src", []>, 743 T1Special<{1,0,?,0}>; 744def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, 745 "mov\t$dst, $src", []>, 746 T1Special<{1,0,?,?}>; 747} // neverHasSideEffects 748 749// multiply register 750let isCommutable = 1 in 751def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMUL32, 752 "mul", "\t$dst, $rhs, $dst", /* A8.6.105 MUL Encoding T1 */ 753 [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>, 754 T1DataProcessing<0b1101>; 755 756// move inverse register 757def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 758 "mvn", "\t$dst, $src", 759 [(set tGPR:$dst, (not tGPR:$src))]>, 760 T1DataProcessing<0b1111>; 761 762// bitwise or register 763let isCommutable = 1 in 764def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 765 "orr", "\t$dst, $rhs", 766 [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>, 767 T1DataProcessing<0b1100>; 768 769// swaps 770def tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 771 "rev", "\t$dst, $src", 772 [(set tGPR:$dst, (bswap tGPR:$src))]>, 773 Requires<[IsThumb1Only, HasV6]>, 774 T1Misc<{1,0,1,0,0,0,?}>; 775 776def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 777 "rev16", "\t$dst, $src", 778 [(set tGPR:$dst, 779 (or (and (srl tGPR:$src, (i32 8)), 0xFF), 780 (or (and (shl tGPR:$src, (i32 8)), 0xFF00), 781 (or (and (srl tGPR:$src, (i32 8)), 0xFF0000), 782 (and (shl tGPR:$src, (i32 8)), 0xFF000000)))))]>, 783 Requires<[IsThumb1Only, HasV6]>, 784 T1Misc<{1,0,1,0,0,1,?}>; 785 786def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 787 "revsh", "\t$dst, $src", 788 [(set tGPR:$dst, 789 (sext_inreg 790 (or (srl (and tGPR:$src, 0xFF00), (i32 8)), 791 (shl tGPR:$src, (i32 8))), i16))]>, 792 Requires<[IsThumb1Only, HasV6]>, 793 T1Misc<{1,0,1,0,1,1,?}>; 794 795// rotate right register 796def tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 797 "ror", "\t$dst, $rhs", 798 [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>, 799 T1DataProcessing<0b0111>; 800 801// negate register 802def tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALUi, 803 "rsb", "\t$dst, $src, #0", 804 [(set tGPR:$dst, (ineg tGPR:$src))]>, 805 T1DataProcessing<0b1001>; 806 807// Subtract with carry register 808let Uses = [CPSR] in 809def tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 810 "sbc", "\t$dst, $rhs", 811 [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>, 812 T1DataProcessing<0b0110>; 813 814// Subtract immediate 815def tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 816 "sub", "\t$dst, $lhs, $rhs", 817 [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>, 818 T1General<0b01111>; 819 820def tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 821 "sub", "\t$dst, $rhs", 822 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>, 823 T1General<{1,1,1,?,?}>; 824 825// subtract register 826def tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 827 "sub", "\t$dst, $lhs, $rhs", 828 [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>, 829 T1General<0b01101>; 830 831// TODO: A7-96: STMIA - store multiple. 832 833// sign-extend byte 834def tSXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 835 "sxtb", "\t$dst, $src", 836 [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>, 837 Requires<[IsThumb1Only, HasV6]>, 838 T1Misc<{0,0,1,0,0,1,?}>; 839 840// sign-extend short 841def tSXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 842 "sxth", "\t$dst, $src", 843 [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, 844 Requires<[IsThumb1Only, HasV6]>, 845 T1Misc<{0,0,1,0,0,0,?}>; 846 847// test 848let isCommutable = 1, Defs = [CPSR] in 849def tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 850 "tst", "\t$lhs, $rhs", 851 [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>, 852 T1DataProcessing<0b1000>; 853 854// zero-extend byte 855def tUXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 856 "uxtb", "\t$dst, $src", 857 [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, 858 Requires<[IsThumb1Only, HasV6]>, 859 T1Misc<{0,0,1,0,1,1,?}>; 860 861// zero-extend short 862def tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr, 863 "uxth", "\t$dst, $src", 864 [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>, 865 Requires<[IsThumb1Only, HasV6]>, 866 T1Misc<{0,0,1,0,1,0,?}>; 867 868 869// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC operation. 870// Expanded after instruction selection into a branch sequence. 871let usesCustomInserter = 1 in // Expanded after instruction selection. 872 def tMOVCCr_pseudo : 873 PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc), 874 NoItinerary, "${:comment} tMOVCCr $cc", 875 [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>; 876 877 878// 16-bit movcc in IT blocks for Thumb2. 879let neverHasSideEffects = 1 in { 880def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr, 881 "mov", "\t$dst, $rhs", []>, 882 T1Special<{1,0,?,?}>; 883 884def tMOVCCi : T1pIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMOVi, 885 "mov", "\t$dst, $rhs", []>, 886 T1General<{1,0,0,?,?}>; 887} // neverHasSideEffects 888 889// tLEApcrel - Load a pc-relative address into a register without offending the 890// assembler. 891let neverHasSideEffects = 1 in { 892let isReMaterializable = 1 in 893def tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi, 894 "adr$p\t$dst, #$label", []>, 895 T1Encoding<{1,0,1,0,0,?}>; // A6.2 & A8.6.10 896 897} // neverHasSideEffects 898def tLEApcrelJT : T1I<(outs tGPR:$dst), 899 (ins i32imm:$label, nohash_imm:$id, pred:$p), 900 IIC_iALUi, "adr$p\t$dst, #${label}_${id}", []>, 901 T1Encoding<{1,0,1,0,0,?}>; // A6.2 & A8.6.10 902 903//===----------------------------------------------------------------------===// 904// TLS Instructions 905// 906 907// __aeabi_read_tp preserves the registers r1-r3. 908let isCall = 1, 909 Defs = [R0, LR] in { 910 def tTPsoft : TIx2<0b11110, 0b11, 1, (outs), (ins), IIC_Br, 911 "bl\t__aeabi_read_tp", 912 [(set R0, ARMthread_pointer)]>; 913} 914 915// SJLJ Exception handling intrinsics 916// eh_sjlj_setjmp() is an instruction sequence to store the return 917// address and save #0 in R0 for the non-longjmp case. 918// Since by its nature we may be coming from some other function to get 919// here, and we're using the stack frame for the containing function to 920// save/restore registers, we can't keep anything live in regs across 921// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 922// when we get here from a longjmp(). We force everthing out of registers 923// except for our own input by listing the relevant registers in Defs. By 924// doing so, we also cause the prologue/epilogue code to actively preserve 925// all of the callee-saved resgisters, which is exactly what we want. 926// $val is a scratch register for our use. 927let Defs = 928 [ R0, R1, R2, R3, R4, R5, R6, R7, R12 ], hasSideEffects = 1, 929 isBarrier = 1 in { 930 def tInt_eh_sjlj_setjmp : ThumbXI<(outs),(ins tGPR:$src, tGPR:$val), 931 AddrModeNone, SizeSpecial, NoItinerary, 932 "mov\t$val, pc\t${:comment} begin eh.setjmp\n\t" 933 "adds\t$val, #7\n\t" 934 "str\t$val, [$src, #4]\n\t" 935 "movs\tr0, #0\n\t" 936 "b\t1f\n\t" 937 "movs\tr0, #1\t${:comment} end eh.setjmp\n\t" 938 "1:", "", 939 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>; 940} 941 942// FIXME: Non-Darwin version(s) 943let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, 944 Defs = [ R7, LR, SP ] in { 945def tInt_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch), 946 AddrModeNone, SizeSpecial, IndexModeNone, 947 Pseudo, NoItinerary, 948 "ldr\t$scratch, [$src, #8]\n\t" 949 "mov\tsp, $scratch\n\t" 950 "ldr\t$scratch, [$src, #4]\n\t" 951 "ldr\tr7, [$src]\n\t" 952 "bx\t$scratch", "", 953 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>, 954 Requires<[IsThumb, IsDarwin]>; 955} 956 957//===----------------------------------------------------------------------===// 958// Non-Instruction Patterns 959// 960 961// Add with carry 962def : T1Pat<(addc tGPR:$lhs, imm0_7:$rhs), 963 (tADDi3 tGPR:$lhs, imm0_7:$rhs)>; 964def : T1Pat<(addc tGPR:$lhs, imm8_255:$rhs), 965 (tADDi8 tGPR:$lhs, imm8_255:$rhs)>; 966def : T1Pat<(addc tGPR:$lhs, tGPR:$rhs), 967 (tADDrr tGPR:$lhs, tGPR:$rhs)>; 968 969// Subtract with carry 970def : T1Pat<(addc tGPR:$lhs, imm0_7_neg:$rhs), 971 (tSUBi3 tGPR:$lhs, imm0_7_neg:$rhs)>; 972def : T1Pat<(addc tGPR:$lhs, imm8_255_neg:$rhs), 973 (tSUBi8 tGPR:$lhs, imm8_255_neg:$rhs)>; 974def : T1Pat<(subc tGPR:$lhs, tGPR:$rhs), 975 (tSUBrr tGPR:$lhs, tGPR:$rhs)>; 976 977// ConstantPool, GlobalAddress 978def : T1Pat<(ARMWrapper tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>; 979def : T1Pat<(ARMWrapper tconstpool :$dst), (tLEApcrel tconstpool :$dst)>; 980 981// JumpTable 982def : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), 983 (tLEApcrelJT tjumptable:$dst, imm:$id)>; 984 985// Direct calls 986def : T1Pat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>, 987 Requires<[IsThumb, IsNotDarwin]>; 988def : T1Pat<(ARMtcall texternalsym:$func), (tBLr9 texternalsym:$func)>, 989 Requires<[IsThumb, IsDarwin]>; 990 991def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>, 992 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 993def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi_r9 texternalsym:$func)>, 994 Requires<[IsThumb, HasV5T, IsDarwin]>; 995 996// Indirect calls to ARM routines 997def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>, 998 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 999def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr_r9 GPR:$dst)>, 1000 Requires<[IsThumb, HasV5T, IsDarwin]>; 1001 1002// zextload i1 -> zextload i8 1003def : T1Pat<(zextloadi1 t_addrmode_s1:$addr), 1004 (tLDRB t_addrmode_s1:$addr)>; 1005 1006// extload -> zextload 1007def : T1Pat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 1008def : T1Pat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 1009def : T1Pat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>; 1010 1011// If it's impossible to use [r,r] address mode for sextload, select to 1012// ldr{b|h} + sxt{b|h} instead. 1013def : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 1014 (tSXTB (tLDRB t_addrmode_s1:$addr))>, 1015 Requires<[IsThumb1Only, HasV6]>; 1016def : T1Pat<(sextloadi16 t_addrmode_s2:$addr), 1017 (tSXTH (tLDRH t_addrmode_s2:$addr))>, 1018 Requires<[IsThumb1Only, HasV6]>; 1019 1020def : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 1021 (tASRri (tLSLri (tLDRB t_addrmode_s1:$addr), 24), 24)>; 1022def : T1Pat<(sextloadi16 t_addrmode_s1:$addr), 1023 (tASRri (tLSLri (tLDRH t_addrmode_s1:$addr), 16), 16)>; 1024 1025// Large immediate handling. 1026 1027// Two piece imms. 1028def : T1Pat<(i32 thumb_immshifted:$src), 1029 (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)), 1030 (thumb_immshifted_shamt imm:$src))>; 1031 1032def : T1Pat<(i32 imm0_255_comp:$src), 1033 (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>; 1034 1035// Pseudo instruction that combines ldr from constpool and add pc. This should 1036// be expanded into two instructions late to allow if-conversion and 1037// scheduling. 1038let isReMaterializable = 1 in 1039def tLDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp), 1040 NoItinerary, 1041 "${:comment} ldr.n\t$dst, $addr\n$cp:\n\tadd\t$dst, pc", 1042 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)), 1043 imm:$cp))]>, 1044 Requires<[IsThumb1Only]>; 1045