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