ARMInstrThumb.td revision 67077419c63d7714f8254cca12489e7a13e8684f
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 : 129 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary, 130 [(ARMcallseq_end imm:$amt1, imm:$amt2)]>, 131 Requires<[IsThumb, IsThumb1Only]>; 132 133def tADJCALLSTACKDOWN : 134 PseudoInst<(outs), (ins i32imm:$amt), NoItinerary, 135 [(ARMcallseq_start imm:$amt)]>, 136 Requires<[IsThumb, IsThumb1Only]>; 137} 138 139class T1Disassembly<bits<2> op1, bits<8> op2> 140 : T1Encoding<0b101111> { 141 let Inst{9-8} = op1; 142 let Inst{7-0} = op2; 143} 144 145def tNOP : T1pI<(outs), (ins), NoItinerary, "nop", "", 146 [/* For disassembly only; pattern left blank */]>, 147 T1Disassembly<0b11, 0x00>; // A8.6.110 148 149def tYIELD : T1pI<(outs), (ins), NoItinerary, "yield", "", 150 [/* For disassembly only; pattern left blank */]>, 151 T1Disassembly<0b11, 0x10>; // A8.6.410 152 153def tWFE : T1pI<(outs), (ins), NoItinerary, "wfe", "", 154 [/* For disassembly only; pattern left blank */]>, 155 T1Disassembly<0b11, 0x20>; // A8.6.408 156 157def tWFI : T1pI<(outs), (ins), NoItinerary, "wfi", "", 158 [/* For disassembly only; pattern left blank */]>, 159 T1Disassembly<0b11, 0x30>; // A8.6.409 160 161def tSEV : T1pI<(outs), (ins), NoItinerary, "sev", "", 162 [/* For disassembly only; pattern left blank */]>, 163 T1Disassembly<0b11, 0x40>; // A8.6.157 164 165// The i32imm operand $val can be used by a debugger to store more information 166// about the breakpoint. 167def tBKPT : T1I<(outs), (ins i32imm:$val), NoItinerary, "bkpt\t$val", 168 [/* For disassembly only; pattern left blank */]>, 169 T1Disassembly<0b10, {?,?,?,?,?,?,?,?}> { 170 // A8.6.22 171 bits<8> val; 172 let Inst{7-0} = val; 173} 174 175def tSETENDBE : T1I<(outs), (ins), NoItinerary, "setend\tbe", 176 [/* For disassembly only; pattern left blank */]>, 177 T1Encoding<0b101101> { 178 // A8.6.156 179 let Inst{9-5} = 0b10010; 180 let Inst{4} = 1; 181 let Inst{3} = 1; // Big-Endian 182 let Inst{2-0} = 0b000; 183} 184 185def tSETENDLE : T1I<(outs), (ins), NoItinerary, "setend\tle", 186 [/* For disassembly only; pattern left blank */]>, 187 T1Encoding<0b101101> { 188 // A8.6.156 189 let Inst{9-5} = 0b10010; 190 let Inst{4} = 1; 191 let Inst{3} = 0; // Little-Endian 192 let Inst{2-0} = 0b000; 193} 194 195// Change Processor State is a system instruction -- for disassembly only. 196// The singleton $opt operand contains the following information: 197// opt{4-0} = mode ==> don't care 198// opt{5} = changemode ==> 0 (false for 16-bit Thumb instr) 199// opt{8-6} = AIF from Inst{2-0} 200// opt{10-9} = 1:imod from Inst{4} with 0b10 as enable and 0b11 as disable 201// 202// The opt{4-0} and opt{5} sub-fields are to accommodate 32-bit Thumb and ARM 203// CPS which has more options. 204def tCPS : T1I<(outs), (ins cps_opt:$opt), NoItinerary, "cps$opt", 205 [/* For disassembly only; pattern left blank */]>, 206 T1Misc<0b0110011> { 207 // A8.6.38 & B6.1.1 208 let Inst{3} = 0; // FIXME: Finish encoding. 209} 210 211// For both thumb1 and thumb2. 212let isNotDuplicable = 1, isCodeGenOnly = 1 in 213def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr, "", 214 [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>, 215 T1Special<{0,0,?,?}> { 216 // A8.6.6 Rm = pc 217 bits<3> dst; 218 let Inst{6-3} = 0b1111; 219 let Inst{2-0} = dst; 220} 221 222// PC relative add. 223def tADDrPCi : T1I<(outs tGPR:$dst), (ins t_imm_s4:$rhs), IIC_iALUi, 224 "add\t$dst, pc, $rhs", []>, 225 T1Encoding<{1,0,1,0,0,?}> { 226 // A6.2 & A8.6.10 227 bits<3> dst; 228 bits<8> rhs; 229 let Inst{10-8} = dst; 230 let Inst{7-0} = rhs; 231} 232 233// ADD <Rd>, sp, #<imm8> 234// This is rematerializable, which is particularly useful for taking the 235// address of locals. 236let isReMaterializable = 1 in 237def tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, t_imm_s4:$rhs), IIC_iALUi, 238 "add\t$dst, $sp, $rhs", []>, 239 T1Encoding<{1,0,1,0,1,?}> { 240 // A6.2 & A8.6.8 241 bits<3> dst; 242 bits<8> rhs; 243 let Inst{10-8} = dst; 244 let Inst{7-0} = rhs; 245} 246 247// ADD sp, sp, #<imm7> 248def tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), IIC_iALUi, 249 "add\t$dst, $rhs", []>, 250 T1Misc<{0,0,0,0,0,?,?}> { 251 // A6.2.5 & A8.6.8 252 bits<7> rhs; 253 let Inst{6-0} = rhs; 254} 255 256// SUB sp, sp, #<imm7> 257// FIXME: The encoding and the ASM string don't match up. 258def tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), IIC_iALUi, 259 "sub\t$dst, $rhs", []>, 260 T1Misc<{0,0,0,0,1,?,?}> { 261 // A6.2.5 & A8.6.214 262 bits<7> rhs; 263 let Inst{6-0} = rhs; 264} 265 266// ADD <Rm>, sp 267def tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 268 "add\t$dst, $rhs", []>, 269 T1Special<{0,0,?,?}> { 270 // A8.6.9 Encoding T1 271 bits<4> dst; 272 let Inst{7} = dst{3}; 273 let Inst{6-3} = 0b1101; 274 let Inst{2-0} = dst{2-0}; 275} 276 277// ADD sp, <Rm> 278def tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 279 "add\t$dst, $rhs", []>, 280 T1Special<{0,0,?,?}> { 281 // A8.6.9 Encoding T2 282 bits<4> dst; 283 let Inst{7} = 1; 284 let Inst{6-3} = dst; 285 let Inst{2-0} = 0b101; 286} 287 288//===----------------------------------------------------------------------===// 289// Control Flow Instructions. 290// 291 292let isReturn = 1, isTerminator = 1, isBarrier = 1 in { 293 def tBX_RET : TI<(outs), (ins), IIC_Br, "bx\tlr", 294 [(ARMretflag)]>, 295 T1Special<{1,1,0,?}> { 296 // A6.2.3 & A8.6.25 297 let Inst{6-3} = 0b1110; // Rm = lr 298 let Inst{2-0} = 0b000; 299 } 300 301 // Alternative return instruction used by vararg functions. 302 def tBX_RET_vararg : TI<(outs), (ins tGPR:$Rm), 303 IIC_Br, "bx\t$Rm", 304 []>, 305 T1Special<{1,1,0,?}> { 306 // A6.2.3 & A8.6.25 307 bits<4> Rm; 308 let Inst{6-3} = Rm; 309 let Inst{2-0} = 0b000; 310 } 311} 312 313// Indirect branches 314let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 315 def tBRIND : TI<(outs), (ins GPR:$Rm), IIC_Br, "mov\tpc, $Rm", 316 [(brind GPR:$Rm)]>, 317 T1Special<{1,0,?,?}> { 318 // A8.6.97 319 bits<4> Rm; 320 let Inst{7} = 1; // <Rd> = Inst{7:2-0} = pc 321 let Inst{6-3} = Rm; 322 let Inst{2-0} = 0b111; 323 } 324} 325 326// FIXME: remove when we have a way to marking a MI with these properties. 327let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 328 hasExtraDefRegAllocReq = 1 in 329def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$regs, variable_ops), 330 IIC_iPop_Br, 331 "pop${p}\t$regs", []>, 332 T1Misc<{1,1,0,?,?,?,?}> { 333 // A8.6.121 334 bits<16> regs; 335 let Inst{8} = regs{15}; // registers = P:'0000000':register_list 336 let Inst{7-0} = regs{7-0}; 337} 338 339// All calls clobber the non-callee saved registers. SP is marked as 340// a use to prevent stack-pointer assignments that appear immediately 341// before calls from potentially appearing dead. 342let isCall = 1, 343 // On non-Darwin platforms R9 is callee-saved. 344 Defs = [R0, R1, R2, R3, R12, LR, 345 D0, D1, D2, D3, D4, D5, D6, D7, 346 D16, D17, D18, D19, D20, D21, D22, D23, 347 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR], 348 Uses = [SP] in { 349 // Also used for Thumb2 350 def tBL : TIx2<0b11110, 0b11, 1, 351 (outs), (ins i32imm:$func, variable_ops), IIC_Br, 352 "bl\t$func", 353 [(ARMtcall tglobaladdr:$func)]>, 354 Requires<[IsThumb, IsNotDarwin]>; 355 356 // ARMv5T and above, also used for Thumb2 357 def tBLXi : TIx2<0b11110, 0b11, 0, 358 (outs), (ins i32imm:$func, variable_ops), IIC_Br, 359 "blx\t$func", 360 [(ARMcall tglobaladdr:$func)]>, 361 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 362 363 // Also used for Thumb2 364 def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 365 "blx\t$func", 366 [(ARMtcall GPR:$func)]>, 367 Requires<[IsThumb, HasV5T, IsNotDarwin]>, 368 T1Special<{1,1,1,?}>; // A6.2.3 & A8.6.24; 369 370 // ARMv4T 371 let isCodeGenOnly = 1 in 372 def tBX : TIx2<{?,?,?,?,?}, {?,?}, ?, 373 (outs), (ins tGPR:$func, variable_ops), IIC_Br, 374 "mov\tlr, pc\n\tbx\t$func", 375 [(ARMcall_nolink tGPR:$func)]>, 376 Requires<[IsThumb, IsThumb1Only, IsNotDarwin]>; 377} 378 379let isCall = 1, 380 // On Darwin R9 is call-clobbered. 381 // R7 is marked as a use to prevent frame-pointer assignments from being 382 // moved above / below calls. 383 Defs = [R0, R1, R2, R3, R9, R12, LR, 384 D0, D1, D2, D3, D4, D5, D6, D7, 385 D16, D17, D18, D19, D20, D21, D22, D23, 386 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR], 387 Uses = [R7, SP] in { 388 // Also used for Thumb2 389 def tBLr9 : TIx2<0b11110, 0b11, 1, 390 (outs), (ins pred:$p, i32imm:$func, variable_ops), IIC_Br, 391 "bl${p}\t$func", 392 [(ARMtcall tglobaladdr:$func)]>, 393 Requires<[IsThumb, IsDarwin]>; 394 395 // ARMv5T and above, also used for Thumb2 396 def tBLXi_r9 : TIx2<0b11110, 0b11, 0, 397 (outs), (ins pred:$p, i32imm:$func, variable_ops), IIC_Br, 398 "blx${p}\t$func", 399 [(ARMcall tglobaladdr:$func)]>, 400 Requires<[IsThumb, HasV5T, IsDarwin]>; 401 402 // Also used for Thumb2 403 def tBLXr_r9 : TI<(outs), (ins pred:$p, GPR:$func, variable_ops), IIC_Br, 404 "blx${p}\t$func", 405 [(ARMtcall GPR:$func)]>, 406 Requires<[IsThumb, HasV5T, IsDarwin]>, 407 T1Special<{1,1,1,?}> { 408 // A6.2.3 & A8.6.24 409 bits<4> func; 410 let Inst{6-3} = func; 411 let Inst{2-0} = 0b000; 412 } 413 414 // ARMv4T 415 let isCodeGenOnly = 1 in 416 def tBXr9 : TIx2<{?,?,?,?,?}, {?,?}, ?, 417 (outs), (ins tGPR:$func, variable_ops), IIC_Br, 418 "mov\tlr, pc\n\tbx\t$func", 419 [(ARMcall_nolink tGPR:$func)]>, 420 Requires<[IsThumb, IsThumb1Only, IsDarwin]>; 421} 422 423let isBranch = 1, isTerminator = 1 in { 424 let isBarrier = 1 in { 425 let isPredicable = 1 in 426 def tB : T1I<(outs), (ins brtarget:$target), IIC_Br, 427 "b\t$target", [(br bb:$target)]>, 428 T1Encoding<{1,1,1,0,0,?}>; 429 430 // Far jump 431 let Defs = [LR] in 432 def tBfar : TIx2<0b11110, 0b11, 1, (outs), (ins brtarget:$target), IIC_Br, 433 "bl\t$target",[]>; 434 435 def tBR_JTr : tPseudoInst<(outs), 436 (ins tGPR:$target, i32imm:$jt, i32imm:$id), 437 Size2Bytes, IIC_Br, 438 [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]> { 439 list<Predicate> Predicates = [IsThumb, IsThumb1Only]; 440 } 441 } 442} 443 444// FIXME: should be able to write a pattern for ARMBrcond, but can't use 445// a two-value operand where a dag node expects two operands. :( 446let isBranch = 1, isTerminator = 1 in 447 def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br, 448 "b$cc\t$target", 449 [/*(ARMbrcond bb:$target, imm:$cc)*/]>, 450 T1Encoding<{1,1,0,1,?,?}>; 451 452// Compare and branch on zero / non-zero 453let isBranch = 1, isTerminator = 1 in { 454 def tCBZ : T1I<(outs), (ins tGPR:$Rn, brtarget:$target), IIC_Br, 455 "cbz\t$Rn, $target", []>, 456 T1Misc<{0,0,?,1,?,?,?}> { 457 // A8.6.27 458 bits<6> target; 459 bits<3> Rn; 460 let Inst{9} = target{5}; 461 let Inst{7-3} = target{4-0}; 462 let Inst{2-0} = Rn; 463 } 464 465 def tCBNZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br, 466 "cbnz\t$cmp, $target", []>, 467 T1Misc<{1,0,?,1,?,?,?}> { 468 // A8.6.27 469 bits<6> target; 470 bits<3> Rn; 471 let Inst{9} = target{5}; 472 let Inst{7-3} = target{4-0}; 473 let Inst{2-0} = Rn; 474 } 475} 476 477// A8.6.218 Supervisor Call (Software Interrupt) -- for disassembly only 478// A8.6.16 B: Encoding T1 479// If Inst{11-8} == 0b1111 then SEE SVC 480let isCall = 1, Uses = [SP] in 481def tSVC : T1pI<(outs), (ins i32imm:$imm), IIC_Br, 482 "svc", "\t$imm", []>, Encoding16 { 483 bits<8> imm; 484 let Inst{15-12} = 0b1101; 485 let Inst{11-8} = 0b1111; 486 let Inst{7-0} = imm; 487} 488 489// A8.6.16 B: Encoding T1 490// If Inst{11-8} == 0b1110 then UNDEFINED 491let isBarrier = 1, isTerminator = 1 in 492def tTRAP : TI<(outs), (ins), IIC_Br, 493 "trap", [(trap)]>, Encoding16 { 494 let Inst = 0xdefe; 495} 496 497//===----------------------------------------------------------------------===// 498// Load Store Instructions. 499// 500 501let canFoldAsLoad = 1, isReMaterializable = 1 in 502def tLDR : T1pI4<(outs tGPR:$Rt), (ins t_addrmode_s4:$addr), IIC_iLoad_r, 503 "ldr", "\t$Rt, $addr", 504 [(set tGPR:$Rt, (load t_addrmode_s4:$addr))]>, 505 T1LdSt<0b100>; 506 507def tLDRi: T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoad_r, 508 "ldr", "\t$dst, $addr", 509 []>, 510 T1LdSt4Imm<{1,?,?}>; 511 512def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoad_bh_r, 513 "ldrb", "\t$dst, $addr", 514 [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>, 515 T1LdSt<0b110>; 516def tLDRBi: T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoad_bh_r, 517 "ldrb", "\t$dst, $addr", 518 []>, 519 T1LdSt1Imm<{1,?,?}>; 520 521def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoad_bh_r, 522 "ldrh", "\t$dst, $addr", 523 [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>, 524 T1LdSt<0b101>; 525def tLDRHi: T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoad_bh_r, 526 "ldrh", "\t$dst, $addr", 527 []>, 528 T1LdSt2Imm<{1,?,?}>; 529 530let AddedComplexity = 10 in 531def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoad_bh_r, 532 "ldrsb", "\t$dst, $addr", 533 [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>, 534 T1LdSt<0b011>; 535 536let AddedComplexity = 10 in 537def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoad_bh_r, 538 "ldrsh", "\t$dst, $addr", 539 [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>, 540 T1LdSt<0b111>; 541 542let canFoldAsLoad = 1 in 543def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoad_i, 544 "ldr", "\t$dst, $addr", 545 [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>, 546 T1LdStSP<{1,?,?}>; 547 548// Special instruction for restore. It cannot clobber condition register 549// when it's expanded by eliminateCallFramePseudoInstr(). 550let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1 in 551def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoad_i, 552 "ldr", "\t$dst, $addr", []>, 553 T1LdStSP<{1,?,?}>; 554 555// Load tconstpool 556// FIXME: Use ldr.n to work around a Darwin assembler bug. 557let canFoldAsLoad = 1, isReMaterializable = 1 in 558def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoad_i, 559 "ldr", ".n\t$dst, $addr", 560 [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>, 561 T1Encoding<{0,1,0,0,1,?}>; // A6.2 & A8.6.59 562 563// Special LDR for loads from non-pc-relative constpools. 564let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1, 565 isReMaterializable = 1 in 566def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoad_i, 567 "ldr", "\t$dst, $addr", []>, 568 T1LdStSP<{1,?,?}>; 569 570def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStore_r, 571 "str", "\t$src, $addr", 572 [(store tGPR:$src, t_addrmode_s4:$addr)]>, 573 T1LdSt<0b000>; 574def tSTRi: T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStore_r, 575 "str", "\t$src, $addr", 576 []>, 577 T1LdSt4Imm<{0,?,?}>; 578 579def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStore_bh_r, 580 "strb", "\t$src, $addr", 581 [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>, 582 T1LdSt<0b010>; 583def tSTRBi: T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStore_bh_r, 584 "strb", "\t$src, $addr", 585 []>, 586 T1LdSt1Imm<{0,?,?}>; 587 588def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStore_bh_r, 589 "strh", "\t$src, $addr", 590 [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>, 591 T1LdSt<0b001>; 592def tSTRHi: T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStore_bh_r, 593 "strh", "\t$src, $addr", 594 []>, 595 T1LdSt2Imm<{0,?,?}>; 596 597def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStore_i, 598 "str", "\t$src, $addr", 599 [(store tGPR:$src, t_addrmode_sp:$addr)]>, 600 T1LdStSP<{0,?,?}>; 601 602let mayStore = 1, neverHasSideEffects = 1 in { 603// Special instruction for spill. It cannot clobber condition register 604// when it's expanded by eliminateCallFramePseudoInstr(). 605def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStore_i, 606 "str", "\t$src, $addr", []>, 607 T1LdStSP<{0,?,?}>; 608} 609 610//===----------------------------------------------------------------------===// 611// Load / store multiple Instructions. 612// 613 614multiclass thumb_ldst_mult<string asm, InstrItinClass itin, 615 InstrItinClass itin_upd, bits<6> T1Enc, 616 bit L_bit> { 617 def IA : 618 T1I<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 619 itin, !strconcat(asm, "ia${p}\t$Rn, $regs"), []>, 620 T1Encoding<T1Enc> { 621 bits<3> Rn; 622 bits<8> regs; 623 let Inst{10-8} = Rn; 624 let Inst{7-0} = regs; 625 } 626 def IA_UPD : 627 T1It<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 628 itin_upd, !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []>, 629 T1Encoding<T1Enc> { 630 bits<3> Rn; 631 bits<8> regs; 632 let Inst{10-8} = Rn; 633 let Inst{7-0} = regs; 634 } 635} 636 637// These require base address to be written back or one of the loaded regs. 638let neverHasSideEffects = 1 in { 639 640let mayLoad = 1, hasExtraDefRegAllocReq = 1 in 641defm tLDM : thumb_ldst_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 642 {1,1,0,0,1,?}, 1>; 643 644let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 645defm tSTM : thumb_ldst_mult<"stm", IIC_iStore_m, IIC_iStore_mu, 646 {1,1,0,0,0,?}, 0>; 647 648} // neverHasSideEffects 649 650let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in 651def tPOP : T1I<(outs), (ins pred:$p, reglist:$regs, variable_ops), 652 IIC_iPop, 653 "pop${p}\t$regs", []>, 654 T1Misc<{1,1,0,?,?,?,?}> { 655 bits<16> regs; 656 let Inst{8} = regs{15}; 657 let Inst{7-0} = regs{7-0}; 658} 659 660let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in 661def tPUSH : T1I<(outs), (ins pred:$p, reglist:$regs, variable_ops), 662 IIC_iStore_m, 663 "push${p}\t$regs", []>, 664 T1Misc<{0,1,0,?,?,?,?}> { 665 bits<16> regs; 666 let Inst{8} = regs{14}; 667 let Inst{7-0} = regs{7-0}; 668} 669 670//===----------------------------------------------------------------------===// 671// Arithmetic Instructions. 672// 673 674// Add with carry register 675let isCommutable = 1, Uses = [CPSR] in 676def tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 677 "adc", "\t$dst, $rhs", 678 [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>, 679 T1DataProcessing<0b0101> { 680 // A8.6.2 681 bits<3> lhs; 682 bits<3> rhs; 683 let Inst{5-3} = lhs; 684 let Inst{2-0} = rhs; 685} 686 687// Add immediate 688def tADDi3 : T1sI<(outs tGPR:$Rd), (ins tGPR:$Rn, i32imm:$imm3), IIC_iALUi, 689 "add", "\t$Rd, $Rn, $imm3", 690 [(set tGPR:$Rd, (add tGPR:$Rn, imm0_7:$imm3))]>, 691 T1General<0b01110> { 692 // A8.6.4 T1 693 bits<3> Rd; 694 bits<3> Rn; 695 bits<3> imm3; 696 let Inst{8-6} = imm3; 697 let Inst{5-3} = Rn; 698 let Inst{2-0} = Rd; 699} 700 701def tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 702 "add", "\t$dst, $rhs", 703 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>, 704 T1General<{1,1,0,?,?}> { 705 // A8.6.4 T2 706 bits<3> lhs; 707 bits<8> rhs; 708 let Inst{10-8} = lhs; 709 let Inst{7-0} = rhs; 710} 711 712// Add register 713let isCommutable = 1 in 714def tADDrr : T1sI<(outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm), IIC_iALUr, 715 "add", "\t$Rd, $Rn, $Rm", 716 [(set tGPR:$Rd, (add tGPR:$Rn, tGPR:$Rm))]>, 717 T1General<0b01100> { 718 // A8.6.6 T1 719 bits<3> Rm; 720 bits<3> Rn; 721 bits<3> Rd; 722 let Inst{8-6} = Rm; 723 let Inst{5-3} = Rn; 724 let Inst{2-0} = Rd; 725} 726 727let neverHasSideEffects = 1 in 728def tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr, 729 "add", "\t$dst, $rhs", []>, 730 T1Special<{0,0,?,?}> { 731 // A8.6.6 T2 732 bits<4> dst; 733 bits<4> rhs; 734 let Inst{6-3} = rhs; 735 let Inst{7} = dst{3}; 736 let Inst{2-0} = dst{2-0}; 737} 738 739// AND register 740let isCommutable = 1 in 741def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iBITr, 742 "and", "\t$dst, $rhs", 743 [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>, 744 T1DataProcessing<0b0000> { 745 // A8.6.12 746 bits<3> rhs; 747 bits<3> dst; 748 let Inst{5-3} = rhs; 749 let Inst{2-0} = dst; 750} 751 752// ASR immediate 753def tASRri : T1sI<(outs tGPR:$Rd), (ins tGPR:$Rm, i32imm:$imm5), IIC_iMOVsi, 754 "asr", "\t$Rd, $Rm, $imm5", 755 [(set tGPR:$Rd, (sra tGPR:$Rm, (i32 imm:$imm5)))]>, 756 T1General<{0,1,0,?,?}> { 757 // A8.6.14 758 bits<3> Rd; 759 bits<3> Rm; 760 bits<5> imm5; 761 let Inst{10-6} = imm5; 762 let Inst{5-3} = Rm; 763 let Inst{2-0} = Rd; 764} 765 766// ASR register 767def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 768 "asr", "\t$dst, $rhs", 769 [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>, 770 T1DataProcessing<0b0100> { 771 // A8.6.15 772 bits<3> rhs; 773 bits<3> dst; 774 let Inst{5-3} = rhs; 775 let Inst{2-0} = dst; 776} 777 778// BIC register 779def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iBITr, 780 "bic", "\t$dst, $rhs", 781 [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>, 782 T1DataProcessing<0b1110> { 783 // A8.6.20 784 bits<3> dst; 785 bits<3> rhs; 786 let Inst{5-3} = rhs; 787 let Inst{2-0} = dst; 788} 789 790// CMN register 791let isCompare = 1, Defs = [CPSR] in { 792//FIXME: Disable CMN, as CCodes are backwards from compare expectations 793// Compare-to-zero still works out, just not the relationals 794//def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr, 795// "cmn", "\t$lhs, $rhs", 796// [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>, 797// T1DataProcessing<0b1011>; 798def tCMNz : T1pI<(outs), (ins tGPR:$Rn, tGPR:$Rm), IIC_iCMPr, 799 "cmn", "\t$Rn, $Rm", 800 [(ARMcmpZ tGPR:$Rn, (ineg tGPR:$Rm))]>, 801 T1DataProcessing<0b1011> { 802 // A8.6.33 803 bits<3> Rm; 804 bits<3> Rn; 805 let Inst{5-3} = Rm; 806 let Inst{2-0} = Rn; 807} 808} 809 810// CMP immediate 811let isCompare = 1, Defs = [CPSR] in { 812def tCMPi8 : T1pI<(outs), (ins tGPR:$Rn, i32imm:$imm8), IIC_iCMPi, 813 "cmp", "\t$Rn, $imm8", 814 [(ARMcmp tGPR:$Rn, imm0_255:$imm8)]>, 815 T1General<{1,0,1,?,?}> { 816 // A8.6.35 817 bits<3> Rn; 818 bits<8> imm8; 819 let Inst{10-8} = Rn; 820 let Inst{7-0} = imm8; 821} 822 823def tCMPzi8 : T1pI<(outs), (ins tGPR:$Rn, i32imm:$imm8), IIC_iCMPi, 824 "cmp", "\t$Rn, $imm8", 825 [(ARMcmpZ tGPR:$Rn, imm0_255:$imm8)]>, 826 T1General<{1,0,1,?,?}> { 827 // A8.6.35 828 bits<3> Rn; 829 let Inst{10-8} = Rn; 830 let Inst{7-0} = 0x00; 831} 832 833// CMP register 834def tCMPr : T1pI<(outs), (ins tGPR:$Rn, tGPR:$Rm), IIC_iCMPr, 835 "cmp", "\t$Rn, $Rm", 836 [(ARMcmp tGPR:$Rn, tGPR:$Rm)]>, 837 T1DataProcessing<0b1010> { 838 // A8.6.36 T1 839 bits<3> Rm; 840 bits<3> Rn; 841 let Inst{5-3} = Rm; 842 let Inst{2-0} = Rn; 843} 844def tCMPzr : T1pI<(outs), (ins tGPR:$Rn, tGPR:$Rm), IIC_iCMPr, 845 "cmp", "\t$Rn, $Rm", 846 [(ARMcmpZ tGPR:$Rn, tGPR:$Rm)]>, 847 T1DataProcessing<0b1010> { 848 // A8.6.36 T1 849 bits<3> Rm; 850 bits<3> Rn; 851 let Inst{5-3} = Rm; 852 let Inst{2-0} = Rn; 853} 854 855def tCMPhir : T1pI<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_iCMPr, 856 "cmp", "\t$Rn, $Rm", []>, 857 T1Special<{0,1,?,?}> { 858 // A8.6.36 T2 859 bits<4> Rm; 860 bits<4> Rn; 861 let Inst{7} = Rn{3}; 862 let Inst{6-3} = Rm; 863 let Inst{2-0} = Rn{2-0}; 864} 865def tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr, 866 "cmp", "\t$lhs, $rhs", []>, 867 T1Special<{0,1,?,?}> { 868 // A8.6.36 T2 869 bits<4> Rm; 870 bits<4> Rn; 871 let Inst{7} = Rn{3}; 872 let Inst{6-3} = Rm; 873 let Inst{2-0} = Rn{2-0}; 874} 875 876} // isCompare = 1, Defs = [CPSR] 877 878 879// XOR register 880let isCommutable = 1 in 881def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iBITr, 882 "eor", "\t$dst, $rhs", 883 [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>, 884 T1DataProcessing<0b0001> { 885 // A8.6.45 886 bits<3> dst; 887 bits<3> rhs; 888 let Inst{5-3} = rhs; 889 let Inst{2-0} = dst; 890} 891 892// LSL immediate 893def tLSLri : T1sI<(outs tGPR:$Rd), (ins tGPR:$Rm, i32imm:$imm5), IIC_iMOVsi, 894 "lsl", "\t$Rd, $Rm, $imm5", 895 [(set tGPR:$Rd, (shl tGPR:$Rm, (i32 imm:$imm5)))]>, 896 T1General<{0,0,0,?,?}> { 897 // A8.6.88 898 bits<3> Rd; 899 bits<3> Rm; 900 bits<5> imm5; 901 let Inst{10-6} = imm5; 902 let Inst{5-3} = Rm; 903 let Inst{2-0} = Rd; 904} 905 906// LSL register 907def tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 908 "lsl", "\t$dst, $rhs", 909 [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>, 910 T1DataProcessing<0b0010> { 911 // A8.6.89 912 bits<3> dst; 913 bits<3> rhs; 914 let Inst{5-3} = rhs; 915 let Inst{2-0} = dst; 916} 917 918// LSR immediate 919def tLSRri : T1sI<(outs tGPR:$Rd), (ins tGPR:$Rm, i32imm:$imm5), IIC_iMOVsi, 920 "lsr", "\t$Rd, $Rm, $imm5", 921 [(set tGPR:$Rd, (srl tGPR:$Rm, (i32 imm:$imm5)))]>, 922 T1General<{0,0,1,?,?}> { 923 // A8.6.90 924 bits<3> Rd; 925 bits<3> Rm; 926 bits<5> imm5; 927 let Inst{10-6} = imm5; 928 let Inst{5-3} = Rm; 929 let Inst{2-0} = Rd; 930} 931 932// LSR register 933def tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 934 "lsr", "\t$dst, $rhs", 935 [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>, 936 T1DataProcessing<0b0011> { 937 // A8.6.91 938 bits<3> dst; 939 bits<3> rhs; 940 let Inst{5-3} = rhs; 941 let Inst{2-0} = dst; 942} 943 944// Move register 945let isMoveImm = 1 in 946def tMOVi8 : T1sI<(outs tGPR:$Rd), (ins i32imm:$imm8), IIC_iMOVi, 947 "mov", "\t$Rd, $imm8", 948 [(set tGPR:$Rd, imm0_255:$imm8)]>, 949 T1General<{1,0,0,?,?}> { 950 // A8.6.96 951 bits<3> Rd; 952 bits<8> imm8; 953 let Inst{10-8} = Rd; 954 let Inst{7-0} = imm8; 955} 956 957// TODO: A7-73: MOV(2) - mov setting flag. 958 959let neverHasSideEffects = 1 in { 960// FIXME: Make this predicable. 961def tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 962 "mov\t$dst, $src", []>, 963 T1Special<0b1000>; 964let Defs = [CPSR] in 965def tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr, 966 "movs\t$dst, $src", []>, Encoding16 { 967 let Inst{15-6} = 0b0000000000; 968} 969 970// FIXME: Make these predicable. 971def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr, 972 "mov\t$dst, $src", []>, 973 T1Special<{1,0,0,?}>; 974def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr, 975 "mov\t$dst, $src", []>, 976 T1Special<{1,0,?,0}>; 977def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, 978 "mov\t$dst, $src", []>, 979 T1Special<{1,0,?,?}>; 980} // neverHasSideEffects 981 982// multiply register 983let isCommutable = 1 in 984def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMUL32, 985 "mul", "\t$dst, $rhs, $dst", /* A8.6.105 MUL Encoding T1 */ 986 [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>, 987 T1DataProcessing<0b1101> { 988 // A8.6.105 989 bits<3> dst; 990 bits<3> rhs; 991 let Inst{5-3} = rhs; 992 let Inst{2-0} = dst; 993} 994 995// move inverse register 996def tMVN : T1sI<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iMVNr, 997 "mvn", "\t$Rd, $Rm", 998 [(set tGPR:$Rd, (not tGPR:$Rm))]>, 999 T1DataProcessing<0b1111> { 1000 // A8.6.107 1001 bits<3> Rd; 1002 bits<3> Rm; 1003 let Inst{5-3} = Rm; 1004 let Inst{2-0} = Rd; 1005} 1006 1007// Bitwise or register 1008let isCommutable = 1 in 1009def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iBITr, 1010 "orr", "\t$dst, $rhs", 1011 [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>, 1012 T1DataProcessing<0b1100> { 1013 // A8.6.114 1014 bits<3> dst; 1015 bits<3> rhs; 1016 let Inst{5-3} = rhs; 1017 let Inst{2-0} = dst; 1018} 1019 1020// Swaps 1021def tREV : T1pI<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iUNAr, 1022 "rev", "\t$Rd, $Rm", 1023 [(set tGPR:$Rd, (bswap tGPR:$Rm))]>, 1024 Requires<[IsThumb, IsThumb1Only, HasV6]>, 1025 T1Misc<{1,0,1,0,0,0,?}> { 1026 // A8.6.134 1027 bits<3> Rm; 1028 bits<3> Rd; 1029 let Inst{5-3} = Rm; 1030 let Inst{2-0} = Rd; 1031} 1032 1033def tREV16 : T1pI<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iUNAr, 1034 "rev16", "\t$Rd, $Rm", 1035 [(set tGPR:$Rd, 1036 (or (and (srl tGPR:$Rm, (i32 8)), 0xFF), 1037 (or (and (shl tGPR:$Rm, (i32 8)), 0xFF00), 1038 (or (and (srl tGPR:$Rm, (i32 8)), 0xFF0000), 1039 (and (shl tGPR:$Rm, (i32 8)), 0xFF000000)))))]>, 1040 Requires<[IsThumb, IsThumb1Only, HasV6]>, 1041 T1Misc<{1,0,1,0,0,1,?}> { 1042 // A8.6.135 1043 bits<3> Rm; 1044 bits<3> Rd; 1045 let Inst{5-3} = Rm; 1046 let Inst{2-0} = Rd; 1047} 1048 1049def tREVSH : T1pI<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iUNAr, 1050 "revsh", "\t$Rd, $Rm", 1051 [(set tGPR:$Rd, 1052 (sext_inreg 1053 (or (srl (and tGPR:$Rm, 0xFF00), (i32 8)), 1054 (shl tGPR:$Rm, (i32 8))), i16))]>, 1055 Requires<[IsThumb, IsThumb1Only, HasV6]>, 1056 T1Misc<{1,0,1,0,1,1,?}> { 1057 // A8.6.136 1058 bits<3> Rm; 1059 bits<3> Rd; 1060 let Inst{5-3} = Rm; 1061 let Inst{2-0} = Rd; 1062} 1063 1064// rotate right register 1065def tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr, 1066 "ror", "\t$dst, $rhs", 1067 [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>, 1068 T1DataProcessing<0b0111> { 1069 // A8.6.139 1070 bits<3> rhs; 1071 bits<3> dst; 1072 let Inst{5-3} = rhs; 1073 let Inst{2-0} = dst; 1074} 1075 1076// negate register 1077def tRSB : T1sI<(outs tGPR:$Rd), (ins tGPR:$Rn), IIC_iALUi, 1078 "rsb", "\t$Rd, $Rn, #0", 1079 [(set tGPR:$Rd, (ineg tGPR:$Rn))]>, 1080 T1DataProcessing<0b1001> { 1081 // A8.6.141 1082 bits<3> Rn; 1083 bits<3> Rd; 1084 let Inst{5-3} = Rn; 1085 let Inst{2-0} = Rd; 1086} 1087 1088// Subtract with carry register 1089let Uses = [CPSR] in 1090def tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr, 1091 "sbc", "\t$dst, $rhs", 1092 [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>, 1093 T1DataProcessing<0b0110> { 1094 // A8.6.151 1095 bits<3> rhs; 1096 bits<3> dst; 1097 let Inst{5-3} = rhs; 1098 let Inst{2-0} = dst; 1099} 1100 1101// Subtract immediate 1102def tSUBi3 : T1sI<(outs tGPR:$Rd), (ins tGPR:$Rn, i32imm:$imm3), IIC_iALUi, 1103 "sub", "\t$Rd, $Rn, $imm3", 1104 [(set tGPR:$Rd, (add tGPR:$Rn, imm0_7_neg:$imm3))]>, 1105 T1General<0b01111> { 1106 // A8.6.210 T1 1107 bits<3> imm3; 1108 bits<3> Rn; 1109 bits<3> Rd; 1110 let Inst{8-6} = imm3; 1111 let Inst{5-3} = Rn; 1112 let Inst{2-0} = Rd; 1113} 1114 1115def tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi, 1116 "sub", "\t$dst, $rhs", 1117 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>, 1118 T1General<{1,1,1,?,?}> { 1119 // A8.6.210 T2 1120 bits<8> rhs; 1121 bits<3> dst; 1122 let Inst{10-8} = dst; 1123 let Inst{7-0} = rhs; 1124} 1125 1126// subtract register 1127def tSUBrr : T1sI<(outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm), IIC_iALUr, 1128 "sub", "\t$Rd, $Rn, $Rm", 1129 [(set tGPR:$Rd, (sub tGPR:$Rn, tGPR:$Rm))]>, 1130 T1General<0b01101> { 1131 // A8.6.212 1132 bits<3> Rm; 1133 bits<3> Rn; 1134 bits<3> Rd; 1135 let Inst{8-6} = Rm; 1136 let Inst{5-3} = Rn; 1137 let Inst{2-0} = Rd; 1138} 1139 1140// TODO: A7-96: STMIA - store multiple. 1141 1142// sign-extend byte 1143def tSXTB : T1pI<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iUNAr, 1144 "sxtb", "\t$Rd, $Rm", 1145 [(set tGPR:$Rd, (sext_inreg tGPR:$Rm, i8))]>, 1146 Requires<[IsThumb, IsThumb1Only, HasV6]>, 1147 T1Misc<{0,0,1,0,0,1,?}> { 1148 // A8.6.222 1149 bits<3> Rm; 1150 bits<3> Rd; 1151 let Inst{5-3} = Rm; 1152 let Inst{2-0} = Rd; 1153} 1154 1155// sign-extend short 1156def tSXTH : T1pI<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iUNAr, 1157 "sxth", "\t$Rd, $Rm", 1158 [(set tGPR:$Rd, (sext_inreg tGPR:$Rm, i16))]>, 1159 Requires<[IsThumb, IsThumb1Only, HasV6]>, 1160 T1Misc<{0,0,1,0,0,0,?}> { 1161 // A8.6.224 1162 bits<3> Rm; 1163 bits<3> Rd; 1164 let Inst{5-3} = Rm; 1165 let Inst{2-0} = Rd; 1166} 1167 1168// test 1169let isCompare = 1, isCommutable = 1, Defs = [CPSR] in 1170def tTST : T1pI<(outs), (ins tGPR:$Rn, tGPR:$Rm), IIC_iTSTr, 1171 "tst", "\t$Rn, $Rm", 1172 [(ARMcmpZ (and_su tGPR:$Rn, tGPR:$Rm), 0)]>, 1173 T1DataProcessing<0b1000> { 1174 // A8.6.230 1175 bits<3> Rm; 1176 bits<3> Rn; 1177 let Inst{5-3} = Rm; 1178 let Inst{2-0} = Rn; 1179} 1180 1181// zero-extend byte 1182def tUXTB : T1pI<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iUNAr, 1183 "uxtb", "\t$Rd, $Rm", 1184 [(set tGPR:$Rd, (and tGPR:$Rm, 0xFF))]>, 1185 Requires<[IsThumb, IsThumb1Only, HasV6]>, 1186 T1Misc<{0,0,1,0,1,1,?}> { 1187 // A8.6.262 1188 bits<3> Rm; 1189 bits<3> Rd; 1190 let Inst{5-3} = Rm; 1191 let Inst{2-0} = Rd; 1192} 1193 1194// zero-extend short 1195def tUXTH : T1pI<(outs tGPR:$Rd), (ins tGPR:$Rm), IIC_iUNAr, 1196 "uxth", "\t$Rd, $Rm", 1197 [(set tGPR:$Rd, (and tGPR:$Rm, 0xFFFF))]>, 1198 Requires<[IsThumb, IsThumb1Only, HasV6]>, 1199 T1Misc<{0,0,1,0,1,0,?}> { 1200 // A8.6.264 1201 bits<3> Rm; 1202 bits<3> Rd; 1203 let Inst{5-3} = Rm; 1204 let Inst{2-0} = Rd; 1205} 1206 1207 1208// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC operation. 1209// Expanded after instruction selection into a branch sequence. 1210let usesCustomInserter = 1 in // Expanded after instruction selection. 1211 def tMOVCCr_pseudo : 1212 PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc), 1213 NoItinerary, 1214 [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>; 1215 1216 1217// 16-bit movcc in IT blocks for Thumb2. 1218let neverHasSideEffects = 1 in { 1219def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr, 1220 "mov", "\t$dst, $rhs", []>, 1221 T1Special<{1,0,?,?}> { 1222 bits<4> rhs; 1223 bits<4> dst; 1224 let Inst{7} = dst{3}; 1225 let Inst{6-3} = rhs; 1226 let Inst{2-0} = dst{2-0}; 1227} 1228 1229let isMoveImm = 1 in 1230def tMOVCCi : T1pIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMOVi, 1231 "mov", "\t$dst, $rhs", []>, 1232 T1General<{1,0,0,?,?}> { 1233 bits<8> rhs; 1234 bits<3> dst; 1235 let Inst{10-8} = dst; 1236 let Inst{7-0} = rhs; 1237} 1238 1239} // neverHasSideEffects 1240 1241// tLEApcrel - Load a pc-relative address into a register without offending the 1242// assembler. 1243let neverHasSideEffects = 1, isReMaterializable = 1 in 1244def tLEApcrel : T1I<(outs tGPR:$Rd), (ins i32imm:$label, pred:$p), IIC_iALUi, 1245 "adr${p}\t$Rd, #$label", []>, 1246 T1Encoding<{1,0,1,0,0,?}> { 1247 // A6.2 & A8.6.10 1248 bits<3> Rd; 1249 let Inst{10-8} = Rd; 1250 // FIXME: Add label encoding/fixup 1251} 1252 1253def tLEApcrelJT : T1I<(outs tGPR:$Rd), 1254 (ins i32imm:$label, nohash_imm:$id, pred:$p), 1255 IIC_iALUi, "adr${p}\t$Rd, #${label}_${id}", []>, 1256 T1Encoding<{1,0,1,0,0,?}> { 1257 // A6.2 & A8.6.10 1258 bits<3> Rd; 1259 let Inst{10-8} = Rd; 1260 // FIXME: Add label encoding/fixup 1261} 1262 1263//===----------------------------------------------------------------------===// 1264// TLS Instructions 1265// 1266 1267// __aeabi_read_tp preserves the registers r1-r3. 1268let isCall = 1, 1269 Defs = [R0, LR], Uses = [SP] in { 1270 def tTPsoft : TIx2<0b11110, 0b11, 1, (outs), (ins), IIC_Br, 1271 "bl\t__aeabi_read_tp", 1272 [(set R0, ARMthread_pointer)]>; 1273} 1274 1275// SJLJ Exception handling intrinsics 1276// eh_sjlj_setjmp() is an instruction sequence to store the return 1277// address and save #0 in R0 for the non-longjmp case. 1278// Since by its nature we may be coming from some other function to get 1279// here, and we're using the stack frame for the containing function to 1280// save/restore registers, we can't keep anything live in regs across 1281// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 1282// when we get here from a longjmp(). We force everthing out of registers 1283// except for our own input by listing the relevant registers in Defs. By 1284// doing so, we also cause the prologue/epilogue code to actively preserve 1285// all of the callee-saved resgisters, which is exactly what we want. 1286// $val is a scratch register for our use. 1287let Defs = 1288 [ R0, R1, R2, R3, R4, R5, R6, R7, R12 ], hasSideEffects = 1, 1289 isBarrier = 1, isCodeGenOnly = 1 in { 1290 def tInt_eh_sjlj_setjmp : ThumbXI<(outs),(ins tGPR:$src, tGPR:$val), 1291 AddrModeNone, SizeSpecial, NoItinerary, "", "", 1292 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>; 1293} 1294 1295// FIXME: Non-Darwin version(s) 1296let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, isCodeGenOnly = 1, 1297 Defs = [ R7, LR, SP ] in { 1298def tInt_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch), 1299 AddrModeNone, SizeSpecial, IndexModeNone, 1300 Pseudo, NoItinerary, "", "", 1301 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>, 1302 Requires<[IsThumb, IsDarwin]>; 1303} 1304 1305//===----------------------------------------------------------------------===// 1306// Non-Instruction Patterns 1307// 1308 1309// Add with carry 1310def : T1Pat<(addc tGPR:$lhs, imm0_7:$rhs), 1311 (tADDi3 tGPR:$lhs, imm0_7:$rhs)>; 1312def : T1Pat<(addc tGPR:$lhs, imm8_255:$rhs), 1313 (tADDi8 tGPR:$lhs, imm8_255:$rhs)>; 1314def : T1Pat<(addc tGPR:$lhs, tGPR:$rhs), 1315 (tADDrr tGPR:$lhs, tGPR:$rhs)>; 1316 1317// Subtract with carry 1318def : T1Pat<(addc tGPR:$lhs, imm0_7_neg:$rhs), 1319 (tSUBi3 tGPR:$lhs, imm0_7_neg:$rhs)>; 1320def : T1Pat<(addc tGPR:$lhs, imm8_255_neg:$rhs), 1321 (tSUBi8 tGPR:$lhs, imm8_255_neg:$rhs)>; 1322def : T1Pat<(subc tGPR:$lhs, tGPR:$rhs), 1323 (tSUBrr tGPR:$lhs, tGPR:$rhs)>; 1324 1325// ConstantPool, GlobalAddress 1326def : T1Pat<(ARMWrapper tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>; 1327def : T1Pat<(ARMWrapper tconstpool :$dst), (tLEApcrel tconstpool :$dst)>; 1328 1329// JumpTable 1330def : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), 1331 (tLEApcrelJT tjumptable:$dst, imm:$id)>; 1332 1333// Direct calls 1334def : T1Pat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>, 1335 Requires<[IsThumb, IsNotDarwin]>; 1336def : T1Pat<(ARMtcall texternalsym:$func), (tBLr9 texternalsym:$func)>, 1337 Requires<[IsThumb, IsDarwin]>; 1338 1339def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>, 1340 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 1341def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi_r9 texternalsym:$func)>, 1342 Requires<[IsThumb, HasV5T, IsDarwin]>; 1343 1344// Indirect calls to ARM routines 1345def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>, 1346 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 1347def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr_r9 GPR:$dst)>, 1348 Requires<[IsThumb, HasV5T, IsDarwin]>; 1349 1350// zextload i1 -> zextload i8 1351def : T1Pat<(zextloadi1 t_addrmode_s1:$addr), 1352 (tLDRB t_addrmode_s1:$addr)>; 1353 1354// extload -> zextload 1355def : T1Pat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 1356def : T1Pat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 1357def : T1Pat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>; 1358 1359// If it's impossible to use [r,r] address mode for sextload, select to 1360// ldr{b|h} + sxt{b|h} instead. 1361def : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 1362 (tSXTB (tLDRB t_addrmode_s1:$addr))>, 1363 Requires<[IsThumb, IsThumb1Only, HasV6]>; 1364def : T1Pat<(sextloadi16 t_addrmode_s2:$addr), 1365 (tSXTH (tLDRH t_addrmode_s2:$addr))>, 1366 Requires<[IsThumb, IsThumb1Only, HasV6]>; 1367 1368def : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 1369 (tASRri (tLSLri (tLDRB t_addrmode_s1:$addr), 24), 24)>; 1370def : T1Pat<(sextloadi16 t_addrmode_s1:$addr), 1371 (tASRri (tLSLri (tLDRH t_addrmode_s1:$addr), 16), 16)>; 1372 1373// Large immediate handling. 1374 1375// Two piece imms. 1376def : T1Pat<(i32 thumb_immshifted:$src), 1377 (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)), 1378 (thumb_immshifted_shamt imm:$src))>; 1379 1380def : T1Pat<(i32 imm0_255_comp:$src), 1381 (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>; 1382 1383// Pseudo instruction that combines ldr from constpool and add pc. This should 1384// be expanded into two instructions late to allow if-conversion and 1385// scheduling. 1386let isReMaterializable = 1 in 1387def tLDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp), 1388 NoItinerary, 1389 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)), 1390 imm:$cp))]>, 1391 Requires<[IsThumb, IsThumb1Only]>; 1392