ARMInstrThumb2.td revision da663f7b51acdc076eb40cbaf197816ca26ff64c
1//===- ARMInstrThumb2.td - Thumb2 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 Thumb2 instruction set. 11// 12//===----------------------------------------------------------------------===// 13 14// IT block predicate field 15def it_pred : Operand<i32> { 16 let PrintMethod = "printMandatoryPredicateOperand"; 17} 18 19// IT block condition mask 20def it_mask : Operand<i32> { 21 let PrintMethod = "printThumbITMask"; 22} 23 24// Table branch address 25def tb_addrmode : Operand<i32> { 26 let PrintMethod = "printTBAddrMode"; 27} 28 29// Shifted operands. No register controlled shifts for Thumb2. 30// Note: We do not support rrx shifted operands yet. 31def t2_so_reg : Operand<i32>, // reg imm 32 ComplexPattern<i32, 2, "SelectT2ShifterOperandReg", 33 [shl,srl,sra,rotr]> { 34 let EncoderMethod = "getT2SORegOpValue"; 35 let PrintMethod = "printT2SOOperand"; 36 let MIOperandInfo = (ops rGPR, i32imm); 37} 38 39// t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value 40def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{ 41 return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32); 42}]>; 43 44// t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value 45def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{ 46 return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32); 47}]>; 48 49// t2_so_imm - Match a 32-bit immediate operand, which is an 50// 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit 51// immediate splatted into multiple bytes of the word. t2_so_imm values are 52// represented in the imm field in the same 12-bit form that they are encoded 53// into t2_so_imm instructions: the 8-bit immediate is the least significant 54// bits [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11]. 55def t2_so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_t2_so_imm(N); }]> { 56 let EncoderMethod = "getT2SOImmOpValue"; 57} 58 59// t2_so_imm_not - Match an immediate that is a complement 60// of a t2_so_imm. 61def t2_so_imm_not : Operand<i32>, 62 PatLeaf<(imm), [{ 63 return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1; 64}], t2_so_imm_not_XFORM>; 65 66// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm. 67def t2_so_imm_neg : Operand<i32>, 68 PatLeaf<(imm), [{ 69 return ARM_AM::getT2SOImmVal(-((uint32_t)N->getZExtValue())) != -1; 70}], t2_so_imm_neg_XFORM>; 71 72// Break t2_so_imm's up into two pieces. This handles immediates with up to 16 73// bits set in them. This uses t2_so_imm2part to match and t2_so_imm2part_[12] 74// to get the first/second pieces. 75def t2_so_imm2part : Operand<i32>, 76 PatLeaf<(imm), [{ 77 return ARM_AM::isT2SOImmTwoPartVal((unsigned)N->getZExtValue()); 78 }]> { 79} 80 81def t2_so_imm2part_1 : SDNodeXForm<imm, [{ 82 unsigned V = ARM_AM::getT2SOImmTwoPartFirst((unsigned)N->getZExtValue()); 83 return CurDAG->getTargetConstant(V, MVT::i32); 84}]>; 85 86def t2_so_imm2part_2 : SDNodeXForm<imm, [{ 87 unsigned V = ARM_AM::getT2SOImmTwoPartSecond((unsigned)N->getZExtValue()); 88 return CurDAG->getTargetConstant(V, MVT::i32); 89}]>; 90 91def t2_so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{ 92 return ARM_AM::isT2SOImmTwoPartVal(-(int)N->getZExtValue()); 93 }]> { 94} 95 96def t2_so_neg_imm2part_1 : SDNodeXForm<imm, [{ 97 unsigned V = ARM_AM::getT2SOImmTwoPartFirst(-(int)N->getZExtValue()); 98 return CurDAG->getTargetConstant(V, MVT::i32); 99}]>; 100 101def t2_so_neg_imm2part_2 : SDNodeXForm<imm, [{ 102 unsigned V = ARM_AM::getT2SOImmTwoPartSecond(-(int)N->getZExtValue()); 103 return CurDAG->getTargetConstant(V, MVT::i32); 104}]>; 105 106/// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31]. 107def imm1_31 : PatLeaf<(i32 imm), [{ 108 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32; 109}]>; 110 111/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095]. 112def imm0_4095 : Operand<i32>, 113 PatLeaf<(i32 imm), [{ 114 return (uint32_t)N->getZExtValue() < 4096; 115}]>; 116 117def imm0_4095_neg : PatLeaf<(i32 imm), [{ 118 return (uint32_t)(-N->getZExtValue()) < 4096; 119}], imm_neg_XFORM>; 120 121def imm0_255_neg : PatLeaf<(i32 imm), [{ 122 return (uint32_t)(-N->getZExtValue()) < 255; 123}], imm_neg_XFORM>; 124 125def imm0_255_not : PatLeaf<(i32 imm), [{ 126 return (uint32_t)(~N->getZExtValue()) < 255; 127}], imm_comp_XFORM>; 128 129// Define Thumb2 specific addressing modes. 130 131// t2addrmode_imm12 := reg + imm12 132def t2addrmode_imm12 : Operand<i32>, 133 ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> { 134 let PrintMethod = "printAddrModeImm12Operand"; 135 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 136} 137 138// t2addrmode_imm8 := reg +/- imm8 139def t2addrmode_imm8 : Operand<i32>, 140 ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> { 141 let PrintMethod = "printT2AddrModeImm8Operand"; 142 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 143} 144 145def t2am_imm8_offset : Operand<i32>, 146 ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", 147 [], [SDNPWantRoot]> { 148 let PrintMethod = "printT2AddrModeImm8OffsetOperand"; 149} 150 151// t2addrmode_imm8s4 := reg +/- (imm8 << 2) 152def t2addrmode_imm8s4 : Operand<i32> { 153 let PrintMethod = "printT2AddrModeImm8s4Operand"; 154 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 155} 156 157def t2am_imm8s4_offset : Operand<i32> { 158 let PrintMethod = "printT2AddrModeImm8s4OffsetOperand"; 159} 160 161// t2addrmode_so_reg := reg + (reg << imm2) 162def t2addrmode_so_reg : Operand<i32>, 163 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> { 164 let PrintMethod = "printT2AddrModeSoRegOperand"; 165 let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm); 166} 167 168 169//===----------------------------------------------------------------------===// 170// Multiclass helpers... 171// 172 173 174class T2OneRegImm<dag oops, dag iops, InstrItinClass itin, 175 string opc, string asm, list<dag> pattern> 176 : T2I<oops, iops, itin, opc, asm, pattern> { 177 bits<4> Rd; 178 bits<12> imm; 179 180 let Inst{11-8} = Rd{3-0}; 181 let Inst{26} = imm{11}; 182 let Inst{14-12} = imm{10-8}; 183 let Inst{7-0} = imm{7-0}; 184} 185 186 187class T2sOneRegImm<dag oops, dag iops, InstrItinClass itin, 188 string opc, string asm, list<dag> pattern> 189 : T2sI<oops, iops, itin, opc, asm, pattern> { 190 bits<4> Rd; 191 bits<4> Rn; 192 bits<12> imm; 193 194 let Inst{11-8} = Rd{3-0}; 195 let Inst{26} = imm{11}; 196 let Inst{14-12} = imm{10-8}; 197 let Inst{7-0} = imm{7-0}; 198} 199 200class T2OneRegCmpImm<dag oops, dag iops, InstrItinClass itin, 201 string opc, string asm, list<dag> pattern> 202 : T2I<oops, iops, itin, opc, asm, pattern> { 203 bits<4> Rn; 204 bits<12> imm; 205 206 let Inst{19-16} = Rn{3-0}; 207 let Inst{26} = imm{11}; 208 let Inst{14-12} = imm{10-8}; 209 let Inst{7-0} = imm{7-0}; 210} 211 212 213class T2OneRegShiftedReg<dag oops, dag iops, InstrItinClass itin, 214 string opc, string asm, list<dag> pattern> 215 : T2I<oops, iops, itin, opc, asm, pattern> { 216 bits<4> Rd; 217 bits<12> ShiftedRm; 218 219 let Inst{11-8} = Rd{3-0}; 220 let Inst{3-0} = ShiftedRm{3-0}; 221 let Inst{5-4} = ShiftedRm{6-5}; 222 let Inst{14-12} = ShiftedRm{11-9}; 223 let Inst{7-6} = ShiftedRm{8-7}; 224} 225 226class T2sOneRegShiftedReg<dag oops, dag iops, InstrItinClass itin, 227 string opc, string asm, list<dag> pattern> 228 : T2I<oops, iops, itin, opc, asm, pattern> { 229 bits<4> Rd; 230 bits<12> ShiftedRm; 231 232 let Inst{11-8} = Rd{3-0}; 233 let Inst{3-0} = ShiftedRm{3-0}; 234 let Inst{5-4} = ShiftedRm{6-5}; 235 let Inst{14-12} = ShiftedRm{11-9}; 236 let Inst{7-6} = ShiftedRm{8-7}; 237} 238 239class T2OneRegCmpShiftedReg<dag oops, dag iops, InstrItinClass itin, 240 string opc, string asm, list<dag> pattern> 241 : T2I<oops, iops, itin, opc, asm, pattern> { 242 bits<4> Rn; 243 bits<12> ShiftedRm; 244 245 let Inst{19-16} = Rn{3-0}; 246 let Inst{3-0} = ShiftedRm{3-0}; 247 let Inst{5-4} = ShiftedRm{6-5}; 248 let Inst{14-12} = ShiftedRm{11-9}; 249 let Inst{7-6} = ShiftedRm{8-7}; 250} 251 252class T2TwoReg<dag oops, dag iops, InstrItinClass itin, 253 string opc, string asm, list<dag> pattern> 254 : T2I<oops, iops, itin, opc, asm, pattern> { 255 bits<4> Rd; 256 bits<4> Rm; 257 258 let Inst{11-8} = Rd{3-0}; 259 let Inst{3-0} = Rm{3-0}; 260} 261 262class T2sTwoReg<dag oops, dag iops, InstrItinClass itin, 263 string opc, string asm, list<dag> pattern> 264 : T2sI<oops, iops, itin, opc, asm, pattern> { 265 bits<4> Rd; 266 bits<4> Rm; 267 268 let Inst{11-8} = Rd{3-0}; 269 let Inst{3-0} = Rm{3-0}; 270} 271 272class T2TwoRegCmp<dag oops, dag iops, InstrItinClass itin, 273 string opc, string asm, list<dag> pattern> 274 : T2I<oops, iops, itin, opc, asm, pattern> { 275 bits<4> Rn; 276 bits<4> Rm; 277 278 let Inst{19-16} = Rn{3-0}; 279 let Inst{3-0} = Rm{3-0}; 280} 281 282 283class T2TwoRegImm<dag oops, dag iops, InstrItinClass itin, 284 string opc, string asm, list<dag> pattern> 285 : T2I<oops, iops, itin, opc, asm, pattern> { 286 bits<4> Rd; 287 bits<4> Rm; 288 289 let Inst{11-8} = Rd{3-0}; 290 let Inst{3-0} = Rm{3-0}; 291} 292 293class T2sTwoRegImm<dag oops, dag iops, InstrItinClass itin, 294 string opc, string asm, list<dag> pattern> 295 : T2sI<oops, iops, itin, opc, asm, pattern> { 296 bits<4> Rd; 297 bits<4> Rn; 298 bits<12> imm; 299 300 let Inst{11-8} = Rd{3-0}; 301 let Inst{19-16} = Rn{3-0}; 302 let Inst{26} = imm{11}; 303 let Inst{14-12} = imm{10-8}; 304 let Inst{7-0} = imm{7-0}; 305} 306 307class T2TwoRegShiftImm<dag oops, dag iops, InstrItinClass itin, 308 string opc, string asm, list<dag> pattern> 309 : T2I<oops, iops, itin, opc, asm, pattern> { 310 bits<4> Rd; 311 bits<4> Rm; 312 bits<5> imm; 313 314 let Inst{11-8} = Rd{3-0}; 315 let Inst{3-0} = Rm{3-0}; 316 let Inst{14-12} = imm{4-2}; 317 let Inst{7-6} = imm{1-0}; 318} 319 320class T2sTwoRegShiftImm<dag oops, dag iops, InstrItinClass itin, 321 string opc, string asm, list<dag> pattern> 322 : T2sI<oops, iops, itin, opc, asm, pattern> { 323 bits<4> Rd; 324 bits<4> Rm; 325 bits<5> imm; 326 327 let Inst{11-8} = Rd{3-0}; 328 let Inst{3-0} = Rm{3-0}; 329 let Inst{14-12} = imm{4-2}; 330 let Inst{7-6} = imm{1-0}; 331} 332 333class T2ThreeReg<dag oops, dag iops, InstrItinClass itin, 334 string opc, string asm, list<dag> pattern> 335 : T2I<oops, iops, itin, opc, asm, pattern> { 336 bits<4> Rd; 337 bits<4> Rn; 338 bits<4> Rm; 339 340 let Inst{11-8} = Rd{3-0}; 341 let Inst{19-16} = Rn{3-0}; 342 let Inst{3-0} = Rm{3-0}; 343} 344 345class T2sThreeReg<dag oops, dag iops, InstrItinClass itin, 346 string opc, string asm, list<dag> pattern> 347 : T2sI<oops, iops, itin, opc, asm, pattern> { 348 bits<4> Rd; 349 bits<4> Rn; 350 bits<4> Rm; 351 352 let Inst{11-8} = Rd{3-0}; 353 let Inst{19-16} = Rn{3-0}; 354 let Inst{3-0} = Rm{3-0}; 355} 356 357class T2TwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin, 358 string opc, string asm, list<dag> pattern> 359 : T2I<oops, iops, itin, opc, asm, pattern> { 360 bits<4> Rd; 361 bits<4> Rn; 362 bits<12> ShiftedRm; 363 364 let Inst{11-8} = Rd{3-0}; 365 let Inst{19-16} = Rn{3-0}; 366 let Inst{3-0} = ShiftedRm{3-0}; 367 let Inst{5-4} = ShiftedRm{6-5}; 368 let Inst{14-12} = ShiftedRm{11-9}; 369 let Inst{7-6} = ShiftedRm{8-7}; 370} 371 372class T2sTwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin, 373 string opc, string asm, list<dag> pattern> 374 : T2sI<oops, iops, itin, opc, asm, pattern> { 375 bits<4> Rd; 376 bits<4> Rn; 377 bits<12> ShiftedRm; 378 379 let Inst{11-8} = Rd{3-0}; 380 let Inst{19-16} = Rn{3-0}; 381 let Inst{3-0} = ShiftedRm{3-0}; 382 let Inst{5-4} = ShiftedRm{6-5}; 383 let Inst{14-12} = ShiftedRm{11-9}; 384 let Inst{7-6} = ShiftedRm{8-7}; 385} 386 387/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a 388/// unary operation that produces a value. These are predicable and can be 389/// changed to modify CPSR. 390multiclass T2I_un_irs<bits<4> opcod, string opc, 391 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 392 PatFrag opnode, bit Cheap = 0, bit ReMat = 0> { 393 // shifted imm 394 def i : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), iii, 395 opc, "\t$Rd, $imm", 396 [(set rGPR:$Rd, (opnode t2_so_imm:$imm))]> { 397 let isAsCheapAsAMove = Cheap; 398 let isReMaterializable = ReMat; 399 let Inst{31-27} = 0b11110; 400 let Inst{25} = 0; 401 let Inst{24-21} = opcod; 402 let Inst{20} = ?; // The S bit. 403 let Inst{19-16} = 0b1111; // Rn 404 let Inst{15} = 0; 405 } 406 // register 407 def r : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), iir, 408 opc, ".w\t$Rd, $Rm", 409 [(set rGPR:$Rd, (opnode rGPR:$Rm))]> { 410 let Inst{31-27} = 0b11101; 411 let Inst{26-25} = 0b01; 412 let Inst{24-21} = opcod; 413 let Inst{20} = ?; // The S bit. 414 let Inst{19-16} = 0b1111; // Rn 415 let Inst{14-12} = 0b000; // imm3 416 let Inst{7-6} = 0b00; // imm2 417 let Inst{5-4} = 0b00; // type 418 } 419 // shifted register 420 def s : T2sOneRegShiftedReg<(outs rGPR:$Rd), (ins t2_so_reg:$ShiftedRm), iis, 421 opc, ".w\t$Rd, $ShiftedRm", 422 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm))]> { 423 let Inst{31-27} = 0b11101; 424 let Inst{26-25} = 0b01; 425 let Inst{24-21} = opcod; 426 let Inst{20} = ?; // The S bit. 427 let Inst{19-16} = 0b1111; // Rn 428 } 429} 430 431/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a 432/// binary operation that produces a value. These are predicable and can be 433/// changed to modify CPSR. 434multiclass T2I_bin_irs<bits<4> opcod, string opc, 435 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 436 PatFrag opnode, bit Commutable = 0, string wide = ""> { 437 // shifted imm 438 def ri : T2sTwoRegImm< 439 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), iii, 440 opc, "\t$Rd, $Rn, $imm", 441 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]> { 442 let Inst{31-27} = 0b11110; 443 let Inst{25} = 0; 444 let Inst{24-21} = opcod; 445 let Inst{20} = ?; // The S bit. 446 let Inst{15} = 0; 447 } 448 // register 449 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), iir, 450 opc, !strconcat(wide, "\t$Rd, $Rn, $Rm"), 451 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> { 452 let isCommutable = Commutable; 453 let Inst{31-27} = 0b11101; 454 let Inst{26-25} = 0b01; 455 let Inst{24-21} = opcod; 456 let Inst{20} = ?; // The S bit. 457 let Inst{14-12} = 0b000; // imm3 458 let Inst{7-6} = 0b00; // imm2 459 let Inst{5-4} = 0b00; // type 460 } 461 // shifted register 462 def rs : T2sTwoRegShiftedReg< 463 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), iis, 464 opc, !strconcat(wide, "\t$Rd, $Rn, $ShiftedRm"), 465 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]> { 466 let Inst{31-27} = 0b11101; 467 let Inst{26-25} = 0b01; 468 let Inst{24-21} = opcod; 469 let Inst{20} = ?; // The S bit. 470 } 471} 472 473/// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need 474// the ".w" prefix to indicate that they are wide. 475multiclass T2I_bin_w_irs<bits<4> opcod, string opc, 476 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 477 PatFrag opnode, bit Commutable = 0> : 478 T2I_bin_irs<opcod, opc, iii, iir, iis, opnode, Commutable, ".w">; 479 480/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are 481/// reversed. The 'rr' form is only defined for the disassembler; for codegen 482/// it is equivalent to the T2I_bin_irs counterpart. 483multiclass T2I_rbin_irs<bits<4> opcod, string opc, PatFrag opnode> { 484 // shifted imm 485 def ri : T2sTwoRegImm< 486 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi, 487 opc, ".w\t$Rd, $Rn, $imm", 488 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> { 489 let Inst{31-27} = 0b11110; 490 let Inst{25} = 0; 491 let Inst{24-21} = opcod; 492 let Inst{20} = ?; // The S bit. 493 let Inst{15} = 0; 494 } 495 // register 496 def rr : T2sThreeReg< 497 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr, 498 opc, "\t$Rd, $Rn, $Rm", 499 [/* For disassembly only; pattern left blank */]> { 500 let Inst{31-27} = 0b11101; 501 let Inst{26-25} = 0b01; 502 let Inst{24-21} = opcod; 503 let Inst{20} = ?; // The S bit. 504 let Inst{14-12} = 0b000; // imm3 505 let Inst{7-6} = 0b00; // imm2 506 let Inst{5-4} = 0b00; // type 507 } 508 // shifted register 509 def rs : T2sTwoRegShiftedReg< 510 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), 511 IIC_iALUsir, opc, "\t$Rd, $Rn, $ShiftedRm", 512 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> { 513 let Inst{31-27} = 0b11101; 514 let Inst{26-25} = 0b01; 515 let Inst{24-21} = opcod; 516 let Inst{20} = ?; // The S bit. 517 } 518} 519 520/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the 521/// instruction modifies the CPSR register. 522let Defs = [CPSR] in { 523multiclass T2I_bin_s_irs<bits<4> opcod, string opc, 524 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 525 PatFrag opnode, bit Commutable = 0> { 526 // shifted imm 527 def ri : T2TwoRegImm< 528 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), iii, 529 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm", 530 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> { 531 let Inst{31-27} = 0b11110; 532 let Inst{25} = 0; 533 let Inst{24-21} = opcod; 534 let Inst{20} = 1; // The S bit. 535 let Inst{15} = 0; 536 } 537 // register 538 def rr : T2ThreeReg< 539 (outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), iir, 540 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $Rm", 541 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> { 542 let isCommutable = Commutable; 543 let Inst{31-27} = 0b11101; 544 let Inst{26-25} = 0b01; 545 let Inst{24-21} = opcod; 546 let Inst{20} = 1; // The S bit. 547 let Inst{14-12} = 0b000; // imm3 548 let Inst{7-6} = 0b00; // imm2 549 let Inst{5-4} = 0b00; // type 550 } 551 // shifted register 552 def rs : T2TwoRegShiftedReg< 553 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), iis, 554 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $ShiftedRm", 555 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> { 556 let Inst{31-27} = 0b11101; 557 let Inst{26-25} = 0b01; 558 let Inst{24-21} = opcod; 559 let Inst{20} = 1; // The S bit. 560 } 561} 562} 563 564/// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg}) 565/// patterns for a binary operation that produces a value. 566multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode, 567 bit Commutable = 0> { 568 // shifted imm 569 // The register-immediate version is re-materializable. This is useful 570 // in particular for taking the address of a local. 571 let isReMaterializable = 1 in { 572 def ri : T2sTwoRegImm< 573 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_imm:$imm), IIC_iALUi, 574 opc, ".w\t$Rd, $Rn, $imm", 575 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_imm:$imm))]> { 576 let Inst{31-27} = 0b11110; 577 let Inst{25} = 0; 578 let Inst{24} = 1; 579 let Inst{23-21} = op23_21; 580 let Inst{20} = 0; // The S bit. 581 let Inst{15} = 0; 582 } 583 } 584 // 12-bit imm 585 def ri12 : T2TwoRegImm< 586 (outs rGPR:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi, 587 !strconcat(opc, "w"), "\t$Rd, $Rn, $imm", 588 [(set rGPR:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]> { 589 let Inst{31-27} = 0b11110; 590 let Inst{25} = 1; 591 let Inst{24} = 0; 592 let Inst{23-21} = op23_21; 593 let Inst{20} = 0; // The S bit. 594 let Inst{15} = 0; 595 } 596 // register 597 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins GPR:$Rn, rGPR:$Rm), IIC_iALUr, 598 opc, ".w\t$Rd, $Rn, $Rm", 599 [(set rGPR:$Rd, (opnode GPR:$Rn, rGPR:$Rm))]> { 600 let isCommutable = Commutable; 601 let Inst{31-27} = 0b11101; 602 let Inst{26-25} = 0b01; 603 let Inst{24} = 1; 604 let Inst{23-21} = op23_21; 605 let Inst{20} = 0; // The S bit. 606 let Inst{14-12} = 0b000; // imm3 607 let Inst{7-6} = 0b00; // imm2 608 let Inst{5-4} = 0b00; // type 609 } 610 // shifted register 611 def rs : T2sTwoRegShiftedReg< 612 (outs rGPR:$Rd), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), 613 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm", 614 [(set rGPR:$Rd, (opnode GPR:$Rn, t2_so_reg:$ShiftedRm))]> { 615 let Inst{31-27} = 0b11101; 616 let Inst{26-25} = 0b01; 617 let Inst{24} = 1; 618 let Inst{23-21} = op23_21; 619 let Inst{20} = 0; // The S bit. 620 } 621} 622 623/// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns 624/// for a binary operation that produces a value and use the carry 625/// bit. It's not predicable. 626let Uses = [CPSR] in { 627multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, 628 bit Commutable = 0> { 629 // shifted imm 630 def ri : T2sTwoRegImm<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), 631 IIC_iALUi, opc, "\t$Rd, $Rn, $imm", 632 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>, 633 Requires<[IsThumb2]> { 634 let Inst{31-27} = 0b11110; 635 let Inst{25} = 0; 636 let Inst{24-21} = opcod; 637 let Inst{20} = 0; // The S bit. 638 let Inst{15} = 0; 639 } 640 // register 641 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr, 642 opc, ".w\t$Rd, $Rn, $Rm", 643 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>, 644 Requires<[IsThumb2]> { 645 let isCommutable = Commutable; 646 let Inst{31-27} = 0b11101; 647 let Inst{26-25} = 0b01; 648 let Inst{24-21} = opcod; 649 let Inst{20} = 0; // The S bit. 650 let Inst{14-12} = 0b000; // imm3 651 let Inst{7-6} = 0b00; // imm2 652 let Inst{5-4} = 0b00; // type 653 } 654 // shifted register 655 def rs : T2sTwoRegShiftedReg< 656 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), 657 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm", 658 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>, 659 Requires<[IsThumb2]> { 660 let Inst{31-27} = 0b11101; 661 let Inst{26-25} = 0b01; 662 let Inst{24-21} = opcod; 663 let Inst{20} = 0; // The S bit. 664 } 665} 666 667// Carry setting variants 668let Defs = [CPSR] in { 669multiclass T2I_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode, 670 bit Commutable = 0> { 671 // shifted imm 672 def ri : T2sTwoRegImm< 673 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi, 674 opc, "\t$Rd, $Rn, $imm", 675 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>, 676 Requires<[IsThumb2]> { 677 let Inst{31-27} = 0b11110; 678 let Inst{25} = 0; 679 let Inst{24-21} = opcod; 680 let Inst{20} = 1; // The S bit. 681 let Inst{15} = 0; 682 } 683 // register 684 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr, 685 opc, ".w\t$Rd, $Rn, $Rm", 686 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>, 687 Requires<[IsThumb2]> { 688 let isCommutable = Commutable; 689 let Inst{31-27} = 0b11101; 690 let Inst{26-25} = 0b01; 691 let Inst{24-21} = opcod; 692 let Inst{20} = 1; // The S bit. 693 let Inst{14-12} = 0b000; // imm3 694 let Inst{7-6} = 0b00; // imm2 695 let Inst{5-4} = 0b00; // type 696 } 697 // shifted register 698 def rs : T2sTwoRegShiftedReg< 699 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), 700 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm", 701 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>, 702 Requires<[IsThumb2]> { 703 let Inst{31-27} = 0b11101; 704 let Inst{26-25} = 0b01; 705 let Inst{24-21} = opcod; 706 let Inst{20} = 1; // The S bit. 707 } 708} 709} 710} 711 712/// T2I_rbin_s_is - Same as T2I_rbin_irs except sets 's' bit and the register 713/// version is not needed since this is only for codegen. 714let Defs = [CPSR] in { 715multiclass T2I_rbin_s_is<bits<4> opcod, string opc, PatFrag opnode> { 716 // shifted imm 717 def ri : T2TwoRegImm< 718 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi, 719 !strconcat(opc, "s"), ".w\t$Rd, $Rn, $imm", 720 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> { 721 let Inst{31-27} = 0b11110; 722 let Inst{25} = 0; 723 let Inst{24-21} = opcod; 724 let Inst{20} = 1; // The S bit. 725 let Inst{15} = 0; 726 } 727 // shifted register 728 def rs : T2TwoRegShiftedReg< 729 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), 730 IIC_iALUsi, !strconcat(opc, "s"), "\t$Rd, $Rn, $ShiftedRm", 731 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> { 732 let Inst{31-27} = 0b11101; 733 let Inst{26-25} = 0b01; 734 let Inst{24-21} = opcod; 735 let Inst{20} = 1; // The S bit. 736 } 737} 738} 739 740/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift / 741// rotate operation that produces a value. 742multiclass T2I_sh_ir<bits<2> opcod, string opc, PatFrag opnode> { 743 // 5-bit imm 744 def ri : T2sTwoRegShiftImm< 745 (outs rGPR:$Rd), (ins rGPR:$Rm, i32imm:$imm), IIC_iMOVsi, 746 opc, ".w\t$Rd, $Rm, $imm", 747 [(set rGPR:$Rd, (opnode rGPR:$Rm, imm1_31:$imm))]> { 748 let Inst{31-27} = 0b11101; 749 let Inst{26-21} = 0b010010; 750 let Inst{19-16} = 0b1111; // Rn 751 let Inst{5-4} = opcod; 752 } 753 // register 754 def rr : T2sThreeReg< 755 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMOVsr, 756 opc, ".w\t$Rd, $Rn, $Rm", 757 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> { 758 let Inst{31-27} = 0b11111; 759 let Inst{26-23} = 0b0100; 760 let Inst{22-21} = opcod; 761 let Inst{15-12} = 0b1111; 762 let Inst{7-4} = 0b0000; 763 } 764} 765 766/// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test 767/// patterns. Similar to T2I_bin_irs except the instruction does not produce 768/// a explicit result, only implicitly set CPSR. 769let isCompare = 1, Defs = [CPSR] in { 770multiclass T2I_cmp_irs<bits<4> opcod, string opc, 771 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 772 PatFrag opnode> { 773 // shifted imm 774 def ri : T2OneRegCmpImm< 775 (outs), (ins GPR:$Rn, t2_so_imm:$imm), iii, 776 opc, ".w\t$Rn, $imm", 777 [(opnode GPR:$Rn, t2_so_imm:$imm)]> { 778 let Inst{31-27} = 0b11110; 779 let Inst{25} = 0; 780 let Inst{24-21} = opcod; 781 let Inst{20} = 1; // The S bit. 782 let Inst{15} = 0; 783 let Inst{11-8} = 0b1111; // Rd 784 } 785 // register 786 def rr : T2TwoRegCmp< 787 (outs), (ins GPR:$lhs, rGPR:$rhs), iir, 788 opc, ".w\t$lhs, $rhs", 789 [(opnode GPR:$lhs, rGPR:$rhs)]> { 790 let Inst{31-27} = 0b11101; 791 let Inst{26-25} = 0b01; 792 let Inst{24-21} = opcod; 793 let Inst{20} = 1; // The S bit. 794 let Inst{14-12} = 0b000; // imm3 795 let Inst{11-8} = 0b1111; // Rd 796 let Inst{7-6} = 0b00; // imm2 797 let Inst{5-4} = 0b00; // type 798 } 799 // shifted register 800 def rs : T2OneRegCmpShiftedReg< 801 (outs), (ins GPR:$Rn, t2_so_reg:$ShiftedRm), iis, 802 opc, ".w\t$Rn, $ShiftedRm", 803 [(opnode GPR:$Rn, t2_so_reg:$ShiftedRm)]> { 804 let Inst{31-27} = 0b11101; 805 let Inst{26-25} = 0b01; 806 let Inst{24-21} = opcod; 807 let Inst{20} = 1; // The S bit. 808 let Inst{11-8} = 0b1111; // Rd 809 } 810} 811} 812 813/// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns. 814multiclass T2I_ld<bit signed, bits<2> opcod, string opc, 815 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> { 816 def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), iii, 817 opc, ".w\t$dst, $addr", 818 [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]> { 819 let Inst{31-27} = 0b11111; 820 let Inst{26-25} = 0b00; 821 let Inst{24} = signed; 822 let Inst{23} = 1; 823 let Inst{22-21} = opcod; 824 let Inst{20} = 1; // load 825 } 826 def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), iii, 827 opc, "\t$dst, $addr", 828 [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]> { 829 let Inst{31-27} = 0b11111; 830 let Inst{26-25} = 0b00; 831 let Inst{24} = signed; 832 let Inst{23} = 0; 833 let Inst{22-21} = opcod; 834 let Inst{20} = 1; // load 835 let Inst{11} = 1; 836 // Offset: index==TRUE, wback==FALSE 837 let Inst{10} = 1; // The P bit. 838 let Inst{8} = 0; // The W bit. 839 } 840 def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), iis, 841 opc, ".w\t$dst, $addr", 842 [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]> { 843 let Inst{31-27} = 0b11111; 844 let Inst{26-25} = 0b00; 845 let Inst{24} = signed; 846 let Inst{23} = 0; 847 let Inst{22-21} = opcod; 848 let Inst{20} = 1; // load 849 let Inst{11-6} = 0b000000; 850 } 851 852 // FIXME: Is the pci variant actually needed? 853 def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), iii, 854 opc, ".w\t$dst, $addr", 855 [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]> { 856 let isReMaterializable = 1; 857 let Inst{31-27} = 0b11111; 858 let Inst{26-25} = 0b00; 859 let Inst{24} = signed; 860 let Inst{23} = ?; // add = (U == '1') 861 let Inst{22-21} = opcod; 862 let Inst{20} = 1; // load 863 let Inst{19-16} = 0b1111; // Rn 864 } 865} 866 867/// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns. 868multiclass T2I_st<bits<2> opcod, string opc, 869 InstrItinClass iii, InstrItinClass iis, PatFrag opnode> { 870 def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), iii, 871 opc, ".w\t$src, $addr", 872 [(opnode GPR:$src, t2addrmode_imm12:$addr)]> { 873 let Inst{31-27} = 0b11111; 874 let Inst{26-23} = 0b0001; 875 let Inst{22-21} = opcod; 876 let Inst{20} = 0; // !load 877 } 878 def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), iii, 879 opc, "\t$src, $addr", 880 [(opnode GPR:$src, t2addrmode_imm8:$addr)]> { 881 let Inst{31-27} = 0b11111; 882 let Inst{26-23} = 0b0000; 883 let Inst{22-21} = opcod; 884 let Inst{20} = 0; // !load 885 let Inst{11} = 1; 886 // Offset: index==TRUE, wback==FALSE 887 let Inst{10} = 1; // The P bit. 888 let Inst{8} = 0; // The W bit. 889 } 890 def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), iis, 891 opc, ".w\t$src, $addr", 892 [(opnode GPR:$src, t2addrmode_so_reg:$addr)]> { 893 let Inst{31-27} = 0b11111; 894 let Inst{26-23} = 0b0000; 895 let Inst{22-21} = opcod; 896 let Inst{20} = 0; // !load 897 let Inst{11-6} = 0b000000; 898 } 899} 900 901/// T2I_ext_rrot - A unary operation with two forms: one whose operand is a 902/// register and one whose operand is a register rotated by 8/16/24. 903multiclass T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode> { 904 def r : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iEXTr, 905 opc, ".w\t$Rd, $Rm", 906 [(set rGPR:$Rd, (opnode rGPR:$Rm))]> { 907 let Inst{31-27} = 0b11111; 908 let Inst{26-23} = 0b0100; 909 let Inst{22-20} = opcod; 910 let Inst{19-16} = 0b1111; // Rn 911 let Inst{15-12} = 0b1111; 912 let Inst{7} = 1; 913 let Inst{5-4} = 0b00; // rotate 914 } 915 def r_rot : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, i32imm:$rot), IIC_iEXTr, 916 opc, ".w\t$Rd, $Rm, ror $rot", 917 [(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]> { 918 let Inst{31-27} = 0b11111; 919 let Inst{26-23} = 0b0100; 920 let Inst{22-20} = opcod; 921 let Inst{19-16} = 0b1111; // Rn 922 let Inst{15-12} = 0b1111; 923 let Inst{7} = 1; 924 925 bits<2> rot; 926 let Inst{5-4} = rot{1-0}; // rotate 927 } 928} 929 930// UXTB16 - Requres T2ExtractPack, does not need the .w qualifier. 931multiclass T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode> { 932 def r : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iEXTr, 933 opc, "\t$Rd, $Rm", 934 [(set rGPR:$Rd, (opnode rGPR:$Rm))]>, 935 Requires<[HasT2ExtractPack, IsThumb2]> { 936 let Inst{31-27} = 0b11111; 937 let Inst{26-23} = 0b0100; 938 let Inst{22-20} = opcod; 939 let Inst{19-16} = 0b1111; // Rn 940 let Inst{15-12} = 0b1111; 941 let Inst{7} = 1; 942 let Inst{5-4} = 0b00; // rotate 943 } 944 def r_rot : T2TwoReg<(outs rGPR:$dst), (ins rGPR:$Rm, i32imm:$rot), IIC_iEXTr, 945 opc, "\t$dst, $Rm, ror $rot", 946 [(set rGPR:$dst, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>, 947 Requires<[HasT2ExtractPack, IsThumb2]> { 948 let Inst{31-27} = 0b11111; 949 let Inst{26-23} = 0b0100; 950 let Inst{22-20} = opcod; 951 let Inst{19-16} = 0b1111; // Rn 952 let Inst{15-12} = 0b1111; 953 let Inst{7} = 1; 954 955 bits<2> rot; 956 let Inst{5-4} = rot{1-0}; // rotate 957 } 958} 959 960// SXTB16 - Requres T2ExtractPack, does not need the .w qualifier, no pattern 961// supported yet. 962multiclass T2I_ext_rrot_sxtb16<bits<3> opcod, string opc> { 963 def r : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iEXTr, 964 opc, "\t$Rd, $Rm", []> { 965 let Inst{31-27} = 0b11111; 966 let Inst{26-23} = 0b0100; 967 let Inst{22-20} = opcod; 968 let Inst{19-16} = 0b1111; // Rn 969 let Inst{15-12} = 0b1111; 970 let Inst{7} = 1; 971 let Inst{5-4} = 0b00; // rotate 972 } 973 def r_rot : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, i32imm:$rot), IIC_iEXTr, 974 opc, "\t$Rd, $Rm, ror $rot", []> { 975 let Inst{31-27} = 0b11111; 976 let Inst{26-23} = 0b0100; 977 let Inst{22-20} = opcod; 978 let Inst{19-16} = 0b1111; // Rn 979 let Inst{15-12} = 0b1111; 980 let Inst{7} = 1; 981 982 bits<2> rot; 983 let Inst{5-4} = rot{1-0}; // rotate 984 } 985} 986 987/// T2I_exta_rrot - A binary operation with two forms: one whose operand is a 988/// register and one whose operand is a register rotated by 8/16/24. 989multiclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> { 990 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iEXTAr, 991 opc, "\t$Rd, $Rn, $Rm", 992 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>, 993 Requires<[HasT2ExtractPack, IsThumb2]> { 994 let Inst{31-27} = 0b11111; 995 let Inst{26-23} = 0b0100; 996 let Inst{22-20} = opcod; 997 let Inst{15-12} = 0b1111; 998 let Inst{7} = 1; 999 let Inst{5-4} = 0b00; // rotate 1000 } 1001 def rr_rot : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, i32imm:$rot), 1002 IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot", 1003 [(set rGPR:$Rd, (opnode rGPR:$Rn, 1004 (rotr rGPR:$Rm, rot_imm:$rot)))]>, 1005 Requires<[HasT2ExtractPack, IsThumb2]> { 1006 let Inst{31-27} = 0b11111; 1007 let Inst{26-23} = 0b0100; 1008 let Inst{22-20} = opcod; 1009 let Inst{15-12} = 0b1111; 1010 let Inst{7} = 1; 1011 1012 bits<2> rot; 1013 let Inst{5-4} = rot{1-0}; // rotate 1014 } 1015} 1016 1017// DO variant - disassembly only, no pattern 1018 1019multiclass T2I_exta_rrot_DO<bits<3> opcod, string opc> { 1020 def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iEXTAr, 1021 opc, "\t$Rd, $Rn, $Rm", []> { 1022 let Inst{31-27} = 0b11111; 1023 let Inst{26-23} = 0b0100; 1024 let Inst{22-20} = opcod; 1025 let Inst{15-12} = 0b1111; 1026 let Inst{7} = 1; 1027 let Inst{5-4} = 0b00; // rotate 1028 } 1029 def rr_rot : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, i32imm:$rot), 1030 IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot", []> { 1031 let Inst{31-27} = 0b11111; 1032 let Inst{26-23} = 0b0100; 1033 let Inst{22-20} = opcod; 1034 let Inst{15-12} = 0b1111; 1035 let Inst{7} = 1; 1036 1037 bits<2> rot; 1038 let Inst{5-4} = rot{1-0}; // rotate 1039 } 1040} 1041 1042//===----------------------------------------------------------------------===// 1043// Instructions 1044//===----------------------------------------------------------------------===// 1045 1046//===----------------------------------------------------------------------===// 1047// Miscellaneous Instructions. 1048// 1049 1050class T2PCOneRegImm<dag oops, dag iops, InstrItinClass itin, 1051 string asm, list<dag> pattern> 1052 : T2XI<oops, iops, itin, asm, pattern> { 1053 bits<4> Rd; 1054 bits<12> label; 1055 1056 let Inst{11-8} = Rd{3-0}; 1057 let Inst{26} = label{11}; 1058 let Inst{14-12} = label{10-8}; 1059 let Inst{7-0} = label{7-0}; 1060} 1061 1062// LEApcrel - Load a pc-relative address into a register without offending the 1063// assembler. 1064let neverHasSideEffects = 1 in { 1065let isReMaterializable = 1 in 1066def t2LEApcrel : T2PCOneRegImm<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), IIC_iALUi, 1067 "adr${p}.w\t$Rd, #$label", []> { 1068 let Inst{31-27} = 0b11110; 1069 let Inst{25-24} = 0b10; 1070 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE) 1071 let Inst{22} = 0; 1072 let Inst{20} = 0; 1073 let Inst{19-16} = 0b1111; // Rn 1074 let Inst{15} = 0; 1075 1076 1077} 1078} // neverHasSideEffects 1079def t2LEApcrelJT : T2PCOneRegImm<(outs rGPR:$Rd), 1080 (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi, 1081 "adr${p}.w\t$Rd, #${label}_${id}", []> { 1082 let Inst{31-27} = 0b11110; 1083 let Inst{25-24} = 0b10; 1084 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE) 1085 let Inst{22} = 0; 1086 let Inst{20} = 0; 1087 let Inst{19-16} = 0b1111; // Rn 1088 let Inst{15} = 0; 1089} 1090 1091// ADD r, sp, {so_imm|i12} 1092def t2ADDrSPi : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$sp, t2_so_imm:$imm), 1093 IIC_iALUi, "add", ".w\t$Rd, $sp, $imm", []> { 1094 let Inst{31-27} = 0b11110; 1095 let Inst{25} = 0; 1096 let Inst{24-21} = 0b1000; 1097 let Inst{20} = ?; // The S bit. 1098 let Inst{19-16} = 0b1101; // Rn = sp 1099 let Inst{15} = 0; 1100} 1101def t2ADDrSPi12 : T2TwoRegImm<(outs GPR:$Rd), (ins GPR:$sp, imm0_4095:$imm), 1102 IIC_iALUi, "addw", "\t$Rd, $sp, $imm", []> { 1103 let Inst{31-27} = 0b11110; 1104 let Inst{25} = 1; 1105 let Inst{24-21} = 0b0000; 1106 let Inst{20} = 0; // The S bit. 1107 let Inst{19-16} = 0b1101; // Rn = sp 1108 let Inst{15} = 0; 1109} 1110 1111// ADD r, sp, so_reg 1112def t2ADDrSPs : T2sTwoRegShiftedReg< 1113 (outs GPR:$Rd), (ins GPR:$sp, t2_so_reg:$ShiftedRm), 1114 IIC_iALUsi, "add", ".w\t$Rd, $sp, $ShiftedRm", []> { 1115 let Inst{31-27} = 0b11101; 1116 let Inst{26-25} = 0b01; 1117 let Inst{24-21} = 0b1000; 1118 let Inst{20} = ?; // The S bit. 1119 let Inst{19-16} = 0b1101; // Rn = sp 1120 let Inst{15} = 0; 1121} 1122 1123// SUB r, sp, {so_imm|i12} 1124def t2SUBrSPi : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$sp, t2_so_imm:$imm), 1125 IIC_iALUi, "sub", ".w\t$Rd, $sp, $imm", []> { 1126 let Inst{31-27} = 0b11110; 1127 let Inst{25} = 0; 1128 let Inst{24-21} = 0b1101; 1129 let Inst{20} = ?; // The S bit. 1130 let Inst{19-16} = 0b1101; // Rn = sp 1131 let Inst{15} = 0; 1132} 1133def t2SUBrSPi12 : T2TwoRegImm<(outs GPR:$Rd), (ins GPR:$sp, imm0_4095:$imm), 1134 IIC_iALUi, "subw", "\t$Rd, $sp, $imm", []> { 1135 let Inst{31-27} = 0b11110; 1136 let Inst{25} = 1; 1137 let Inst{24-21} = 0b0101; 1138 let Inst{20} = 0; // The S bit. 1139 let Inst{19-16} = 0b1101; // Rn = sp 1140 let Inst{15} = 0; 1141} 1142 1143// SUB r, sp, so_reg 1144def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs), 1145 IIC_iALUsi, 1146 "sub", "\t$dst, $sp, $rhs", []> { 1147 let Inst{31-27} = 0b11101; 1148 let Inst{26-25} = 0b01; 1149 let Inst{24-21} = 0b1101; 1150 let Inst{20} = ?; // The S bit. 1151 let Inst{19-16} = 0b1101; // Rn = sp 1152 let Inst{15} = 0; 1153} 1154 1155// Signed and unsigned division on v7-M 1156def t2SDIV : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iALUi, 1157 "sdiv", "\t$dst, $a, $b", 1158 [(set rGPR:$dst, (sdiv rGPR:$a, rGPR:$b))]>, 1159 Requires<[HasDivide]> { 1160 let Inst{31-27} = 0b11111; 1161 let Inst{26-21} = 0b011100; 1162 let Inst{20} = 0b1; 1163 let Inst{15-12} = 0b1111; 1164 let Inst{7-4} = 0b1111; 1165} 1166 1167def t2UDIV : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iALUi, 1168 "udiv", "\t$dst, $a, $b", 1169 [(set rGPR:$dst, (udiv rGPR:$a, rGPR:$b))]>, 1170 Requires<[HasDivide]> { 1171 let Inst{31-27} = 0b11111; 1172 let Inst{26-21} = 0b011101; 1173 let Inst{20} = 0b1; 1174 let Inst{15-12} = 0b1111; 1175 let Inst{7-4} = 0b1111; 1176} 1177 1178//===----------------------------------------------------------------------===// 1179// Load / store Instructions. 1180// 1181 1182// Load 1183let canFoldAsLoad = 1, isReMaterializable = 1 in 1184defm t2LDR : T2I_ld<0, 0b10, "ldr", IIC_iLoad_i, IIC_iLoad_si, 1185 UnOpFrag<(load node:$Src)>>; 1186 1187// Loads with zero extension 1188defm t2LDRH : T2I_ld<0, 0b01, "ldrh", IIC_iLoad_bh_i, IIC_iLoad_bh_si, 1189 UnOpFrag<(zextloadi16 node:$Src)>>; 1190defm t2LDRB : T2I_ld<0, 0b00, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_si, 1191 UnOpFrag<(zextloadi8 node:$Src)>>; 1192 1193// Loads with sign extension 1194defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", IIC_iLoad_bh_i, IIC_iLoad_bh_si, 1195 UnOpFrag<(sextloadi16 node:$Src)>>; 1196defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", IIC_iLoad_bh_i, IIC_iLoad_bh_si, 1197 UnOpFrag<(sextloadi8 node:$Src)>>; 1198 1199let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1, 1200 isCodeGenOnly = 1 in { // $dst doesn't exist in asmstring? 1201// Load doubleword 1202def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2), 1203 (ins t2addrmode_imm8s4:$addr), 1204 IIC_iLoad_d_i, "ldrd", "\t$dst1, $addr", []>; 1205def t2LDRDpci : T2Ii8s4<1, 0, 1, (outs rGPR:$dst1, rGPR:$dst2), 1206 (ins i32imm:$addr), IIC_iLoad_d_i, 1207 "ldrd", "\t$dst1, $addr", []> { 1208 let Inst{19-16} = 0b1111; // Rn 1209} 1210} // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 1211 1212// zextload i1 -> zextload i8 1213def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr), 1214 (t2LDRBi12 t2addrmode_imm12:$addr)>; 1215def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr), 1216 (t2LDRBi8 t2addrmode_imm8:$addr)>; 1217def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr), 1218 (t2LDRBs t2addrmode_so_reg:$addr)>; 1219def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)), 1220 (t2LDRBpci tconstpool:$addr)>; 1221 1222// extload -> zextload 1223// FIXME: Reduce the number of patterns by legalizing extload to zextload 1224// earlier? 1225def : T2Pat<(extloadi1 t2addrmode_imm12:$addr), 1226 (t2LDRBi12 t2addrmode_imm12:$addr)>; 1227def : T2Pat<(extloadi1 t2addrmode_imm8:$addr), 1228 (t2LDRBi8 t2addrmode_imm8:$addr)>; 1229def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr), 1230 (t2LDRBs t2addrmode_so_reg:$addr)>; 1231def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)), 1232 (t2LDRBpci tconstpool:$addr)>; 1233 1234def : T2Pat<(extloadi8 t2addrmode_imm12:$addr), 1235 (t2LDRBi12 t2addrmode_imm12:$addr)>; 1236def : T2Pat<(extloadi8 t2addrmode_imm8:$addr), 1237 (t2LDRBi8 t2addrmode_imm8:$addr)>; 1238def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr), 1239 (t2LDRBs t2addrmode_so_reg:$addr)>; 1240def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)), 1241 (t2LDRBpci tconstpool:$addr)>; 1242 1243def : T2Pat<(extloadi16 t2addrmode_imm12:$addr), 1244 (t2LDRHi12 t2addrmode_imm12:$addr)>; 1245def : T2Pat<(extloadi16 t2addrmode_imm8:$addr), 1246 (t2LDRHi8 t2addrmode_imm8:$addr)>; 1247def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr), 1248 (t2LDRHs t2addrmode_so_reg:$addr)>; 1249def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)), 1250 (t2LDRHpci tconstpool:$addr)>; 1251 1252// FIXME: The destination register of the loads and stores can't be PC, but 1253// can be SP. We need another regclass (similar to rGPR) to represent 1254// that. Not a pressing issue since these are selected manually, 1255// not via pattern. 1256 1257// Indexed loads 1258let mayLoad = 1, neverHasSideEffects = 1 in { 1259def t2LDR_PRE : T2Iidxldst<0, 0b10, 1, 1, (outs GPR:$dst, GPR:$base_wb), 1260 (ins t2addrmode_imm8:$addr), 1261 AddrModeT2_i8, IndexModePre, IIC_iLoad_iu, 1262 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", 1263 []>; 1264 1265def t2LDR_POST : T2Iidxldst<0, 0b10, 1, 0, (outs GPR:$dst, GPR:$base_wb), 1266 (ins GPR:$base, t2am_imm8_offset:$offset), 1267 AddrModeT2_i8, IndexModePost, IIC_iLoad_iu, 1268 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", 1269 []>; 1270 1271def t2LDRB_PRE : T2Iidxldst<0, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb), 1272 (ins t2addrmode_imm8:$addr), 1273 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, 1274 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", 1275 []>; 1276def t2LDRB_POST : T2Iidxldst<0, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb), 1277 (ins GPR:$base, t2am_imm8_offset:$offset), 1278 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, 1279 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", 1280 []>; 1281 1282def t2LDRH_PRE : T2Iidxldst<0, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb), 1283 (ins t2addrmode_imm8:$addr), 1284 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, 1285 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", 1286 []>; 1287def t2LDRH_POST : T2Iidxldst<0, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb), 1288 (ins GPR:$base, t2am_imm8_offset:$offset), 1289 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, 1290 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", 1291 []>; 1292 1293def t2LDRSB_PRE : T2Iidxldst<1, 0b00, 1, 1, (outs GPR:$dst, GPR:$base_wb), 1294 (ins t2addrmode_imm8:$addr), 1295 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, 1296 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", 1297 []>; 1298def t2LDRSB_POST : T2Iidxldst<1, 0b00, 1, 0, (outs GPR:$dst, GPR:$base_wb), 1299 (ins GPR:$base, t2am_imm8_offset:$offset), 1300 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, 1301 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", 1302 []>; 1303 1304def t2LDRSH_PRE : T2Iidxldst<1, 0b01, 1, 1, (outs GPR:$dst, GPR:$base_wb), 1305 (ins t2addrmode_imm8:$addr), 1306 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, 1307 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", 1308 []>; 1309def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$dst, GPR:$base_wb), 1310 (ins GPR:$base, t2am_imm8_offset:$offset), 1311 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, 1312 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", 1313 []>; 1314} // mayLoad = 1, neverHasSideEffects = 1 1315 1316// LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are 1317// for disassembly only. 1318// Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4 1319class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii> 1320 : T2Ii8<(outs GPR:$dst), (ins t2addrmode_imm8:$addr), ii, opc, 1321 "\t$dst, $addr", []> { 1322 let Inst{31-27} = 0b11111; 1323 let Inst{26-25} = 0b00; 1324 let Inst{24} = signed; 1325 let Inst{23} = 0; 1326 let Inst{22-21} = type; 1327 let Inst{20} = 1; // load 1328 let Inst{11} = 1; 1329 let Inst{10-8} = 0b110; // PUW. 1330} 1331 1332def t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>; 1333def t2LDRBT : T2IldT<0, 0b00, "ldrbt", IIC_iLoad_bh_i>; 1334def t2LDRHT : T2IldT<0, 0b01, "ldrht", IIC_iLoad_bh_i>; 1335def t2LDRSBT : T2IldT<1, 0b00, "ldrsbt", IIC_iLoad_bh_i>; 1336def t2LDRSHT : T2IldT<1, 0b01, "ldrsht", IIC_iLoad_bh_i>; 1337 1338// Store 1339defm t2STR :T2I_st<0b10,"str", IIC_iStore_i, IIC_iStore_si, 1340 BinOpFrag<(store node:$LHS, node:$RHS)>>; 1341defm t2STRB:T2I_st<0b00,"strb", IIC_iStore_bh_i, IIC_iStore_bh_si, 1342 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>; 1343defm t2STRH:T2I_st<0b01,"strh", IIC_iStore_bh_i, IIC_iStore_bh_si, 1344 BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>; 1345 1346// Store doubleword 1347let mayLoad = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1, 1348 isCodeGenOnly = 1 in // $src2 doesn't exist in asm string 1349def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs), 1350 (ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr), 1351 IIC_iStore_d_r, "strd", "\t$src1, $addr", []>; 1352 1353// Indexed stores 1354def t2STR_PRE : T2Iidxldst<0, 0b10, 0, 1, (outs GPR:$base_wb), 1355 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), 1356 AddrModeT2_i8, IndexModePre, IIC_iStore_iu, 1357 "str", "\t$src, [$base, $offset]!", "$base = $base_wb", 1358 [(set GPR:$base_wb, 1359 (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; 1360 1361def t2STR_POST : T2Iidxldst<0, 0b10, 0, 0, (outs GPR:$base_wb), 1362 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), 1363 AddrModeT2_i8, IndexModePost, IIC_iStore_iu, 1364 "str", "\t$src, [$base], $offset", "$base = $base_wb", 1365 [(set GPR:$base_wb, 1366 (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; 1367 1368def t2STRH_PRE : T2Iidxldst<0, 0b01, 0, 1, (outs GPR:$base_wb), 1369 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), 1370 AddrModeT2_i8, IndexModePre, IIC_iStore_iu, 1371 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb", 1372 [(set GPR:$base_wb, 1373 (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; 1374 1375def t2STRH_POST : T2Iidxldst<0, 0b01, 0, 0, (outs GPR:$base_wb), 1376 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), 1377 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu, 1378 "strh", "\t$src, [$base], $offset", "$base = $base_wb", 1379 [(set GPR:$base_wb, 1380 (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; 1381 1382def t2STRB_PRE : T2Iidxldst<0, 0b00, 0, 1, (outs GPR:$base_wb), 1383 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), 1384 AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu, 1385 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb", 1386 [(set GPR:$base_wb, 1387 (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; 1388 1389def t2STRB_POST : T2Iidxldst<0, 0b00, 0, 0, (outs GPR:$base_wb), 1390 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), 1391 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu, 1392 "strb", "\t$src, [$base], $offset", "$base = $base_wb", 1393 [(set GPR:$base_wb, 1394 (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; 1395 1396// STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly 1397// only. 1398// Ref: A8.6.193 STR (immediate, Thumb) Encoding T4 1399class T2IstT<bits<2> type, string opc, InstrItinClass ii> 1400 : T2Ii8<(outs GPR:$src), (ins t2addrmode_imm8:$addr), ii, opc, 1401 "\t$src, $addr", []> { 1402 let Inst{31-27} = 0b11111; 1403 let Inst{26-25} = 0b00; 1404 let Inst{24} = 0; // not signed 1405 let Inst{23} = 0; 1406 let Inst{22-21} = type; 1407 let Inst{20} = 0; // store 1408 let Inst{11} = 1; 1409 let Inst{10-8} = 0b110; // PUW 1410} 1411 1412def t2STRT : T2IstT<0b10, "strt", IIC_iStore_i>; 1413def t2STRBT : T2IstT<0b00, "strbt", IIC_iStore_bh_i>; 1414def t2STRHT : T2IstT<0b01, "strht", IIC_iStore_bh_i>; 1415 1416// ldrd / strd pre / post variants 1417// For disassembly only. 1418 1419def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs GPR:$dst1, GPR:$dst2), 1420 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru, 1421 "ldrd", "\t$dst1, $dst2, [$base, $imm]!", []>; 1422 1423def t2LDRD_POST : T2Ii8s4<0, 1, 1, (outs GPR:$dst1, GPR:$dst2), 1424 (ins GPR:$base, t2am_imm8s4_offset:$imm), IIC_iLoad_d_ru, 1425 "ldrd", "\t$dst1, $dst2, [$base], $imm", []>; 1426 1427def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs), 1428 (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm), 1429 IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base, $imm]!", []>; 1430 1431def t2STRD_POST : T2Ii8s4<0, 1, 0, (outs), 1432 (ins GPR:$src1, GPR:$src2, GPR:$base, t2am_imm8s4_offset:$imm), 1433 IIC_iStore_d_ru, "strd", "\t$src1, $src2, [$base], $imm", []>; 1434 1435// T2Ipl (Preload Data/Instruction) signals the memory system of possible future 1436// data/instruction access. These are for disassembly only. 1437// instr_write is inverted for Thumb mode: (prefetch 3) -> (preload 0), 1438// (prefetch 1) -> (preload 2), (prefetch 2) -> (preload 1). 1439multiclass T2Ipl<bits<1> write, bits<1> instr, string opc> { 1440 1441 def i12 : T2Ii12<(outs), (ins t2addrmode_imm12:$addr), IIC_Preload, opc, 1442 "\t$addr", 1443 [(ARMPreload t2addrmode_imm12:$addr, (i32 write), (i32 instr))]> { 1444 let Inst{31-25} = 0b1111100; 1445 let Inst{24} = instr; 1446 let Inst{23} = 1; // U = 1 1447 let Inst{22} = 0; 1448 let Inst{21} = write; 1449 let Inst{20} = 1; 1450 let Inst{15-12} = 0b1111; 1451 } 1452 1453 def i8 : T2Ii8<(outs), (ins t2addrmode_imm8:$addr), IIC_Preload, opc, 1454 "\t$addr", 1455 [(ARMPreload t2addrmode_imm8:$addr, (i32 write), (i32 instr))]> { 1456 let Inst{31-25} = 0b1111100; 1457 let Inst{24} = instr; 1458 let Inst{23} = 0; // U = 0 1459 let Inst{22} = 0; 1460 let Inst{21} = write; 1461 let Inst{20} = 1; 1462 let Inst{15-12} = 0b1111; 1463 let Inst{11-8} = 0b1100; 1464 } 1465 1466 def s : T2Iso<(outs), (ins t2addrmode_so_reg:$addr), IIC_Preload, opc, 1467 "\t$addr", 1468 [(ARMPreload t2addrmode_so_reg:$addr, (i32 write), (i32 instr))]> { 1469 let Inst{31-25} = 0b1111100; 1470 let Inst{24} = instr; 1471 let Inst{23} = 0; // add = TRUE for T1 1472 let Inst{22} = 0; 1473 let Inst{21} = write; 1474 let Inst{20} = 1; 1475 let Inst{15-12} = 0b1111; 1476 let Inst{11-6} = 0000000; 1477 } 1478 1479 let isCodeGenOnly = 1 in 1480 def pci : T2Ipc<(outs), (ins i32imm:$addr), IIC_Preload, opc, 1481 "\t$addr", 1482 []> { 1483 let Inst{31-25} = 0b1111100; 1484 let Inst{24} = write; 1485 let Inst{23} = ?; // add = (U == 1) 1486 let Inst{22} = 0; 1487 let Inst{21} = instr; 1488 let Inst{20} = 1; 1489 let Inst{19-16} = 0b1111; // Rn = 0b1111 1490 let Inst{15-12} = 0b1111; 1491 } 1492} 1493 1494defm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>; 1495defm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>; 1496defm t2PLI : T2Ipl<0, 1, "pli">, Requires<[IsThumb2,HasV7]>; 1497 1498//===----------------------------------------------------------------------===// 1499// Load / store multiple Instructions. 1500// 1501 1502multiclass thumb2_ldst_mult<string asm, InstrItinClass itin, 1503 InstrItinClass itin_upd, bit L_bit> { 1504 def ia : 1505 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1506 itin, !strconcat(asm, "${p}.w\t$Rn, $regs"), []> { 1507 bits<4> Rn; 1508 bits<16> regs; 1509 1510 let Inst{31-27} = 0b11101; 1511 let Inst{26-25} = 0b00; 1512 let Inst{24-23} = 0b01; // Increment After 1513 let Inst{22} = 0; 1514 let Inst{21} = 0; // No writeback 1515 let Inst{20} = L_bit; 1516 let Inst{19-16} = Rn; 1517 let Inst{15-0} = regs; 1518 } 1519 def ia_UPD : 1520 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1521 itin_upd, !strconcat(asm, "${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> { 1522 bits<4> Rn; 1523 bits<16> regs; 1524 1525 let Inst{31-27} = 0b11101; 1526 let Inst{26-25} = 0b00; 1527 let Inst{24-23} = 0b01; // Increment After 1528 let Inst{22} = 0; 1529 let Inst{21} = 1; // Writeback 1530 let Inst{20} = L_bit; 1531 let Inst{19-16} = Rn; 1532 let Inst{15-0} = regs; 1533 } 1534 def db : 1535 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1536 itin, !strconcat(asm, "db${p}.w\t$Rn, $regs"), []> { 1537 bits<4> Rn; 1538 bits<16> regs; 1539 1540 let Inst{31-27} = 0b11101; 1541 let Inst{26-25} = 0b00; 1542 let Inst{24-23} = 0b10; // Decrement Before 1543 let Inst{22} = 0; 1544 let Inst{21} = 0; // No writeback 1545 let Inst{20} = L_bit; 1546 let Inst{19-16} = Rn; 1547 let Inst{15-0} = regs; 1548 } 1549 def db_UPD : 1550 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1551 itin_upd, !strconcat(asm, "db${p}.w\t$Rn, $regs"), "$Rn = $wb", []> { 1552 bits<4> Rn; 1553 bits<16> regs; 1554 1555 let Inst{31-27} = 0b11101; 1556 let Inst{26-25} = 0b00; 1557 let Inst{24-23} = 0b10; // Decrement Before 1558 let Inst{22} = 0; 1559 let Inst{21} = 1; // Writeback 1560 let Inst{20} = L_bit; 1561 let Inst{19-16} = Rn; 1562 let Inst{15-0} = regs; 1563 } 1564} 1565 1566/* TODO: 1567let neverHasSideEffects = 1 in { 1568 1569let mayLoad = 1, hasExtraDefRegAllocReq = 1 in 1570defm t2LDM : thumb2_ldst_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>; 1571 1572let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 1573defm t2STM : thumb2_ldst_mult<"stm", IIC_iStore_m, IIC_iStore_mu, 0>; 1574 1575} // neverHasSideEffects 1576*/ 1577 1578let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1, 1579 isCodeGenOnly = 1 in { 1580def t2LDM : T2XI<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p, 1581 reglist:$dsts, variable_ops), IIC_iLoad_m, 1582 "ldm${amode}${p}.w\t$Rn, $dsts", []> { 1583 let Inst{31-27} = 0b11101; 1584 let Inst{26-25} = 0b00; 1585 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10' 1586 let Inst{22} = 0; 1587 let Inst{21} = 0; // The W bit. 1588 let Inst{20} = 1; // Load 1589} 1590 1591def t2LDM_UPD : T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p, 1592 reglist:$dsts, variable_ops), 1593 IIC_iLoad_mu, 1594 "ldm${amode}${p}.w\t$Rn!, $dsts", 1595 "$Rn = $wb", []> { 1596 let Inst{31-27} = 0b11101; 1597 let Inst{26-25} = 0b00; 1598 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10' 1599 let Inst{22} = 0; 1600 let Inst{21} = 1; // The W bit. 1601 let Inst{20} = 1; // Load 1602} 1603} // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq 1604 1605let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1, 1606 isCodeGenOnly = 1 in { 1607def t2STM : T2XI<(outs), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p, 1608 reglist:$srcs, variable_ops), IIC_iStore_m, 1609 "stm${amode}${p}.w\t$Rn, $srcs", []> { 1610 let Inst{31-27} = 0b11101; 1611 let Inst{26-25} = 0b00; 1612 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10' 1613 let Inst{22} = 0; 1614 let Inst{21} = 0; // The W bit. 1615 let Inst{20} = 0; // Store 1616} 1617 1618def t2STM_UPD : T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p, 1619 reglist:$srcs, variable_ops), 1620 IIC_iStore_m, 1621 "stm${amode}${p}.w\t$Rn!, $srcs", 1622 "$Rn = $wb", []> { 1623 let Inst{31-27} = 0b11101; 1624 let Inst{26-25} = 0b00; 1625 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10' 1626 let Inst{22} = 0; 1627 let Inst{21} = 1; // The W bit. 1628 let Inst{20} = 0; // Store 1629} 1630} // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq 1631 1632//===----------------------------------------------------------------------===// 1633// Move Instructions. 1634// 1635 1636let neverHasSideEffects = 1 in 1637def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr, 1638 "mov", ".w\t$dst, $src", []> { 1639 let Inst{31-27} = 0b11101; 1640 let Inst{26-25} = 0b01; 1641 let Inst{24-21} = 0b0010; 1642 let Inst{20} = ?; // The S bit. 1643 let Inst{19-16} = 0b1111; // Rn 1644 let Inst{14-12} = 0b000; 1645 let Inst{7-4} = 0b0000; 1646} 1647 1648// AddedComplexity to ensure isel tries t2MOVi before t2MOVi16. 1649let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in 1650def t2MOVi : T2sI<(outs rGPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi, 1651 "mov", ".w\t$dst, $src", 1652 [(set rGPR:$dst, t2_so_imm:$src)]> { 1653 let Inst{31-27} = 0b11110; 1654 let Inst{25} = 0; 1655 let Inst{24-21} = 0b0010; 1656 let Inst{20} = ?; // The S bit. 1657 let Inst{19-16} = 0b1111; // Rn 1658 let Inst{15} = 0; 1659} 1660 1661let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1662def t2MOVi16 : T2I<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVi, 1663 "movw", "\t$dst, $src", 1664 [(set rGPR:$dst, imm0_65535:$src)]> { 1665 let Inst{31-27} = 0b11110; 1666 let Inst{25} = 1; 1667 let Inst{24-21} = 0b0010; 1668 let Inst{20} = 0; // The S bit. 1669 let Inst{15} = 0; 1670} 1671 1672let Constraints = "$src = $dst" in 1673def t2MOVTi16 : T2I<(outs rGPR:$dst), (ins rGPR:$src, i32imm:$imm), IIC_iMOVi, 1674 "movt", "\t$dst, $imm", 1675 [(set rGPR:$dst, 1676 (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]> { 1677 let Inst{31-27} = 0b11110; 1678 let Inst{25} = 1; 1679 let Inst{24-21} = 0b0110; 1680 let Inst{20} = 0; // The S bit. 1681 let Inst{15} = 0; 1682} 1683 1684def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>; 1685 1686//===----------------------------------------------------------------------===// 1687// Extend Instructions. 1688// 1689 1690// Sign extenders 1691 1692defm t2SXTB : T2I_ext_rrot<0b100, "sxtb", 1693 UnOpFrag<(sext_inreg node:$Src, i8)>>; 1694defm t2SXTH : T2I_ext_rrot<0b000, "sxth", 1695 UnOpFrag<(sext_inreg node:$Src, i16)>>; 1696defm t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">; 1697 1698defm t2SXTAB : T2I_exta_rrot<0b100, "sxtab", 1699 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>; 1700defm t2SXTAH : T2I_exta_rrot<0b000, "sxtah", 1701 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>; 1702defm t2SXTAB16 : T2I_exta_rrot_DO<0b010, "sxtab16">; 1703 1704// TODO: SXT(A){B|H}16 - done for disassembly only 1705 1706// Zero extenders 1707 1708let AddedComplexity = 16 in { 1709defm t2UXTB : T2I_ext_rrot<0b101, "uxtb", 1710 UnOpFrag<(and node:$Src, 0x000000FF)>>; 1711defm t2UXTH : T2I_ext_rrot<0b001, "uxth", 1712 UnOpFrag<(and node:$Src, 0x0000FFFF)>>; 1713defm t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16", 1714 UnOpFrag<(and node:$Src, 0x00FF00FF)>>; 1715 1716// FIXME: This pattern incorrectly assumes the shl operator is a rotate. 1717// The transformation should probably be done as a combiner action 1718// instead so we can include a check for masking back in the upper 1719// eight bits of the source into the lower eight bits of the result. 1720//def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF), 1721// (t2UXTB16r_rot rGPR:$Src, 24)>, 1722// Requires<[HasT2ExtractPack, IsThumb2]>; 1723def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF), 1724 (t2UXTB16r_rot rGPR:$Src, 8)>, 1725 Requires<[HasT2ExtractPack, IsThumb2]>; 1726 1727defm t2UXTAB : T2I_exta_rrot<0b101, "uxtab", 1728 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; 1729defm t2UXTAH : T2I_exta_rrot<0b001, "uxtah", 1730 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; 1731defm t2UXTAB16 : T2I_exta_rrot_DO<0b011, "uxtab16">; 1732} 1733 1734//===----------------------------------------------------------------------===// 1735// Arithmetic Instructions. 1736// 1737 1738defm t2ADD : T2I_bin_ii12rs<0b000, "add", 1739 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>; 1740defm t2SUB : T2I_bin_ii12rs<0b101, "sub", 1741 BinOpFrag<(sub node:$LHS, node:$RHS)>>; 1742 1743// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants. 1744defm t2ADDS : T2I_bin_s_irs <0b1000, "add", 1745 IIC_iALUi, IIC_iALUr, IIC_iALUsi, 1746 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>; 1747defm t2SUBS : T2I_bin_s_irs <0b1101, "sub", 1748 IIC_iALUi, IIC_iALUr, IIC_iALUsi, 1749 BinOpFrag<(subc node:$LHS, node:$RHS)>>; 1750 1751defm t2ADC : T2I_adde_sube_irs<0b1010, "adc", 1752 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>; 1753defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc", 1754 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>; 1755defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc", 1756 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>; 1757defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc", 1758 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>; 1759 1760// RSB 1761defm t2RSB : T2I_rbin_irs <0b1110, "rsb", 1762 BinOpFrag<(sub node:$LHS, node:$RHS)>>; 1763defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb", 1764 BinOpFrag<(subc node:$LHS, node:$RHS)>>; 1765 1766// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 1767// The assume-no-carry-in form uses the negation of the input since add/sub 1768// assume opposite meanings of the carry flag (i.e., carry == !borrow). 1769// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory 1770// details. 1771// The AddedComplexity preferences the first variant over the others since 1772// it can be shrunk to a 16-bit wide encoding, while the others cannot. 1773let AddedComplexity = 1 in 1774def : T2Pat<(add GPR:$src, imm0_255_neg:$imm), 1775 (t2SUBri GPR:$src, imm0_255_neg:$imm)>; 1776def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm), 1777 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>; 1778def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm), 1779 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>; 1780let AddedComplexity = 1 in 1781def : T2Pat<(addc rGPR:$src, imm0_255_neg:$imm), 1782 (t2SUBSri rGPR:$src, imm0_255_neg:$imm)>; 1783def : T2Pat<(addc rGPR:$src, t2_so_imm_neg:$imm), 1784 (t2SUBSri rGPR:$src, t2_so_imm_neg:$imm)>; 1785// The with-carry-in form matches bitwise not instead of the negation. 1786// Effectively, the inverse interpretation of the carry flag already accounts 1787// for part of the negation. 1788let AddedComplexity = 1 in 1789def : T2Pat<(adde rGPR:$src, imm0_255_not:$imm), 1790 (t2SBCSri rGPR:$src, imm0_255_not:$imm)>; 1791def : T2Pat<(adde rGPR:$src, t2_so_imm_not:$imm), 1792 (t2SBCSri rGPR:$src, t2_so_imm_not:$imm)>; 1793 1794// Select Bytes -- for disassembly only 1795 1796def t2SEL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, "sel", 1797 "\t$dst, $a, $b", []> { 1798 let Inst{31-27} = 0b11111; 1799 let Inst{26-24} = 0b010; 1800 let Inst{23} = 0b1; 1801 let Inst{22-20} = 0b010; 1802 let Inst{15-12} = 0b1111; 1803 let Inst{7} = 0b1; 1804 let Inst{6-4} = 0b000; 1805} 1806 1807// A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned) 1808// And Miscellaneous operations -- for disassembly only 1809class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc, 1810 list<dag> pat = [/* For disassembly only; pattern left blank */]> 1811 : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), NoItinerary, opc, 1812 "\t$dst, $a, $b", pat> { 1813 let Inst{31-27} = 0b11111; 1814 let Inst{26-23} = 0b0101; 1815 let Inst{22-20} = op22_20; 1816 let Inst{15-12} = 0b1111; 1817 let Inst{7-4} = op7_4; 1818} 1819 1820// Saturating add/subtract -- for disassembly only 1821 1822def t2QADD : T2I_pam<0b000, 0b1000, "qadd", 1823 [(set rGPR:$dst, (int_arm_qadd rGPR:$a, rGPR:$b))]>; 1824def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">; 1825def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">; 1826def t2QASX : T2I_pam<0b010, 0b0001, "qasx">; 1827def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd">; 1828def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub">; 1829def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">; 1830def t2QSUB : T2I_pam<0b000, 0b1010, "qsub", 1831 [(set rGPR:$dst, (int_arm_qsub rGPR:$a, rGPR:$b))]>; 1832def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">; 1833def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">; 1834def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">; 1835def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">; 1836def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">; 1837def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">; 1838def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">; 1839def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">; 1840 1841// Signed/Unsigned add/subtract -- for disassembly only 1842 1843def t2SASX : T2I_pam<0b010, 0b0000, "sasx">; 1844def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">; 1845def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">; 1846def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">; 1847def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">; 1848def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">; 1849def t2UASX : T2I_pam<0b010, 0b0100, "uasx">; 1850def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">; 1851def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">; 1852def t2USAX : T2I_pam<0b110, 0b0100, "usax">; 1853def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">; 1854def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">; 1855 1856// Signed/Unsigned halving add/subtract -- for disassembly only 1857 1858def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">; 1859def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">; 1860def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">; 1861def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">; 1862def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">; 1863def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">; 1864def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">; 1865def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">; 1866def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">; 1867def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">; 1868def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">; 1869def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">; 1870 1871// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only 1872 1873def t2USAD8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst), 1874 (ins rGPR:$a, rGPR:$b), 1875 NoItinerary, "usad8", "\t$dst, $a, $b", []> { 1876 let Inst{15-12} = 0b1111; 1877} 1878def t2USADA8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst), 1879 (ins rGPR:$a, rGPR:$b, rGPR:$acc), NoItinerary, "usada8", 1880 "\t$dst, $a, $b, $acc", []>; 1881 1882// Signed/Unsigned saturate -- for disassembly only 1883 1884def t2SSAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh), 1885 NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh", 1886 [/* For disassembly only; pattern left blank */]> { 1887 let Inst{31-27} = 0b11110; 1888 let Inst{25-22} = 0b1100; 1889 let Inst{20} = 0; 1890 let Inst{15} = 0; 1891} 1892 1893def t2SSAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary, 1894 "ssat16", "\t$dst, $bit_pos, $a", 1895 [/* For disassembly only; pattern left blank */]> { 1896 let Inst{31-27} = 0b11110; 1897 let Inst{25-22} = 0b1100; 1898 let Inst{20} = 0; 1899 let Inst{15} = 0; 1900 let Inst{21} = 1; // sh = '1' 1901 let Inst{14-12} = 0b000; // imm3 = '000' 1902 let Inst{7-6} = 0b00; // imm2 = '00' 1903} 1904 1905def t2USAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh), 1906 NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh", 1907 [/* For disassembly only; pattern left blank */]> { 1908 let Inst{31-27} = 0b11110; 1909 let Inst{25-22} = 0b1110; 1910 let Inst{20} = 0; 1911 let Inst{15} = 0; 1912} 1913 1914def t2USAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary, 1915 "usat16", "\t$dst, $bit_pos, $a", 1916 [/* For disassembly only; pattern left blank */]> { 1917 let Inst{31-27} = 0b11110; 1918 let Inst{25-22} = 0b1110; 1919 let Inst{20} = 0; 1920 let Inst{15} = 0; 1921 let Inst{21} = 1; // sh = '1' 1922 let Inst{14-12} = 0b000; // imm3 = '000' 1923 let Inst{7-6} = 0b00; // imm2 = '00' 1924} 1925 1926def : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>; 1927def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>; 1928 1929//===----------------------------------------------------------------------===// 1930// Shift and rotate Instructions. 1931// 1932 1933defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>; 1934defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>; 1935defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>; 1936defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>; 1937 1938let Uses = [CPSR] in { 1939def t2RRX : T2sI<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi, 1940 "rrx", "\t$dst, $src", 1941 [(set rGPR:$dst, (ARMrrx rGPR:$src))]> { 1942 let Inst{31-27} = 0b11101; 1943 let Inst{26-25} = 0b01; 1944 let Inst{24-21} = 0b0010; 1945 let Inst{20} = ?; // The S bit. 1946 let Inst{19-16} = 0b1111; // Rn 1947 let Inst{14-12} = 0b000; 1948 let Inst{7-4} = 0b0011; 1949} 1950} 1951 1952let Defs = [CPSR] in { 1953def t2MOVsrl_flag : T2TwoRegShiftImm< 1954 (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi, 1955 "lsrs", ".w\t$Rd, $Rm, #1", 1956 [(set rGPR:$Rd, (ARMsrl_flag rGPR:$Rm))]> { 1957 let Inst{31-27} = 0b11101; 1958 let Inst{26-25} = 0b01; 1959 let Inst{24-21} = 0b0010; 1960 let Inst{20} = 1; // The S bit. 1961 let Inst{19-16} = 0b1111; // Rn 1962 let Inst{5-4} = 0b01; // Shift type. 1963 // Shift amount = Inst{14-12:7-6} = 1. 1964 let Inst{14-12} = 0b000; 1965 let Inst{7-6} = 0b01; 1966} 1967def t2MOVsra_flag : T2TwoRegShiftImm< 1968 (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi, 1969 "asrs", ".w\t$Rd, $Rm, #1", 1970 [(set rGPR:$Rd, (ARMsra_flag rGPR:$Rm))]> { 1971 let Inst{31-27} = 0b11101; 1972 let Inst{26-25} = 0b01; 1973 let Inst{24-21} = 0b0010; 1974 let Inst{20} = 1; // The S bit. 1975 let Inst{19-16} = 0b1111; // Rn 1976 let Inst{5-4} = 0b10; // Shift type. 1977 // Shift amount = Inst{14-12:7-6} = 1. 1978 let Inst{14-12} = 0b000; 1979 let Inst{7-6} = 0b01; 1980} 1981} 1982 1983//===----------------------------------------------------------------------===// 1984// Bitwise Instructions. 1985// 1986 1987defm t2AND : T2I_bin_w_irs<0b0000, "and", 1988 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 1989 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>; 1990defm t2ORR : T2I_bin_w_irs<0b0010, "orr", 1991 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 1992 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>; 1993defm t2EOR : T2I_bin_w_irs<0b0100, "eor", 1994 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 1995 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>; 1996 1997defm t2BIC : T2I_bin_w_irs<0b0001, "bic", 1998 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 1999 BinOpFrag<(and node:$LHS, (not node:$RHS))>>; 2000 2001let Constraints = "$src = $dst" in 2002def t2BFC : T2I<(outs rGPR:$dst), (ins rGPR:$src, bf_inv_mask_imm:$imm), 2003 IIC_iUNAsi, "bfc", "\t$dst, $imm", 2004 [(set rGPR:$dst, (and rGPR:$src, bf_inv_mask_imm:$imm))]> { 2005 let Inst{31-27} = 0b11110; 2006 let Inst{25} = 1; 2007 let Inst{24-20} = 0b10110; 2008 let Inst{19-16} = 0b1111; // Rn 2009 let Inst{15} = 0; 2010} 2011 2012def t2SBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width), 2013 IIC_iUNAsi, "sbfx", "\t$dst, $src, $lsb, $width", []> { 2014 let Inst{31-27} = 0b11110; 2015 let Inst{25} = 1; 2016 let Inst{24-20} = 0b10100; 2017 let Inst{15} = 0; 2018} 2019 2020def t2UBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width), 2021 IIC_iUNAsi, "ubfx", "\t$dst, $src, $lsb, $width", []> { 2022 let Inst{31-27} = 0b11110; 2023 let Inst{25} = 1; 2024 let Inst{24-20} = 0b11100; 2025 let Inst{15} = 0; 2026} 2027 2028// A8.6.18 BFI - Bitfield insert (Encoding T1) 2029let Constraints = "$src = $dst" in 2030def t2BFI : T2I<(outs rGPR:$dst), 2031 (ins rGPR:$src, rGPR:$val, bf_inv_mask_imm:$imm), 2032 IIC_iBITi, "bfi", "\t$dst, $val, $imm", 2033 [(set rGPR:$dst, (ARMbfi rGPR:$src, rGPR:$val, 2034 bf_inv_mask_imm:$imm))]> { 2035 let Inst{31-27} = 0b11110; 2036 let Inst{25} = 1; 2037 let Inst{24-20} = 0b10110; 2038 let Inst{15} = 0; 2039} 2040 2041defm t2ORN : T2I_bin_irs<0b0011, "orn", 2042 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 2043 BinOpFrag<(or node:$LHS, (not node:$RHS))>, 0, "">; 2044 2045// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version 2046let AddedComplexity = 1 in 2047defm t2MVN : T2I_un_irs <0b0011, "mvn", 2048 IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi, 2049 UnOpFrag<(not node:$Src)>, 1, 1>; 2050 2051 2052let AddedComplexity = 1 in 2053def : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm), 2054 (t2BICri rGPR:$src, t2_so_imm_not:$imm)>; 2055 2056// FIXME: Disable this pattern on Darwin to workaround an assembler bug. 2057def : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm), 2058 (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>, 2059 Requires<[IsThumb2]>; 2060 2061def : T2Pat<(t2_so_imm_not:$src), 2062 (t2MVNi t2_so_imm_not:$src)>; 2063 2064//===----------------------------------------------------------------------===// 2065// Multiply Instructions. 2066// 2067let isCommutable = 1 in 2068def t2MUL: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32, 2069 "mul", "\t$dst, $a, $b", 2070 [(set rGPR:$dst, (mul rGPR:$a, rGPR:$b))]> { 2071 let Inst{31-27} = 0b11111; 2072 let Inst{26-23} = 0b0110; 2073 let Inst{22-20} = 0b000; 2074 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2075 let Inst{7-4} = 0b0000; // Multiply 2076} 2077 2078def t2MLA: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32, 2079 "mla", "\t$dst, $a, $b, $c", 2080 [(set rGPR:$dst, (add (mul rGPR:$a, rGPR:$b), rGPR:$c))]> { 2081 let Inst{31-27} = 0b11111; 2082 let Inst{26-23} = 0b0110; 2083 let Inst{22-20} = 0b000; 2084 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2085 let Inst{7-4} = 0b0000; // Multiply 2086} 2087 2088def t2MLS: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32, 2089 "mls", "\t$dst, $a, $b, $c", 2090 [(set rGPR:$dst, (sub rGPR:$c, (mul rGPR:$a, rGPR:$b)))]> { 2091 let Inst{31-27} = 0b11111; 2092 let Inst{26-23} = 0b0110; 2093 let Inst{22-20} = 0b000; 2094 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2095 let Inst{7-4} = 0b0001; // Multiply and Subtract 2096} 2097 2098// Extra precision multiplies with low / high results 2099let neverHasSideEffects = 1 in { 2100let isCommutable = 1 in { 2101def t2SMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst), 2102 (ins rGPR:$a, rGPR:$b), IIC_iMUL64, 2103 "smull", "\t$ldst, $hdst, $a, $b", []> { 2104 let Inst{31-27} = 0b11111; 2105 let Inst{26-23} = 0b0111; 2106 let Inst{22-20} = 0b000; 2107 let Inst{7-4} = 0b0000; 2108} 2109 2110def t2UMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst), 2111 (ins rGPR:$a, rGPR:$b), IIC_iMUL64, 2112 "umull", "\t$ldst, $hdst, $a, $b", []> { 2113 let Inst{31-27} = 0b11111; 2114 let Inst{26-23} = 0b0111; 2115 let Inst{22-20} = 0b010; 2116 let Inst{7-4} = 0b0000; 2117} 2118} // isCommutable 2119 2120// Multiply + accumulate 2121def t2SMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst), 2122 (ins rGPR:$a, rGPR:$b), IIC_iMAC64, 2123 "smlal", "\t$ldst, $hdst, $a, $b", []>{ 2124 let Inst{31-27} = 0b11111; 2125 let Inst{26-23} = 0b0111; 2126 let Inst{22-20} = 0b100; 2127 let Inst{7-4} = 0b0000; 2128} 2129 2130def t2UMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst), 2131 (ins rGPR:$a, rGPR:$b), IIC_iMAC64, 2132 "umlal", "\t$ldst, $hdst, $a, $b", []>{ 2133 let Inst{31-27} = 0b11111; 2134 let Inst{26-23} = 0b0111; 2135 let Inst{22-20} = 0b110; 2136 let Inst{7-4} = 0b0000; 2137} 2138 2139def t2UMAAL : T2I<(outs rGPR:$ldst, rGPR:$hdst), 2140 (ins rGPR:$a, rGPR:$b), IIC_iMAC64, 2141 "umaal", "\t$ldst, $hdst, $a, $b", []>{ 2142 let Inst{31-27} = 0b11111; 2143 let Inst{26-23} = 0b0111; 2144 let Inst{22-20} = 0b110; 2145 let Inst{7-4} = 0b0110; 2146} 2147} // neverHasSideEffects 2148 2149// Rounding variants of the below included for disassembly only 2150 2151// Most significant word multiply 2152def t2SMMUL : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32, 2153 "smmul", "\t$dst, $a, $b", 2154 [(set rGPR:$dst, (mulhs rGPR:$a, rGPR:$b))]> { 2155 let Inst{31-27} = 0b11111; 2156 let Inst{26-23} = 0b0110; 2157 let Inst{22-20} = 0b101; 2158 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2159 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) 2160} 2161 2162def t2SMMULR : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32, 2163 "smmulr", "\t$dst, $a, $b", []> { 2164 let Inst{31-27} = 0b11111; 2165 let Inst{26-23} = 0b0110; 2166 let Inst{22-20} = 0b101; 2167 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2168 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) 2169} 2170 2171def t2SMMLA : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32, 2172 "smmla", "\t$dst, $a, $b, $c", 2173 [(set rGPR:$dst, (add (mulhs rGPR:$a, rGPR:$b), rGPR:$c))]> { 2174 let Inst{31-27} = 0b11111; 2175 let Inst{26-23} = 0b0110; 2176 let Inst{22-20} = 0b101; 2177 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2178 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) 2179} 2180 2181def t2SMMLAR: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32, 2182 "smmlar", "\t$dst, $a, $b, $c", []> { 2183 let Inst{31-27} = 0b11111; 2184 let Inst{26-23} = 0b0110; 2185 let Inst{22-20} = 0b101; 2186 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2187 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) 2188} 2189 2190def t2SMMLS: T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32, 2191 "smmls", "\t$dst, $a, $b, $c", 2192 [(set rGPR:$dst, (sub rGPR:$c, (mulhs rGPR:$a, rGPR:$b)))]> { 2193 let Inst{31-27} = 0b11111; 2194 let Inst{26-23} = 0b0110; 2195 let Inst{22-20} = 0b110; 2196 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2197 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) 2198} 2199 2200def t2SMMLSR:T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32, 2201 "smmlsr", "\t$dst, $a, $b, $c", []> { 2202 let Inst{31-27} = 0b11111; 2203 let Inst{26-23} = 0b0110; 2204 let Inst{22-20} = 0b110; 2205 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2206 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) 2207} 2208 2209multiclass T2I_smul<string opc, PatFrag opnode> { 2210 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16, 2211 !strconcat(opc, "bb"), "\t$dst, $a, $b", 2212 [(set rGPR:$dst, (opnode (sext_inreg rGPR:$a, i16), 2213 (sext_inreg rGPR:$b, i16)))]> { 2214 let Inst{31-27} = 0b11111; 2215 let Inst{26-23} = 0b0110; 2216 let Inst{22-20} = 0b001; 2217 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2218 let Inst{7-6} = 0b00; 2219 let Inst{5-4} = 0b00; 2220 } 2221 2222 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16, 2223 !strconcat(opc, "bt"), "\t$dst, $a, $b", 2224 [(set rGPR:$dst, (opnode (sext_inreg rGPR:$a, i16), 2225 (sra rGPR:$b, (i32 16))))]> { 2226 let Inst{31-27} = 0b11111; 2227 let Inst{26-23} = 0b0110; 2228 let Inst{22-20} = 0b001; 2229 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2230 let Inst{7-6} = 0b00; 2231 let Inst{5-4} = 0b01; 2232 } 2233 2234 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16, 2235 !strconcat(opc, "tb"), "\t$dst, $a, $b", 2236 [(set rGPR:$dst, (opnode (sra rGPR:$a, (i32 16)), 2237 (sext_inreg rGPR:$b, i16)))]> { 2238 let Inst{31-27} = 0b11111; 2239 let Inst{26-23} = 0b0110; 2240 let Inst{22-20} = 0b001; 2241 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2242 let Inst{7-6} = 0b00; 2243 let Inst{5-4} = 0b10; 2244 } 2245 2246 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16, 2247 !strconcat(opc, "tt"), "\t$dst, $a, $b", 2248 [(set rGPR:$dst, (opnode (sra rGPR:$a, (i32 16)), 2249 (sra rGPR:$b, (i32 16))))]> { 2250 let Inst{31-27} = 0b11111; 2251 let Inst{26-23} = 0b0110; 2252 let Inst{22-20} = 0b001; 2253 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2254 let Inst{7-6} = 0b00; 2255 let Inst{5-4} = 0b11; 2256 } 2257 2258 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16, 2259 !strconcat(opc, "wb"), "\t$dst, $a, $b", 2260 [(set rGPR:$dst, (sra (opnode rGPR:$a, 2261 (sext_inreg rGPR:$b, i16)), (i32 16)))]> { 2262 let Inst{31-27} = 0b11111; 2263 let Inst{26-23} = 0b0110; 2264 let Inst{22-20} = 0b011; 2265 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2266 let Inst{7-6} = 0b00; 2267 let Inst{5-4} = 0b00; 2268 } 2269 2270 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16, 2271 !strconcat(opc, "wt"), "\t$dst, $a, $b", 2272 [(set rGPR:$dst, (sra (opnode rGPR:$a, 2273 (sra rGPR:$b, (i32 16))), (i32 16)))]> { 2274 let Inst{31-27} = 0b11111; 2275 let Inst{26-23} = 0b0110; 2276 let Inst{22-20} = 0b011; 2277 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2278 let Inst{7-6} = 0b00; 2279 let Inst{5-4} = 0b01; 2280 } 2281} 2282 2283 2284multiclass T2I_smla<string opc, PatFrag opnode> { 2285 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16, 2286 !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc", 2287 [(set rGPR:$dst, (add rGPR:$acc, 2288 (opnode (sext_inreg rGPR:$a, i16), 2289 (sext_inreg rGPR:$b, i16))))]> { 2290 let Inst{31-27} = 0b11111; 2291 let Inst{26-23} = 0b0110; 2292 let Inst{22-20} = 0b001; 2293 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2294 let Inst{7-6} = 0b00; 2295 let Inst{5-4} = 0b00; 2296 } 2297 2298 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16, 2299 !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc", 2300 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sext_inreg rGPR:$a, i16), 2301 (sra rGPR:$b, (i32 16)))))]> { 2302 let Inst{31-27} = 0b11111; 2303 let Inst{26-23} = 0b0110; 2304 let Inst{22-20} = 0b001; 2305 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2306 let Inst{7-6} = 0b00; 2307 let Inst{5-4} = 0b01; 2308 } 2309 2310 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16, 2311 !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc", 2312 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)), 2313 (sext_inreg rGPR:$b, i16))))]> { 2314 let Inst{31-27} = 0b11111; 2315 let Inst{26-23} = 0b0110; 2316 let Inst{22-20} = 0b001; 2317 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2318 let Inst{7-6} = 0b00; 2319 let Inst{5-4} = 0b10; 2320 } 2321 2322 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16, 2323 !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc", 2324 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)), 2325 (sra rGPR:$b, (i32 16)))))]> { 2326 let Inst{31-27} = 0b11111; 2327 let Inst{26-23} = 0b0110; 2328 let Inst{22-20} = 0b001; 2329 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2330 let Inst{7-6} = 0b00; 2331 let Inst{5-4} = 0b11; 2332 } 2333 2334 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16, 2335 !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc", 2336 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a, 2337 (sext_inreg rGPR:$b, i16)), (i32 16))))]> { 2338 let Inst{31-27} = 0b11111; 2339 let Inst{26-23} = 0b0110; 2340 let Inst{22-20} = 0b011; 2341 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2342 let Inst{7-6} = 0b00; 2343 let Inst{5-4} = 0b00; 2344 } 2345 2346 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16, 2347 !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc", 2348 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a, 2349 (sra rGPR:$b, (i32 16))), (i32 16))))]> { 2350 let Inst{31-27} = 0b11111; 2351 let Inst{26-23} = 0b0110; 2352 let Inst{22-20} = 0b011; 2353 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2354 let Inst{7-6} = 0b00; 2355 let Inst{5-4} = 0b01; 2356 } 2357} 2358 2359defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 2360defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 2361 2362// Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only 2363def t2SMLALBB : T2I_mac<1, 0b100, 0b1000, (outs rGPR:$ldst,rGPR:$hdst), 2364 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b", 2365 [/* For disassembly only; pattern left blank */]>; 2366def t2SMLALBT : T2I_mac<1, 0b100, 0b1001, (outs rGPR:$ldst,rGPR:$hdst), 2367 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b", 2368 [/* For disassembly only; pattern left blank */]>; 2369def t2SMLALTB : T2I_mac<1, 0b100, 0b1010, (outs rGPR:$ldst,rGPR:$hdst), 2370 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b", 2371 [/* For disassembly only; pattern left blank */]>; 2372def t2SMLALTT : T2I_mac<1, 0b100, 0b1011, (outs rGPR:$ldst,rGPR:$hdst), 2373 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b", 2374 [/* For disassembly only; pattern left blank */]>; 2375 2376// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD 2377// These are for disassembly only. 2378 2379def t2SMUAD: T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), 2380 IIC_iMAC32, "smuad", "\t$dst, $a, $b", []> { 2381 let Inst{15-12} = 0b1111; 2382} 2383def t2SMUADX:T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), 2384 IIC_iMAC32, "smuadx", "\t$dst, $a, $b", []> { 2385 let Inst{15-12} = 0b1111; 2386} 2387def t2SMUSD: T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), 2388 IIC_iMAC32, "smusd", "\t$dst, $a, $b", []> { 2389 let Inst{15-12} = 0b1111; 2390} 2391def t2SMUSDX:T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), 2392 IIC_iMAC32, "smusdx", "\t$dst, $a, $b", []> { 2393 let Inst{15-12} = 0b1111; 2394} 2395def t2SMLAD : T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst), 2396 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlad", 2397 "\t$dst, $a, $b, $acc", []>; 2398def t2SMLADX : T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst), 2399 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smladx", 2400 "\t$dst, $a, $b, $acc", []>; 2401def t2SMLSD : T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst), 2402 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsd", 2403 "\t$dst, $a, $b, $acc", []>; 2404def t2SMLSDX : T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst), 2405 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsdx", 2406 "\t$dst, $a, $b, $acc", []>; 2407def t2SMLALD : T2I_mac<1, 0b100, 0b1100, (outs rGPR:$ldst,rGPR:$hdst), 2408 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlald", 2409 "\t$ldst, $hdst, $a, $b", []>; 2410def t2SMLALDX : T2I_mac<1, 0b100, 0b1101, (outs rGPR:$ldst,rGPR:$hdst), 2411 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaldx", 2412 "\t$ldst, $hdst, $a, $b", []>; 2413def t2SMLSLD : T2I_mac<1, 0b101, 0b1100, (outs rGPR:$ldst,rGPR:$hdst), 2414 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsld", 2415 "\t$ldst, $hdst, $a, $b", []>; 2416def t2SMLSLDX : T2I_mac<1, 0b101, 0b1101, (outs rGPR:$ldst,rGPR:$hdst), 2417 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsldx", 2418 "\t$ldst, $hdst, $a, $b", []>; 2419 2420//===----------------------------------------------------------------------===// 2421// Misc. Arithmetic Instructions. 2422// 2423 2424class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops, 2425 InstrItinClass itin, string opc, string asm, list<dag> pattern> 2426 : T2I<oops, iops, itin, opc, asm, pattern> { 2427 let Inst{31-27} = 0b11111; 2428 let Inst{26-22} = 0b01010; 2429 let Inst{21-20} = op1; 2430 let Inst{15-12} = 0b1111; 2431 let Inst{7-6} = 0b10; 2432 let Inst{5-4} = op2; 2433} 2434 2435def t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr, 2436 "clz", "\t$dst, $src", [(set rGPR:$dst, (ctlz rGPR:$src))]>; 2437 2438def t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr, 2439 "rbit", "\t$dst, $src", 2440 [(set rGPR:$dst, (ARMrbit rGPR:$src))]>; 2441 2442def t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr, 2443 "rev", ".w\t$dst, $src", [(set rGPR:$dst, (bswap rGPR:$src))]>; 2444 2445def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr, 2446 "rev16", ".w\t$dst, $src", 2447 [(set rGPR:$dst, 2448 (or (and (srl rGPR:$src, (i32 8)), 0xFF), 2449 (or (and (shl rGPR:$src, (i32 8)), 0xFF00), 2450 (or (and (srl rGPR:$src, (i32 8)), 0xFF0000), 2451 (and (shl rGPR:$src, (i32 8)), 0xFF000000)))))]>; 2452 2453def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr, 2454 "revsh", ".w\t$dst, $src", 2455 [(set rGPR:$dst, 2456 (sext_inreg 2457 (or (srl (and rGPR:$src, 0xFF00), (i32 8)), 2458 (shl rGPR:$src, (i32 8))), i16))]>; 2459 2460def t2PKHBT : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh), 2461 IIC_iBITsi, "pkhbt", "\t$dst, $src1, $src2$sh", 2462 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF), 2463 (and (shl rGPR:$src2, lsl_amt:$sh), 2464 0xFFFF0000)))]>, 2465 Requires<[HasT2ExtractPack, IsThumb2]> { 2466 let Inst{31-27} = 0b11101; 2467 let Inst{26-25} = 0b01; 2468 let Inst{24-20} = 0b01100; 2469 let Inst{5} = 0; // BT form 2470 let Inst{4} = 0; 2471} 2472 2473// Alternate cases for PKHBT where identities eliminate some nodes. 2474def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)), 2475 (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>, 2476 Requires<[HasT2ExtractPack, IsThumb2]>; 2477def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)), 2478 (t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>, 2479 Requires<[HasT2ExtractPack, IsThumb2]>; 2480 2481// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and 2482// will match the pattern below. 2483def t2PKHTB : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh), 2484 IIC_iBITsi, "pkhtb", "\t$dst, $src1, $src2$sh", 2485 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF0000), 2486 (and (sra rGPR:$src2, asr_amt:$sh), 2487 0xFFFF)))]>, 2488 Requires<[HasT2ExtractPack, IsThumb2]> { 2489 let Inst{31-27} = 0b11101; 2490 let Inst{26-25} = 0b01; 2491 let Inst{24-20} = 0b01100; 2492 let Inst{5} = 1; // TB form 2493 let Inst{4} = 0; 2494} 2495 2496// Alternate cases for PKHTB where identities eliminate some nodes. Note that 2497// a shift amount of 0 is *not legal* here, it is PKHBT instead. 2498def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)), 2499 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>, 2500 Requires<[HasT2ExtractPack, IsThumb2]>; 2501def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), 2502 (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)), 2503 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>, 2504 Requires<[HasT2ExtractPack, IsThumb2]>; 2505 2506//===----------------------------------------------------------------------===// 2507// Comparison Instructions... 2508// 2509defm t2CMP : T2I_cmp_irs<0b1101, "cmp", 2510 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi, 2511 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>; 2512defm t2CMPz : T2I_cmp_irs<0b1101, "cmp", 2513 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi, 2514 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>; 2515 2516//FIXME: Disable CMN, as CCodes are backwards from compare expectations 2517// Compare-to-zero still works out, just not the relationals 2518//defm t2CMN : T2I_cmp_irs<0b1000, "cmn", 2519// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>; 2520defm t2CMNz : T2I_cmp_irs<0b1000, "cmn", 2521 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi, 2522 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>; 2523 2524//def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm), 2525// (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>; 2526 2527def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm), 2528 (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>; 2529 2530defm t2TST : T2I_cmp_irs<0b0000, "tst", 2531 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi, 2532 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>; 2533defm t2TEQ : T2I_cmp_irs<0b0100, "teq", 2534 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi, 2535 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>; 2536 2537// Conditional moves 2538// FIXME: should be able to write a pattern for ARMcmov, but can't use 2539// a two-value operand where a dag node expects two operands. :( 2540let neverHasSideEffects = 1 in { 2541def t2MOVCCr : T2I<(outs rGPR:$dst), (ins rGPR:$false, rGPR:$true), IIC_iCMOVr, 2542 "mov", ".w\t$dst, $true", 2543 [/*(set rGPR:$dst, (ARMcmov rGPR:$false, rGPR:$true, imm:$cc, CCR:$ccr))*/]>, 2544 RegConstraint<"$false = $dst"> { 2545 let Inst{31-27} = 0b11101; 2546 let Inst{26-25} = 0b01; 2547 let Inst{24-21} = 0b0010; 2548 let Inst{20} = 0; // The S bit. 2549 let Inst{19-16} = 0b1111; // Rn 2550 let Inst{14-12} = 0b000; 2551 let Inst{7-4} = 0b0000; 2552} 2553 2554def t2MOVCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true), 2555 IIC_iCMOVi, "mov", ".w\t$dst, $true", 2556[/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>, 2557 RegConstraint<"$false = $dst"> { 2558 let Inst{31-27} = 0b11110; 2559 let Inst{25} = 0; 2560 let Inst{24-21} = 0b0010; 2561 let Inst{20} = 0; // The S bit. 2562 let Inst{19-16} = 0b1111; // Rn 2563 let Inst{15} = 0; 2564} 2565 2566def t2MOVCCi16 : T2I<(outs rGPR:$dst), (ins rGPR:$false, i32imm:$src), 2567 IIC_iCMOVi, 2568 "movw", "\t$dst, $src", []>, 2569 RegConstraint<"$false = $dst"> { 2570 let Inst{31-27} = 0b11110; 2571 let Inst{25} = 1; 2572 let Inst{24-21} = 0b0010; 2573 let Inst{20} = 0; // The S bit. 2574 let Inst{15} = 0; 2575} 2576 2577def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst), 2578 (ins rGPR:$false, i32imm:$src, pred:$p), 2579 IIC_iCMOVix2, "", []>, RegConstraint<"$false = $dst">; 2580 2581def t2MVNCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true), 2582 IIC_iCMOVi, "mvn", ".w\t$dst, $true", 2583[/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm_not:$true, 2584 imm:$cc, CCR:$ccr))*/]>, 2585 RegConstraint<"$false = $dst"> { 2586 let Inst{31-27} = 0b11110; 2587 let Inst{25} = 0; 2588 let Inst{24-21} = 0b0011; 2589 let Inst{20} = 0; // The S bit. 2590 let Inst{19-16} = 0b1111; // Rn 2591 let Inst{15} = 0; 2592} 2593 2594class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 2595 string opc, string asm, list<dag> pattern> 2596 : T2TwoRegShiftImm<oops, iops, itin, opc, asm, pattern> { 2597 let Inst{31-27} = 0b11101; 2598 let Inst{26-25} = 0b01; 2599 let Inst{24-21} = 0b0010; 2600 let Inst{20} = 0; // The S bit. 2601 let Inst{19-16} = 0b1111; // Rn 2602 let Inst{5-4} = opcod; // Shift type. 2603} 2604def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$Rd), 2605 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm), 2606 IIC_iCMOVsi, "lsl", ".w\t$Rd, $Rm, $imm", []>, 2607 RegConstraint<"$false = $Rd">; 2608def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$Rd), 2609 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm), 2610 IIC_iCMOVsi, "lsr", ".w\t$Rd, $Rm, $imm", []>, 2611 RegConstraint<"$false = $Rd">; 2612def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$Rd), 2613 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm), 2614 IIC_iCMOVsi, "asr", ".w\t$Rd, $Rm, $imm", []>, 2615 RegConstraint<"$false = $Rd">; 2616def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$Rd), 2617 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm), 2618 IIC_iCMOVsi, "ror", ".w\t$Rd, $Rm, $imm", []>, 2619 RegConstraint<"$false = $Rd">; 2620} // neverHasSideEffects 2621 2622//===----------------------------------------------------------------------===// 2623// Atomic operations intrinsics 2624// 2625 2626// memory barriers protect the atomic sequences 2627let hasSideEffects = 1 in { 2628def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary, 2629 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>, 2630 Requires<[IsThumb, HasDB]> { 2631 bits<4> opt; 2632 let Inst{31-4} = 0xf3bf8f5; 2633 let Inst{3-0} = opt; 2634} 2635} 2636 2637def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary, 2638 "dsb", "\t$opt", 2639 [/* For disassembly only; pattern left blank */]>, 2640 Requires<[IsThumb, HasDB]> { 2641 bits<4> opt; 2642 let Inst{31-4} = 0xf3bf8f4; 2643 let Inst{3-0} = opt; 2644} 2645 2646// ISB has only full system option -- for disassembly only 2647def t2ISB : T2I<(outs), (ins), NoItinerary, "isb", "", 2648 [/* For disassembly only; pattern left blank */]>, 2649 Requires<[IsThumb2, HasV7]> { 2650 let Inst{31-4} = 0xf3bf8f6; 2651 let Inst{3-0} = 0b1111; 2652} 2653 2654class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz, 2655 InstrItinClass itin, string opc, string asm, string cstr, 2656 list<dag> pattern, bits<4> rt2 = 0b1111> 2657 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> { 2658 let Inst{31-27} = 0b11101; 2659 let Inst{26-20} = 0b0001101; 2660 let Inst{11-8} = rt2; 2661 let Inst{7-6} = 0b01; 2662 let Inst{5-4} = opcod; 2663 let Inst{3-0} = 0b1111; 2664} 2665class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz, 2666 InstrItinClass itin, string opc, string asm, string cstr, 2667 list<dag> pattern, bits<4> rt2 = 0b1111> 2668 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> { 2669 let Inst{31-27} = 0b11101; 2670 let Inst{26-20} = 0b0001100; 2671 let Inst{11-8} = rt2; 2672 let Inst{7-6} = 0b01; 2673 let Inst{5-4} = opcod; 2674} 2675 2676let mayLoad = 1 in { 2677def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone, 2678 Size4Bytes, NoItinerary, "ldrexb", "\t$dest, [$ptr]", 2679 "", []>; 2680def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone, 2681 Size4Bytes, NoItinerary, "ldrexh", "\t$dest, [$ptr]", 2682 "", []>; 2683def t2LDREX : Thumb2I<(outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone, 2684 Size4Bytes, NoItinerary, 2685 "ldrex", "\t$dest, [$ptr]", "", 2686 []> { 2687 let Inst{31-27} = 0b11101; 2688 let Inst{26-20} = 0b0000101; 2689 let Inst{11-8} = 0b1111; 2690 let Inst{7-0} = 0b00000000; // imm8 = 0 2691} 2692def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$dest, rGPR:$dest2), (ins rGPR:$ptr), 2693 AddrModeNone, Size4Bytes, NoItinerary, 2694 "ldrexd", "\t$dest, $dest2, [$ptr]", "", 2695 [], {?, ?, ?, ?}>; 2696} 2697 2698let mayStore = 1, Constraints = "@earlyclobber $success" in { 2699def t2STREXB : T2I_strex<0b00, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr), 2700 AddrModeNone, Size4Bytes, NoItinerary, 2701 "strexb", "\t$success, $src, [$ptr]", "", []>; 2702def t2STREXH : T2I_strex<0b01, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr), 2703 AddrModeNone, Size4Bytes, NoItinerary, 2704 "strexh", "\t$success, $src, [$ptr]", "", []>; 2705def t2STREX : Thumb2I<(outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr), 2706 AddrModeNone, Size4Bytes, NoItinerary, 2707 "strex", "\t$success, $src, [$ptr]", "", 2708 []> { 2709 let Inst{31-27} = 0b11101; 2710 let Inst{26-20} = 0b0000100; 2711 let Inst{7-0} = 0b00000000; // imm8 = 0 2712} 2713def t2STREXD : T2I_strex<0b11, (outs rGPR:$success), 2714 (ins rGPR:$src, rGPR:$src2, rGPR:$ptr), 2715 AddrModeNone, Size4Bytes, NoItinerary, 2716 "strexd", "\t$success, $src, $src2, [$ptr]", "", [], 2717 {?, ?, ?, ?}>; 2718} 2719 2720// Clear-Exclusive is for disassembly only. 2721def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "", 2722 [/* For disassembly only; pattern left blank */]>, 2723 Requires<[IsARM, HasV7]> { 2724 let Inst{31-20} = 0xf3b; 2725 let Inst{15-14} = 0b10; 2726 let Inst{12} = 0; 2727 let Inst{7-4} = 0b0010; 2728} 2729 2730//===----------------------------------------------------------------------===// 2731// TLS Instructions 2732// 2733 2734// __aeabi_read_tp preserves the registers r1-r3. 2735let isCall = 1, 2736 Defs = [R0, R12, LR, CPSR] in { 2737 def t2TPsoft : T2XI<(outs), (ins), IIC_Br, 2738 "bl\t__aeabi_read_tp", 2739 [(set R0, ARMthread_pointer)]> { 2740 let Inst{31-27} = 0b11110; 2741 let Inst{15-14} = 0b11; 2742 let Inst{12} = 1; 2743 } 2744} 2745 2746//===----------------------------------------------------------------------===// 2747// SJLJ Exception handling intrinsics 2748// eh_sjlj_setjmp() is an instruction sequence to store the return 2749// address and save #0 in R0 for the non-longjmp case. 2750// Since by its nature we may be coming from some other function to get 2751// here, and we're using the stack frame for the containing function to 2752// save/restore registers, we can't keep anything live in regs across 2753// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 2754// when we get here from a longjmp(). We force everthing out of registers 2755// except for our own input by listing the relevant registers in Defs. By 2756// doing so, we also cause the prologue/epilogue code to actively preserve 2757// all of the callee-saved resgisters, which is exactly what we want. 2758// $val is a scratch register for our use. 2759let Defs = 2760 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0, 2761 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, 2762 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, 2763 D31 ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in { 2764 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val), 2765 AddrModeNone, SizeSpecial, NoItinerary, "", "", 2766 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>, 2767 Requires<[IsThumb2, HasVFP2]>; 2768} 2769 2770let Defs = 2771 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ], 2772 hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in { 2773 def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val), 2774 AddrModeNone, SizeSpecial, NoItinerary, "", "", 2775 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>, 2776 Requires<[IsThumb2, NoVFP]>; 2777} 2778 2779 2780//===----------------------------------------------------------------------===// 2781// Control-Flow Instructions 2782// 2783 2784// FIXME: remove when we have a way to marking a MI with these properties. 2785// FIXME: $dst1 should be a def. But the extra ops must be in the end of the 2786// operand list. 2787// FIXME: Should pc be an implicit operand like PICADD, etc? 2788let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 2789 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in 2790 def t2LDM_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p, 2791 reglist:$dsts, variable_ops), 2792 IIC_iLoad_mBr, 2793 "ldm${amode}${p}.w\t$Rn!, $dsts", 2794 "$Rn = $wb", []> { 2795 let Inst{31-27} = 0b11101; 2796 let Inst{26-25} = 0b00; 2797 let Inst{24-23} = {?, ?}; // IA: '01', DB: '10' 2798 let Inst{22} = 0; 2799 let Inst{21} = 1; // The W bit. 2800 let Inst{20} = 1; // Load 2801} 2802 2803let isBranch = 1, isTerminator = 1, isBarrier = 1 in { 2804let isPredicable = 1 in 2805def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br, 2806 "b.w\t$target", 2807 [(br bb:$target)]> { 2808 let Inst{31-27} = 0b11110; 2809 let Inst{15-14} = 0b10; 2810 let Inst{12} = 1; 2811} 2812 2813let isNotDuplicable = 1, isIndirectBranch = 1, 2814 isCodeGenOnly = 1 in { // $id doesn't exist in asmstring, should be lowered. 2815def t2BR_JT : 2816 T2JTI<(outs), 2817 (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id), 2818 IIC_Br, "mov\tpc, $target$jt", 2819 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]> { 2820 let Inst{31-27} = 0b11101; 2821 let Inst{26-20} = 0b0100100; 2822 let Inst{19-16} = 0b1111; 2823 let Inst{14-12} = 0b000; 2824 let Inst{11-8} = 0b1111; // Rd = pc 2825 let Inst{7-4} = 0b0000; 2826} 2827 2828// FIXME: Add a non-pc based case that can be predicated. 2829let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered. 2830def t2TBB : 2831 T2JTI<(outs), 2832 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id), 2833 IIC_Br, "tbb\t$index$jt", []> { 2834 let Inst{31-27} = 0b11101; 2835 let Inst{26-20} = 0b0001101; 2836 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction) 2837 let Inst{15-8} = 0b11110000; 2838 let Inst{7-4} = 0b0000; // B form 2839} 2840 2841let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered. 2842def t2TBH : 2843 T2JTI<(outs), 2844 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id), 2845 IIC_Br, "tbh\t$index$jt", []> { 2846 let Inst{31-27} = 0b11101; 2847 let Inst{26-20} = 0b0001101; 2848 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction) 2849 let Inst{15-8} = 0b11110000; 2850 let Inst{7-4} = 0b0001; // H form 2851} 2852 2853// Generic versions of the above two instructions, for disassembly only 2854 2855def t2TBBgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br, 2856 "tbb", "\t[$a, $b]", []>{ 2857 let Inst{31-27} = 0b11101; 2858 let Inst{26-20} = 0b0001101; 2859 let Inst{15-8} = 0b11110000; 2860 let Inst{7-4} = 0b0000; // B form 2861} 2862 2863def t2TBHgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br, 2864 "tbh", "\t[$a, $b, lsl #1]", []> { 2865 let Inst{31-27} = 0b11101; 2866 let Inst{26-20} = 0b0001101; 2867 let Inst{15-8} = 0b11110000; 2868 let Inst{7-4} = 0b0001; // H form 2869} 2870} // isNotDuplicable, isIndirectBranch 2871 2872} // isBranch, isTerminator, isBarrier 2873 2874// FIXME: should be able to write a pattern for ARMBrcond, but can't use 2875// a two-value operand where a dag node expects two operands. :( 2876let isBranch = 1, isTerminator = 1 in 2877def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br, 2878 "b", ".w\t$target", 2879 [/*(ARMbrcond bb:$target, imm:$cc)*/]> { 2880 let Inst{31-27} = 0b11110; 2881 let Inst{15-14} = 0b10; 2882 let Inst{12} = 0; 2883} 2884 2885 2886// IT block 2887let Defs = [ITSTATE] in 2888def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask), 2889 AddrModeNone, Size2Bytes, IIC_iALUx, 2890 "it$mask\t$cc", "", []> { 2891 // 16-bit instruction. 2892 let Inst{31-16} = 0x0000; 2893 let Inst{15-8} = 0b10111111; 2894} 2895 2896// Branch and Exchange Jazelle -- for disassembly only 2897// Rm = Inst{19-16} 2898def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func", 2899 [/* For disassembly only; pattern left blank */]> { 2900 let Inst{31-27} = 0b11110; 2901 let Inst{26} = 0; 2902 let Inst{25-20} = 0b111100; 2903 let Inst{15-14} = 0b10; 2904 let Inst{12} = 0; 2905} 2906 2907// Change Processor State is a system instruction -- for disassembly only. 2908// The singleton $opt operand contains the following information: 2909// opt{4-0} = mode from Inst{4-0} 2910// opt{5} = changemode from Inst{17} 2911// opt{8-6} = AIF from Inst{8-6} 2912// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable 2913def t2CPS : T2XI<(outs),(ins cps_opt:$opt), NoItinerary, "cps$opt", 2914 [/* For disassembly only; pattern left blank */]> { 2915 let Inst{31-27} = 0b11110; 2916 let Inst{26} = 0; 2917 let Inst{25-20} = 0b111010; 2918 let Inst{15-14} = 0b10; 2919 let Inst{12} = 0; 2920} 2921 2922// A6.3.4 Branches and miscellaneous control 2923// Table A6-14 Change Processor State, and hint instructions 2924// Helper class for disassembly only. 2925class T2I_hint<bits<8> op7_0, string opc, string asm> 2926 : T2I<(outs), (ins), NoItinerary, opc, asm, 2927 [/* For disassembly only; pattern left blank */]> { 2928 let Inst{31-20} = 0xf3a; 2929 let Inst{15-14} = 0b10; 2930 let Inst{12} = 0; 2931 let Inst{10-8} = 0b000; 2932 let Inst{7-0} = op7_0; 2933} 2934 2935def t2NOP : T2I_hint<0b00000000, "nop", ".w">; 2936def t2YIELD : T2I_hint<0b00000001, "yield", ".w">; 2937def t2WFE : T2I_hint<0b00000010, "wfe", ".w">; 2938def t2WFI : T2I_hint<0b00000011, "wfi", ".w">; 2939def t2SEV : T2I_hint<0b00000100, "sev", ".w">; 2940 2941def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt", 2942 [/* For disassembly only; pattern left blank */]> { 2943 let Inst{31-20} = 0xf3a; 2944 let Inst{15-14} = 0b10; 2945 let Inst{12} = 0; 2946 let Inst{10-8} = 0b000; 2947 let Inst{7-4} = 0b1111; 2948} 2949 2950// Secure Monitor Call is a system instruction -- for disassembly only 2951// Option = Inst{19-16} 2952def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt", 2953 [/* For disassembly only; pattern left blank */]> { 2954 let Inst{31-27} = 0b11110; 2955 let Inst{26-20} = 0b1111111; 2956 let Inst{15-12} = 0b1000; 2957} 2958 2959// Store Return State is a system instruction -- for disassembly only 2960def t2SRSDBW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode", 2961 [/* For disassembly only; pattern left blank */]> { 2962 let Inst{31-27} = 0b11101; 2963 let Inst{26-20} = 0b0000010; // W = 1 2964} 2965 2966def t2SRSDB : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode", 2967 [/* For disassembly only; pattern left blank */]> { 2968 let Inst{31-27} = 0b11101; 2969 let Inst{26-20} = 0b0000000; // W = 0 2970} 2971 2972def t2SRSIAW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode", 2973 [/* For disassembly only; pattern left blank */]> { 2974 let Inst{31-27} = 0b11101; 2975 let Inst{26-20} = 0b0011010; // W = 1 2976} 2977 2978def t2SRSIA : T2I<(outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode", 2979 [/* For disassembly only; pattern left blank */]> { 2980 let Inst{31-27} = 0b11101; 2981 let Inst{26-20} = 0b0011000; // W = 0 2982} 2983 2984// Return From Exception is a system instruction -- for disassembly only 2985def t2RFEDBW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfedb", "\t$base!", 2986 [/* For disassembly only; pattern left blank */]> { 2987 let Inst{31-27} = 0b11101; 2988 let Inst{26-20} = 0b0000011; // W = 1 2989} 2990 2991def t2RFEDB : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeab", "\t$base", 2992 [/* For disassembly only; pattern left blank */]> { 2993 let Inst{31-27} = 0b11101; 2994 let Inst{26-20} = 0b0000001; // W = 0 2995} 2996 2997def t2RFEIAW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base!", 2998 [/* For disassembly only; pattern left blank */]> { 2999 let Inst{31-27} = 0b11101; 3000 let Inst{26-20} = 0b0011011; // W = 1 3001} 3002 3003def t2RFEIA : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base", 3004 [/* For disassembly only; pattern left blank */]> { 3005 let Inst{31-27} = 0b11101; 3006 let Inst{26-20} = 0b0011001; // W = 0 3007} 3008 3009//===----------------------------------------------------------------------===// 3010// Non-Instruction Patterns 3011// 3012 3013// Two piece so_imms. 3014def : T2Pat<(or rGPR:$LHS, t2_so_imm2part:$RHS), 3015 (t2ORRri (t2ORRri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)), 3016 (t2_so_imm2part_2 imm:$RHS))>; 3017def : T2Pat<(xor rGPR:$LHS, t2_so_imm2part:$RHS), 3018 (t2EORri (t2EORri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)), 3019 (t2_so_imm2part_2 imm:$RHS))>; 3020def : T2Pat<(add rGPR:$LHS, t2_so_imm2part:$RHS), 3021 (t2ADDri (t2ADDri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)), 3022 (t2_so_imm2part_2 imm:$RHS))>; 3023def : T2Pat<(add rGPR:$LHS, t2_so_neg_imm2part:$RHS), 3024 (t2SUBri (t2SUBri rGPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)), 3025 (t2_so_neg_imm2part_2 imm:$RHS))>; 3026 3027// 32-bit immediate using movw + movt. 3028// This is a single pseudo instruction to make it re-materializable. 3029// FIXME: Remove this when we can do generalized remat. 3030let isReMaterializable = 1 in 3031def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2, 3032 "", [(set rGPR:$dst, (i32 imm:$src))]>, 3033 Requires<[IsThumb, HasV6T2]>; 3034 3035// ConstantPool, GlobalAddress, and JumpTable 3036def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>, 3037 Requires<[IsThumb2, DontUseMovt]>; 3038def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>; 3039def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>, 3040 Requires<[IsThumb2, UseMovt]>; 3041 3042def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), 3043 (t2LEApcrelJT tjumptable:$dst, imm:$id)>; 3044 3045// Pseudo instruction that combines ldr from constpool and add pc. This should 3046// be expanded into two instructions late to allow if-conversion and 3047// scheduling. 3048let canFoldAsLoad = 1, isReMaterializable = 1 in 3049def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp), 3050 IIC_iLoadiALU, "", 3051 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)), 3052 imm:$cp))]>, 3053 Requires<[IsThumb2]>; 3054 3055//===----------------------------------------------------------------------===// 3056// Move between special register and ARM core register -- for disassembly only 3057// 3058 3059// Rd = Instr{11-8} 3060def t2MRS : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, cpsr", 3061 [/* For disassembly only; pattern left blank */]> { 3062 let Inst{31-27} = 0b11110; 3063 let Inst{26} = 0; 3064 let Inst{25-21} = 0b11111; 3065 let Inst{20} = 0; // The R bit. 3066 let Inst{15-14} = 0b10; 3067 let Inst{12} = 0; 3068} 3069 3070// Rd = Instr{11-8} 3071def t2MRSsys : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr", 3072 [/* For disassembly only; pattern left blank */]> { 3073 let Inst{31-27} = 0b11110; 3074 let Inst{26} = 0; 3075 let Inst{25-21} = 0b11111; 3076 let Inst{20} = 1; // The R bit. 3077 let Inst{15-14} = 0b10; 3078 let Inst{12} = 0; 3079} 3080 3081// Rn = Inst{19-16} 3082def t2MSR : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr", 3083 "\tcpsr$mask, $src", 3084 [/* For disassembly only; pattern left blank */]> { 3085 let Inst{31-27} = 0b11110; 3086 let Inst{26} = 0; 3087 let Inst{25-21} = 0b11100; 3088 let Inst{20} = 0; // The R bit. 3089 let Inst{15-14} = 0b10; 3090 let Inst{12} = 0; 3091} 3092 3093// Rn = Inst{19-16} 3094def t2MSRsys : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr", 3095 "\tspsr$mask, $src", 3096 [/* For disassembly only; pattern left blank */]> { 3097 let Inst{31-27} = 0b11110; 3098 let Inst{26} = 0; 3099 let Inst{25-21} = 0b11100; 3100 let Inst{20} = 1; // The R bit. 3101 let Inst{15-14} = 0b10; 3102 let Inst{12} = 0; 3103} 3104