ARMInstrThumb2.td revision 73fe34a3ee866867d5028f4a9afa2c3b8efebcba
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 : T2sTwoRegImm<(outs GPR:$Rd), (ins GPR:$sp, t2_so_reg:$imm), 1145 IIC_iALUsi, 1146 "sub", "\t$Rd, $sp, $imm", []> { 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 : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi, 1157 "sdiv", "\t$Rd, $Rn, $Rm", 1158 [(set rGPR:$Rd, (sdiv rGPR:$Rn, rGPR:$Rm))]>, 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 : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi, 1168 "udiv", "\t$Rd, $Rn, $Rm", 1169 [(set rGPR:$Rd, (udiv rGPR:$Rn, rGPR:$Rm))]>, 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, "ia${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, "ia${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 1566let neverHasSideEffects = 1 in { 1567 1568let mayLoad = 1, hasExtraDefRegAllocReq = 1 in 1569defm t2LDM : thumb2_ldst_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>; 1570 1571let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 1572defm t2STM : thumb2_ldst_mult<"stm", IIC_iStore_m, IIC_iStore_mu, 0>; 1573 1574} // neverHasSideEffects 1575 1576 1577//===----------------------------------------------------------------------===// 1578// Move Instructions. 1579// 1580 1581let neverHasSideEffects = 1 in 1582def t2MOVr : T2sTwoReg<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVr, 1583 "mov", ".w\t$Rd, $Rm", []> { 1584 let Inst{31-27} = 0b11101; 1585 let Inst{26-25} = 0b01; 1586 let Inst{24-21} = 0b0010; 1587 let Inst{20} = ?; // The S bit. 1588 let Inst{19-16} = 0b1111; // Rn 1589 let Inst{14-12} = 0b000; 1590 let Inst{7-4} = 0b0000; 1591} 1592 1593// AddedComplexity to ensure isel tries t2MOVi before t2MOVi16. 1594let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in 1595def t2MOVi : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), IIC_iMOVi, 1596 "mov", ".w\t$Rd, $imm", 1597 [(set rGPR:$Rd, t2_so_imm:$imm)]> { 1598 let Inst{31-27} = 0b11110; 1599 let Inst{25} = 0; 1600 let Inst{24-21} = 0b0010; 1601 let Inst{20} = ?; // The S bit. 1602 let Inst{19-16} = 0b1111; // Rn 1603 let Inst{15} = 0; 1604} 1605 1606let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1607def t2MOVi16 : T2I<(outs rGPR:$Rd), (ins i32imm:$imm), IIC_iMOVi, 1608 "movw", "\t$Rd, $imm", 1609 [(set rGPR:$Rd, imm0_65535:$imm)]> { 1610 let Inst{31-27} = 0b11110; 1611 let Inst{25} = 1; 1612 let Inst{24-21} = 0b0010; 1613 let Inst{20} = 0; // The S bit. 1614 let Inst{15} = 0; 1615 1616 bits<4> Rd; 1617 bits<16> imm; 1618 1619 let Inst{11-8} = Rd{3-0}; 1620 let Inst{19-16} = imm{15-12}; 1621 let Inst{26} = imm{11}; 1622 let Inst{14-12} = imm{10-8}; 1623 let Inst{7-0} = imm{7-0}; 1624} 1625 1626let Constraints = "$src = $Rd" in 1627def t2MOVTi16 : T2I<(outs rGPR:$Rd), (ins rGPR:$src, i32imm:$imm), IIC_iMOVi, 1628 "movt", "\t$Rd, $imm", 1629 [(set rGPR:$Rd, 1630 (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]> { 1631 let Inst{31-27} = 0b11110; 1632 let Inst{25} = 1; 1633 let Inst{24-21} = 0b0110; 1634 let Inst{20} = 0; // The S bit. 1635 let Inst{15} = 0; 1636 1637 bits<4> Rd; 1638 bits<16> imm; 1639 1640 let Inst{11-8} = Rd{3-0}; 1641 let Inst{19-16} = imm{15-12}; 1642 let Inst{26} = imm{11}; 1643 let Inst{14-12} = imm{10-8}; 1644 let Inst{7-0} = imm{7-0}; 1645} 1646 1647def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>; 1648 1649//===----------------------------------------------------------------------===// 1650// Extend Instructions. 1651// 1652 1653// Sign extenders 1654 1655defm t2SXTB : T2I_ext_rrot<0b100, "sxtb", 1656 UnOpFrag<(sext_inreg node:$Src, i8)>>; 1657defm t2SXTH : T2I_ext_rrot<0b000, "sxth", 1658 UnOpFrag<(sext_inreg node:$Src, i16)>>; 1659defm t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">; 1660 1661defm t2SXTAB : T2I_exta_rrot<0b100, "sxtab", 1662 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>; 1663defm t2SXTAH : T2I_exta_rrot<0b000, "sxtah", 1664 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>; 1665defm t2SXTAB16 : T2I_exta_rrot_DO<0b010, "sxtab16">; 1666 1667// TODO: SXT(A){B|H}16 - done for disassembly only 1668 1669// Zero extenders 1670 1671let AddedComplexity = 16 in { 1672defm t2UXTB : T2I_ext_rrot<0b101, "uxtb", 1673 UnOpFrag<(and node:$Src, 0x000000FF)>>; 1674defm t2UXTH : T2I_ext_rrot<0b001, "uxth", 1675 UnOpFrag<(and node:$Src, 0x0000FFFF)>>; 1676defm t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16", 1677 UnOpFrag<(and node:$Src, 0x00FF00FF)>>; 1678 1679// FIXME: This pattern incorrectly assumes the shl operator is a rotate. 1680// The transformation should probably be done as a combiner action 1681// instead so we can include a check for masking back in the upper 1682// eight bits of the source into the lower eight bits of the result. 1683//def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF), 1684// (t2UXTB16r_rot rGPR:$Src, 24)>, 1685// Requires<[HasT2ExtractPack, IsThumb2]>; 1686def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF), 1687 (t2UXTB16r_rot rGPR:$Src, 8)>, 1688 Requires<[HasT2ExtractPack, IsThumb2]>; 1689 1690defm t2UXTAB : T2I_exta_rrot<0b101, "uxtab", 1691 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; 1692defm t2UXTAH : T2I_exta_rrot<0b001, "uxtah", 1693 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; 1694defm t2UXTAB16 : T2I_exta_rrot_DO<0b011, "uxtab16">; 1695} 1696 1697//===----------------------------------------------------------------------===// 1698// Arithmetic Instructions. 1699// 1700 1701defm t2ADD : T2I_bin_ii12rs<0b000, "add", 1702 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>; 1703defm t2SUB : T2I_bin_ii12rs<0b101, "sub", 1704 BinOpFrag<(sub node:$LHS, node:$RHS)>>; 1705 1706// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants. 1707defm t2ADDS : T2I_bin_s_irs <0b1000, "add", 1708 IIC_iALUi, IIC_iALUr, IIC_iALUsi, 1709 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>; 1710defm t2SUBS : T2I_bin_s_irs <0b1101, "sub", 1711 IIC_iALUi, IIC_iALUr, IIC_iALUsi, 1712 BinOpFrag<(subc node:$LHS, node:$RHS)>>; 1713 1714defm t2ADC : T2I_adde_sube_irs<0b1010, "adc", 1715 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>; 1716defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc", 1717 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>; 1718defm t2ADCS : T2I_adde_sube_s_irs<0b1010, "adc", 1719 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>; 1720defm t2SBCS : T2I_adde_sube_s_irs<0b1011, "sbc", 1721 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS)>>; 1722 1723// RSB 1724defm t2RSB : T2I_rbin_irs <0b1110, "rsb", 1725 BinOpFrag<(sub node:$LHS, node:$RHS)>>; 1726defm t2RSBS : T2I_rbin_s_is <0b1110, "rsb", 1727 BinOpFrag<(subc node:$LHS, node:$RHS)>>; 1728 1729// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 1730// The assume-no-carry-in form uses the negation of the input since add/sub 1731// assume opposite meanings of the carry flag (i.e., carry == !borrow). 1732// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory 1733// details. 1734// The AddedComplexity preferences the first variant over the others since 1735// it can be shrunk to a 16-bit wide encoding, while the others cannot. 1736let AddedComplexity = 1 in 1737def : T2Pat<(add GPR:$src, imm0_255_neg:$imm), 1738 (t2SUBri GPR:$src, imm0_255_neg:$imm)>; 1739def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm), 1740 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>; 1741def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm), 1742 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>; 1743let AddedComplexity = 1 in 1744def : T2Pat<(addc rGPR:$src, imm0_255_neg:$imm), 1745 (t2SUBSri rGPR:$src, imm0_255_neg:$imm)>; 1746def : T2Pat<(addc rGPR:$src, t2_so_imm_neg:$imm), 1747 (t2SUBSri rGPR:$src, t2_so_imm_neg:$imm)>; 1748// The with-carry-in form matches bitwise not instead of the negation. 1749// Effectively, the inverse interpretation of the carry flag already accounts 1750// for part of the negation. 1751let AddedComplexity = 1 in 1752def : T2Pat<(adde rGPR:$src, imm0_255_not:$imm), 1753 (t2SBCSri rGPR:$src, imm0_255_not:$imm)>; 1754def : T2Pat<(adde rGPR:$src, t2_so_imm_not:$imm), 1755 (t2SBCSri rGPR:$src, t2_so_imm_not:$imm)>; 1756 1757// Select Bytes -- for disassembly only 1758 1759def t2SEL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), NoItinerary, "sel", 1760 "\t$dst, $a, $b", []> { 1761 let Inst{31-27} = 0b11111; 1762 let Inst{26-24} = 0b010; 1763 let Inst{23} = 0b1; 1764 let Inst{22-20} = 0b010; 1765 let Inst{15-12} = 0b1111; 1766 let Inst{7} = 0b1; 1767 let Inst{6-4} = 0b000; 1768} 1769 1770// A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned) 1771// And Miscellaneous operations -- for disassembly only 1772class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc, 1773 list<dag> pat = [/* For disassembly only; pattern left blank */]> 1774 : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), NoItinerary, opc, 1775 "\t$dst, $a, $b", pat> { 1776 let Inst{31-27} = 0b11111; 1777 let Inst{26-23} = 0b0101; 1778 let Inst{22-20} = op22_20; 1779 let Inst{15-12} = 0b1111; 1780 let Inst{7-4} = op7_4; 1781} 1782 1783// Saturating add/subtract -- for disassembly only 1784 1785def t2QADD : T2I_pam<0b000, 0b1000, "qadd", 1786 [(set rGPR:$dst, (int_arm_qadd rGPR:$a, rGPR:$b))]>; 1787def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">; 1788def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">; 1789def t2QASX : T2I_pam<0b010, 0b0001, "qasx">; 1790def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd">; 1791def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub">; 1792def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">; 1793def t2QSUB : T2I_pam<0b000, 0b1010, "qsub", 1794 [(set rGPR:$dst, (int_arm_qsub rGPR:$a, rGPR:$b))]>; 1795def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">; 1796def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">; 1797def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">; 1798def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">; 1799def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">; 1800def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">; 1801def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">; 1802def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">; 1803 1804// Signed/Unsigned add/subtract -- for disassembly only 1805 1806def t2SASX : T2I_pam<0b010, 0b0000, "sasx">; 1807def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">; 1808def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">; 1809def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">; 1810def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">; 1811def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">; 1812def t2UASX : T2I_pam<0b010, 0b0100, "uasx">; 1813def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">; 1814def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">; 1815def t2USAX : T2I_pam<0b110, 0b0100, "usax">; 1816def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">; 1817def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">; 1818 1819// Signed/Unsigned halving add/subtract -- for disassembly only 1820 1821def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">; 1822def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">; 1823def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">; 1824def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">; 1825def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">; 1826def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">; 1827def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">; 1828def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">; 1829def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">; 1830def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">; 1831def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">; 1832def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">; 1833 1834// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only 1835 1836def t2USAD8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst), 1837 (ins rGPR:$a, rGPR:$b), 1838 NoItinerary, "usad8", "\t$dst, $a, $b", []> { 1839 let Inst{15-12} = 0b1111; 1840} 1841def t2USADA8 : T2I_mac<0, 0b111, 0b0000, (outs rGPR:$dst), 1842 (ins rGPR:$a, rGPR:$b, rGPR:$acc), NoItinerary, "usada8", 1843 "\t$dst, $a, $b, $acc", []>; 1844 1845// Signed/Unsigned saturate -- for disassembly only 1846 1847def t2SSAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh), 1848 NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh", 1849 [/* For disassembly only; pattern left blank */]> { 1850 let Inst{31-27} = 0b11110; 1851 let Inst{25-22} = 0b1100; 1852 let Inst{20} = 0; 1853 let Inst{15} = 0; 1854} 1855 1856def t2SSAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary, 1857 "ssat16", "\t$dst, $bit_pos, $a", 1858 [/* For disassembly only; pattern left blank */]> { 1859 let Inst{31-27} = 0b11110; 1860 let Inst{25-22} = 0b1100; 1861 let Inst{20} = 0; 1862 let Inst{15} = 0; 1863 let Inst{21} = 1; // sh = '1' 1864 let Inst{14-12} = 0b000; // imm3 = '000' 1865 let Inst{7-6} = 0b00; // imm2 = '00' 1866} 1867 1868def t2USAT: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a, shift_imm:$sh), 1869 NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh", 1870 [/* For disassembly only; pattern left blank */]> { 1871 let Inst{31-27} = 0b11110; 1872 let Inst{25-22} = 0b1110; 1873 let Inst{20} = 0; 1874 let Inst{15} = 0; 1875} 1876 1877def t2USAT16: T2I<(outs rGPR:$dst), (ins i32imm:$bit_pos, rGPR:$a), NoItinerary, 1878 "usat16", "\t$dst, $bit_pos, $a", 1879 [/* For disassembly only; pattern left blank */]> { 1880 let Inst{31-27} = 0b11110; 1881 let Inst{25-22} = 0b1110; 1882 let Inst{20} = 0; 1883 let Inst{15} = 0; 1884 let Inst{21} = 1; // sh = '1' 1885 let Inst{14-12} = 0b000; // imm3 = '000' 1886 let Inst{7-6} = 0b00; // imm2 = '00' 1887} 1888 1889def : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>; 1890def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>; 1891 1892//===----------------------------------------------------------------------===// 1893// Shift and rotate Instructions. 1894// 1895 1896defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>; 1897defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>; 1898defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>; 1899defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>; 1900 1901let Uses = [CPSR] in { 1902def t2RRX : T2sI<(outs rGPR:$dst), (ins rGPR:$src), IIC_iMOVsi, 1903 "rrx", "\t$dst, $src", 1904 [(set rGPR:$dst, (ARMrrx rGPR:$src))]> { 1905 let Inst{31-27} = 0b11101; 1906 let Inst{26-25} = 0b01; 1907 let Inst{24-21} = 0b0010; 1908 let Inst{20} = ?; // The S bit. 1909 let Inst{19-16} = 0b1111; // Rn 1910 let Inst{14-12} = 0b000; 1911 let Inst{7-4} = 0b0011; 1912} 1913} 1914 1915let Defs = [CPSR] in { 1916def t2MOVsrl_flag : T2TwoRegShiftImm< 1917 (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi, 1918 "lsrs", ".w\t$Rd, $Rm, #1", 1919 [(set rGPR:$Rd, (ARMsrl_flag rGPR:$Rm))]> { 1920 let Inst{31-27} = 0b11101; 1921 let Inst{26-25} = 0b01; 1922 let Inst{24-21} = 0b0010; 1923 let Inst{20} = 1; // The S bit. 1924 let Inst{19-16} = 0b1111; // Rn 1925 let Inst{5-4} = 0b01; // Shift type. 1926 // Shift amount = Inst{14-12:7-6} = 1. 1927 let Inst{14-12} = 0b000; 1928 let Inst{7-6} = 0b01; 1929} 1930def t2MOVsra_flag : T2TwoRegShiftImm< 1931 (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi, 1932 "asrs", ".w\t$Rd, $Rm, #1", 1933 [(set rGPR:$Rd, (ARMsra_flag rGPR:$Rm))]> { 1934 let Inst{31-27} = 0b11101; 1935 let Inst{26-25} = 0b01; 1936 let Inst{24-21} = 0b0010; 1937 let Inst{20} = 1; // The S bit. 1938 let Inst{19-16} = 0b1111; // Rn 1939 let Inst{5-4} = 0b10; // Shift type. 1940 // Shift amount = Inst{14-12:7-6} = 1. 1941 let Inst{14-12} = 0b000; 1942 let Inst{7-6} = 0b01; 1943} 1944} 1945 1946//===----------------------------------------------------------------------===// 1947// Bitwise Instructions. 1948// 1949 1950defm t2AND : T2I_bin_w_irs<0b0000, "and", 1951 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 1952 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>; 1953defm t2ORR : T2I_bin_w_irs<0b0010, "orr", 1954 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 1955 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>; 1956defm t2EOR : T2I_bin_w_irs<0b0100, "eor", 1957 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 1958 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>; 1959 1960defm t2BIC : T2I_bin_w_irs<0b0001, "bic", 1961 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 1962 BinOpFrag<(and node:$LHS, (not node:$RHS))>>; 1963 1964let Constraints = "$src = $dst" in 1965def t2BFC : T2I<(outs rGPR:$dst), (ins rGPR:$src, bf_inv_mask_imm:$imm), 1966 IIC_iUNAsi, "bfc", "\t$dst, $imm", 1967 [(set rGPR:$dst, (and rGPR:$src, bf_inv_mask_imm:$imm))]> { 1968 let Inst{31-27} = 0b11110; 1969 let Inst{25} = 1; 1970 let Inst{24-20} = 0b10110; 1971 let Inst{19-16} = 0b1111; // Rn 1972 let Inst{15} = 0; 1973} 1974 1975def t2SBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width), 1976 IIC_iUNAsi, "sbfx", "\t$dst, $src, $lsb, $width", []> { 1977 let Inst{31-27} = 0b11110; 1978 let Inst{25} = 1; 1979 let Inst{24-20} = 0b10100; 1980 let Inst{15} = 0; 1981} 1982 1983def t2UBFX: T2I<(outs rGPR:$dst), (ins rGPR:$src, imm0_31:$lsb, imm0_31:$width), 1984 IIC_iUNAsi, "ubfx", "\t$dst, $src, $lsb, $width", []> { 1985 let Inst{31-27} = 0b11110; 1986 let Inst{25} = 1; 1987 let Inst{24-20} = 0b11100; 1988 let Inst{15} = 0; 1989} 1990 1991// A8.6.18 BFI - Bitfield insert (Encoding T1) 1992let Constraints = "$src = $dst" in 1993def t2BFI : T2I<(outs rGPR:$dst), 1994 (ins rGPR:$src, rGPR:$val, bf_inv_mask_imm:$imm), 1995 IIC_iBITi, "bfi", "\t$dst, $val, $imm", 1996 [(set rGPR:$dst, (ARMbfi rGPR:$src, rGPR:$val, 1997 bf_inv_mask_imm:$imm))]> { 1998 let Inst{31-27} = 0b11110; 1999 let Inst{25} = 1; 2000 let Inst{24-20} = 0b10110; 2001 let Inst{15} = 0; 2002} 2003 2004defm t2ORN : T2I_bin_irs<0b0011, "orn", 2005 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 2006 BinOpFrag<(or node:$LHS, (not node:$RHS))>, 0, "">; 2007 2008// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version 2009let AddedComplexity = 1 in 2010defm t2MVN : T2I_un_irs <0b0011, "mvn", 2011 IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi, 2012 UnOpFrag<(not node:$Src)>, 1, 1>; 2013 2014 2015let AddedComplexity = 1 in 2016def : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm), 2017 (t2BICri rGPR:$src, t2_so_imm_not:$imm)>; 2018 2019// FIXME: Disable this pattern on Darwin to workaround an assembler bug. 2020def : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm), 2021 (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>, 2022 Requires<[IsThumb2]>; 2023 2024def : T2Pat<(t2_so_imm_not:$src), 2025 (t2MVNi t2_so_imm_not:$src)>; 2026 2027//===----------------------------------------------------------------------===// 2028// Multiply Instructions. 2029// 2030let isCommutable = 1 in 2031def t2MUL: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32, 2032 "mul", "\t$dst, $a, $b", 2033 [(set rGPR:$dst, (mul rGPR:$a, rGPR:$b))]> { 2034 let Inst{31-27} = 0b11111; 2035 let Inst{26-23} = 0b0110; 2036 let Inst{22-20} = 0b000; 2037 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2038 let Inst{7-4} = 0b0000; // Multiply 2039} 2040 2041def t2MLA: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32, 2042 "mla", "\t$dst, $a, $b, $c", 2043 [(set rGPR:$dst, (add (mul rGPR:$a, rGPR:$b), rGPR:$c))]> { 2044 let Inst{31-27} = 0b11111; 2045 let Inst{26-23} = 0b0110; 2046 let Inst{22-20} = 0b000; 2047 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2048 let Inst{7-4} = 0b0000; // Multiply 2049} 2050 2051def t2MLS: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32, 2052 "mls", "\t$dst, $a, $b, $c", 2053 [(set rGPR:$dst, (sub rGPR:$c, (mul rGPR:$a, rGPR:$b)))]> { 2054 let Inst{31-27} = 0b11111; 2055 let Inst{26-23} = 0b0110; 2056 let Inst{22-20} = 0b000; 2057 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2058 let Inst{7-4} = 0b0001; // Multiply and Subtract 2059} 2060 2061// Extra precision multiplies with low / high results 2062let neverHasSideEffects = 1 in { 2063let isCommutable = 1 in { 2064def t2SMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst), 2065 (ins rGPR:$a, rGPR:$b), IIC_iMUL64, 2066 "smull", "\t$ldst, $hdst, $a, $b", []> { 2067 let Inst{31-27} = 0b11111; 2068 let Inst{26-23} = 0b0111; 2069 let Inst{22-20} = 0b000; 2070 let Inst{7-4} = 0b0000; 2071} 2072 2073def t2UMULL : T2I<(outs rGPR:$ldst, rGPR:$hdst), 2074 (ins rGPR:$a, rGPR:$b), IIC_iMUL64, 2075 "umull", "\t$ldst, $hdst, $a, $b", []> { 2076 let Inst{31-27} = 0b11111; 2077 let Inst{26-23} = 0b0111; 2078 let Inst{22-20} = 0b010; 2079 let Inst{7-4} = 0b0000; 2080} 2081} // isCommutable 2082 2083// Multiply + accumulate 2084def t2SMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst), 2085 (ins rGPR:$a, rGPR:$b), IIC_iMAC64, 2086 "smlal", "\t$ldst, $hdst, $a, $b", []>{ 2087 let Inst{31-27} = 0b11111; 2088 let Inst{26-23} = 0b0111; 2089 let Inst{22-20} = 0b100; 2090 let Inst{7-4} = 0b0000; 2091} 2092 2093def t2UMLAL : T2I<(outs rGPR:$ldst, rGPR:$hdst), 2094 (ins rGPR:$a, rGPR:$b), IIC_iMAC64, 2095 "umlal", "\t$ldst, $hdst, $a, $b", []>{ 2096 let Inst{31-27} = 0b11111; 2097 let Inst{26-23} = 0b0111; 2098 let Inst{22-20} = 0b110; 2099 let Inst{7-4} = 0b0000; 2100} 2101 2102def t2UMAAL : T2I<(outs rGPR:$ldst, rGPR:$hdst), 2103 (ins rGPR:$a, rGPR:$b), IIC_iMAC64, 2104 "umaal", "\t$ldst, $hdst, $a, $b", []>{ 2105 let Inst{31-27} = 0b11111; 2106 let Inst{26-23} = 0b0111; 2107 let Inst{22-20} = 0b110; 2108 let Inst{7-4} = 0b0110; 2109} 2110} // neverHasSideEffects 2111 2112// Rounding variants of the below included for disassembly only 2113 2114// Most significant word multiply 2115def t2SMMUL : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32, 2116 "smmul", "\t$dst, $a, $b", 2117 [(set rGPR:$dst, (mulhs rGPR:$a, rGPR:$b))]> { 2118 let Inst{31-27} = 0b11111; 2119 let Inst{26-23} = 0b0110; 2120 let Inst{22-20} = 0b101; 2121 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2122 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) 2123} 2124 2125def t2SMMULR : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL32, 2126 "smmulr", "\t$dst, $a, $b", []> { 2127 let Inst{31-27} = 0b11111; 2128 let Inst{26-23} = 0b0110; 2129 let Inst{22-20} = 0b101; 2130 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2131 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) 2132} 2133 2134def t2SMMLA : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32, 2135 "smmla", "\t$dst, $a, $b, $c", 2136 [(set rGPR:$dst, (add (mulhs rGPR:$a, rGPR:$b), rGPR:$c))]> { 2137 let Inst{31-27} = 0b11111; 2138 let Inst{26-23} = 0b0110; 2139 let Inst{22-20} = 0b101; 2140 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2141 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) 2142} 2143 2144def t2SMMLAR: T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32, 2145 "smmlar", "\t$dst, $a, $b, $c", []> { 2146 let Inst{31-27} = 0b11111; 2147 let Inst{26-23} = 0b0110; 2148 let Inst{22-20} = 0b101; 2149 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2150 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) 2151} 2152 2153def t2SMMLS: T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32, 2154 "smmls", "\t$dst, $a, $b, $c", 2155 [(set rGPR:$dst, (sub rGPR:$c, (mulhs rGPR:$a, rGPR:$b)))]> { 2156 let Inst{31-27} = 0b11111; 2157 let Inst{26-23} = 0b0110; 2158 let Inst{22-20} = 0b110; 2159 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2160 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) 2161} 2162 2163def t2SMMLSR:T2I <(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$c), IIC_iMAC32, 2164 "smmlsr", "\t$dst, $a, $b, $c", []> { 2165 let Inst{31-27} = 0b11111; 2166 let Inst{26-23} = 0b0110; 2167 let Inst{22-20} = 0b110; 2168 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2169 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) 2170} 2171 2172multiclass T2I_smul<string opc, PatFrag opnode> { 2173 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16, 2174 !strconcat(opc, "bb"), "\t$dst, $a, $b", 2175 [(set rGPR:$dst, (opnode (sext_inreg rGPR:$a, i16), 2176 (sext_inreg rGPR:$b, i16)))]> { 2177 let Inst{31-27} = 0b11111; 2178 let Inst{26-23} = 0b0110; 2179 let Inst{22-20} = 0b001; 2180 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2181 let Inst{7-6} = 0b00; 2182 let Inst{5-4} = 0b00; 2183 } 2184 2185 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16, 2186 !strconcat(opc, "bt"), "\t$dst, $a, $b", 2187 [(set rGPR:$dst, (opnode (sext_inreg rGPR:$a, i16), 2188 (sra rGPR:$b, (i32 16))))]> { 2189 let Inst{31-27} = 0b11111; 2190 let Inst{26-23} = 0b0110; 2191 let Inst{22-20} = 0b001; 2192 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2193 let Inst{7-6} = 0b00; 2194 let Inst{5-4} = 0b01; 2195 } 2196 2197 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16, 2198 !strconcat(opc, "tb"), "\t$dst, $a, $b", 2199 [(set rGPR:$dst, (opnode (sra rGPR:$a, (i32 16)), 2200 (sext_inreg rGPR:$b, i16)))]> { 2201 let Inst{31-27} = 0b11111; 2202 let Inst{26-23} = 0b0110; 2203 let Inst{22-20} = 0b001; 2204 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2205 let Inst{7-6} = 0b00; 2206 let Inst{5-4} = 0b10; 2207 } 2208 2209 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16, 2210 !strconcat(opc, "tt"), "\t$dst, $a, $b", 2211 [(set rGPR:$dst, (opnode (sra rGPR:$a, (i32 16)), 2212 (sra rGPR:$b, (i32 16))))]> { 2213 let Inst{31-27} = 0b11111; 2214 let Inst{26-23} = 0b0110; 2215 let Inst{22-20} = 0b001; 2216 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2217 let Inst{7-6} = 0b00; 2218 let Inst{5-4} = 0b11; 2219 } 2220 2221 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16, 2222 !strconcat(opc, "wb"), "\t$dst, $a, $b", 2223 [(set rGPR:$dst, (sra (opnode rGPR:$a, 2224 (sext_inreg rGPR:$b, i16)), (i32 16)))]> { 2225 let Inst{31-27} = 0b11111; 2226 let Inst{26-23} = 0b0110; 2227 let Inst{22-20} = 0b011; 2228 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2229 let Inst{7-6} = 0b00; 2230 let Inst{5-4} = 0b00; 2231 } 2232 2233 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), IIC_iMUL16, 2234 !strconcat(opc, "wt"), "\t$dst, $a, $b", 2235 [(set rGPR:$dst, (sra (opnode rGPR:$a, 2236 (sra rGPR:$b, (i32 16))), (i32 16)))]> { 2237 let Inst{31-27} = 0b11111; 2238 let Inst{26-23} = 0b0110; 2239 let Inst{22-20} = 0b011; 2240 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2241 let Inst{7-6} = 0b00; 2242 let Inst{5-4} = 0b01; 2243 } 2244} 2245 2246 2247multiclass T2I_smla<string opc, PatFrag opnode> { 2248 def BB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16, 2249 !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc", 2250 [(set rGPR:$dst, (add rGPR:$acc, 2251 (opnode (sext_inreg rGPR:$a, i16), 2252 (sext_inreg rGPR:$b, i16))))]> { 2253 let Inst{31-27} = 0b11111; 2254 let Inst{26-23} = 0b0110; 2255 let Inst{22-20} = 0b001; 2256 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2257 let Inst{7-6} = 0b00; 2258 let Inst{5-4} = 0b00; 2259 } 2260 2261 def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16, 2262 !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc", 2263 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sext_inreg rGPR:$a, i16), 2264 (sra rGPR:$b, (i32 16)))))]> { 2265 let Inst{31-27} = 0b11111; 2266 let Inst{26-23} = 0b0110; 2267 let Inst{22-20} = 0b001; 2268 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2269 let Inst{7-6} = 0b00; 2270 let Inst{5-4} = 0b01; 2271 } 2272 2273 def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16, 2274 !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc", 2275 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)), 2276 (sext_inreg rGPR:$b, i16))))]> { 2277 let Inst{31-27} = 0b11111; 2278 let Inst{26-23} = 0b0110; 2279 let Inst{22-20} = 0b001; 2280 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2281 let Inst{7-6} = 0b00; 2282 let Inst{5-4} = 0b10; 2283 } 2284 2285 def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16, 2286 !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc", 2287 [(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)), 2288 (sra rGPR:$b, (i32 16)))))]> { 2289 let Inst{31-27} = 0b11111; 2290 let Inst{26-23} = 0b0110; 2291 let Inst{22-20} = 0b001; 2292 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2293 let Inst{7-6} = 0b00; 2294 let Inst{5-4} = 0b11; 2295 } 2296 2297 def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16, 2298 !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc", 2299 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a, 2300 (sext_inreg rGPR:$b, i16)), (i32 16))))]> { 2301 let Inst{31-27} = 0b11111; 2302 let Inst{26-23} = 0b0110; 2303 let Inst{22-20} = 0b011; 2304 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2305 let Inst{7-6} = 0b00; 2306 let Inst{5-4} = 0b00; 2307 } 2308 2309 def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16, 2310 !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc", 2311 [(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a, 2312 (sra rGPR:$b, (i32 16))), (i32 16))))]> { 2313 let Inst{31-27} = 0b11111; 2314 let Inst{26-23} = 0b0110; 2315 let Inst{22-20} = 0b011; 2316 let Inst{15-12} = {?, ?, ?, ?}; // Ra 2317 let Inst{7-6} = 0b00; 2318 let Inst{5-4} = 0b01; 2319 } 2320} 2321 2322defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 2323defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 2324 2325// Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only 2326def t2SMLALBB : T2I_mac<1, 0b100, 0b1000, (outs rGPR:$ldst,rGPR:$hdst), 2327 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b", 2328 [/* For disassembly only; pattern left blank */]>; 2329def t2SMLALBT : T2I_mac<1, 0b100, 0b1001, (outs rGPR:$ldst,rGPR:$hdst), 2330 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b", 2331 [/* For disassembly only; pattern left blank */]>; 2332def t2SMLALTB : T2I_mac<1, 0b100, 0b1010, (outs rGPR:$ldst,rGPR:$hdst), 2333 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b", 2334 [/* For disassembly only; pattern left blank */]>; 2335def t2SMLALTT : T2I_mac<1, 0b100, 0b1011, (outs rGPR:$ldst,rGPR:$hdst), 2336 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b", 2337 [/* For disassembly only; pattern left blank */]>; 2338 2339// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD 2340// These are for disassembly only. 2341 2342def t2SMUAD: T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), 2343 IIC_iMAC32, "smuad", "\t$dst, $a, $b", []> { 2344 let Inst{15-12} = 0b1111; 2345} 2346def t2SMUADX:T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), 2347 IIC_iMAC32, "smuadx", "\t$dst, $a, $b", []> { 2348 let Inst{15-12} = 0b1111; 2349} 2350def t2SMUSD: T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), 2351 IIC_iMAC32, "smusd", "\t$dst, $a, $b", []> { 2352 let Inst{15-12} = 0b1111; 2353} 2354def t2SMUSDX:T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b), 2355 IIC_iMAC32, "smusdx", "\t$dst, $a, $b", []> { 2356 let Inst{15-12} = 0b1111; 2357} 2358def t2SMLAD : T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst), 2359 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlad", 2360 "\t$dst, $a, $b, $acc", []>; 2361def t2SMLADX : T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst), 2362 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smladx", 2363 "\t$dst, $a, $b, $acc", []>; 2364def t2SMLSD : T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst), 2365 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsd", 2366 "\t$dst, $a, $b, $acc", []>; 2367def t2SMLSDX : T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst), 2368 (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsdx", 2369 "\t$dst, $a, $b, $acc", []>; 2370def t2SMLALD : T2I_mac<1, 0b100, 0b1100, (outs rGPR:$ldst,rGPR:$hdst), 2371 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlald", 2372 "\t$ldst, $hdst, $a, $b", []>; 2373def t2SMLALDX : T2I_mac<1, 0b100, 0b1101, (outs rGPR:$ldst,rGPR:$hdst), 2374 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaldx", 2375 "\t$ldst, $hdst, $a, $b", []>; 2376def t2SMLSLD : T2I_mac<1, 0b101, 0b1100, (outs rGPR:$ldst,rGPR:$hdst), 2377 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsld", 2378 "\t$ldst, $hdst, $a, $b", []>; 2379def t2SMLSLDX : T2I_mac<1, 0b101, 0b1101, (outs rGPR:$ldst,rGPR:$hdst), 2380 (ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsldx", 2381 "\t$ldst, $hdst, $a, $b", []>; 2382 2383//===----------------------------------------------------------------------===// 2384// Misc. Arithmetic Instructions. 2385// 2386 2387class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops, 2388 InstrItinClass itin, string opc, string asm, list<dag> pattern> 2389 : T2I<oops, iops, itin, opc, asm, pattern> { 2390 let Inst{31-27} = 0b11111; 2391 let Inst{26-22} = 0b01010; 2392 let Inst{21-20} = op1; 2393 let Inst{15-12} = 0b1111; 2394 let Inst{7-6} = 0b10; 2395 let Inst{5-4} = op2; 2396} 2397 2398def t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr, 2399 "clz", "\t$dst, $src", [(set rGPR:$dst, (ctlz rGPR:$src))]>; 2400 2401def t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr, 2402 "rbit", "\t$dst, $src", 2403 [(set rGPR:$dst, (ARMrbit rGPR:$src))]>; 2404 2405def t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr, 2406 "rev", ".w\t$dst, $src", [(set rGPR:$dst, (bswap rGPR:$src))]>; 2407 2408def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr, 2409 "rev16", ".w\t$dst, $src", 2410 [(set rGPR:$dst, 2411 (or (and (srl rGPR:$src, (i32 8)), 0xFF), 2412 (or (and (shl rGPR:$src, (i32 8)), 0xFF00), 2413 (or (and (srl rGPR:$src, (i32 8)), 0xFF0000), 2414 (and (shl rGPR:$src, (i32 8)), 0xFF000000)))))]>; 2415 2416def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr, 2417 "revsh", ".w\t$dst, $src", 2418 [(set rGPR:$dst, 2419 (sext_inreg 2420 (or (srl (and rGPR:$src, 0xFF00), (i32 8)), 2421 (shl rGPR:$src, (i32 8))), i16))]>; 2422 2423def t2PKHBT : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh), 2424 IIC_iBITsi, "pkhbt", "\t$dst, $src1, $src2$sh", 2425 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF), 2426 (and (shl rGPR:$src2, lsl_amt:$sh), 2427 0xFFFF0000)))]>, 2428 Requires<[HasT2ExtractPack, IsThumb2]> { 2429 let Inst{31-27} = 0b11101; 2430 let Inst{26-25} = 0b01; 2431 let Inst{24-20} = 0b01100; 2432 let Inst{5} = 0; // BT form 2433 let Inst{4} = 0; 2434} 2435 2436// Alternate cases for PKHBT where identities eliminate some nodes. 2437def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)), 2438 (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>, 2439 Requires<[HasT2ExtractPack, IsThumb2]>; 2440def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)), 2441 (t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>, 2442 Requires<[HasT2ExtractPack, IsThumb2]>; 2443 2444// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and 2445// will match the pattern below. 2446def t2PKHTB : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh), 2447 IIC_iBITsi, "pkhtb", "\t$dst, $src1, $src2$sh", 2448 [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF0000), 2449 (and (sra rGPR:$src2, asr_amt:$sh), 2450 0xFFFF)))]>, 2451 Requires<[HasT2ExtractPack, IsThumb2]> { 2452 let Inst{31-27} = 0b11101; 2453 let Inst{26-25} = 0b01; 2454 let Inst{24-20} = 0b01100; 2455 let Inst{5} = 1; // TB form 2456 let Inst{4} = 0; 2457} 2458 2459// Alternate cases for PKHTB where identities eliminate some nodes. Note that 2460// a shift amount of 0 is *not legal* here, it is PKHBT instead. 2461def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)), 2462 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>, 2463 Requires<[HasT2ExtractPack, IsThumb2]>; 2464def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), 2465 (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)), 2466 (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>, 2467 Requires<[HasT2ExtractPack, IsThumb2]>; 2468 2469//===----------------------------------------------------------------------===// 2470// Comparison Instructions... 2471// 2472defm t2CMP : T2I_cmp_irs<0b1101, "cmp", 2473 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi, 2474 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>; 2475defm t2CMPz : T2I_cmp_irs<0b1101, "cmp", 2476 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi, 2477 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>; 2478 2479//FIXME: Disable CMN, as CCodes are backwards from compare expectations 2480// Compare-to-zero still works out, just not the relationals 2481//defm t2CMN : T2I_cmp_irs<0b1000, "cmn", 2482// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>; 2483defm t2CMNz : T2I_cmp_irs<0b1000, "cmn", 2484 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi, 2485 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>; 2486 2487//def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm), 2488// (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>; 2489 2490def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm), 2491 (t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>; 2492 2493defm t2TST : T2I_cmp_irs<0b0000, "tst", 2494 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi, 2495 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>; 2496defm t2TEQ : T2I_cmp_irs<0b0100, "teq", 2497 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi, 2498 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>; 2499 2500// Conditional moves 2501// FIXME: should be able to write a pattern for ARMcmov, but can't use 2502// a two-value operand where a dag node expects two operands. :( 2503let neverHasSideEffects = 1 in { 2504def t2MOVCCr : T2I<(outs rGPR:$dst), (ins rGPR:$false, rGPR:$true), IIC_iCMOVr, 2505 "mov", ".w\t$dst, $true", 2506 [/*(set rGPR:$dst, (ARMcmov rGPR:$false, rGPR:$true, imm:$cc, CCR:$ccr))*/]>, 2507 RegConstraint<"$false = $dst"> { 2508 let Inst{31-27} = 0b11101; 2509 let Inst{26-25} = 0b01; 2510 let Inst{24-21} = 0b0010; 2511 let Inst{20} = 0; // The S bit. 2512 let Inst{19-16} = 0b1111; // Rn 2513 let Inst{14-12} = 0b000; 2514 let Inst{7-4} = 0b0000; 2515} 2516 2517def t2MOVCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true), 2518 IIC_iCMOVi, "mov", ".w\t$dst, $true", 2519[/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>, 2520 RegConstraint<"$false = $dst"> { 2521 let Inst{31-27} = 0b11110; 2522 let Inst{25} = 0; 2523 let Inst{24-21} = 0b0010; 2524 let Inst{20} = 0; // The S bit. 2525 let Inst{19-16} = 0b1111; // Rn 2526 let Inst{15} = 0; 2527} 2528 2529def t2MOVCCi16 : T2I<(outs rGPR:$Rd), (ins rGPR:$false, i32imm:$imm), 2530 IIC_iCMOVi, 2531 "movw", "\t$Rd, $imm", []>, 2532 RegConstraint<"$false = $Rd"> { 2533 let Inst{31-27} = 0b11110; 2534 let Inst{25} = 1; 2535 let Inst{24-21} = 0b0010; 2536 let Inst{20} = 0; // The S bit. 2537 let Inst{15} = 0; 2538 2539 bits<4> Rd; 2540 bits<16> imm; 2541 2542 let Inst{11-8} = Rd{3-0}; 2543 let Inst{19-16} = imm{15-12}; 2544 let Inst{26} = imm{11}; 2545 let Inst{14-12} = imm{10-8}; 2546 let Inst{7-0} = imm{7-0}; 2547} 2548 2549def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst), 2550 (ins rGPR:$false, i32imm:$src, pred:$p), 2551 IIC_iCMOVix2, "", []>, RegConstraint<"$false = $dst">; 2552 2553def t2MVNCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true), 2554 IIC_iCMOVi, "mvn", ".w\t$dst, $true", 2555[/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm_not:$true, 2556 imm:$cc, CCR:$ccr))*/]>, 2557 RegConstraint<"$false = $dst"> { 2558 let Inst{31-27} = 0b11110; 2559 let Inst{25} = 0; 2560 let Inst{24-21} = 0b0011; 2561 let Inst{20} = 0; // The S bit. 2562 let Inst{19-16} = 0b1111; // Rn 2563 let Inst{15} = 0; 2564} 2565 2566class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 2567 string opc, string asm, list<dag> pattern> 2568 : T2TwoRegShiftImm<oops, iops, itin, opc, asm, pattern> { 2569 let Inst{31-27} = 0b11101; 2570 let Inst{26-25} = 0b01; 2571 let Inst{24-21} = 0b0010; 2572 let Inst{20} = 0; // The S bit. 2573 let Inst{19-16} = 0b1111; // Rn 2574 let Inst{5-4} = opcod; // Shift type. 2575} 2576def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$Rd), 2577 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm), 2578 IIC_iCMOVsi, "lsl", ".w\t$Rd, $Rm, $imm", []>, 2579 RegConstraint<"$false = $Rd">; 2580def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$Rd), 2581 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm), 2582 IIC_iCMOVsi, "lsr", ".w\t$Rd, $Rm, $imm", []>, 2583 RegConstraint<"$false = $Rd">; 2584def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$Rd), 2585 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm), 2586 IIC_iCMOVsi, "asr", ".w\t$Rd, $Rm, $imm", []>, 2587 RegConstraint<"$false = $Rd">; 2588def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$Rd), 2589 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm), 2590 IIC_iCMOVsi, "ror", ".w\t$Rd, $Rm, $imm", []>, 2591 RegConstraint<"$false = $Rd">; 2592} // neverHasSideEffects 2593 2594//===----------------------------------------------------------------------===// 2595// Atomic operations intrinsics 2596// 2597 2598// memory barriers protect the atomic sequences 2599let hasSideEffects = 1 in { 2600def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary, 2601 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>, 2602 Requires<[IsThumb, HasDB]> { 2603 bits<4> opt; 2604 let Inst{31-4} = 0xf3bf8f5; 2605 let Inst{3-0} = opt; 2606} 2607} 2608 2609def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary, 2610 "dsb", "\t$opt", 2611 [/* For disassembly only; pattern left blank */]>, 2612 Requires<[IsThumb, HasDB]> { 2613 bits<4> opt; 2614 let Inst{31-4} = 0xf3bf8f4; 2615 let Inst{3-0} = opt; 2616} 2617 2618// ISB has only full system option -- for disassembly only 2619def t2ISB : T2I<(outs), (ins), NoItinerary, "isb", "", 2620 [/* For disassembly only; pattern left blank */]>, 2621 Requires<[IsThumb2, HasV7]> { 2622 let Inst{31-4} = 0xf3bf8f6; 2623 let Inst{3-0} = 0b1111; 2624} 2625 2626class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz, 2627 InstrItinClass itin, string opc, string asm, string cstr, 2628 list<dag> pattern, bits<4> rt2 = 0b1111> 2629 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> { 2630 let Inst{31-27} = 0b11101; 2631 let Inst{26-20} = 0b0001101; 2632 let Inst{11-8} = rt2; 2633 let Inst{7-6} = 0b01; 2634 let Inst{5-4} = opcod; 2635 let Inst{3-0} = 0b1111; 2636} 2637class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz, 2638 InstrItinClass itin, string opc, string asm, string cstr, 2639 list<dag> pattern, bits<4> rt2 = 0b1111> 2640 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> { 2641 let Inst{31-27} = 0b11101; 2642 let Inst{26-20} = 0b0001100; 2643 let Inst{11-8} = rt2; 2644 let Inst{7-6} = 0b01; 2645 let Inst{5-4} = opcod; 2646} 2647 2648let mayLoad = 1 in { 2649def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone, 2650 Size4Bytes, NoItinerary, "ldrexb", "\t$dest, [$ptr]", 2651 "", []>; 2652def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone, 2653 Size4Bytes, NoItinerary, "ldrexh", "\t$dest, [$ptr]", 2654 "", []>; 2655def t2LDREX : Thumb2I<(outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone, 2656 Size4Bytes, NoItinerary, 2657 "ldrex", "\t$dest, [$ptr]", "", 2658 []> { 2659 let Inst{31-27} = 0b11101; 2660 let Inst{26-20} = 0b0000101; 2661 let Inst{11-8} = 0b1111; 2662 let Inst{7-0} = 0b00000000; // imm8 = 0 2663} 2664def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$dest, rGPR:$dest2), (ins rGPR:$ptr), 2665 AddrModeNone, Size4Bytes, NoItinerary, 2666 "ldrexd", "\t$dest, $dest2, [$ptr]", "", 2667 [], {?, ?, ?, ?}>; 2668} 2669 2670let mayStore = 1, Constraints = "@earlyclobber $success" in { 2671def t2STREXB : T2I_strex<0b00, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr), 2672 AddrModeNone, Size4Bytes, NoItinerary, 2673 "strexb", "\t$success, $src, [$ptr]", "", []>; 2674def t2STREXH : T2I_strex<0b01, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr), 2675 AddrModeNone, Size4Bytes, NoItinerary, 2676 "strexh", "\t$success, $src, [$ptr]", "", []>; 2677def t2STREX : Thumb2I<(outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr), 2678 AddrModeNone, Size4Bytes, NoItinerary, 2679 "strex", "\t$success, $src, [$ptr]", "", 2680 []> { 2681 let Inst{31-27} = 0b11101; 2682 let Inst{26-20} = 0b0000100; 2683 let Inst{7-0} = 0b00000000; // imm8 = 0 2684} 2685def t2STREXD : T2I_strex<0b11, (outs rGPR:$success), 2686 (ins rGPR:$src, rGPR:$src2, rGPR:$ptr), 2687 AddrModeNone, Size4Bytes, NoItinerary, 2688 "strexd", "\t$success, $src, $src2, [$ptr]", "", [], 2689 {?, ?, ?, ?}>; 2690} 2691 2692// Clear-Exclusive is for disassembly only. 2693def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "", 2694 [/* For disassembly only; pattern left blank */]>, 2695 Requires<[IsARM, HasV7]> { 2696 let Inst{31-20} = 0xf3b; 2697 let Inst{15-14} = 0b10; 2698 let Inst{12} = 0; 2699 let Inst{7-4} = 0b0010; 2700} 2701 2702//===----------------------------------------------------------------------===// 2703// TLS Instructions 2704// 2705 2706// __aeabi_read_tp preserves the registers r1-r3. 2707let isCall = 1, 2708 Defs = [R0, R12, LR, CPSR] in { 2709 def t2TPsoft : T2XI<(outs), (ins), IIC_Br, 2710 "bl\t__aeabi_read_tp", 2711 [(set R0, ARMthread_pointer)]> { 2712 let Inst{31-27} = 0b11110; 2713 let Inst{15-14} = 0b11; 2714 let Inst{12} = 1; 2715 } 2716} 2717 2718//===----------------------------------------------------------------------===// 2719// SJLJ Exception handling intrinsics 2720// eh_sjlj_setjmp() is an instruction sequence to store the return 2721// address and save #0 in R0 for the non-longjmp case. 2722// Since by its nature we may be coming from some other function to get 2723// here, and we're using the stack frame for the containing function to 2724// save/restore registers, we can't keep anything live in regs across 2725// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 2726// when we get here from a longjmp(). We force everthing out of registers 2727// except for our own input by listing the relevant registers in Defs. By 2728// doing so, we also cause the prologue/epilogue code to actively preserve 2729// all of the callee-saved resgisters, which is exactly what we want. 2730// $val is a scratch register for our use. 2731let Defs = 2732 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0, 2733 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, 2734 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, 2735 D31 ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in { 2736 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val), 2737 AddrModeNone, SizeSpecial, NoItinerary, "", "", 2738 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>, 2739 Requires<[IsThumb2, HasVFP2]>; 2740} 2741 2742let Defs = 2743 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ], 2744 hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in { 2745 def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val), 2746 AddrModeNone, SizeSpecial, NoItinerary, "", "", 2747 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>, 2748 Requires<[IsThumb2, NoVFP]>; 2749} 2750 2751 2752//===----------------------------------------------------------------------===// 2753// Control-Flow Instructions 2754// 2755 2756// FIXME: remove when we have a way to marking a MI with these properties. 2757// FIXME: $dst1 should be a def. But the extra ops must be in the end of the 2758// operand list. 2759// FIXME: Should pc be an implicit operand like PICADD, etc? 2760let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 2761 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in 2762def t2LDMIA_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, 2763 reglist:$dsts, variable_ops), 2764 IIC_iLoad_mBr, 2765 "ldmia${p}.w\t$Rn!, $dsts", 2766 "$Rn = $wb", []> { 2767 let Inst{24-23} = 0b01; // IA: '01', DB: '10' 2768 let Inst{21} = 1; // The W bit. 2769 let Inst{20} = 1; // Load 2770} 2771 2772let isBranch = 1, isTerminator = 1, isBarrier = 1 in { 2773let isPredicable = 1 in 2774def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br, 2775 "b.w\t$target", 2776 [(br bb:$target)]> { 2777 let Inst{31-27} = 0b11110; 2778 let Inst{15-14} = 0b10; 2779 let Inst{12} = 1; 2780} 2781 2782let isNotDuplicable = 1, isIndirectBranch = 1, 2783 isCodeGenOnly = 1 in { // $id doesn't exist in asmstring, should be lowered. 2784def t2BR_JT : 2785 T2JTI<(outs), 2786 (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id), 2787 IIC_Br, "mov\tpc, $target$jt", 2788 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]> { 2789 let Inst{31-27} = 0b11101; 2790 let Inst{26-20} = 0b0100100; 2791 let Inst{19-16} = 0b1111; 2792 let Inst{14-12} = 0b000; 2793 let Inst{11-8} = 0b1111; // Rd = pc 2794 let Inst{7-4} = 0b0000; 2795} 2796 2797// FIXME: Add a non-pc based case that can be predicated. 2798let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered. 2799def t2TBB : 2800 T2JTI<(outs), 2801 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id), 2802 IIC_Br, "tbb\t$index$jt", []> { 2803 let Inst{31-27} = 0b11101; 2804 let Inst{26-20} = 0b0001101; 2805 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction) 2806 let Inst{15-8} = 0b11110000; 2807 let Inst{7-4} = 0b0000; // B form 2808} 2809 2810let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered. 2811def t2TBH : 2812 T2JTI<(outs), 2813 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id), 2814 IIC_Br, "tbh\t$index$jt", []> { 2815 let Inst{31-27} = 0b11101; 2816 let Inst{26-20} = 0b0001101; 2817 let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction) 2818 let Inst{15-8} = 0b11110000; 2819 let Inst{7-4} = 0b0001; // H form 2820} 2821 2822// Generic versions of the above two instructions, for disassembly only 2823 2824def t2TBBgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br, 2825 "tbb", "\t[$a, $b]", []>{ 2826 let Inst{31-27} = 0b11101; 2827 let Inst{26-20} = 0b0001101; 2828 let Inst{15-8} = 0b11110000; 2829 let Inst{7-4} = 0b0000; // B form 2830} 2831 2832def t2TBHgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br, 2833 "tbh", "\t[$a, $b, lsl #1]", []> { 2834 let Inst{31-27} = 0b11101; 2835 let Inst{26-20} = 0b0001101; 2836 let Inst{15-8} = 0b11110000; 2837 let Inst{7-4} = 0b0001; // H form 2838} 2839} // isNotDuplicable, isIndirectBranch 2840 2841} // isBranch, isTerminator, isBarrier 2842 2843// FIXME: should be able to write a pattern for ARMBrcond, but can't use 2844// a two-value operand where a dag node expects two operands. :( 2845let isBranch = 1, isTerminator = 1 in 2846def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br, 2847 "b", ".w\t$target", 2848 [/*(ARMbrcond bb:$target, imm:$cc)*/]> { 2849 let Inst{31-27} = 0b11110; 2850 let Inst{15-14} = 0b10; 2851 let Inst{12} = 0; 2852} 2853 2854 2855// IT block 2856let Defs = [ITSTATE] in 2857def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask), 2858 AddrModeNone, Size2Bytes, IIC_iALUx, 2859 "it$mask\t$cc", "", []> { 2860 // 16-bit instruction. 2861 let Inst{31-16} = 0x0000; 2862 let Inst{15-8} = 0b10111111; 2863} 2864 2865// Branch and Exchange Jazelle -- for disassembly only 2866// Rm = Inst{19-16} 2867def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func", 2868 [/* For disassembly only; pattern left blank */]> { 2869 let Inst{31-27} = 0b11110; 2870 let Inst{26} = 0; 2871 let Inst{25-20} = 0b111100; 2872 let Inst{15-14} = 0b10; 2873 let Inst{12} = 0; 2874} 2875 2876// Change Processor State is a system instruction -- for disassembly only. 2877// The singleton $opt operand contains the following information: 2878// opt{4-0} = mode from Inst{4-0} 2879// opt{5} = changemode from Inst{17} 2880// opt{8-6} = AIF from Inst{8-6} 2881// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable 2882def t2CPS : T2XI<(outs),(ins cps_opt:$opt), NoItinerary, "cps$opt", 2883 [/* For disassembly only; pattern left blank */]> { 2884 let Inst{31-27} = 0b11110; 2885 let Inst{26} = 0; 2886 let Inst{25-20} = 0b111010; 2887 let Inst{15-14} = 0b10; 2888 let Inst{12} = 0; 2889} 2890 2891// A6.3.4 Branches and miscellaneous control 2892// Table A6-14 Change Processor State, and hint instructions 2893// Helper class for disassembly only. 2894class T2I_hint<bits<8> op7_0, string opc, string asm> 2895 : T2I<(outs), (ins), NoItinerary, opc, asm, 2896 [/* For disassembly only; pattern left blank */]> { 2897 let Inst{31-20} = 0xf3a; 2898 let Inst{15-14} = 0b10; 2899 let Inst{12} = 0; 2900 let Inst{10-8} = 0b000; 2901 let Inst{7-0} = op7_0; 2902} 2903 2904def t2NOP : T2I_hint<0b00000000, "nop", ".w">; 2905def t2YIELD : T2I_hint<0b00000001, "yield", ".w">; 2906def t2WFE : T2I_hint<0b00000010, "wfe", ".w">; 2907def t2WFI : T2I_hint<0b00000011, "wfi", ".w">; 2908def t2SEV : T2I_hint<0b00000100, "sev", ".w">; 2909 2910def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt", 2911 [/* For disassembly only; pattern left blank */]> { 2912 let Inst{31-20} = 0xf3a; 2913 let Inst{15-14} = 0b10; 2914 let Inst{12} = 0; 2915 let Inst{10-8} = 0b000; 2916 let Inst{7-4} = 0b1111; 2917} 2918 2919// Secure Monitor Call is a system instruction -- for disassembly only 2920// Option = Inst{19-16} 2921def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt", 2922 [/* For disassembly only; pattern left blank */]> { 2923 let Inst{31-27} = 0b11110; 2924 let Inst{26-20} = 0b1111111; 2925 let Inst{15-12} = 0b1000; 2926} 2927 2928// Store Return State is a system instruction -- for disassembly only 2929def t2SRSDBW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode", 2930 [/* For disassembly only; pattern left blank */]> { 2931 let Inst{31-27} = 0b11101; 2932 let Inst{26-20} = 0b0000010; // W = 1 2933} 2934 2935def t2SRSDB : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode", 2936 [/* For disassembly only; pattern left blank */]> { 2937 let Inst{31-27} = 0b11101; 2938 let Inst{26-20} = 0b0000000; // W = 0 2939} 2940 2941def t2SRSIAW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode", 2942 [/* For disassembly only; pattern left blank */]> { 2943 let Inst{31-27} = 0b11101; 2944 let Inst{26-20} = 0b0011010; // W = 1 2945} 2946 2947def t2SRSIA : T2I<(outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode", 2948 [/* For disassembly only; pattern left blank */]> { 2949 let Inst{31-27} = 0b11101; 2950 let Inst{26-20} = 0b0011000; // W = 0 2951} 2952 2953// Return From Exception is a system instruction -- for disassembly only 2954def t2RFEDBW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfedb", "\t$base!", 2955 [/* For disassembly only; pattern left blank */]> { 2956 let Inst{31-27} = 0b11101; 2957 let Inst{26-20} = 0b0000011; // W = 1 2958} 2959 2960def t2RFEDB : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeab", "\t$base", 2961 [/* For disassembly only; pattern left blank */]> { 2962 let Inst{31-27} = 0b11101; 2963 let Inst{26-20} = 0b0000001; // W = 0 2964} 2965 2966def t2RFEIAW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base!", 2967 [/* For disassembly only; pattern left blank */]> { 2968 let Inst{31-27} = 0b11101; 2969 let Inst{26-20} = 0b0011011; // W = 1 2970} 2971 2972def t2RFEIA : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base", 2973 [/* For disassembly only; pattern left blank */]> { 2974 let Inst{31-27} = 0b11101; 2975 let Inst{26-20} = 0b0011001; // W = 0 2976} 2977 2978//===----------------------------------------------------------------------===// 2979// Non-Instruction Patterns 2980// 2981 2982// Two piece so_imms. 2983def : T2Pat<(or rGPR:$LHS, t2_so_imm2part:$RHS), 2984 (t2ORRri (t2ORRri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)), 2985 (t2_so_imm2part_2 imm:$RHS))>; 2986def : T2Pat<(xor rGPR:$LHS, t2_so_imm2part:$RHS), 2987 (t2EORri (t2EORri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)), 2988 (t2_so_imm2part_2 imm:$RHS))>; 2989def : T2Pat<(add rGPR:$LHS, t2_so_imm2part:$RHS), 2990 (t2ADDri (t2ADDri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)), 2991 (t2_so_imm2part_2 imm:$RHS))>; 2992def : T2Pat<(add rGPR:$LHS, t2_so_neg_imm2part:$RHS), 2993 (t2SUBri (t2SUBri rGPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)), 2994 (t2_so_neg_imm2part_2 imm:$RHS))>; 2995 2996// 32-bit immediate using movw + movt. 2997// This is a single pseudo instruction to make it re-materializable. 2998// FIXME: Remove this when we can do generalized remat. 2999let isReMaterializable = 1 in 3000def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2, 3001 "", [(set rGPR:$dst, (i32 imm:$src))]>, 3002 Requires<[IsThumb, HasV6T2]>; 3003 3004// ConstantPool, GlobalAddress, and JumpTable 3005def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>, 3006 Requires<[IsThumb2, DontUseMovt]>; 3007def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>; 3008def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>, 3009 Requires<[IsThumb2, UseMovt]>; 3010 3011def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), 3012 (t2LEApcrelJT tjumptable:$dst, imm:$id)>; 3013 3014// Pseudo instruction that combines ldr from constpool and add pc. This should 3015// be expanded into two instructions late to allow if-conversion and 3016// scheduling. 3017let canFoldAsLoad = 1, isReMaterializable = 1 in 3018def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp), 3019 IIC_iLoadiALU, "", 3020 [(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)), 3021 imm:$cp))]>, 3022 Requires<[IsThumb2]>; 3023 3024//===----------------------------------------------------------------------===// 3025// Move between special register and ARM core register -- for disassembly only 3026// 3027 3028// Rd = Instr{11-8} 3029def t2MRS : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, cpsr", 3030 [/* For disassembly only; pattern left blank */]> { 3031 let Inst{31-27} = 0b11110; 3032 let Inst{26} = 0; 3033 let Inst{25-21} = 0b11111; 3034 let Inst{20} = 0; // The R bit. 3035 let Inst{15-14} = 0b10; 3036 let Inst{12} = 0; 3037} 3038 3039// Rd = Instr{11-8} 3040def t2MRSsys : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr", 3041 [/* For disassembly only; pattern left blank */]> { 3042 let Inst{31-27} = 0b11110; 3043 let Inst{26} = 0; 3044 let Inst{25-21} = 0b11111; 3045 let Inst{20} = 1; // The R bit. 3046 let Inst{15-14} = 0b10; 3047 let Inst{12} = 0; 3048} 3049 3050// Rn = Inst{19-16} 3051def t2MSR : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr", 3052 "\tcpsr$mask, $src", 3053 [/* For disassembly only; pattern left blank */]> { 3054 let Inst{31-27} = 0b11110; 3055 let Inst{26} = 0; 3056 let Inst{25-21} = 0b11100; 3057 let Inst{20} = 0; // The R bit. 3058 let Inst{15-14} = 0b10; 3059 let Inst{12} = 0; 3060} 3061 3062// Rn = Inst{19-16} 3063def t2MSRsys : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr", 3064 "\tspsr$mask, $src", 3065 [/* For disassembly only; pattern left blank */]> { 3066 let Inst{31-27} = 0b11110; 3067 let Inst{26} = 0; 3068 let Inst{25-21} = 0b11100; 3069 let Inst{20} = 1; // The R bit. 3070 let Inst{15-14} = 0b10; 3071 let Inst{12} = 0; 3072} 3073