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