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