ARMInstrThumb2.td revision 65bf80e2b7d3c839331be63cdd28a8d101936bca
1//===-- ARMInstrThumb2.td - Thumb2 support for ARM ---------*- tablegen -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file describes the Thumb2 instruction set. 11// 12//===----------------------------------------------------------------------===// 13 14// IT block predicate field 15def it_pred_asmoperand : AsmOperandClass { 16 let Name = "ITCondCode"; 17 let ParserMethod = "parseITCondCode"; 18} 19def it_pred : Operand<i32> { 20 let PrintMethod = "printMandatoryPredicateOperand"; 21 let ParserMatchClass = it_pred_asmoperand; 22} 23 24// IT block condition mask 25def it_mask_asmoperand : AsmOperandClass { let Name = "ITMask"; } 26def it_mask : Operand<i32> { 27 let PrintMethod = "printThumbITMask"; 28 let ParserMatchClass = it_mask_asmoperand; 29} 30 31// t2_shift_imm: An integer that encodes a shift amount and the type of shift 32// (asr or lsl). The 6-bit immediate encodes as: 33// {5} 0 ==> lsl 34// 1 asr 35// {4-0} imm5 shift amount. 36// asr #32 not allowed 37def t2_shift_imm : Operand<i32> { 38 let PrintMethod = "printShiftImmOperand"; 39 let ParserMatchClass = ShifterImmAsmOperand; 40 let DecoderMethod = "DecodeT2ShifterImmOperand"; 41} 42 43// Shifted operands. No register controlled shifts for Thumb2. 44// Note: We do not support rrx shifted operands yet. 45def t2_so_reg : Operand<i32>, // reg imm 46 ComplexPattern<i32, 2, "SelectT2ShifterOperandReg", 47 [shl,srl,sra,rotr]> { 48 let EncoderMethod = "getT2SORegOpValue"; 49 let PrintMethod = "printT2SOOperand"; 50 let DecoderMethod = "DecodeSORegImmOperand"; 51 let ParserMatchClass = ShiftedImmAsmOperand; 52 let MIOperandInfo = (ops rGPR, i32imm); 53} 54 55// t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value 56def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{ 57 return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32); 58}]>; 59 60// t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value 61def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{ 62 return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32); 63}]>; 64 65// so_imm_notSext_XFORM - Return a so_imm value packed into the format 66// described for so_imm_notSext def below, with sign extension from 16 67// bits. 68def t2_so_imm_notSext16_XFORM : SDNodeXForm<imm, [{ 69 APInt apIntN = N->getAPIntValue(); 70 unsigned N16bitSignExt = apIntN.trunc(16).sext(32).getZExtValue(); 71 return CurDAG->getTargetConstant(~N16bitSignExt, MVT::i32); 72}]>; 73 74// t2_so_imm - Match a 32-bit immediate operand, which is an 75// 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit 76// immediate splatted into multiple bytes of the word. 77def t2_so_imm_asmoperand : ImmAsmOperand { let Name = "T2SOImm"; } 78def t2_so_imm : Operand<i32>, ImmLeaf<i32, [{ 79 return ARM_AM::getT2SOImmVal(Imm) != -1; 80 }]> { 81 let ParserMatchClass = t2_so_imm_asmoperand; 82 let EncoderMethod = "getT2SOImmOpValue"; 83 let DecoderMethod = "DecodeT2SOImm"; 84} 85 86// t2_so_imm_not - Match an immediate that is a complement 87// of a t2_so_imm. 88// Note: this pattern doesn't require an encoder method and such, as it's 89// only used on aliases (Pat<> and InstAlias<>). The actual encoding 90// is handled by the destination instructions, which use t2_so_imm. 91def t2_so_imm_not_asmoperand : AsmOperandClass { let Name = "T2SOImmNot"; } 92def t2_so_imm_not : Operand<i32>, PatLeaf<(imm), [{ 93 return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1; 94}], t2_so_imm_not_XFORM> { 95 let ParserMatchClass = t2_so_imm_not_asmoperand; 96} 97 98// t2_so_imm_notSext - match an immediate that is a complement of a t2_so_imm 99// if the upper 16 bits are zero. 100def t2_so_imm_notSext : Operand<i32>, PatLeaf<(imm), [{ 101 APInt apIntN = N->getAPIntValue(); 102 if (!apIntN.isIntN(16)) return false; 103 unsigned N16bitSignExt = apIntN.trunc(16).sext(32).getZExtValue(); 104 return ARM_AM::getT2SOImmVal(~N16bitSignExt) != -1; 105 }], t2_so_imm_notSext16_XFORM> { 106 let ParserMatchClass = t2_so_imm_not_asmoperand; 107} 108 109// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm. 110def t2_so_imm_neg_asmoperand : AsmOperandClass { let Name = "T2SOImmNeg"; } 111def t2_so_imm_neg : Operand<i32>, PatLeaf<(imm), [{ 112 int64_t Value = -(int)N->getZExtValue(); 113 return Value && ARM_AM::getT2SOImmVal(Value) != -1; 114}], t2_so_imm_neg_XFORM> { 115 let ParserMatchClass = t2_so_imm_neg_asmoperand; 116} 117 118/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095]. 119def imm0_4095_asmoperand: ImmAsmOperand { let Name = "Imm0_4095"; } 120def imm0_4095 : Operand<i32>, ImmLeaf<i32, [{ 121 return Imm >= 0 && Imm < 4096; 122}]> { 123 let ParserMatchClass = imm0_4095_asmoperand; 124} 125 126def imm0_4095_neg_asmoperand: AsmOperandClass { let Name = "Imm0_4095Neg"; } 127def imm0_4095_neg : Operand<i32>, PatLeaf<(i32 imm), [{ 128 return (uint32_t)(-N->getZExtValue()) < 4096; 129}], imm_neg_XFORM> { 130 let ParserMatchClass = imm0_4095_neg_asmoperand; 131} 132 133def imm0_255_neg : PatLeaf<(i32 imm), [{ 134 return (uint32_t)(-N->getZExtValue()) < 255; 135}], imm_neg_XFORM>; 136 137def imm0_255_not : PatLeaf<(i32 imm), [{ 138 return (uint32_t)(~N->getZExtValue()) < 255; 139}], imm_comp_XFORM>; 140 141def lo5AllOne : PatLeaf<(i32 imm), [{ 142 // Returns true if all low 5-bits are 1. 143 return (((uint32_t)N->getZExtValue()) & 0x1FUL) == 0x1FUL; 144}]>; 145 146// Define Thumb2 specific addressing modes. 147 148// t2addrmode_imm12 := reg + imm12 149def t2addrmode_imm12_asmoperand : AsmOperandClass {let Name="MemUImm12Offset";} 150def t2addrmode_imm12 : Operand<i32>, 151 ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> { 152 let PrintMethod = "printAddrModeImm12Operand"; 153 let EncoderMethod = "getAddrModeImm12OpValue"; 154 let DecoderMethod = "DecodeT2AddrModeImm12"; 155 let ParserMatchClass = t2addrmode_imm12_asmoperand; 156 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 157} 158 159// t2ldrlabel := imm12 160def t2ldrlabel : Operand<i32> { 161 let EncoderMethod = "getAddrModeImm12OpValue"; 162 let PrintMethod = "printT2LdrLabelOperand"; 163} 164 165def t2ldr_pcrel_imm12_asmoperand : AsmOperandClass {let Name = "MemPCRelImm12";} 166def t2ldr_pcrel_imm12 : Operand<i32> { 167 let ParserMatchClass = t2ldr_pcrel_imm12_asmoperand; 168 // used for assembler pseudo instruction and maps to t2ldrlabel, so 169 // doesn't need encoder or print methods of its own. 170} 171 172// ADR instruction labels. 173def t2adrlabel : Operand<i32> { 174 let EncoderMethod = "getT2AdrLabelOpValue"; 175 let PrintMethod = "printAdrLabelOperand"; 176} 177 178 179// t2addrmode_posimm8 := reg + imm8 180def MemPosImm8OffsetAsmOperand : AsmOperandClass {let Name="MemPosImm8Offset";} 181def t2addrmode_posimm8 : Operand<i32> { 182 let PrintMethod = "printT2AddrModeImm8Operand"; 183 let EncoderMethod = "getT2AddrModeImm8OpValue"; 184 let DecoderMethod = "DecodeT2AddrModeImm8"; 185 let ParserMatchClass = MemPosImm8OffsetAsmOperand; 186 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 187} 188 189// t2addrmode_negimm8 := reg - imm8 190def MemNegImm8OffsetAsmOperand : AsmOperandClass {let Name="MemNegImm8Offset";} 191def t2addrmode_negimm8 : Operand<i32>, 192 ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> { 193 let PrintMethod = "printT2AddrModeImm8Operand"; 194 let EncoderMethod = "getT2AddrModeImm8OpValue"; 195 let DecoderMethod = "DecodeT2AddrModeImm8"; 196 let ParserMatchClass = MemNegImm8OffsetAsmOperand; 197 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 198} 199 200// t2addrmode_imm8 := reg +/- imm8 201def MemImm8OffsetAsmOperand : AsmOperandClass { let Name = "MemImm8Offset"; } 202def t2addrmode_imm8 : Operand<i32>, 203 ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> { 204 let PrintMethod = "printT2AddrModeImm8Operand"; 205 let EncoderMethod = "getT2AddrModeImm8OpValue"; 206 let DecoderMethod = "DecodeT2AddrModeImm8"; 207 let ParserMatchClass = MemImm8OffsetAsmOperand; 208 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 209} 210 211def t2am_imm8_offset : Operand<i32>, 212 ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", 213 [], [SDNPWantRoot]> { 214 let PrintMethod = "printT2AddrModeImm8OffsetOperand"; 215 let EncoderMethod = "getT2AddrModeImm8OffsetOpValue"; 216 let DecoderMethod = "DecodeT2Imm8"; 217} 218 219// t2addrmode_imm8s4 := reg +/- (imm8 << 2) 220def MemImm8s4OffsetAsmOperand : AsmOperandClass {let Name = "MemImm8s4Offset";} 221def t2addrmode_imm8s4 : Operand<i32> { 222 let PrintMethod = "printT2AddrModeImm8s4Operand"; 223 let EncoderMethod = "getT2AddrModeImm8s4OpValue"; 224 let DecoderMethod = "DecodeT2AddrModeImm8s4"; 225 let ParserMatchClass = MemImm8s4OffsetAsmOperand; 226 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 227} 228 229def t2am_imm8s4_offset_asmoperand : AsmOperandClass { let Name = "Imm8s4"; } 230def t2am_imm8s4_offset : Operand<i32> { 231 let PrintMethod = "printT2AddrModeImm8s4OffsetOperand"; 232 let EncoderMethod = "getT2Imm8s4OpValue"; 233 let DecoderMethod = "DecodeT2Imm8S4"; 234} 235 236// t2addrmode_imm0_1020s4 := reg + (imm8 << 2) 237def MemImm0_1020s4OffsetAsmOperand : AsmOperandClass { 238 let Name = "MemImm0_1020s4Offset"; 239} 240def t2addrmode_imm0_1020s4 : Operand<i32> { 241 let PrintMethod = "printT2AddrModeImm0_1020s4Operand"; 242 let EncoderMethod = "getT2AddrModeImm0_1020s4OpValue"; 243 let DecoderMethod = "DecodeT2AddrModeImm0_1020s4"; 244 let ParserMatchClass = MemImm0_1020s4OffsetAsmOperand; 245 let MIOperandInfo = (ops GPRnopc:$base, i32imm:$offsimm); 246} 247 248// t2addrmode_so_reg := reg + (reg << imm2) 249def t2addrmode_so_reg_asmoperand : AsmOperandClass {let Name="T2MemRegOffset";} 250def t2addrmode_so_reg : Operand<i32>, 251 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> { 252 let PrintMethod = "printT2AddrModeSoRegOperand"; 253 let EncoderMethod = "getT2AddrModeSORegOpValue"; 254 let DecoderMethod = "DecodeT2AddrModeSOReg"; 255 let ParserMatchClass = t2addrmode_so_reg_asmoperand; 256 let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm); 257} 258 259// Addresses for the TBB/TBH instructions. 260def addrmode_tbb_asmoperand : AsmOperandClass { let Name = "MemTBB"; } 261def addrmode_tbb : Operand<i32> { 262 let PrintMethod = "printAddrModeTBB"; 263 let ParserMatchClass = addrmode_tbb_asmoperand; 264 let MIOperandInfo = (ops GPR:$Rn, rGPR:$Rm); 265} 266def addrmode_tbh_asmoperand : AsmOperandClass { let Name = "MemTBH"; } 267def addrmode_tbh : Operand<i32> { 268 let PrintMethod = "printAddrModeTBH"; 269 let ParserMatchClass = addrmode_tbh_asmoperand; 270 let MIOperandInfo = (ops GPR:$Rn, rGPR:$Rm); 271} 272 273//===----------------------------------------------------------------------===// 274// Multiclass helpers... 275// 276 277 278class T2OneRegImm<dag oops, dag iops, InstrItinClass itin, 279 string opc, string asm, list<dag> pattern> 280 : T2I<oops, iops, itin, opc, asm, pattern> { 281 bits<4> Rd; 282 bits<12> imm; 283 284 let Inst{11-8} = Rd; 285 let Inst{26} = imm{11}; 286 let Inst{14-12} = imm{10-8}; 287 let Inst{7-0} = imm{7-0}; 288} 289 290 291class T2sOneRegImm<dag oops, dag iops, InstrItinClass itin, 292 string opc, string asm, list<dag> pattern> 293 : T2sI<oops, iops, itin, opc, asm, pattern> { 294 bits<4> Rd; 295 bits<4> Rn; 296 bits<12> imm; 297 298 let Inst{11-8} = Rd; 299 let Inst{26} = imm{11}; 300 let Inst{14-12} = imm{10-8}; 301 let Inst{7-0} = imm{7-0}; 302} 303 304class T2OneRegCmpImm<dag oops, dag iops, InstrItinClass itin, 305 string opc, string asm, list<dag> pattern> 306 : T2I<oops, iops, itin, opc, asm, pattern> { 307 bits<4> Rn; 308 bits<12> imm; 309 310 let Inst{19-16} = Rn; 311 let Inst{26} = imm{11}; 312 let Inst{14-12} = imm{10-8}; 313 let Inst{7-0} = imm{7-0}; 314} 315 316 317class T2OneRegShiftedReg<dag oops, dag iops, InstrItinClass itin, 318 string opc, string asm, list<dag> pattern> 319 : T2I<oops, iops, itin, opc, asm, pattern> { 320 bits<4> Rd; 321 bits<12> ShiftedRm; 322 323 let Inst{11-8} = Rd; 324 let Inst{3-0} = ShiftedRm{3-0}; 325 let Inst{5-4} = ShiftedRm{6-5}; 326 let Inst{14-12} = ShiftedRm{11-9}; 327 let Inst{7-6} = ShiftedRm{8-7}; 328} 329 330class T2sOneRegShiftedReg<dag oops, dag iops, InstrItinClass itin, 331 string opc, string asm, list<dag> pattern> 332 : T2sI<oops, iops, itin, opc, asm, pattern> { 333 bits<4> Rd; 334 bits<12> ShiftedRm; 335 336 let Inst{11-8} = Rd; 337 let Inst{3-0} = ShiftedRm{3-0}; 338 let Inst{5-4} = ShiftedRm{6-5}; 339 let Inst{14-12} = ShiftedRm{11-9}; 340 let Inst{7-6} = ShiftedRm{8-7}; 341} 342 343class T2OneRegCmpShiftedReg<dag oops, dag iops, InstrItinClass itin, 344 string opc, string asm, list<dag> pattern> 345 : T2I<oops, iops, itin, opc, asm, pattern> { 346 bits<4> Rn; 347 bits<12> ShiftedRm; 348 349 let Inst{19-16} = Rn; 350 let Inst{3-0} = ShiftedRm{3-0}; 351 let Inst{5-4} = ShiftedRm{6-5}; 352 let Inst{14-12} = ShiftedRm{11-9}; 353 let Inst{7-6} = ShiftedRm{8-7}; 354} 355 356class T2TwoReg<dag oops, dag iops, InstrItinClass itin, 357 string opc, string asm, list<dag> pattern> 358 : T2I<oops, iops, itin, opc, asm, pattern> { 359 bits<4> Rd; 360 bits<4> Rm; 361 362 let Inst{11-8} = Rd; 363 let Inst{3-0} = Rm; 364} 365 366class T2sTwoReg<dag oops, dag iops, InstrItinClass itin, 367 string opc, string asm, list<dag> pattern> 368 : T2sI<oops, iops, itin, opc, asm, pattern> { 369 bits<4> Rd; 370 bits<4> Rm; 371 372 let Inst{11-8} = Rd; 373 let Inst{3-0} = Rm; 374} 375 376class T2TwoRegCmp<dag oops, dag iops, InstrItinClass itin, 377 string opc, string asm, list<dag> pattern> 378 : T2I<oops, iops, itin, opc, asm, pattern> { 379 bits<4> Rn; 380 bits<4> Rm; 381 382 let Inst{19-16} = Rn; 383 let Inst{3-0} = Rm; 384} 385 386 387class T2TwoRegImm<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<12> imm; 393 394 let Inst{11-8} = Rd; 395 let Inst{19-16} = Rn; 396 let Inst{26} = imm{11}; 397 let Inst{14-12} = imm{10-8}; 398 let Inst{7-0} = imm{7-0}; 399} 400 401class T2sTwoRegImm<dag oops, dag iops, InstrItinClass itin, 402 string opc, string asm, list<dag> pattern> 403 : T2sI<oops, iops, itin, opc, asm, pattern> { 404 bits<4> Rd; 405 bits<4> Rn; 406 bits<12> imm; 407 408 let Inst{11-8} = Rd; 409 let Inst{19-16} = Rn; 410 let Inst{26} = imm{11}; 411 let Inst{14-12} = imm{10-8}; 412 let Inst{7-0} = imm{7-0}; 413} 414 415class T2TwoRegShiftImm<dag oops, dag iops, InstrItinClass itin, 416 string opc, string asm, list<dag> pattern> 417 : T2I<oops, iops, itin, opc, asm, pattern> { 418 bits<4> Rd; 419 bits<4> Rm; 420 bits<5> imm; 421 422 let Inst{11-8} = Rd; 423 let Inst{3-0} = Rm; 424 let Inst{14-12} = imm{4-2}; 425 let Inst{7-6} = imm{1-0}; 426} 427 428class T2sTwoRegShiftImm<dag oops, dag iops, InstrItinClass itin, 429 string opc, string asm, list<dag> pattern> 430 : T2sI<oops, iops, itin, opc, asm, pattern> { 431 bits<4> Rd; 432 bits<4> Rm; 433 bits<5> imm; 434 435 let Inst{11-8} = Rd; 436 let Inst{3-0} = Rm; 437 let Inst{14-12} = imm{4-2}; 438 let Inst{7-6} = imm{1-0}; 439} 440 441class T2ThreeReg<dag oops, dag iops, InstrItinClass itin, 442 string opc, string asm, list<dag> pattern> 443 : T2I<oops, iops, itin, opc, asm, pattern> { 444 bits<4> Rd; 445 bits<4> Rn; 446 bits<4> Rm; 447 448 let Inst{11-8} = Rd; 449 let Inst{19-16} = Rn; 450 let Inst{3-0} = Rm; 451} 452 453class T2sThreeReg<dag oops, dag iops, InstrItinClass itin, 454 string opc, string asm, list<dag> pattern> 455 : T2sI<oops, iops, itin, opc, asm, pattern> { 456 bits<4> Rd; 457 bits<4> Rn; 458 bits<4> Rm; 459 460 let Inst{11-8} = Rd; 461 let Inst{19-16} = Rn; 462 let Inst{3-0} = Rm; 463} 464 465class T2TwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin, 466 string opc, string asm, list<dag> pattern> 467 : T2I<oops, iops, itin, opc, asm, pattern> { 468 bits<4> Rd; 469 bits<4> Rn; 470 bits<12> ShiftedRm; 471 472 let Inst{11-8} = Rd; 473 let Inst{19-16} = Rn; 474 let Inst{3-0} = ShiftedRm{3-0}; 475 let Inst{5-4} = ShiftedRm{6-5}; 476 let Inst{14-12} = ShiftedRm{11-9}; 477 let Inst{7-6} = ShiftedRm{8-7}; 478} 479 480class T2sTwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin, 481 string opc, string asm, list<dag> pattern> 482 : T2sI<oops, iops, itin, opc, asm, pattern> { 483 bits<4> Rd; 484 bits<4> Rn; 485 bits<12> ShiftedRm; 486 487 let Inst{11-8} = Rd; 488 let Inst{19-16} = Rn; 489 let Inst{3-0} = ShiftedRm{3-0}; 490 let Inst{5-4} = ShiftedRm{6-5}; 491 let Inst{14-12} = ShiftedRm{11-9}; 492 let Inst{7-6} = ShiftedRm{8-7}; 493} 494 495class T2FourReg<dag oops, dag iops, InstrItinClass itin, 496 string opc, string asm, list<dag> pattern> 497 : T2I<oops, iops, itin, opc, asm, pattern> { 498 bits<4> Rd; 499 bits<4> Rn; 500 bits<4> Rm; 501 bits<4> Ra; 502 503 let Inst{19-16} = Rn; 504 let Inst{15-12} = Ra; 505 let Inst{11-8} = Rd; 506 let Inst{3-0} = Rm; 507} 508 509class T2MulLong<bits<3> opc22_20, bits<4> opc7_4, 510 dag oops, dag iops, InstrItinClass itin, 511 string opc, string asm, list<dag> pattern> 512 : T2I<oops, iops, itin, opc, asm, pattern> { 513 bits<4> RdLo; 514 bits<4> RdHi; 515 bits<4> Rn; 516 bits<4> Rm; 517 518 let Inst{31-23} = 0b111110111; 519 let Inst{22-20} = opc22_20; 520 let Inst{19-16} = Rn; 521 let Inst{15-12} = RdLo; 522 let Inst{11-8} = RdHi; 523 let Inst{7-4} = opc7_4; 524 let Inst{3-0} = Rm; 525} 526 527 528/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a 529/// binary operation that produces a value. These are predicable and can be 530/// changed to modify CPSR. 531multiclass T2I_bin_irs<bits<4> opcod, string opc, 532 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 533 PatFrag opnode, bit Commutable = 0, 534 string wide = ""> { 535 // shifted imm 536 def ri : T2sTwoRegImm< 537 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), iii, 538 opc, "\t$Rd, $Rn, $imm", 539 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]> { 540 let Inst{31-27} = 0b11110; 541 let Inst{25} = 0; 542 let Inst{24-21} = opcod; 543 let Inst{15} = 0; 544 } 545 // register 546 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), iir, 547 opc, !strconcat(wide, "\t$Rd, $Rn, $Rm"), 548 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> { 549 let isCommutable = Commutable; 550 let Inst{31-27} = 0b11101; 551 let Inst{26-25} = 0b01; 552 let Inst{24-21} = opcod; 553 let Inst{14-12} = 0b000; // imm3 554 let Inst{7-6} = 0b00; // imm2 555 let Inst{5-4} = 0b00; // type 556 } 557 // shifted register 558 def rs : T2sTwoRegShiftedReg< 559 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), iis, 560 opc, !strconcat(wide, "\t$Rd, $Rn, $ShiftedRm"), 561 [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]> { 562 let Inst{31-27} = 0b11101; 563 let Inst{26-25} = 0b01; 564 let Inst{24-21} = opcod; 565 } 566 // Assembly aliases for optional destination operand when it's the same 567 // as the source operand. 568 def : t2InstAlias<!strconcat(opc, "${s}${p} $Rdn, $imm"), 569 (!cast<Instruction>(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, 570 t2_so_imm:$imm, pred:$p, 571 cc_out:$s)>; 572 def : t2InstAlias<!strconcat(opc, "${s}${p}", wide, " $Rdn, $Rm"), 573 (!cast<Instruction>(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, 574 rGPR:$Rm, pred:$p, 575 cc_out:$s)>; 576 def : t2InstAlias<!strconcat(opc, "${s}${p}", wide, " $Rdn, $shift"), 577 (!cast<Instruction>(NAME#"rs") rGPR:$Rdn, rGPR:$Rdn, 578 t2_so_reg:$shift, pred:$p, 579 cc_out:$s)>; 580} 581 582/// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need 583// the ".w" suffix to indicate that they are wide. 584multiclass T2I_bin_w_irs<bits<4> opcod, string opc, 585 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 586 PatFrag opnode, bit Commutable = 0> : 587 T2I_bin_irs<opcod, opc, iii, iir, iis, opnode, Commutable, ".w"> { 588 // Assembler aliases w/ the ".w" suffix. 589 def : t2InstAlias<!strconcat(opc, "${s}${p}.w", " $Rd, $Rn, $imm"), 590 (!cast<Instruction>(NAME#"ri") rGPR:$Rd, rGPR:$Rn, t2_so_imm:$imm, pred:$p, 591 cc_out:$s)>; 592 // Assembler aliases w/o the ".w" suffix. 593 def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rd, $Rn, $Rm"), 594 (!cast<Instruction>(NAME#"rr") rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p, 595 cc_out:$s)>; 596 def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rd, $Rn, $shift"), 597 (!cast<Instruction>(NAME#"rs") rGPR:$Rd, rGPR:$Rn, t2_so_reg:$shift, 598 pred:$p, cc_out:$s)>; 599 600 // and with the optional destination operand, too. 601 def : t2InstAlias<!strconcat(opc, "${s}${p}.w", " $Rdn, $imm"), 602 (!cast<Instruction>(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, t2_so_imm:$imm, 603 pred:$p, cc_out:$s)>; 604 def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rdn, $Rm"), 605 (!cast<Instruction>(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p, 606 cc_out:$s)>; 607 def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rdn, $shift"), 608 (!cast<Instruction>(NAME#"rs") rGPR:$Rdn, rGPR:$Rdn, t2_so_reg:$shift, 609 pred:$p, cc_out:$s)>; 610} 611 612/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are 613/// reversed. The 'rr' form is only defined for the disassembler; for codegen 614/// it is equivalent to the T2I_bin_irs counterpart. 615multiclass T2I_rbin_irs<bits<4> opcod, string opc, PatFrag opnode> { 616 // shifted imm 617 def ri : T2sTwoRegImm< 618 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi, 619 opc, ".w\t$Rd, $Rn, $imm", 620 [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]> { 621 let Inst{31-27} = 0b11110; 622 let Inst{25} = 0; 623 let Inst{24-21} = opcod; 624 let Inst{15} = 0; 625 } 626 // register 627 def rr : T2sThreeReg< 628 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr, 629 opc, "\t$Rd, $Rn, $Rm", 630 [/* For disassembly only; pattern left blank */]> { 631 let Inst{31-27} = 0b11101; 632 let Inst{26-25} = 0b01; 633 let Inst{24-21} = opcod; 634 let Inst{14-12} = 0b000; // imm3 635 let Inst{7-6} = 0b00; // imm2 636 let Inst{5-4} = 0b00; // type 637 } 638 // shifted register 639 def rs : T2sTwoRegShiftedReg< 640 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), 641 IIC_iALUsir, opc, "\t$Rd, $Rn, $ShiftedRm", 642 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]> { 643 let Inst{31-27} = 0b11101; 644 let Inst{26-25} = 0b01; 645 let Inst{24-21} = opcod; 646 } 647} 648 649/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the 650/// instruction modifies the CPSR register. 651/// 652/// These opcodes will be converted to the real non-S opcodes by 653/// AdjustInstrPostInstrSelection after giving then an optional CPSR operand. 654let hasPostISelHook = 1, Defs = [CPSR] in { 655multiclass T2I_bin_s_irs<InstrItinClass iii, InstrItinClass iir, 656 InstrItinClass iis, PatFrag opnode, 657 bit Commutable = 0> { 658 // shifted imm 659 def ri : t2PseudoInst<(outs rGPR:$Rd), 660 (ins GPRnopc:$Rn, t2_so_imm:$imm, pred:$p), 661 4, iii, 662 [(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn, 663 t2_so_imm:$imm))]>; 664 // register 665 def rr : t2PseudoInst<(outs rGPR:$Rd), (ins GPRnopc:$Rn, rGPR:$Rm, pred:$p), 666 4, iir, 667 [(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn, 668 rGPR:$Rm))]> { 669 let isCommutable = Commutable; 670 } 671 // shifted register 672 def rs : t2PseudoInst<(outs rGPR:$Rd), 673 (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm, pred:$p), 674 4, iis, 675 [(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn, 676 t2_so_reg:$ShiftedRm))]>; 677} 678} 679 680/// T2I_rbin_s_is - Same as T2I_bin_s_irs, except selection DAG 681/// operands are reversed. 682let hasPostISelHook = 1, Defs = [CPSR] in { 683multiclass T2I_rbin_s_is<PatFrag opnode> { 684 // shifted imm 685 def ri : t2PseudoInst<(outs rGPR:$Rd), 686 (ins rGPR:$Rn, t2_so_imm:$imm, pred:$p), 687 4, IIC_iALUi, 688 [(set rGPR:$Rd, CPSR, (opnode t2_so_imm:$imm, 689 rGPR:$Rn))]>; 690 // shifted register 691 def rs : t2PseudoInst<(outs rGPR:$Rd), 692 (ins rGPR:$Rn, t2_so_reg:$ShiftedRm, pred:$p), 693 4, IIC_iALUsi, 694 [(set rGPR:$Rd, CPSR, (opnode t2_so_reg:$ShiftedRm, 695 rGPR:$Rn))]>; 696} 697} 698 699/// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg}) 700/// patterns for a binary operation that produces a value. 701multiclass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode, 702 bit Commutable = 0> { 703 // shifted imm 704 // The register-immediate version is re-materializable. This is useful 705 // in particular for taking the address of a local. 706 let isReMaterializable = 1 in { 707 def ri : T2sTwoRegImm< 708 (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, t2_so_imm:$imm), IIC_iALUi, 709 opc, ".w\t$Rd, $Rn, $imm", 710 [(set GPRnopc:$Rd, (opnode GPRnopc:$Rn, t2_so_imm:$imm))]> { 711 let Inst{31-27} = 0b11110; 712 let Inst{25} = 0; 713 let Inst{24} = 1; 714 let Inst{23-21} = op23_21; 715 let Inst{15} = 0; 716 } 717 } 718 // 12-bit imm 719 def ri12 : T2I< 720 (outs GPRnopc:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi, 721 !strconcat(opc, "w"), "\t$Rd, $Rn, $imm", 722 [(set GPRnopc:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]> { 723 bits<4> Rd; 724 bits<4> Rn; 725 bits<12> imm; 726 let Inst{31-27} = 0b11110; 727 let Inst{26} = imm{11}; 728 let Inst{25-24} = 0b10; 729 let Inst{23-21} = op23_21; 730 let Inst{20} = 0; // The S bit. 731 let Inst{19-16} = Rn; 732 let Inst{15} = 0; 733 let Inst{14-12} = imm{10-8}; 734 let Inst{11-8} = Rd; 735 let Inst{7-0} = imm{7-0}; 736 } 737 // register 738 def rr : T2sThreeReg<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, rGPR:$Rm), 739 IIC_iALUr, opc, ".w\t$Rd, $Rn, $Rm", 740 [(set GPRnopc:$Rd, (opnode GPRnopc:$Rn, rGPR:$Rm))]> { 741 let isCommutable = Commutable; 742 let Inst{31-27} = 0b11101; 743 let Inst{26-25} = 0b01; 744 let Inst{24} = 1; 745 let Inst{23-21} = op23_21; 746 let Inst{14-12} = 0b000; // imm3 747 let Inst{7-6} = 0b00; // imm2 748 let Inst{5-4} = 0b00; // type 749 } 750 // shifted register 751 def rs : T2sTwoRegShiftedReg< 752 (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm), 753 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm", 754 [(set GPRnopc:$Rd, (opnode GPRnopc:$Rn, t2_so_reg:$ShiftedRm))]> { 755 let Inst{31-27} = 0b11101; 756 let Inst{26-25} = 0b01; 757 let Inst{24} = 1; 758 let Inst{23-21} = op23_21; 759 } 760} 761 762/// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns 763/// for a binary operation that produces a value and use the carry 764/// bit. It's not predicable. 765let Defs = [CPSR], Uses = [CPSR] in { 766multiclass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, 767 bit Commutable = 0> { 768 // shifted imm 769 def ri : T2sTwoRegImm<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), 770 IIC_iALUi, opc, "\t$Rd, $Rn, $imm", 771 [(set rGPR:$Rd, CPSR, (opnode rGPR:$Rn, t2_so_imm:$imm, CPSR))]>, 772 Requires<[IsThumb2]> { 773 let Inst{31-27} = 0b11110; 774 let Inst{25} = 0; 775 let Inst{24-21} = opcod; 776 let Inst{15} = 0; 777 } 778 // register 779 def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr, 780 opc, ".w\t$Rd, $Rn, $Rm", 781 [(set rGPR:$Rd, CPSR, (opnode rGPR:$Rn, rGPR:$Rm, CPSR))]>, 782 Requires<[IsThumb2]> { 783 let isCommutable = Commutable; 784 let Inst{31-27} = 0b11101; 785 let Inst{26-25} = 0b01; 786 let Inst{24-21} = opcod; 787 let Inst{14-12} = 0b000; // imm3 788 let Inst{7-6} = 0b00; // imm2 789 let Inst{5-4} = 0b00; // type 790 } 791 // shifted register 792 def rs : T2sTwoRegShiftedReg< 793 (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), 794 IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm", 795 [(set rGPR:$Rd, CPSR, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm, CPSR))]>, 796 Requires<[IsThumb2]> { 797 let Inst{31-27} = 0b11101; 798 let Inst{26-25} = 0b01; 799 let Inst{24-21} = opcod; 800 } 801} 802} 803 804/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift / 805// rotate operation that produces a value. 806multiclass T2I_sh_ir<bits<2> opcod, string opc, Operand ty, PatFrag opnode> { 807 // 5-bit imm 808 def ri : T2sTwoRegShiftImm< 809 (outs rGPR:$Rd), (ins rGPR:$Rm, ty:$imm), IIC_iMOVsi, 810 opc, ".w\t$Rd, $Rm, $imm", 811 [(set rGPR:$Rd, (opnode rGPR:$Rm, (i32 ty:$imm)))]> { 812 let Inst{31-27} = 0b11101; 813 let Inst{26-21} = 0b010010; 814 let Inst{19-16} = 0b1111; // Rn 815 let Inst{5-4} = opcod; 816 } 817 // register 818 def rr : T2sThreeReg< 819 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMOVsr, 820 opc, ".w\t$Rd, $Rn, $Rm", 821 [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]> { 822 let Inst{31-27} = 0b11111; 823 let Inst{26-23} = 0b0100; 824 let Inst{22-21} = opcod; 825 let Inst{15-12} = 0b1111; 826 let Inst{7-4} = 0b0000; 827 } 828 829 // Optional destination register 830 def : t2InstAlias<!strconcat(opc, "${s}${p}", ".w $Rdn, $imm"), 831 (!cast<Instruction>(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, ty:$imm, pred:$p, 832 cc_out:$s)>; 833 def : t2InstAlias<!strconcat(opc, "${s}${p}", ".w $Rdn, $Rm"), 834 (!cast<Instruction>(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p, 835 cc_out:$s)>; 836 837 // Assembler aliases w/o the ".w" suffix. 838 def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rd, $Rn, $imm"), 839 (!cast<Instruction>(NAME#"ri") rGPR:$Rd, rGPR:$Rn, ty:$imm, pred:$p, 840 cc_out:$s)>; 841 def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rd, $Rn, $Rm"), 842 (!cast<Instruction>(NAME#"rr") rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p, 843 cc_out:$s)>; 844 845 // and with the optional destination operand, too. 846 def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rdn, $imm"), 847 (!cast<Instruction>(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, ty:$imm, pred:$p, 848 cc_out:$s)>; 849 def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rdn, $Rm"), 850 (!cast<Instruction>(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p, 851 cc_out:$s)>; 852} 853 854/// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test 855/// patterns. Similar to T2I_bin_irs except the instruction does not produce 856/// a explicit result, only implicitly set CPSR. 857multiclass T2I_cmp_irs<bits<4> opcod, string opc, 858 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 859 PatFrag opnode> { 860let isCompare = 1, Defs = [CPSR] in { 861 // shifted imm 862 def ri : T2OneRegCmpImm< 863 (outs), (ins GPRnopc:$Rn, t2_so_imm:$imm), iii, 864 opc, ".w\t$Rn, $imm", 865 [(opnode GPRnopc:$Rn, t2_so_imm:$imm)]> { 866 let Inst{31-27} = 0b11110; 867 let Inst{25} = 0; 868 let Inst{24-21} = opcod; 869 let Inst{20} = 1; // The S bit. 870 let Inst{15} = 0; 871 let Inst{11-8} = 0b1111; // Rd 872 } 873 // register 874 def rr : T2TwoRegCmp< 875 (outs), (ins GPRnopc:$Rn, rGPR:$Rm), iir, 876 opc, ".w\t$Rn, $Rm", 877 [(opnode GPRnopc:$Rn, rGPR:$Rm)]> { 878 let Inst{31-27} = 0b11101; 879 let Inst{26-25} = 0b01; 880 let Inst{24-21} = opcod; 881 let Inst{20} = 1; // The S bit. 882 let Inst{14-12} = 0b000; // imm3 883 let Inst{11-8} = 0b1111; // Rd 884 let Inst{7-6} = 0b00; // imm2 885 let Inst{5-4} = 0b00; // type 886 } 887 // shifted register 888 def rs : T2OneRegCmpShiftedReg< 889 (outs), (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm), iis, 890 opc, ".w\t$Rn, $ShiftedRm", 891 [(opnode GPRnopc:$Rn, t2_so_reg:$ShiftedRm)]> { 892 let Inst{31-27} = 0b11101; 893 let Inst{26-25} = 0b01; 894 let Inst{24-21} = opcod; 895 let Inst{20} = 1; // The S bit. 896 let Inst{11-8} = 0b1111; // Rd 897 } 898} 899 900 // Assembler aliases w/o the ".w" suffix. 901 // No alias here for 'rr' version as not all instantiations of this 902 // multiclass want one (CMP in particular, does not). 903 def : t2InstAlias<!strconcat(opc, "${p}", " $Rn, $imm"), 904 (!cast<Instruction>(NAME#"ri") GPRnopc:$Rn, t2_so_imm:$imm, pred:$p)>; 905 def : t2InstAlias<!strconcat(opc, "${p}", " $Rn, $shift"), 906 (!cast<Instruction>(NAME#"rs") GPRnopc:$Rn, t2_so_reg:$shift, pred:$p)>; 907} 908 909/// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns. 910multiclass T2I_ld<bit signed, bits<2> opcod, string opc, 911 InstrItinClass iii, InstrItinClass iis, RegisterClass target, 912 PatFrag opnode> { 913 def i12 : T2Ii12<(outs target:$Rt), (ins t2addrmode_imm12:$addr), iii, 914 opc, ".w\t$Rt, $addr", 915 [(set target:$Rt, (opnode t2addrmode_imm12:$addr))]> { 916 bits<4> Rt; 917 bits<17> addr; 918 let Inst{31-25} = 0b1111100; 919 let Inst{24} = signed; 920 let Inst{23} = 1; 921 let Inst{22-21} = opcod; 922 let Inst{20} = 1; // load 923 let Inst{19-16} = addr{16-13}; // Rn 924 let Inst{15-12} = Rt; 925 let Inst{11-0} = addr{11-0}; // imm 926 } 927 def i8 : T2Ii8 <(outs target:$Rt), (ins t2addrmode_negimm8:$addr), iii, 928 opc, "\t$Rt, $addr", 929 [(set target:$Rt, (opnode t2addrmode_negimm8:$addr))]> { 930 bits<4> Rt; 931 bits<13> addr; 932 let Inst{31-27} = 0b11111; 933 let Inst{26-25} = 0b00; 934 let Inst{24} = signed; 935 let Inst{23} = 0; 936 let Inst{22-21} = opcod; 937 let Inst{20} = 1; // load 938 let Inst{19-16} = addr{12-9}; // Rn 939 let Inst{15-12} = Rt; 940 let Inst{11} = 1; 941 // Offset: index==TRUE, wback==FALSE 942 let Inst{10} = 1; // The P bit. 943 let Inst{9} = addr{8}; // U 944 let Inst{8} = 0; // The W bit. 945 let Inst{7-0} = addr{7-0}; // imm 946 } 947 def s : T2Iso <(outs target:$Rt), (ins t2addrmode_so_reg:$addr), iis, 948 opc, ".w\t$Rt, $addr", 949 [(set target:$Rt, (opnode t2addrmode_so_reg:$addr))]> { 950 let Inst{31-27} = 0b11111; 951 let Inst{26-25} = 0b00; 952 let Inst{24} = signed; 953 let Inst{23} = 0; 954 let Inst{22-21} = opcod; 955 let Inst{20} = 1; // load 956 let Inst{11-6} = 0b000000; 957 958 bits<4> Rt; 959 let Inst{15-12} = Rt; 960 961 bits<10> addr; 962 let Inst{19-16} = addr{9-6}; // Rn 963 let Inst{3-0} = addr{5-2}; // Rm 964 let Inst{5-4} = addr{1-0}; // imm 965 966 let DecoderMethod = "DecodeT2LoadShift"; 967 } 968 969 // pci variant is very similar to i12, but supports negative offsets 970 // from the PC. 971 def pci : T2Ipc <(outs target:$Rt), (ins t2ldrlabel:$addr), iii, 972 opc, ".w\t$Rt, $addr", 973 [(set target:$Rt, (opnode (ARMWrapper tconstpool:$addr)))]> { 974 let isReMaterializable = 1; 975 let Inst{31-27} = 0b11111; 976 let Inst{26-25} = 0b00; 977 let Inst{24} = signed; 978 let Inst{23} = ?; // add = (U == '1') 979 let Inst{22-21} = opcod; 980 let Inst{20} = 1; // load 981 let Inst{19-16} = 0b1111; // Rn 982 bits<4> Rt; 983 bits<12> addr; 984 let Inst{15-12} = Rt{3-0}; 985 let Inst{11-0} = addr{11-0}; 986 } 987} 988 989/// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns. 990multiclass T2I_st<bits<2> opcod, string opc, 991 InstrItinClass iii, InstrItinClass iis, RegisterClass target, 992 PatFrag opnode> { 993 def i12 : T2Ii12<(outs), (ins target:$Rt, t2addrmode_imm12:$addr), iii, 994 opc, ".w\t$Rt, $addr", 995 [(opnode target:$Rt, t2addrmode_imm12:$addr)]> { 996 let Inst{31-27} = 0b11111; 997 let Inst{26-23} = 0b0001; 998 let Inst{22-21} = opcod; 999 let Inst{20} = 0; // !load 1000 1001 bits<4> Rt; 1002 let Inst{15-12} = Rt; 1003 1004 bits<17> addr; 1005 let addr{12} = 1; // add = TRUE 1006 let Inst{19-16} = addr{16-13}; // Rn 1007 let Inst{23} = addr{12}; // U 1008 let Inst{11-0} = addr{11-0}; // imm 1009 } 1010 def i8 : T2Ii8 <(outs), (ins target:$Rt, t2addrmode_negimm8:$addr), iii, 1011 opc, "\t$Rt, $addr", 1012 [(opnode target:$Rt, t2addrmode_negimm8:$addr)]> { 1013 let Inst{31-27} = 0b11111; 1014 let Inst{26-23} = 0b0000; 1015 let Inst{22-21} = opcod; 1016 let Inst{20} = 0; // !load 1017 let Inst{11} = 1; 1018 // Offset: index==TRUE, wback==FALSE 1019 let Inst{10} = 1; // The P bit. 1020 let Inst{8} = 0; // The W bit. 1021 1022 bits<4> Rt; 1023 let Inst{15-12} = Rt; 1024 1025 bits<13> addr; 1026 let Inst{19-16} = addr{12-9}; // Rn 1027 let Inst{9} = addr{8}; // U 1028 let Inst{7-0} = addr{7-0}; // imm 1029 } 1030 def s : T2Iso <(outs), (ins target:$Rt, t2addrmode_so_reg:$addr), iis, 1031 opc, ".w\t$Rt, $addr", 1032 [(opnode target:$Rt, t2addrmode_so_reg:$addr)]> { 1033 let Inst{31-27} = 0b11111; 1034 let Inst{26-23} = 0b0000; 1035 let Inst{22-21} = opcod; 1036 let Inst{20} = 0; // !load 1037 let Inst{11-6} = 0b000000; 1038 1039 bits<4> Rt; 1040 let Inst{15-12} = Rt; 1041 1042 bits<10> addr; 1043 let Inst{19-16} = addr{9-6}; // Rn 1044 let Inst{3-0} = addr{5-2}; // Rm 1045 let Inst{5-4} = addr{1-0}; // imm 1046 } 1047} 1048 1049/// T2I_ext_rrot - A unary operation with two forms: one whose operand is a 1050/// register and one whose operand is a register rotated by 8/16/24. 1051class T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode> 1052 : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), IIC_iEXTr, 1053 opc, ".w\t$Rd, $Rm$rot", 1054 [(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>, 1055 Requires<[IsThumb2]> { 1056 let Inst{31-27} = 0b11111; 1057 let Inst{26-23} = 0b0100; 1058 let Inst{22-20} = opcod; 1059 let Inst{19-16} = 0b1111; // Rn 1060 let Inst{15-12} = 0b1111; 1061 let Inst{7} = 1; 1062 1063 bits<2> rot; 1064 let Inst{5-4} = rot{1-0}; // rotate 1065} 1066 1067// UXTB16 - Requres T2ExtractPack, does not need the .w qualifier. 1068class T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode> 1069 : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), 1070 IIC_iEXTr, opc, "\t$Rd, $Rm$rot", 1071 [(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>, 1072 Requires<[HasT2ExtractPack, IsThumb2]> { 1073 bits<2> rot; 1074 let Inst{31-27} = 0b11111; 1075 let Inst{26-23} = 0b0100; 1076 let Inst{22-20} = opcod; 1077 let Inst{19-16} = 0b1111; // Rn 1078 let Inst{15-12} = 0b1111; 1079 let Inst{7} = 1; 1080 let Inst{5-4} = rot; 1081} 1082 1083// SXTB16 - Requres T2ExtractPack, does not need the .w qualifier, no pattern 1084// supported yet. 1085class T2I_ext_rrot_sxtb16<bits<3> opcod, string opc> 1086 : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), IIC_iEXTr, 1087 opc, "\t$Rd, $Rm$rot", []>, 1088 Requires<[IsThumb2, HasT2ExtractPack]> { 1089 bits<2> rot; 1090 let Inst{31-27} = 0b11111; 1091 let Inst{26-23} = 0b0100; 1092 let Inst{22-20} = opcod; 1093 let Inst{19-16} = 0b1111; // Rn 1094 let Inst{15-12} = 0b1111; 1095 let Inst{7} = 1; 1096 let Inst{5-4} = rot; 1097} 1098 1099/// T2I_exta_rrot - A binary operation with two forms: one whose operand is a 1100/// register and one whose operand is a register rotated by 8/16/24. 1101class T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> 1102 : T2ThreeReg<(outs rGPR:$Rd), 1103 (ins rGPR:$Rn, rGPR:$Rm, rot_imm:$rot), 1104 IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm$rot", 1105 [(set rGPR:$Rd, (opnode rGPR:$Rn, (rotr rGPR:$Rm,rot_imm:$rot)))]>, 1106 Requires<[HasT2ExtractPack, IsThumb2]> { 1107 bits<2> rot; 1108 let Inst{31-27} = 0b11111; 1109 let Inst{26-23} = 0b0100; 1110 let Inst{22-20} = opcod; 1111 let Inst{15-12} = 0b1111; 1112 let Inst{7} = 1; 1113 let Inst{5-4} = rot; 1114} 1115 1116class T2I_exta_rrot_np<bits<3> opcod, string opc> 1117 : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm,rot_imm:$rot), 1118 IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm$rot", []> { 1119 bits<2> rot; 1120 let Inst{31-27} = 0b11111; 1121 let Inst{26-23} = 0b0100; 1122 let Inst{22-20} = opcod; 1123 let Inst{15-12} = 0b1111; 1124 let Inst{7} = 1; 1125 let Inst{5-4} = rot; 1126} 1127 1128//===----------------------------------------------------------------------===// 1129// Instructions 1130//===----------------------------------------------------------------------===// 1131 1132//===----------------------------------------------------------------------===// 1133// Miscellaneous Instructions. 1134// 1135 1136class T2PCOneRegImm<dag oops, dag iops, InstrItinClass itin, 1137 string asm, list<dag> pattern> 1138 : T2XI<oops, iops, itin, asm, pattern> { 1139 bits<4> Rd; 1140 bits<12> label; 1141 1142 let Inst{11-8} = Rd; 1143 let Inst{26} = label{11}; 1144 let Inst{14-12} = label{10-8}; 1145 let Inst{7-0} = label{7-0}; 1146} 1147 1148// LEApcrel - Load a pc-relative address into a register without offending the 1149// assembler. 1150def t2ADR : T2PCOneRegImm<(outs rGPR:$Rd), 1151 (ins t2adrlabel:$addr, pred:$p), 1152 IIC_iALUi, "adr{$p}.w\t$Rd, $addr", []> { 1153 let Inst{31-27} = 0b11110; 1154 let Inst{25-24} = 0b10; 1155 // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE) 1156 let Inst{22} = 0; 1157 let Inst{20} = 0; 1158 let Inst{19-16} = 0b1111; // Rn 1159 let Inst{15} = 0; 1160 1161 bits<4> Rd; 1162 bits<13> addr; 1163 let Inst{11-8} = Rd; 1164 let Inst{23} = addr{12}; 1165 let Inst{21} = addr{12}; 1166 let Inst{26} = addr{11}; 1167 let Inst{14-12} = addr{10-8}; 1168 let Inst{7-0} = addr{7-0}; 1169 1170 let DecoderMethod = "DecodeT2Adr"; 1171} 1172 1173let neverHasSideEffects = 1, isReMaterializable = 1 in 1174def t2LEApcrel : t2PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), 1175 4, IIC_iALUi, []>; 1176def t2LEApcrelJT : t2PseudoInst<(outs rGPR:$Rd), 1177 (ins i32imm:$label, nohash_imm:$id, pred:$p), 1178 4, IIC_iALUi, 1179 []>; 1180 1181 1182//===----------------------------------------------------------------------===// 1183// Load / store Instructions. 1184// 1185 1186// Load 1187let canFoldAsLoad = 1, isReMaterializable = 1 in 1188defm t2LDR : T2I_ld<0, 0b10, "ldr", IIC_iLoad_i, IIC_iLoad_si, GPR, 1189 UnOpFrag<(load node:$Src)>>; 1190 1191// Loads with zero extension 1192defm t2LDRH : T2I_ld<0, 0b01, "ldrh", IIC_iLoad_bh_i, IIC_iLoad_bh_si, 1193 rGPR, UnOpFrag<(zextloadi16 node:$Src)>>; 1194defm t2LDRB : T2I_ld<0, 0b00, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_si, 1195 rGPR, UnOpFrag<(zextloadi8 node:$Src)>>; 1196 1197// Loads with sign extension 1198defm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", IIC_iLoad_bh_i, IIC_iLoad_bh_si, 1199 rGPR, UnOpFrag<(sextloadi16 node:$Src)>>; 1200defm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", IIC_iLoad_bh_i, IIC_iLoad_bh_si, 1201 rGPR, UnOpFrag<(sextloadi8 node:$Src)>>; 1202 1203let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in { 1204// Load doubleword 1205def t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$Rt, rGPR:$Rt2), 1206 (ins t2addrmode_imm8s4:$addr), 1207 IIC_iLoad_d_i, "ldrd", "\t$Rt, $Rt2, $addr", "", []>; 1208} // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 1209 1210// zextload i1 -> zextload i8 1211def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr), 1212 (t2LDRBi12 t2addrmode_imm12:$addr)>; 1213def : T2Pat<(zextloadi1 t2addrmode_negimm8:$addr), 1214 (t2LDRBi8 t2addrmode_negimm8:$addr)>; 1215def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr), 1216 (t2LDRBs t2addrmode_so_reg:$addr)>; 1217def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)), 1218 (t2LDRBpci tconstpool:$addr)>; 1219 1220// extload -> zextload 1221// FIXME: Reduce the number of patterns by legalizing extload to zextload 1222// earlier? 1223def : T2Pat<(extloadi1 t2addrmode_imm12:$addr), 1224 (t2LDRBi12 t2addrmode_imm12:$addr)>; 1225def : T2Pat<(extloadi1 t2addrmode_negimm8:$addr), 1226 (t2LDRBi8 t2addrmode_negimm8:$addr)>; 1227def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr), 1228 (t2LDRBs t2addrmode_so_reg:$addr)>; 1229def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)), 1230 (t2LDRBpci tconstpool:$addr)>; 1231 1232def : T2Pat<(extloadi8 t2addrmode_imm12:$addr), 1233 (t2LDRBi12 t2addrmode_imm12:$addr)>; 1234def : T2Pat<(extloadi8 t2addrmode_negimm8:$addr), 1235 (t2LDRBi8 t2addrmode_negimm8:$addr)>; 1236def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr), 1237 (t2LDRBs t2addrmode_so_reg:$addr)>; 1238def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)), 1239 (t2LDRBpci tconstpool:$addr)>; 1240 1241def : T2Pat<(extloadi16 t2addrmode_imm12:$addr), 1242 (t2LDRHi12 t2addrmode_imm12:$addr)>; 1243def : T2Pat<(extloadi16 t2addrmode_negimm8:$addr), 1244 (t2LDRHi8 t2addrmode_negimm8:$addr)>; 1245def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr), 1246 (t2LDRHs t2addrmode_so_reg:$addr)>; 1247def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)), 1248 (t2LDRHpci tconstpool:$addr)>; 1249 1250// FIXME: The destination register of the loads and stores can't be PC, but 1251// can be SP. We need another regclass (similar to rGPR) to represent 1252// that. Not a pressing issue since these are selected manually, 1253// not via pattern. 1254 1255// Indexed loads 1256 1257let mayLoad = 1, neverHasSideEffects = 1 in { 1258def t2LDR_PRE : T2Ipreldst<0, 0b10, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), 1259 (ins t2addrmode_imm8:$addr), 1260 AddrModeT2_i8, IndexModePre, IIC_iLoad_iu, 1261 "ldr", "\t$Rt, $addr!", "$addr.base = $Rn_wb", 1262 []> { 1263 let AsmMatchConverter = "cvtLdWriteBackRegT2AddrModeImm8"; 1264} 1265 1266def t2LDR_POST : T2Ipostldst<0, 0b10, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 1267 (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset), 1268 AddrModeT2_i8, IndexModePost, IIC_iLoad_iu, 1269 "ldr", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>; 1270 1271def t2LDRB_PRE : T2Ipreldst<0, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), 1272 (ins t2addrmode_imm8:$addr), 1273 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, 1274 "ldrb", "\t$Rt, $addr!", "$addr.base = $Rn_wb", 1275 []> { 1276 let AsmMatchConverter = "cvtLdWriteBackRegT2AddrModeImm8"; 1277} 1278def t2LDRB_POST : T2Ipostldst<0, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 1279 (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset), 1280 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, 1281 "ldrb", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>; 1282 1283def t2LDRH_PRE : T2Ipreldst<0, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), 1284 (ins t2addrmode_imm8:$addr), 1285 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, 1286 "ldrh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", 1287 []> { 1288 let AsmMatchConverter = "cvtLdWriteBackRegT2AddrModeImm8"; 1289} 1290def t2LDRH_POST : T2Ipostldst<0, 0b01, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 1291 (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset), 1292 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, 1293 "ldrh", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>; 1294 1295def t2LDRSB_PRE : T2Ipreldst<1, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), 1296 (ins t2addrmode_imm8:$addr), 1297 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, 1298 "ldrsb", "\t$Rt, $addr!", "$addr.base = $Rn_wb", 1299 []> { 1300 let AsmMatchConverter = "cvtLdWriteBackRegT2AddrModeImm8"; 1301} 1302def t2LDRSB_POST : T2Ipostldst<1, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 1303 (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset), 1304 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, 1305 "ldrsb", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>; 1306 1307def t2LDRSH_PRE : T2Ipreldst<1, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), 1308 (ins t2addrmode_imm8:$addr), 1309 AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, 1310 "ldrsh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", 1311 []> { 1312 let AsmMatchConverter = "cvtLdWriteBackRegT2AddrModeImm8"; 1313} 1314def t2LDRSH_POST : T2Ipostldst<1, 0b01, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 1315 (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset), 1316 AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, 1317 "ldrsh", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>; 1318} // mayLoad = 1, neverHasSideEffects = 1 1319 1320// LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110). 1321// Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4 1322class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii> 1323 : T2Ii8<(outs rGPR:$Rt), (ins t2addrmode_posimm8:$addr), ii, opc, 1324 "\t$Rt, $addr", []> { 1325 bits<4> Rt; 1326 bits<13> addr; 1327 let Inst{31-27} = 0b11111; 1328 let Inst{26-25} = 0b00; 1329 let Inst{24} = signed; 1330 let Inst{23} = 0; 1331 let Inst{22-21} = type; 1332 let Inst{20} = 1; // load 1333 let Inst{19-16} = addr{12-9}; 1334 let Inst{15-12} = Rt; 1335 let Inst{11} = 1; 1336 let Inst{10-8} = 0b110; // PUW. 1337 let Inst{7-0} = addr{7-0}; 1338} 1339 1340def t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>; 1341def t2LDRBT : T2IldT<0, 0b00, "ldrbt", IIC_iLoad_bh_i>; 1342def t2LDRHT : T2IldT<0, 0b01, "ldrht", IIC_iLoad_bh_i>; 1343def t2LDRSBT : T2IldT<1, 0b00, "ldrsbt", IIC_iLoad_bh_i>; 1344def t2LDRSHT : T2IldT<1, 0b01, "ldrsht", IIC_iLoad_bh_i>; 1345 1346// Store 1347defm t2STR :T2I_st<0b10,"str", IIC_iStore_i, IIC_iStore_si, GPR, 1348 BinOpFrag<(store node:$LHS, node:$RHS)>>; 1349defm t2STRB:T2I_st<0b00,"strb", IIC_iStore_bh_i, IIC_iStore_bh_si, 1350 rGPR, BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>; 1351defm t2STRH:T2I_st<0b01,"strh", IIC_iStore_bh_i, IIC_iStore_bh_si, 1352 rGPR, BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>; 1353 1354// Store doubleword 1355let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in 1356def t2STRDi8 : T2Ii8s4<1, 0, 0, (outs), 1357 (ins GPR:$Rt, GPR:$Rt2, t2addrmode_imm8s4:$addr), 1358 IIC_iStore_d_r, "strd", "\t$Rt, $Rt2, $addr", "", []>; 1359 1360// Indexed stores 1361 1362let mayStore = 1, neverHasSideEffects = 1 in { 1363def t2STR_PRE : T2Ipreldst<0, 0b10, 0, 1, (outs GPRnopc:$Rn_wb), 1364 (ins GPRnopc:$Rt, t2addrmode_imm8:$addr), 1365 AddrModeT2_i8, IndexModePre, IIC_iStore_iu, 1366 "str", "\t$Rt, $addr!", 1367 "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> { 1368 let AsmMatchConverter = "cvtStWriteBackRegT2AddrModeImm8"; 1369} 1370def t2STRH_PRE : T2Ipreldst<0, 0b01, 0, 1, (outs GPRnopc:$Rn_wb), 1371 (ins rGPR:$Rt, t2addrmode_imm8:$addr), 1372 AddrModeT2_i8, IndexModePre, IIC_iStore_iu, 1373 "strh", "\t$Rt, $addr!", 1374 "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> { 1375 let AsmMatchConverter = "cvtStWriteBackRegT2AddrModeImm8"; 1376} 1377 1378def t2STRB_PRE : T2Ipreldst<0, 0b00, 0, 1, (outs GPRnopc:$Rn_wb), 1379 (ins rGPR:$Rt, t2addrmode_imm8:$addr), 1380 AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu, 1381 "strb", "\t$Rt, $addr!", 1382 "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []> { 1383 let AsmMatchConverter = "cvtStWriteBackRegT2AddrModeImm8"; 1384} 1385} // mayStore = 1, neverHasSideEffects = 1 1386 1387def t2STR_POST : T2Ipostldst<0, 0b10, 0, 0, (outs GPRnopc:$Rn_wb), 1388 (ins GPRnopc:$Rt, addr_offset_none:$Rn, 1389 t2am_imm8_offset:$offset), 1390 AddrModeT2_i8, IndexModePost, IIC_iStore_iu, 1391 "str", "\t$Rt, $Rn$offset", 1392 "$Rn = $Rn_wb,@earlyclobber $Rn_wb", 1393 [(set GPRnopc:$Rn_wb, 1394 (post_store GPRnopc:$Rt, addr_offset_none:$Rn, 1395 t2am_imm8_offset:$offset))]>; 1396 1397def t2STRH_POST : T2Ipostldst<0, 0b01, 0, 0, (outs GPRnopc:$Rn_wb), 1398 (ins rGPR:$Rt, addr_offset_none:$Rn, 1399 t2am_imm8_offset:$offset), 1400 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu, 1401 "strh", "\t$Rt, $Rn$offset", 1402 "$Rn = $Rn_wb,@earlyclobber $Rn_wb", 1403 [(set GPRnopc:$Rn_wb, 1404 (post_truncsti16 rGPR:$Rt, addr_offset_none:$Rn, 1405 t2am_imm8_offset:$offset))]>; 1406 1407def t2STRB_POST : T2Ipostldst<0, 0b00, 0, 0, (outs GPRnopc:$Rn_wb), 1408 (ins rGPR:$Rt, addr_offset_none:$Rn, 1409 t2am_imm8_offset:$offset), 1410 AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu, 1411 "strb", "\t$Rt, $Rn$offset", 1412 "$Rn = $Rn_wb,@earlyclobber $Rn_wb", 1413 [(set GPRnopc:$Rn_wb, 1414 (post_truncsti8 rGPR:$Rt, addr_offset_none:$Rn, 1415 t2am_imm8_offset:$offset))]>; 1416 1417// Pseudo-instructions for pattern matching the pre-indexed stores. We can't 1418// put the patterns on the instruction definitions directly as ISel wants 1419// the address base and offset to be separate operands, not a single 1420// complex operand like we represent the instructions themselves. The 1421// pseudos map between the two. 1422let usesCustomInserter = 1, 1423 Constraints = "$Rn = $Rn_wb,@earlyclobber $Rn_wb" in { 1424def t2STR_preidx: t2PseudoInst<(outs GPRnopc:$Rn_wb), 1425 (ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset, pred:$p), 1426 4, IIC_iStore_ru, 1427 [(set GPRnopc:$Rn_wb, 1428 (pre_store rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset))]>; 1429def t2STRB_preidx: t2PseudoInst<(outs GPRnopc:$Rn_wb), 1430 (ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset, pred:$p), 1431 4, IIC_iStore_ru, 1432 [(set GPRnopc:$Rn_wb, 1433 (pre_truncsti8 rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset))]>; 1434def t2STRH_preidx: t2PseudoInst<(outs GPRnopc:$Rn_wb), 1435 (ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset, pred:$p), 1436 4, IIC_iStore_ru, 1437 [(set GPRnopc:$Rn_wb, 1438 (pre_truncsti16 rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset))]>; 1439} 1440 1441// STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly 1442// only. 1443// Ref: A8.6.193 STR (immediate, Thumb) Encoding T4 1444class T2IstT<bits<2> type, string opc, InstrItinClass ii> 1445 : T2Ii8<(outs rGPR:$Rt), (ins t2addrmode_imm8:$addr), ii, opc, 1446 "\t$Rt, $addr", []> { 1447 let Inst{31-27} = 0b11111; 1448 let Inst{26-25} = 0b00; 1449 let Inst{24} = 0; // not signed 1450 let Inst{23} = 0; 1451 let Inst{22-21} = type; 1452 let Inst{20} = 0; // store 1453 let Inst{11} = 1; 1454 let Inst{10-8} = 0b110; // PUW 1455 1456 bits<4> Rt; 1457 bits<13> addr; 1458 let Inst{15-12} = Rt; 1459 let Inst{19-16} = addr{12-9}; 1460 let Inst{7-0} = addr{7-0}; 1461} 1462 1463def t2STRT : T2IstT<0b10, "strt", IIC_iStore_i>; 1464def t2STRBT : T2IstT<0b00, "strbt", IIC_iStore_bh_i>; 1465def t2STRHT : T2IstT<0b01, "strht", IIC_iStore_bh_i>; 1466 1467// ldrd / strd pre / post variants 1468// For disassembly only. 1469 1470def t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs rGPR:$Rt, rGPR:$Rt2, GPR:$wb), 1471 (ins t2addrmode_imm8s4:$addr), IIC_iLoad_d_ru, 1472 "ldrd", "\t$Rt, $Rt2, $addr!", "$addr.base = $wb", []> { 1473 let AsmMatchConverter = "cvtT2LdrdPre"; 1474 let DecoderMethod = "DecodeT2LDRDPreInstruction"; 1475} 1476 1477def t2LDRD_POST : T2Ii8s4post<0, 1, 1, (outs rGPR:$Rt, rGPR:$Rt2, GPR:$wb), 1478 (ins addr_offset_none:$addr, t2am_imm8s4_offset:$imm), 1479 IIC_iLoad_d_ru, "ldrd", "\t$Rt, $Rt2, $addr$imm", 1480 "$addr.base = $wb", []>; 1481 1482def t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs GPR:$wb), 1483 (ins rGPR:$Rt, rGPR:$Rt2, t2addrmode_imm8s4:$addr), 1484 IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, $addr!", 1485 "$addr.base = $wb", []> { 1486 let AsmMatchConverter = "cvtT2StrdPre"; 1487 let DecoderMethod = "DecodeT2STRDPreInstruction"; 1488} 1489 1490def t2STRD_POST : T2Ii8s4post<0, 1, 0, (outs GPR:$wb), 1491 (ins rGPR:$Rt, rGPR:$Rt2, addr_offset_none:$addr, 1492 t2am_imm8s4_offset:$imm), 1493 IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, $addr$imm", 1494 "$addr.base = $wb", []>; 1495 1496// T2Ipl (Preload Data/Instruction) signals the memory system of possible future 1497// data/instruction access. 1498// instr_write is inverted for Thumb mode: (prefetch 3) -> (preload 0), 1499// (prefetch 1) -> (preload 2), (prefetch 2) -> (preload 1). 1500multiclass T2Ipl<bits<1> write, bits<1> instr, string opc> { 1501 1502 def i12 : T2Ii12<(outs), (ins t2addrmode_imm12:$addr), IIC_Preload, opc, 1503 "\t$addr", 1504 [(ARMPreload t2addrmode_imm12:$addr, (i32 write), (i32 instr))]> { 1505 let Inst{31-25} = 0b1111100; 1506 let Inst{24} = instr; 1507 let Inst{22} = 0; 1508 let Inst{21} = write; 1509 let Inst{20} = 1; 1510 let Inst{15-12} = 0b1111; 1511 1512 bits<17> addr; 1513 let addr{12} = 1; // add = TRUE 1514 let Inst{19-16} = addr{16-13}; // Rn 1515 let Inst{23} = addr{12}; // U 1516 let Inst{11-0} = addr{11-0}; // imm12 1517 } 1518 1519 def i8 : T2Ii8<(outs), (ins t2addrmode_negimm8:$addr), IIC_Preload, opc, 1520 "\t$addr", 1521 [(ARMPreload t2addrmode_negimm8:$addr, (i32 write), (i32 instr))]> { 1522 let Inst{31-25} = 0b1111100; 1523 let Inst{24} = instr; 1524 let Inst{23} = 0; // U = 0 1525 let Inst{22} = 0; 1526 let Inst{21} = write; 1527 let Inst{20} = 1; 1528 let Inst{15-12} = 0b1111; 1529 let Inst{11-8} = 0b1100; 1530 1531 bits<13> addr; 1532 let Inst{19-16} = addr{12-9}; // Rn 1533 let Inst{7-0} = addr{7-0}; // imm8 1534 } 1535 1536 def s : T2Iso<(outs), (ins t2addrmode_so_reg:$addr), IIC_Preload, opc, 1537 "\t$addr", 1538 [(ARMPreload t2addrmode_so_reg:$addr, (i32 write), (i32 instr))]> { 1539 let Inst{31-25} = 0b1111100; 1540 let Inst{24} = instr; 1541 let Inst{23} = 0; // add = TRUE for T1 1542 let Inst{22} = 0; 1543 let Inst{21} = write; 1544 let Inst{20} = 1; 1545 let Inst{15-12} = 0b1111; 1546 let Inst{11-6} = 0000000; 1547 1548 bits<10> addr; 1549 let Inst{19-16} = addr{9-6}; // Rn 1550 let Inst{3-0} = addr{5-2}; // Rm 1551 let Inst{5-4} = addr{1-0}; // imm2 1552 1553 let DecoderMethod = "DecodeT2LoadShift"; 1554 } 1555 // FIXME: We should have a separate 'pci' variant here. As-is we represent 1556 // it via the i12 variant, which it's related to, but that means we can 1557 // represent negative immediates, which aren't legal for anything except 1558 // the 'pci' case (Rn == 15). 1559} 1560 1561defm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>; 1562defm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>; 1563defm t2PLI : T2Ipl<0, 1, "pli">, Requires<[IsThumb2,HasV7]>; 1564 1565//===----------------------------------------------------------------------===// 1566// Load / store multiple Instructions. 1567// 1568 1569multiclass thumb2_ld_mult<string asm, InstrItinClass itin, 1570 InstrItinClass itin_upd, bit L_bit> { 1571 def IA : 1572 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1573 itin, !strconcat(asm, "${p}.w\t$Rn, $regs"), []> { 1574 bits<4> Rn; 1575 bits<16> regs; 1576 1577 let Inst{31-27} = 0b11101; 1578 let Inst{26-25} = 0b00; 1579 let Inst{24-23} = 0b01; // Increment After 1580 let Inst{22} = 0; 1581 let Inst{21} = 0; // No writeback 1582 let Inst{20} = L_bit; 1583 let Inst{19-16} = Rn; 1584 let Inst{15-0} = regs; 1585 } 1586 def IA_UPD : 1587 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1588 itin_upd, !strconcat(asm, "${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> { 1589 bits<4> Rn; 1590 bits<16> regs; 1591 1592 let Inst{31-27} = 0b11101; 1593 let Inst{26-25} = 0b00; 1594 let Inst{24-23} = 0b01; // Increment After 1595 let Inst{22} = 0; 1596 let Inst{21} = 1; // Writeback 1597 let Inst{20} = L_bit; 1598 let Inst{19-16} = Rn; 1599 let Inst{15-0} = regs; 1600 } 1601 def DB : 1602 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1603 itin, !strconcat(asm, "db${p}\t$Rn, $regs"), []> { 1604 bits<4> Rn; 1605 bits<16> regs; 1606 1607 let Inst{31-27} = 0b11101; 1608 let Inst{26-25} = 0b00; 1609 let Inst{24-23} = 0b10; // Decrement Before 1610 let Inst{22} = 0; 1611 let Inst{21} = 0; // No writeback 1612 let Inst{20} = L_bit; 1613 let Inst{19-16} = Rn; 1614 let Inst{15-0} = regs; 1615 } 1616 def DB_UPD : 1617 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1618 itin_upd, !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 1619 bits<4> Rn; 1620 bits<16> regs; 1621 1622 let Inst{31-27} = 0b11101; 1623 let Inst{26-25} = 0b00; 1624 let Inst{24-23} = 0b10; // Decrement Before 1625 let Inst{22} = 0; 1626 let Inst{21} = 1; // Writeback 1627 let Inst{20} = L_bit; 1628 let Inst{19-16} = Rn; 1629 let Inst{15-0} = regs; 1630 } 1631} 1632 1633let neverHasSideEffects = 1 in { 1634 1635let mayLoad = 1, hasExtraDefRegAllocReq = 1 in 1636defm t2LDM : thumb2_ld_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>; 1637 1638multiclass thumb2_st_mult<string asm, InstrItinClass itin, 1639 InstrItinClass itin_upd, bit L_bit> { 1640 def IA : 1641 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1642 itin, !strconcat(asm, "${p}.w\t$Rn, $regs"), []> { 1643 bits<4> Rn; 1644 bits<16> regs; 1645 1646 let Inst{31-27} = 0b11101; 1647 let Inst{26-25} = 0b00; 1648 let Inst{24-23} = 0b01; // Increment After 1649 let Inst{22} = 0; 1650 let Inst{21} = 0; // No writeback 1651 let Inst{20} = L_bit; 1652 let Inst{19-16} = Rn; 1653 let Inst{15} = 0; 1654 let Inst{14} = regs{14}; 1655 let Inst{13} = 0; 1656 let Inst{12-0} = regs{12-0}; 1657 } 1658 def IA_UPD : 1659 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1660 itin_upd, !strconcat(asm, "${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> { 1661 bits<4> Rn; 1662 bits<16> regs; 1663 1664 let Inst{31-27} = 0b11101; 1665 let Inst{26-25} = 0b00; 1666 let Inst{24-23} = 0b01; // Increment After 1667 let Inst{22} = 0; 1668 let Inst{21} = 1; // Writeback 1669 let Inst{20} = L_bit; 1670 let Inst{19-16} = Rn; 1671 let Inst{15} = 0; 1672 let Inst{14} = regs{14}; 1673 let Inst{13} = 0; 1674 let Inst{12-0} = regs{12-0}; 1675 } 1676 def DB : 1677 T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1678 itin, !strconcat(asm, "db${p}\t$Rn, $regs"), []> { 1679 bits<4> Rn; 1680 bits<16> regs; 1681 1682 let Inst{31-27} = 0b11101; 1683 let Inst{26-25} = 0b00; 1684 let Inst{24-23} = 0b10; // Decrement Before 1685 let Inst{22} = 0; 1686 let Inst{21} = 0; // No writeback 1687 let Inst{20} = L_bit; 1688 let Inst{19-16} = Rn; 1689 let Inst{15} = 0; 1690 let Inst{14} = regs{14}; 1691 let Inst{13} = 0; 1692 let Inst{12-0} = regs{12-0}; 1693 } 1694 def DB_UPD : 1695 T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1696 itin_upd, !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 1697 bits<4> Rn; 1698 bits<16> regs; 1699 1700 let Inst{31-27} = 0b11101; 1701 let Inst{26-25} = 0b00; 1702 let Inst{24-23} = 0b10; // Decrement Before 1703 let Inst{22} = 0; 1704 let Inst{21} = 1; // Writeback 1705 let Inst{20} = L_bit; 1706 let Inst{19-16} = Rn; 1707 let Inst{15} = 0; 1708 let Inst{14} = regs{14}; 1709 let Inst{13} = 0; 1710 let Inst{12-0} = regs{12-0}; 1711 } 1712} 1713 1714 1715let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 1716defm t2STM : thumb2_st_mult<"stm", IIC_iStore_m, IIC_iStore_mu, 0>; 1717 1718} // neverHasSideEffects 1719 1720 1721//===----------------------------------------------------------------------===// 1722// Move Instructions. 1723// 1724 1725let neverHasSideEffects = 1 in 1726def t2MOVr : T2sTwoReg<(outs GPRnopc:$Rd), (ins GPR:$Rm), IIC_iMOVr, 1727 "mov", ".w\t$Rd, $Rm", []> { 1728 let Inst{31-27} = 0b11101; 1729 let Inst{26-25} = 0b01; 1730 let Inst{24-21} = 0b0010; 1731 let Inst{19-16} = 0b1111; // Rn 1732 let Inst{14-12} = 0b000; 1733 let Inst{7-4} = 0b0000; 1734} 1735def : t2InstAlias<"mov${p}.w $Rd, $Rm", (t2MOVr GPRnopc:$Rd, GPR:$Rm, 1736 pred:$p, zero_reg)>; 1737def : t2InstAlias<"movs${p}.w $Rd, $Rm", (t2MOVr GPRnopc:$Rd, GPR:$Rm, 1738 pred:$p, CPSR)>; 1739def : t2InstAlias<"movs${p} $Rd, $Rm", (t2MOVr GPRnopc:$Rd, GPR:$Rm, 1740 pred:$p, CPSR)>; 1741 1742// AddedComplexity to ensure isel tries t2MOVi before t2MOVi16. 1743let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1, 1744 AddedComplexity = 1 in 1745def t2MOVi : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), IIC_iMOVi, 1746 "mov", ".w\t$Rd, $imm", 1747 [(set rGPR:$Rd, t2_so_imm:$imm)]> { 1748 let Inst{31-27} = 0b11110; 1749 let Inst{25} = 0; 1750 let Inst{24-21} = 0b0010; 1751 let Inst{19-16} = 0b1111; // Rn 1752 let Inst{15} = 0; 1753} 1754 1755// cc_out is handled as part of the explicit mnemonic in the parser for 'mov'. 1756// Use aliases to get that to play nice here. 1757def : t2InstAlias<"movs${p}.w $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm, 1758 pred:$p, CPSR)>; 1759def : t2InstAlias<"movs${p} $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm, 1760 pred:$p, CPSR)>; 1761 1762def : t2InstAlias<"mov${p}.w $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm, 1763 pred:$p, zero_reg)>; 1764def : t2InstAlias<"mov${p} $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm, 1765 pred:$p, zero_reg)>; 1766 1767let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 1768def t2MOVi16 : T2I<(outs rGPR:$Rd), (ins imm0_65535_expr:$imm), IIC_iMOVi, 1769 "movw", "\t$Rd, $imm", 1770 [(set rGPR:$Rd, imm0_65535:$imm)]> { 1771 let Inst{31-27} = 0b11110; 1772 let Inst{25} = 1; 1773 let Inst{24-21} = 0b0010; 1774 let Inst{20} = 0; // The S bit. 1775 let Inst{15} = 0; 1776 1777 bits<4> Rd; 1778 bits<16> imm; 1779 1780 let Inst{11-8} = Rd; 1781 let Inst{19-16} = imm{15-12}; 1782 let Inst{26} = imm{11}; 1783 let Inst{14-12} = imm{10-8}; 1784 let Inst{7-0} = imm{7-0}; 1785 let DecoderMethod = "DecodeT2MOVTWInstruction"; 1786} 1787 1788def t2MOVi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd), 1789 (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>; 1790 1791let Constraints = "$src = $Rd" in { 1792def t2MOVTi16 : T2I<(outs rGPR:$Rd), 1793 (ins rGPR:$src, imm0_65535_expr:$imm), IIC_iMOVi, 1794 "movt", "\t$Rd, $imm", 1795 [(set rGPR:$Rd, 1796 (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]> { 1797 let Inst{31-27} = 0b11110; 1798 let Inst{25} = 1; 1799 let Inst{24-21} = 0b0110; 1800 let Inst{20} = 0; // The S bit. 1801 let Inst{15} = 0; 1802 1803 bits<4> Rd; 1804 bits<16> imm; 1805 1806 let Inst{11-8} = Rd; 1807 let Inst{19-16} = imm{15-12}; 1808 let Inst{26} = imm{11}; 1809 let Inst{14-12} = imm{10-8}; 1810 let Inst{7-0} = imm{7-0}; 1811 let DecoderMethod = "DecodeT2MOVTWInstruction"; 1812} 1813 1814def t2MOVTi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd), 1815 (ins rGPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>; 1816} // Constraints 1817 1818def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>; 1819 1820//===----------------------------------------------------------------------===// 1821// Extend Instructions. 1822// 1823 1824// Sign extenders 1825 1826def t2SXTB : T2I_ext_rrot<0b100, "sxtb", 1827 UnOpFrag<(sext_inreg node:$Src, i8)>>; 1828def t2SXTH : T2I_ext_rrot<0b000, "sxth", 1829 UnOpFrag<(sext_inreg node:$Src, i16)>>; 1830def t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">; 1831 1832def t2SXTAB : T2I_exta_rrot<0b100, "sxtab", 1833 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>; 1834def t2SXTAH : T2I_exta_rrot<0b000, "sxtah", 1835 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>; 1836def t2SXTAB16 : T2I_exta_rrot_np<0b010, "sxtab16">; 1837 1838// Zero extenders 1839 1840let AddedComplexity = 16 in { 1841def t2UXTB : T2I_ext_rrot<0b101, "uxtb", 1842 UnOpFrag<(and node:$Src, 0x000000FF)>>; 1843def t2UXTH : T2I_ext_rrot<0b001, "uxth", 1844 UnOpFrag<(and node:$Src, 0x0000FFFF)>>; 1845def t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16", 1846 UnOpFrag<(and node:$Src, 0x00FF00FF)>>; 1847 1848// FIXME: This pattern incorrectly assumes the shl operator is a rotate. 1849// The transformation should probably be done as a combiner action 1850// instead so we can include a check for masking back in the upper 1851// eight bits of the source into the lower eight bits of the result. 1852//def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF), 1853// (t2UXTB16 rGPR:$Src, 3)>, 1854// Requires<[HasT2ExtractPack, IsThumb2]>; 1855def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF), 1856 (t2UXTB16 rGPR:$Src, 1)>, 1857 Requires<[HasT2ExtractPack, IsThumb2]>; 1858 1859def t2UXTAB : T2I_exta_rrot<0b101, "uxtab", 1860 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; 1861def t2UXTAH : T2I_exta_rrot<0b001, "uxtah", 1862 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; 1863def t2UXTAB16 : T2I_exta_rrot_np<0b011, "uxtab16">; 1864} 1865 1866//===----------------------------------------------------------------------===// 1867// Arithmetic Instructions. 1868// 1869 1870defm t2ADD : T2I_bin_ii12rs<0b000, "add", 1871 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>; 1872defm t2SUB : T2I_bin_ii12rs<0b101, "sub", 1873 BinOpFrag<(sub node:$LHS, node:$RHS)>>; 1874 1875// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants. 1876// 1877// Currently, t2ADDS/t2SUBS are pseudo opcodes that exist only in the 1878// selection DAG. They are "lowered" to real t2ADD/t2SUB opcodes by 1879// AdjustInstrPostInstrSelection where we determine whether or not to 1880// set the "s" bit based on CPSR liveness. 1881// 1882// FIXME: Eliminate t2ADDS/t2SUBS pseudo opcodes after adding tablegen 1883// support for an optional CPSR definition that corresponds to the DAG 1884// node's second value. We can then eliminate the implicit def of CPSR. 1885defm t2ADDS : T2I_bin_s_irs <IIC_iALUi, IIC_iALUr, IIC_iALUsi, 1886 BinOpFrag<(ARMaddc node:$LHS, node:$RHS)>, 1>; 1887defm t2SUBS : T2I_bin_s_irs <IIC_iALUi, IIC_iALUr, IIC_iALUsi, 1888 BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>; 1889 1890let hasPostISelHook = 1 in { 1891defm t2ADC : T2I_adde_sube_irs<0b1010, "adc", 1892 BinOpWithFlagFrag<(ARMadde node:$LHS, node:$RHS, node:$FLAG)>, 1>; 1893defm t2SBC : T2I_adde_sube_irs<0b1011, "sbc", 1894 BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>>; 1895} 1896 1897// RSB 1898defm t2RSB : T2I_rbin_irs <0b1110, "rsb", 1899 BinOpFrag<(sub node:$LHS, node:$RHS)>>; 1900 1901// FIXME: Eliminate them if we can write def : Pat patterns which defines 1902// CPSR and the implicit def of CPSR is not needed. 1903defm t2RSBS : T2I_rbin_s_is <BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>; 1904 1905// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 1906// The assume-no-carry-in form uses the negation of the input since add/sub 1907// assume opposite meanings of the carry flag (i.e., carry == !borrow). 1908// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory 1909// details. 1910// The AddedComplexity preferences the first variant over the others since 1911// it can be shrunk to a 16-bit wide encoding, while the others cannot. 1912let AddedComplexity = 1 in 1913def : T2Pat<(add GPR:$src, imm0_255_neg:$imm), 1914 (t2SUBri GPR:$src, imm0_255_neg:$imm)>; 1915def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm), 1916 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>; 1917def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm), 1918 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>; 1919def : T2Pat<(add GPR:$src, imm0_65535_neg:$imm), 1920 (t2SUBrr GPR:$src, (t2MOVi16 (imm_neg_XFORM imm:$imm)))>; 1921 1922let AddedComplexity = 1 in 1923def : T2Pat<(ARMaddc rGPR:$src, imm0_255_neg:$imm), 1924 (t2SUBSri rGPR:$src, imm0_255_neg:$imm)>; 1925def : T2Pat<(ARMaddc rGPR:$src, t2_so_imm_neg:$imm), 1926 (t2SUBSri rGPR:$src, t2_so_imm_neg:$imm)>; 1927def : T2Pat<(ARMaddc rGPR:$src, imm0_65535_neg:$imm), 1928 (t2SUBSrr rGPR:$src, (t2MOVi16 (imm_neg_XFORM imm:$imm)))>; 1929// The with-carry-in form matches bitwise not instead of the negation. 1930// Effectively, the inverse interpretation of the carry flag already accounts 1931// for part of the negation. 1932let AddedComplexity = 1 in 1933def : T2Pat<(ARMadde rGPR:$src, imm0_255_not:$imm, CPSR), 1934 (t2SBCri rGPR:$src, imm0_255_not:$imm)>; 1935def : T2Pat<(ARMadde rGPR:$src, t2_so_imm_not:$imm, CPSR), 1936 (t2SBCri rGPR:$src, t2_so_imm_not:$imm)>; 1937def : T2Pat<(ARMadde rGPR:$src, imm0_65535_neg:$imm, CPSR), 1938 (t2SBCrr rGPR:$src, (t2MOVi16 (imm_neg_XFORM imm:$imm)))>; 1939 1940// Select Bytes -- for disassembly only 1941 1942def t2SEL : T2ThreeReg<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 1943 NoItinerary, "sel", "\t$Rd, $Rn, $Rm", []>, 1944 Requires<[IsThumb2, HasThumb2DSP]> { 1945 let Inst{31-27} = 0b11111; 1946 let Inst{26-24} = 0b010; 1947 let Inst{23} = 0b1; 1948 let Inst{22-20} = 0b010; 1949 let Inst{15-12} = 0b1111; 1950 let Inst{7} = 0b1; 1951 let Inst{6-4} = 0b000; 1952} 1953 1954// A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned) 1955// And Miscellaneous operations -- for disassembly only 1956class T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc, 1957 list<dag> pat = [/* For disassembly only; pattern left blank */], 1958 dag iops = (ins rGPR:$Rn, rGPR:$Rm), 1959 string asm = "\t$Rd, $Rn, $Rm"> 1960 : T2I<(outs rGPR:$Rd), iops, NoItinerary, opc, asm, pat>, 1961 Requires<[IsThumb2, HasThumb2DSP]> { 1962 let Inst{31-27} = 0b11111; 1963 let Inst{26-23} = 0b0101; 1964 let Inst{22-20} = op22_20; 1965 let Inst{15-12} = 0b1111; 1966 let Inst{7-4} = op7_4; 1967 1968 bits<4> Rd; 1969 bits<4> Rn; 1970 bits<4> Rm; 1971 1972 let Inst{11-8} = Rd; 1973 let Inst{19-16} = Rn; 1974 let Inst{3-0} = Rm; 1975} 1976 1977// Saturating add/subtract -- for disassembly only 1978 1979def t2QADD : T2I_pam<0b000, 0b1000, "qadd", 1980 [(set rGPR:$Rd, (int_arm_qadd rGPR:$Rn, rGPR:$Rm))], 1981 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">; 1982def t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">; 1983def t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">; 1984def t2QASX : T2I_pam<0b010, 0b0001, "qasx">; 1985def t2QDADD : T2I_pam<0b000, 0b1001, "qdadd", [], 1986 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">; 1987def t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub", [], 1988 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">; 1989def t2QSAX : T2I_pam<0b110, 0b0001, "qsax">; 1990def t2QSUB : T2I_pam<0b000, 0b1010, "qsub", 1991 [(set rGPR:$Rd, (int_arm_qsub rGPR:$Rn, rGPR:$Rm))], 1992 (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">; 1993def t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">; 1994def t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">; 1995def t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">; 1996def t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">; 1997def t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">; 1998def t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">; 1999def t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">; 2000def t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">; 2001 2002// Signed/Unsigned add/subtract -- for disassembly only 2003 2004def t2SASX : T2I_pam<0b010, 0b0000, "sasx">; 2005def t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">; 2006def t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">; 2007def t2SSAX : T2I_pam<0b110, 0b0000, "ssax">; 2008def t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">; 2009def t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">; 2010def t2UASX : T2I_pam<0b010, 0b0100, "uasx">; 2011def t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">; 2012def t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">; 2013def t2USAX : T2I_pam<0b110, 0b0100, "usax">; 2014def t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">; 2015def t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">; 2016 2017// Signed/Unsigned halving add/subtract -- for disassembly only 2018 2019def t2SHASX : T2I_pam<0b010, 0b0010, "shasx">; 2020def t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">; 2021def t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">; 2022def t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">; 2023def t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">; 2024def t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">; 2025def t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">; 2026def t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">; 2027def t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">; 2028def t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">; 2029def t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">; 2030def t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">; 2031 2032// Helper class for disassembly only 2033// A6.3.16 & A6.3.17 2034// T2Imac - Thumb2 multiply [accumulate, and absolute difference] instructions. 2035class T2ThreeReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops, 2036 dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern> 2037 : T2ThreeReg<oops, iops, itin, opc, asm, pattern> { 2038 let Inst{31-27} = 0b11111; 2039 let Inst{26-24} = 0b011; 2040 let Inst{23} = long; 2041 let Inst{22-20} = op22_20; 2042 let Inst{7-4} = op7_4; 2043} 2044 2045class T2FourReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops, 2046 dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern> 2047 : T2FourReg<oops, iops, itin, opc, asm, pattern> { 2048 let Inst{31-27} = 0b11111; 2049 let Inst{26-24} = 0b011; 2050 let Inst{23} = long; 2051 let Inst{22-20} = op22_20; 2052 let Inst{7-4} = op7_4; 2053} 2054 2055// Unsigned Sum of Absolute Differences [and Accumulate]. 2056def t2USAD8 : T2ThreeReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd), 2057 (ins rGPR:$Rn, rGPR:$Rm), 2058 NoItinerary, "usad8", "\t$Rd, $Rn, $Rm", []>, 2059 Requires<[IsThumb2, HasThumb2DSP]> { 2060 let Inst{15-12} = 0b1111; 2061} 2062def t2USADA8 : T2FourReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd), 2063 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), NoItinerary, 2064 "usada8", "\t$Rd, $Rn, $Rm, $Ra", []>, 2065 Requires<[IsThumb2, HasThumb2DSP]>; 2066 2067// Signed/Unsigned saturate. 2068class T2SatI<dag oops, dag iops, InstrItinClass itin, 2069 string opc, string asm, list<dag> pattern> 2070 : T2I<oops, iops, itin, opc, asm, pattern> { 2071 bits<4> Rd; 2072 bits<4> Rn; 2073 bits<5> sat_imm; 2074 bits<7> sh; 2075 2076 let Inst{11-8} = Rd; 2077 let Inst{19-16} = Rn; 2078 let Inst{4-0} = sat_imm; 2079 let Inst{21} = sh{5}; 2080 let Inst{14-12} = sh{4-2}; 2081 let Inst{7-6} = sh{1-0}; 2082} 2083 2084def t2SSAT: T2SatI< 2085 (outs rGPR:$Rd), 2086 (ins imm1_32:$sat_imm, rGPR:$Rn, t2_shift_imm:$sh), 2087 NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []> { 2088 let Inst{31-27} = 0b11110; 2089 let Inst{25-22} = 0b1100; 2090 let Inst{20} = 0; 2091 let Inst{15} = 0; 2092 let Inst{5} = 0; 2093} 2094 2095def t2SSAT16: T2SatI< 2096 (outs rGPR:$Rd), (ins imm1_16:$sat_imm, rGPR:$Rn), NoItinerary, 2097 "ssat16", "\t$Rd, $sat_imm, $Rn", []>, 2098 Requires<[IsThumb2, HasThumb2DSP]> { 2099 let Inst{31-27} = 0b11110; 2100 let Inst{25-22} = 0b1100; 2101 let Inst{20} = 0; 2102 let Inst{15} = 0; 2103 let Inst{21} = 1; // sh = '1' 2104 let Inst{14-12} = 0b000; // imm3 = '000' 2105 let Inst{7-6} = 0b00; // imm2 = '00' 2106 let Inst{5-4} = 0b00; 2107} 2108 2109def t2USAT: T2SatI< 2110 (outs rGPR:$Rd), 2111 (ins imm0_31:$sat_imm, rGPR:$Rn, t2_shift_imm:$sh), 2112 NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []> { 2113 let Inst{31-27} = 0b11110; 2114 let Inst{25-22} = 0b1110; 2115 let Inst{20} = 0; 2116 let Inst{15} = 0; 2117} 2118 2119def t2USAT16: T2SatI<(outs rGPR:$Rd), (ins imm0_15:$sat_imm, rGPR:$Rn), 2120 NoItinerary, 2121 "usat16", "\t$Rd, $sat_imm, $Rn", []>, 2122 Requires<[IsThumb2, HasThumb2DSP]> { 2123 let Inst{31-22} = 0b1111001110; 2124 let Inst{20} = 0; 2125 let Inst{15} = 0; 2126 let Inst{21} = 1; // sh = '1' 2127 let Inst{14-12} = 0b000; // imm3 = '000' 2128 let Inst{7-6} = 0b00; // imm2 = '00' 2129 let Inst{5-4} = 0b00; 2130} 2131 2132def : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>; 2133def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>; 2134 2135//===----------------------------------------------------------------------===// 2136// Shift and rotate Instructions. 2137// 2138 2139defm t2LSL : T2I_sh_ir<0b00, "lsl", imm0_31, 2140 BinOpFrag<(shl node:$LHS, node:$RHS)>>; 2141defm t2LSR : T2I_sh_ir<0b01, "lsr", imm_sr, 2142 BinOpFrag<(srl node:$LHS, node:$RHS)>>; 2143defm t2ASR : T2I_sh_ir<0b10, "asr", imm_sr, 2144 BinOpFrag<(sra node:$LHS, node:$RHS)>>; 2145defm t2ROR : T2I_sh_ir<0b11, "ror", imm0_31, 2146 BinOpFrag<(rotr node:$LHS, node:$RHS)>>; 2147 2148// (rotr x, (and y, 0x...1f)) ==> (ROR x, y) 2149def : T2Pat<(rotr rGPR:$lhs, (and rGPR:$rhs, lo5AllOne)), 2150 (t2RORrr rGPR:$lhs, rGPR:$rhs)>; 2151 2152let Uses = [CPSR] in { 2153def t2RRX : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi, 2154 "rrx", "\t$Rd, $Rm", 2155 [(set rGPR:$Rd, (ARMrrx rGPR:$Rm))]> { 2156 let Inst{31-27} = 0b11101; 2157 let Inst{26-25} = 0b01; 2158 let Inst{24-21} = 0b0010; 2159 let Inst{19-16} = 0b1111; // Rn 2160 let Inst{14-12} = 0b000; 2161 let Inst{7-4} = 0b0011; 2162} 2163} 2164 2165let isCodeGenOnly = 1, Defs = [CPSR] in { 2166def t2MOVsrl_flag : T2TwoRegShiftImm< 2167 (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi, 2168 "lsrs", ".w\t$Rd, $Rm, #1", 2169 [(set rGPR:$Rd, (ARMsrl_flag rGPR:$Rm))]> { 2170 let Inst{31-27} = 0b11101; 2171 let Inst{26-25} = 0b01; 2172 let Inst{24-21} = 0b0010; 2173 let Inst{20} = 1; // The S bit. 2174 let Inst{19-16} = 0b1111; // Rn 2175 let Inst{5-4} = 0b01; // Shift type. 2176 // Shift amount = Inst{14-12:7-6} = 1. 2177 let Inst{14-12} = 0b000; 2178 let Inst{7-6} = 0b01; 2179} 2180def t2MOVsra_flag : T2TwoRegShiftImm< 2181 (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi, 2182 "asrs", ".w\t$Rd, $Rm, #1", 2183 [(set rGPR:$Rd, (ARMsra_flag rGPR:$Rm))]> { 2184 let Inst{31-27} = 0b11101; 2185 let Inst{26-25} = 0b01; 2186 let Inst{24-21} = 0b0010; 2187 let Inst{20} = 1; // The S bit. 2188 let Inst{19-16} = 0b1111; // Rn 2189 let Inst{5-4} = 0b10; // Shift type. 2190 // Shift amount = Inst{14-12:7-6} = 1. 2191 let Inst{14-12} = 0b000; 2192 let Inst{7-6} = 0b01; 2193} 2194} 2195 2196//===----------------------------------------------------------------------===// 2197// Bitwise Instructions. 2198// 2199 2200defm t2AND : T2I_bin_w_irs<0b0000, "and", 2201 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 2202 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>; 2203defm t2ORR : T2I_bin_w_irs<0b0010, "orr", 2204 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 2205 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>; 2206defm t2EOR : T2I_bin_w_irs<0b0100, "eor", 2207 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 2208 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>; 2209 2210defm t2BIC : T2I_bin_w_irs<0b0001, "bic", 2211 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 2212 BinOpFrag<(and node:$LHS, (not node:$RHS))>>; 2213 2214class T2BitFI<dag oops, dag iops, InstrItinClass itin, 2215 string opc, string asm, list<dag> pattern> 2216 : T2I<oops, iops, itin, opc, asm, pattern> { 2217 bits<4> Rd; 2218 bits<5> msb; 2219 bits<5> lsb; 2220 2221 let Inst{11-8} = Rd; 2222 let Inst{4-0} = msb{4-0}; 2223 let Inst{14-12} = lsb{4-2}; 2224 let Inst{7-6} = lsb{1-0}; 2225} 2226 2227class T2TwoRegBitFI<dag oops, dag iops, InstrItinClass itin, 2228 string opc, string asm, list<dag> pattern> 2229 : T2BitFI<oops, iops, itin, opc, asm, pattern> { 2230 bits<4> Rn; 2231 2232 let Inst{19-16} = Rn; 2233} 2234 2235let Constraints = "$src = $Rd" in 2236def t2BFC : T2BitFI<(outs rGPR:$Rd), (ins rGPR:$src, bf_inv_mask_imm:$imm), 2237 IIC_iUNAsi, "bfc", "\t$Rd, $imm", 2238 [(set rGPR:$Rd, (and rGPR:$src, bf_inv_mask_imm:$imm))]> { 2239 let Inst{31-27} = 0b11110; 2240 let Inst{26} = 0; // should be 0. 2241 let Inst{25} = 1; 2242 let Inst{24-20} = 0b10110; 2243 let Inst{19-16} = 0b1111; // Rn 2244 let Inst{15} = 0; 2245 let Inst{5} = 0; // should be 0. 2246 2247 bits<10> imm; 2248 let msb{4-0} = imm{9-5}; 2249 let lsb{4-0} = imm{4-0}; 2250} 2251 2252def t2SBFX: T2TwoRegBitFI< 2253 (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm1_32:$msb), 2254 IIC_iUNAsi, "sbfx", "\t$Rd, $Rn, $lsb, $msb", []> { 2255 let Inst{31-27} = 0b11110; 2256 let Inst{25} = 1; 2257 let Inst{24-20} = 0b10100; 2258 let Inst{15} = 0; 2259} 2260 2261def t2UBFX: T2TwoRegBitFI< 2262 (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm1_32:$msb), 2263 IIC_iUNAsi, "ubfx", "\t$Rd, $Rn, $lsb, $msb", []> { 2264 let Inst{31-27} = 0b11110; 2265 let Inst{25} = 1; 2266 let Inst{24-20} = 0b11100; 2267 let Inst{15} = 0; 2268} 2269 2270// A8.6.18 BFI - Bitfield insert (Encoding T1) 2271let Constraints = "$src = $Rd" in { 2272 def t2BFI : T2TwoRegBitFI<(outs rGPR:$Rd), 2273 (ins rGPR:$src, rGPR:$Rn, bf_inv_mask_imm:$imm), 2274 IIC_iBITi, "bfi", "\t$Rd, $Rn, $imm", 2275 [(set rGPR:$Rd, (ARMbfi rGPR:$src, rGPR:$Rn, 2276 bf_inv_mask_imm:$imm))]> { 2277 let Inst{31-27} = 0b11110; 2278 let Inst{26} = 0; // should be 0. 2279 let Inst{25} = 1; 2280 let Inst{24-20} = 0b10110; 2281 let Inst{15} = 0; 2282 let Inst{5} = 0; // should be 0. 2283 2284 bits<10> imm; 2285 let msb{4-0} = imm{9-5}; 2286 let lsb{4-0} = imm{4-0}; 2287 } 2288} 2289 2290defm t2ORN : T2I_bin_irs<0b0011, "orn", 2291 IIC_iBITi, IIC_iBITr, IIC_iBITsi, 2292 BinOpFrag<(or node:$LHS, (not node:$RHS))>, 0, "">; 2293 2294/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a 2295/// unary operation that produces a value. These are predicable and can be 2296/// changed to modify CPSR. 2297multiclass T2I_un_irs<bits<4> opcod, string opc, 2298 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 2299 PatFrag opnode, bit Cheap = 0, bit ReMat = 0> { 2300 // shifted imm 2301 def i : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), iii, 2302 opc, "\t$Rd, $imm", 2303 [(set rGPR:$Rd, (opnode t2_so_imm:$imm))]> { 2304 let isAsCheapAsAMove = Cheap; 2305 let isReMaterializable = ReMat; 2306 let Inst{31-27} = 0b11110; 2307 let Inst{25} = 0; 2308 let Inst{24-21} = opcod; 2309 let Inst{19-16} = 0b1111; // Rn 2310 let Inst{15} = 0; 2311 } 2312 // register 2313 def r : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), iir, 2314 opc, ".w\t$Rd, $Rm", 2315 [(set rGPR:$Rd, (opnode rGPR:$Rm))]> { 2316 let Inst{31-27} = 0b11101; 2317 let Inst{26-25} = 0b01; 2318 let Inst{24-21} = opcod; 2319 let Inst{19-16} = 0b1111; // Rn 2320 let Inst{14-12} = 0b000; // imm3 2321 let Inst{7-6} = 0b00; // imm2 2322 let Inst{5-4} = 0b00; // type 2323 } 2324 // shifted register 2325 def s : T2sOneRegShiftedReg<(outs rGPR:$Rd), (ins t2_so_reg:$ShiftedRm), iis, 2326 opc, ".w\t$Rd, $ShiftedRm", 2327 [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm))]> { 2328 let Inst{31-27} = 0b11101; 2329 let Inst{26-25} = 0b01; 2330 let Inst{24-21} = opcod; 2331 let Inst{19-16} = 0b1111; // Rn 2332 } 2333} 2334 2335// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version 2336let AddedComplexity = 1 in 2337defm t2MVN : T2I_un_irs <0b0011, "mvn", 2338 IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi, 2339 UnOpFrag<(not node:$Src)>, 1, 1>; 2340 2341let AddedComplexity = 1 in 2342def : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm), 2343 (t2BICri rGPR:$src, t2_so_imm_not:$imm)>; 2344 2345// top16Zero - answer true if the upper 16 bits of $src are 0, false otherwise 2346def top16Zero: PatLeaf<(i32 rGPR:$src), [{ 2347 return CurDAG->MaskedValueIsZero(SDValue(N,0), APInt::getHighBitsSet(32, 16)); 2348 }]>; 2349 2350// so_imm_notSext is needed instead of so_imm_not, as the value of imm 2351// will match the extended, not the original bitWidth for $src. 2352def : T2Pat<(and top16Zero:$src, t2_so_imm_notSext:$imm), 2353 (t2BICri rGPR:$src, t2_so_imm_notSext:$imm)>; 2354 2355 2356// FIXME: Disable this pattern on Darwin to workaround an assembler bug. 2357def : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm), 2358 (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>, 2359 Requires<[IsThumb2]>; 2360 2361def : T2Pat<(t2_so_imm_not:$src), 2362 (t2MVNi t2_so_imm_not:$src)>; 2363 2364//===----------------------------------------------------------------------===// 2365// Multiply Instructions. 2366// 2367let isCommutable = 1 in 2368def t2MUL: T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32, 2369 "mul", "\t$Rd, $Rn, $Rm", 2370 [(set rGPR:$Rd, (mul rGPR:$Rn, rGPR:$Rm))]> { 2371 let Inst{31-27} = 0b11111; 2372 let Inst{26-23} = 0b0110; 2373 let Inst{22-20} = 0b000; 2374 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2375 let Inst{7-4} = 0b0000; // Multiply 2376} 2377 2378def t2MLA: T2FourReg< 2379 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, 2380 "mla", "\t$Rd, $Rn, $Rm, $Ra", 2381 [(set rGPR:$Rd, (add (mul rGPR:$Rn, rGPR:$Rm), rGPR:$Ra))]> { 2382 let Inst{31-27} = 0b11111; 2383 let Inst{26-23} = 0b0110; 2384 let Inst{22-20} = 0b000; 2385 let Inst{7-4} = 0b0000; // Multiply 2386} 2387 2388def t2MLS: T2FourReg< 2389 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, 2390 "mls", "\t$Rd, $Rn, $Rm, $Ra", 2391 [(set rGPR:$Rd, (sub rGPR:$Ra, (mul rGPR:$Rn, rGPR:$Rm)))]> { 2392 let Inst{31-27} = 0b11111; 2393 let Inst{26-23} = 0b0110; 2394 let Inst{22-20} = 0b000; 2395 let Inst{7-4} = 0b0001; // Multiply and Subtract 2396} 2397 2398// Extra precision multiplies with low / high results 2399let neverHasSideEffects = 1 in { 2400let isCommutable = 1 in { 2401def t2SMULL : T2MulLong<0b000, 0b0000, 2402 (outs rGPR:$RdLo, rGPR:$RdHi), 2403 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64, 2404 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>; 2405 2406def t2UMULL : T2MulLong<0b010, 0b0000, 2407 (outs rGPR:$RdLo, rGPR:$RdHi), 2408 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64, 2409 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>; 2410} // isCommutable 2411 2412// Multiply + accumulate 2413def t2SMLAL : T2MulLong<0b100, 0b0000, 2414 (outs rGPR:$RdLo, rGPR:$RdHi), 2415 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64, 2416 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>; 2417 2418def t2UMLAL : T2MulLong<0b110, 0b0000, 2419 (outs rGPR:$RdLo, rGPR:$RdHi), 2420 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64, 2421 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>; 2422 2423def t2UMAAL : T2MulLong<0b110, 0b0110, 2424 (outs rGPR:$RdLo, rGPR:$RdHi), 2425 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64, 2426 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 2427 Requires<[IsThumb2, HasThumb2DSP]>; 2428} // neverHasSideEffects 2429 2430// Rounding variants of the below included for disassembly only 2431 2432// Most significant word multiply 2433def t2SMMUL : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32, 2434 "smmul", "\t$Rd, $Rn, $Rm", 2435 [(set rGPR:$Rd, (mulhs rGPR:$Rn, rGPR:$Rm))]>, 2436 Requires<[IsThumb2, HasThumb2DSP]> { 2437 let Inst{31-27} = 0b11111; 2438 let Inst{26-23} = 0b0110; 2439 let Inst{22-20} = 0b101; 2440 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2441 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) 2442} 2443 2444def t2SMMULR : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32, 2445 "smmulr", "\t$Rd, $Rn, $Rm", []>, 2446 Requires<[IsThumb2, HasThumb2DSP]> { 2447 let Inst{31-27} = 0b11111; 2448 let Inst{26-23} = 0b0110; 2449 let Inst{22-20} = 0b101; 2450 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2451 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) 2452} 2453 2454def t2SMMLA : T2FourReg< 2455 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, 2456 "smmla", "\t$Rd, $Rn, $Rm, $Ra", 2457 [(set rGPR:$Rd, (add (mulhs rGPR:$Rm, rGPR:$Rn), rGPR:$Ra))]>, 2458 Requires<[IsThumb2, HasThumb2DSP]> { 2459 let Inst{31-27} = 0b11111; 2460 let Inst{26-23} = 0b0110; 2461 let Inst{22-20} = 0b101; 2462 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) 2463} 2464 2465def t2SMMLAR: T2FourReg< 2466 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, 2467 "smmlar", "\t$Rd, $Rn, $Rm, $Ra", []>, 2468 Requires<[IsThumb2, HasThumb2DSP]> { 2469 let Inst{31-27} = 0b11111; 2470 let Inst{26-23} = 0b0110; 2471 let Inst{22-20} = 0b101; 2472 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) 2473} 2474 2475def t2SMMLS: T2FourReg< 2476 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, 2477 "smmls", "\t$Rd, $Rn, $Rm, $Ra", 2478 [(set rGPR:$Rd, (sub rGPR:$Ra, (mulhs rGPR:$Rn, rGPR:$Rm)))]>, 2479 Requires<[IsThumb2, HasThumb2DSP]> { 2480 let Inst{31-27} = 0b11111; 2481 let Inst{26-23} = 0b0110; 2482 let Inst{22-20} = 0b110; 2483 let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) 2484} 2485 2486def t2SMMLSR:T2FourReg< 2487 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, 2488 "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", []>, 2489 Requires<[IsThumb2, HasThumb2DSP]> { 2490 let Inst{31-27} = 0b11111; 2491 let Inst{26-23} = 0b0110; 2492 let Inst{22-20} = 0b110; 2493 let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) 2494} 2495 2496multiclass T2I_smul<string opc, PatFrag opnode> { 2497 def BB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, 2498 !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm", 2499 [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16), 2500 (sext_inreg rGPR:$Rm, i16)))]>, 2501 Requires<[IsThumb2, HasThumb2DSP]> { 2502 let Inst{31-27} = 0b11111; 2503 let Inst{26-23} = 0b0110; 2504 let Inst{22-20} = 0b001; 2505 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2506 let Inst{7-6} = 0b00; 2507 let Inst{5-4} = 0b00; 2508 } 2509 2510 def BT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, 2511 !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm", 2512 [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16), 2513 (sra rGPR:$Rm, (i32 16))))]>, 2514 Requires<[IsThumb2, HasThumb2DSP]> { 2515 let Inst{31-27} = 0b11111; 2516 let Inst{26-23} = 0b0110; 2517 let Inst{22-20} = 0b001; 2518 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2519 let Inst{7-6} = 0b00; 2520 let Inst{5-4} = 0b01; 2521 } 2522 2523 def TB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, 2524 !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm", 2525 [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)), 2526 (sext_inreg rGPR:$Rm, i16)))]>, 2527 Requires<[IsThumb2, HasThumb2DSP]> { 2528 let Inst{31-27} = 0b11111; 2529 let Inst{26-23} = 0b0110; 2530 let Inst{22-20} = 0b001; 2531 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2532 let Inst{7-6} = 0b00; 2533 let Inst{5-4} = 0b10; 2534 } 2535 2536 def TT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, 2537 !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm", 2538 [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)), 2539 (sra rGPR:$Rm, (i32 16))))]>, 2540 Requires<[IsThumb2, HasThumb2DSP]> { 2541 let Inst{31-27} = 0b11111; 2542 let Inst{26-23} = 0b0110; 2543 let Inst{22-20} = 0b001; 2544 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2545 let Inst{7-6} = 0b00; 2546 let Inst{5-4} = 0b11; 2547 } 2548 2549 def WB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, 2550 !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm", 2551 [(set rGPR:$Rd, (sra (opnode rGPR:$Rn, 2552 (sext_inreg rGPR:$Rm, i16)), (i32 16)))]>, 2553 Requires<[IsThumb2, HasThumb2DSP]> { 2554 let Inst{31-27} = 0b11111; 2555 let Inst{26-23} = 0b0110; 2556 let Inst{22-20} = 0b011; 2557 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2558 let Inst{7-6} = 0b00; 2559 let Inst{5-4} = 0b00; 2560 } 2561 2562 def WT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, 2563 !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm", 2564 [(set rGPR:$Rd, (sra (opnode rGPR:$Rn, 2565 (sra rGPR:$Rm, (i32 16))), (i32 16)))]>, 2566 Requires<[IsThumb2, HasThumb2DSP]> { 2567 let Inst{31-27} = 0b11111; 2568 let Inst{26-23} = 0b0110; 2569 let Inst{22-20} = 0b011; 2570 let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2571 let Inst{7-6} = 0b00; 2572 let Inst{5-4} = 0b01; 2573 } 2574} 2575 2576 2577multiclass T2I_smla<string opc, PatFrag opnode> { 2578 def BB : T2FourReg< 2579 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, 2580 !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra", 2581 [(set rGPR:$Rd, (add rGPR:$Ra, 2582 (opnode (sext_inreg rGPR:$Rn, i16), 2583 (sext_inreg rGPR:$Rm, i16))))]>, 2584 Requires<[IsThumb2, HasThumb2DSP]> { 2585 let Inst{31-27} = 0b11111; 2586 let Inst{26-23} = 0b0110; 2587 let Inst{22-20} = 0b001; 2588 let Inst{7-6} = 0b00; 2589 let Inst{5-4} = 0b00; 2590 } 2591 2592 def BT : T2FourReg< 2593 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, 2594 !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra", 2595 [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sext_inreg rGPR:$Rn, i16), 2596 (sra rGPR:$Rm, (i32 16)))))]>, 2597 Requires<[IsThumb2, HasThumb2DSP]> { 2598 let Inst{31-27} = 0b11111; 2599 let Inst{26-23} = 0b0110; 2600 let Inst{22-20} = 0b001; 2601 let Inst{7-6} = 0b00; 2602 let Inst{5-4} = 0b01; 2603 } 2604 2605 def TB : T2FourReg< 2606 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, 2607 !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra", 2608 [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)), 2609 (sext_inreg rGPR:$Rm, i16))))]>, 2610 Requires<[IsThumb2, HasThumb2DSP]> { 2611 let Inst{31-27} = 0b11111; 2612 let Inst{26-23} = 0b0110; 2613 let Inst{22-20} = 0b001; 2614 let Inst{7-6} = 0b00; 2615 let Inst{5-4} = 0b10; 2616 } 2617 2618 def TT : T2FourReg< 2619 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, 2620 !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra", 2621 [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)), 2622 (sra rGPR:$Rm, (i32 16)))))]>, 2623 Requires<[IsThumb2, HasThumb2DSP]> { 2624 let Inst{31-27} = 0b11111; 2625 let Inst{26-23} = 0b0110; 2626 let Inst{22-20} = 0b001; 2627 let Inst{7-6} = 0b00; 2628 let Inst{5-4} = 0b11; 2629 } 2630 2631 def WB : T2FourReg< 2632 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, 2633 !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra", 2634 [(set rGPR:$Rd, (add rGPR:$Ra, (sra (opnode rGPR:$Rn, 2635 (sext_inreg rGPR:$Rm, i16)), (i32 16))))]>, 2636 Requires<[IsThumb2, HasThumb2DSP]> { 2637 let Inst{31-27} = 0b11111; 2638 let Inst{26-23} = 0b0110; 2639 let Inst{22-20} = 0b011; 2640 let Inst{7-6} = 0b00; 2641 let Inst{5-4} = 0b00; 2642 } 2643 2644 def WT : T2FourReg< 2645 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, 2646 !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra", 2647 [(set rGPR:$Rd, (add rGPR:$Ra, (sra (opnode rGPR:$Rn, 2648 (sra rGPR:$Rm, (i32 16))), (i32 16))))]>, 2649 Requires<[IsThumb2, HasThumb2DSP]> { 2650 let Inst{31-27} = 0b11111; 2651 let Inst{26-23} = 0b0110; 2652 let Inst{22-20} = 0b011; 2653 let Inst{7-6} = 0b00; 2654 let Inst{5-4} = 0b01; 2655 } 2656} 2657 2658defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 2659defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 2660 2661// Halfword multiple accumulate long: SMLAL<x><y> 2662def t2SMLALBB : T2FourReg_mac<1, 0b100, 0b1000, (outs rGPR:$Ra,rGPR:$Rd), 2663 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbb", "\t$Ra, $Rd, $Rn, $Rm", 2664 [/* For disassembly only; pattern left blank */]>, 2665 Requires<[IsThumb2, HasThumb2DSP]>; 2666def t2SMLALBT : T2FourReg_mac<1, 0b100, 0b1001, (outs rGPR:$Ra,rGPR:$Rd), 2667 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbt", "\t$Ra, $Rd, $Rn, $Rm", 2668 [/* For disassembly only; pattern left blank */]>, 2669 Requires<[IsThumb2, HasThumb2DSP]>; 2670def t2SMLALTB : T2FourReg_mac<1, 0b100, 0b1010, (outs rGPR:$Ra,rGPR:$Rd), 2671 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltb", "\t$Ra, $Rd, $Rn, $Rm", 2672 [/* For disassembly only; pattern left blank */]>, 2673 Requires<[IsThumb2, HasThumb2DSP]>; 2674def t2SMLALTT : T2FourReg_mac<1, 0b100, 0b1011, (outs rGPR:$Ra,rGPR:$Rd), 2675 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltt", "\t$Ra, $Rd, $Rn, $Rm", 2676 [/* For disassembly only; pattern left blank */]>, 2677 Requires<[IsThumb2, HasThumb2DSP]>; 2678 2679// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD 2680def t2SMUAD: T2ThreeReg_mac< 2681 0, 0b010, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), 2682 IIC_iMAC32, "smuad", "\t$Rd, $Rn, $Rm", []>, 2683 Requires<[IsThumb2, HasThumb2DSP]> { 2684 let Inst{15-12} = 0b1111; 2685} 2686def t2SMUADX:T2ThreeReg_mac< 2687 0, 0b010, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), 2688 IIC_iMAC32, "smuadx", "\t$Rd, $Rn, $Rm", []>, 2689 Requires<[IsThumb2, HasThumb2DSP]> { 2690 let Inst{15-12} = 0b1111; 2691} 2692def t2SMUSD: T2ThreeReg_mac< 2693 0, 0b100, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), 2694 IIC_iMAC32, "smusd", "\t$Rd, $Rn, $Rm", []>, 2695 Requires<[IsThumb2, HasThumb2DSP]> { 2696 let Inst{15-12} = 0b1111; 2697} 2698def t2SMUSDX:T2ThreeReg_mac< 2699 0, 0b100, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), 2700 IIC_iMAC32, "smusdx", "\t$Rd, $Rn, $Rm", []>, 2701 Requires<[IsThumb2, HasThumb2DSP]> { 2702 let Inst{15-12} = 0b1111; 2703} 2704def t2SMLAD : T2FourReg_mac< 2705 0, 0b010, 0b0000, (outs rGPR:$Rd), 2706 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlad", 2707 "\t$Rd, $Rn, $Rm, $Ra", []>, 2708 Requires<[IsThumb2, HasThumb2DSP]>; 2709def t2SMLADX : T2FourReg_mac< 2710 0, 0b010, 0b0001, (outs rGPR:$Rd), 2711 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smladx", 2712 "\t$Rd, $Rn, $Rm, $Ra", []>, 2713 Requires<[IsThumb2, HasThumb2DSP]>; 2714def t2SMLSD : T2FourReg_mac<0, 0b100, 0b0000, (outs rGPR:$Rd), 2715 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsd", 2716 "\t$Rd, $Rn, $Rm, $Ra", []>, 2717 Requires<[IsThumb2, HasThumb2DSP]>; 2718def t2SMLSDX : T2FourReg_mac<0, 0b100, 0b0001, (outs rGPR:$Rd), 2719 (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsdx", 2720 "\t$Rd, $Rn, $Rm, $Ra", []>, 2721 Requires<[IsThumb2, HasThumb2DSP]>; 2722def t2SMLALD : T2FourReg_mac<1, 0b100, 0b1100, (outs rGPR:$Ra,rGPR:$Rd), 2723 (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64, "smlald", 2724 "\t$Ra, $Rd, $Rn, $Rm", []>, 2725 Requires<[IsThumb2, HasThumb2DSP]>; 2726def t2SMLALDX : T2FourReg_mac<1, 0b100, 0b1101, (outs rGPR:$Ra,rGPR:$Rd), 2727 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaldx", 2728 "\t$Ra, $Rd, $Rn, $Rm", []>, 2729 Requires<[IsThumb2, HasThumb2DSP]>; 2730def t2SMLSLD : T2FourReg_mac<1, 0b101, 0b1100, (outs rGPR:$Ra,rGPR:$Rd), 2731 (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlsld", 2732 "\t$Ra, $Rd, $Rn, $Rm", []>, 2733 Requires<[IsThumb2, HasThumb2DSP]>; 2734def t2SMLSLDX : T2FourReg_mac<1, 0b101, 0b1101, (outs rGPR:$Ra,rGPR:$Rd), 2735 (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlsldx", 2736 "\t$Ra, $Rd, $Rn, $Rm", []>, 2737 Requires<[IsThumb2, HasThumb2DSP]>; 2738 2739//===----------------------------------------------------------------------===// 2740// Division Instructions. 2741// Signed and unsigned division on v7-M 2742// 2743def t2SDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi, 2744 "sdiv", "\t$Rd, $Rn, $Rm", 2745 [(set rGPR:$Rd, (sdiv rGPR:$Rn, rGPR:$Rm))]>, 2746 Requires<[HasDivide, IsThumb2]> { 2747 let Inst{31-27} = 0b11111; 2748 let Inst{26-21} = 0b011100; 2749 let Inst{20} = 0b1; 2750 let Inst{15-12} = 0b1111; 2751 let Inst{7-4} = 0b1111; 2752} 2753 2754def t2UDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUi, 2755 "udiv", "\t$Rd, $Rn, $Rm", 2756 [(set rGPR:$Rd, (udiv rGPR:$Rn, rGPR:$Rm))]>, 2757 Requires<[HasDivide, IsThumb2]> { 2758 let Inst{31-27} = 0b11111; 2759 let Inst{26-21} = 0b011101; 2760 let Inst{20} = 0b1; 2761 let Inst{15-12} = 0b1111; 2762 let Inst{7-4} = 0b1111; 2763} 2764 2765//===----------------------------------------------------------------------===// 2766// Misc. Arithmetic Instructions. 2767// 2768 2769class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops, 2770 InstrItinClass itin, string opc, string asm, list<dag> pattern> 2771 : T2ThreeReg<oops, iops, itin, opc, asm, pattern> { 2772 let Inst{31-27} = 0b11111; 2773 let Inst{26-22} = 0b01010; 2774 let Inst{21-20} = op1; 2775 let Inst{15-12} = 0b1111; 2776 let Inst{7-6} = 0b10; 2777 let Inst{5-4} = op2; 2778 let Rn{3-0} = Rm; 2779} 2780 2781def t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr, 2782 "clz", "\t$Rd, $Rm", [(set rGPR:$Rd, (ctlz rGPR:$Rm))]>; 2783 2784def t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr, 2785 "rbit", "\t$Rd, $Rm", 2786 [(set rGPR:$Rd, (ARMrbit rGPR:$Rm))]>; 2787 2788def t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr, 2789 "rev", ".w\t$Rd, $Rm", [(set rGPR:$Rd, (bswap rGPR:$Rm))]>; 2790 2791def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr, 2792 "rev16", ".w\t$Rd, $Rm", 2793 [(set rGPR:$Rd, (rotr (bswap rGPR:$Rm), (i32 16)))]>; 2794 2795def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr, 2796 "revsh", ".w\t$Rd, $Rm", 2797 [(set rGPR:$Rd, (sra (bswap rGPR:$Rm), (i32 16)))]>; 2798 2799def : T2Pat<(or (sra (shl rGPR:$Rm, (i32 24)), (i32 16)), 2800 (and (srl rGPR:$Rm, (i32 8)), 0xFF)), 2801 (t2REVSH rGPR:$Rm)>; 2802 2803def t2PKHBT : T2ThreeReg< 2804 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, pkh_lsl_amt:$sh), 2805 IIC_iBITsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh", 2806 [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF), 2807 (and (shl rGPR:$Rm, pkh_lsl_amt:$sh), 2808 0xFFFF0000)))]>, 2809 Requires<[HasT2ExtractPack, IsThumb2]> { 2810 let Inst{31-27} = 0b11101; 2811 let Inst{26-25} = 0b01; 2812 let Inst{24-20} = 0b01100; 2813 let Inst{5} = 0; // BT form 2814 let Inst{4} = 0; 2815 2816 bits<5> sh; 2817 let Inst{14-12} = sh{4-2}; 2818 let Inst{7-6} = sh{1-0}; 2819} 2820 2821// Alternate cases for PKHBT where identities eliminate some nodes. 2822def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)), 2823 (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>, 2824 Requires<[HasT2ExtractPack, IsThumb2]>; 2825def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)), 2826 (t2PKHBT rGPR:$src1, rGPR:$src2, imm16_31:$sh)>, 2827 Requires<[HasT2ExtractPack, IsThumb2]>; 2828 2829// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and 2830// will match the pattern below. 2831def t2PKHTB : T2ThreeReg< 2832 (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, pkh_asr_amt:$sh), 2833 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh", 2834 [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF0000), 2835 (and (sra rGPR:$Rm, pkh_asr_amt:$sh), 2836 0xFFFF)))]>, 2837 Requires<[HasT2ExtractPack, IsThumb2]> { 2838 let Inst{31-27} = 0b11101; 2839 let Inst{26-25} = 0b01; 2840 let Inst{24-20} = 0b01100; 2841 let Inst{5} = 1; // TB form 2842 let Inst{4} = 0; 2843 2844 bits<5> sh; 2845 let Inst{14-12} = sh{4-2}; 2846 let Inst{7-6} = sh{1-0}; 2847} 2848 2849// Alternate cases for PKHTB where identities eliminate some nodes. Note that 2850// a shift amount of 0 is *not legal* here, it is PKHBT instead. 2851def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)), 2852 (t2PKHTB rGPR:$src1, rGPR:$src2, imm16_31:$sh)>, 2853 Requires<[HasT2ExtractPack, IsThumb2]>; 2854def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), 2855 (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)), 2856 (t2PKHTB rGPR:$src1, rGPR:$src2, imm1_15:$sh)>, 2857 Requires<[HasT2ExtractPack, IsThumb2]>; 2858 2859//===----------------------------------------------------------------------===// 2860// Comparison Instructions... 2861// 2862defm t2CMP : T2I_cmp_irs<0b1101, "cmp", 2863 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi, 2864 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>; 2865 2866def : T2Pat<(ARMcmpZ GPRnopc:$lhs, t2_so_imm:$imm), 2867 (t2CMPri GPRnopc:$lhs, t2_so_imm:$imm)>; 2868def : T2Pat<(ARMcmpZ GPRnopc:$lhs, rGPR:$rhs), 2869 (t2CMPrr GPRnopc:$lhs, rGPR:$rhs)>; 2870def : T2Pat<(ARMcmpZ GPRnopc:$lhs, t2_so_reg:$rhs), 2871 (t2CMPrs GPRnopc:$lhs, t2_so_reg:$rhs)>; 2872 2873let isCompare = 1, Defs = [CPSR] in { 2874 // shifted imm 2875 def t2CMNri : T2OneRegCmpImm< 2876 (outs), (ins GPRnopc:$Rn, t2_so_imm:$imm), IIC_iCMPi, 2877 "cmn", ".w\t$Rn, $imm", 2878 [(ARMcmn GPRnopc:$Rn, (ineg t2_so_imm:$imm))]> { 2879 let Inst{31-27} = 0b11110; 2880 let Inst{25} = 0; 2881 let Inst{24-21} = 0b1000; 2882 let Inst{20} = 1; // The S bit. 2883 let Inst{15} = 0; 2884 let Inst{11-8} = 0b1111; // Rd 2885 } 2886 // register 2887 def t2CMNzrr : T2TwoRegCmp< 2888 (outs), (ins GPRnopc:$Rn, rGPR:$Rm), IIC_iCMPr, 2889 "cmn", ".w\t$Rn, $Rm", 2890 [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 2891 GPRnopc:$Rn, rGPR:$Rm)]> { 2892 let Inst{31-27} = 0b11101; 2893 let Inst{26-25} = 0b01; 2894 let Inst{24-21} = 0b1000; 2895 let Inst{20} = 1; // The S bit. 2896 let Inst{14-12} = 0b000; // imm3 2897 let Inst{11-8} = 0b1111; // Rd 2898 let Inst{7-6} = 0b00; // imm2 2899 let Inst{5-4} = 0b00; // type 2900 } 2901 // shifted register 2902 def t2CMNzrs : T2OneRegCmpShiftedReg< 2903 (outs), (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm), IIC_iCMPsi, 2904 "cmn", ".w\t$Rn, $ShiftedRm", 2905 [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 2906 GPRnopc:$Rn, t2_so_reg:$ShiftedRm)]> { 2907 let Inst{31-27} = 0b11101; 2908 let Inst{26-25} = 0b01; 2909 let Inst{24-21} = 0b1000; 2910 let Inst{20} = 1; // The S bit. 2911 let Inst{11-8} = 0b1111; // Rd 2912 } 2913} 2914 2915// Assembler aliases w/o the ".w" suffix. 2916// No alias here for 'rr' version as not all instantiations of this multiclass 2917// want one (CMP in particular, does not). 2918def : t2InstAlias<"cmn${p} $Rn, $imm", 2919 (t2CMNri GPRnopc:$Rn, t2_so_imm:$imm, pred:$p)>; 2920def : t2InstAlias<"cmn${p} $Rn, $shift", 2921 (t2CMNzrs GPRnopc:$Rn, t2_so_reg:$shift, pred:$p)>; 2922 2923def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm), 2924 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>; 2925 2926def : T2Pat<(ARMcmpZ GPRnopc:$src, t2_so_imm_neg:$imm), 2927 (t2CMNri GPRnopc:$src, t2_so_imm_neg:$imm)>; 2928 2929defm t2TST : T2I_cmp_irs<0b0000, "tst", 2930 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi, 2931 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>>; 2932defm t2TEQ : T2I_cmp_irs<0b0100, "teq", 2933 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi, 2934 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>>; 2935 2936// Conditional moves 2937// FIXME: should be able to write a pattern for ARMcmov, but can't use 2938// a two-value operand where a dag node expects two operands. :( 2939let neverHasSideEffects = 1 in { 2940 2941let isCommutable = 1 in 2942def t2MOVCCr : t2PseudoInst<(outs rGPR:$Rd), 2943 (ins rGPR:$false, rGPR:$Rm, pred:$p), 2944 4, IIC_iCMOVr, 2945 [/*(set rGPR:$Rd, (ARMcmov rGPR:$false, rGPR:$Rm, imm:$cc, CCR:$ccr))*/]>, 2946 RegConstraint<"$false = $Rd">; 2947 2948let isMoveImm = 1 in 2949def t2MOVCCi : t2PseudoInst<(outs rGPR:$Rd), 2950 (ins rGPR:$false, t2_so_imm:$imm, pred:$p), 2951 4, IIC_iCMOVi, 2952[/*(set rGPR:$Rd,(ARMcmov rGPR:$false,t2_so_imm:$imm, imm:$cc, CCR:$ccr))*/]>, 2953 RegConstraint<"$false = $Rd">; 2954 2955// FIXME: Pseudo-ize these. For now, just mark codegen only. 2956let isCodeGenOnly = 1 in { 2957let isMoveImm = 1 in 2958def t2MOVCCi16 : T2I<(outs rGPR:$Rd), (ins rGPR:$false, imm0_65535_expr:$imm), 2959 IIC_iCMOVi, 2960 "movw", "\t$Rd, $imm", []>, 2961 RegConstraint<"$false = $Rd"> { 2962 let Inst{31-27} = 0b11110; 2963 let Inst{25} = 1; 2964 let Inst{24-21} = 0b0010; 2965 let Inst{20} = 0; // The S bit. 2966 let Inst{15} = 0; 2967 2968 bits<4> Rd; 2969 bits<16> imm; 2970 2971 let Inst{11-8} = Rd; 2972 let Inst{19-16} = imm{15-12}; 2973 let Inst{26} = imm{11}; 2974 let Inst{14-12} = imm{10-8}; 2975 let Inst{7-0} = imm{7-0}; 2976} 2977 2978let isMoveImm = 1 in 2979def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst), 2980 (ins rGPR:$false, i32imm:$src, pred:$p), 2981 IIC_iCMOVix2, []>, RegConstraint<"$false = $dst">; 2982 2983let isMoveImm = 1 in 2984def t2MVNCCi : T2OneRegImm<(outs rGPR:$Rd), (ins rGPR:$false, t2_so_imm:$imm), 2985 IIC_iCMOVi, "mvn", "\t$Rd, $imm", 2986[/*(set rGPR:$Rd,(ARMcmov rGPR:$false,t2_so_imm_not:$imm, 2987 imm:$cc, CCR:$ccr))*/]>, 2988 RegConstraint<"$false = $Rd"> { 2989 let Inst{31-27} = 0b11110; 2990 let Inst{25} = 0; 2991 let Inst{24-21} = 0b0011; 2992 let Inst{20} = 0; // The S bit. 2993 let Inst{19-16} = 0b1111; // Rn 2994 let Inst{15} = 0; 2995} 2996 2997class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin, 2998 string opc, string asm, list<dag> pattern> 2999 : T2TwoRegShiftImm<oops, iops, itin, opc, asm, pattern> { 3000 let Inst{31-27} = 0b11101; 3001 let Inst{26-25} = 0b01; 3002 let Inst{24-21} = 0b0010; 3003 let Inst{20} = 0; // The S bit. 3004 let Inst{19-16} = 0b1111; // Rn 3005 let Inst{5-4} = opcod; // Shift type. 3006} 3007def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$Rd), 3008 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm), 3009 IIC_iCMOVsi, "lsl", ".w\t$Rd, $Rm, $imm", []>, 3010 RegConstraint<"$false = $Rd">; 3011def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$Rd), 3012 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm), 3013 IIC_iCMOVsi, "lsr", ".w\t$Rd, $Rm, $imm", []>, 3014 RegConstraint<"$false = $Rd">; 3015def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$Rd), 3016 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm), 3017 IIC_iCMOVsi, "asr", ".w\t$Rd, $Rm, $imm", []>, 3018 RegConstraint<"$false = $Rd">; 3019def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$Rd), 3020 (ins rGPR:$false, rGPR:$Rm, i32imm:$imm), 3021 IIC_iCMOVsi, "ror", ".w\t$Rd, $Rm, $imm", []>, 3022 RegConstraint<"$false = $Rd">; 3023} // isCodeGenOnly = 1 3024 3025multiclass T2I_bincc_irs<Instruction iri, Instruction irr, Instruction irs, 3026 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis> { 3027 // shifted imm 3028 def ri : t2PseudoExpand<(outs rGPR:$Rd), 3029 (ins rGPR:$Rfalse, rGPR:$Rn, t2_so_imm:$imm, 3030 pred:$p, cc_out:$s), 3031 4, iii, [], 3032 (iri rGPR:$Rd, rGPR:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>, 3033 RegConstraint<"$Rfalse = $Rd">; 3034 // register 3035 def rr : t2PseudoExpand<(outs rGPR:$Rd), 3036 (ins rGPR:$Rfalse, rGPR:$Rn, rGPR:$Rm, 3037 pred:$p, cc_out:$s), 3038 4, iir, [], 3039 (irr rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>, 3040 RegConstraint<"$Rfalse = $Rd">; 3041 // shifted register 3042 def rs : t2PseudoExpand<(outs rGPR:$Rd), 3043 (ins rGPR:$Rfalse, rGPR:$Rn, t2_so_reg:$ShiftedRm, 3044 pred:$p, cc_out:$s), 3045 4, iis, [], 3046 (irs rGPR:$Rd, rGPR:$Rn, t2_so_reg:$ShiftedRm, pred:$p, cc_out:$s)>, 3047 RegConstraint<"$Rfalse = $Rd">; 3048} // T2I_bincc_irs 3049 3050defm t2ANDCC : T2I_bincc_irs<t2ANDri, t2ANDrr, t2ANDrs, 3051 IIC_iBITi, IIC_iBITr, IIC_iBITsi>; 3052defm t2ORRCC : T2I_bincc_irs<t2ORRri, t2ORRrr, t2ORRrs, 3053 IIC_iBITi, IIC_iBITr, IIC_iBITsi>; 3054defm t2EORCC : T2I_bincc_irs<t2EORri, t2EORrr, t2EORrs, 3055 IIC_iBITi, IIC_iBITr, IIC_iBITsi>; 3056} // neverHasSideEffects 3057 3058//===----------------------------------------------------------------------===// 3059// Atomic operations intrinsics 3060// 3061 3062// memory barriers protect the atomic sequences 3063let hasSideEffects = 1 in { 3064def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary, 3065 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>, 3066 Requires<[IsThumb, HasDB]> { 3067 bits<4> opt; 3068 let Inst{31-4} = 0xf3bf8f5; 3069 let Inst{3-0} = opt; 3070} 3071} 3072 3073def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary, 3074 "dsb", "\t$opt", []>, 3075 Requires<[IsThumb, HasDB]> { 3076 bits<4> opt; 3077 let Inst{31-4} = 0xf3bf8f4; 3078 let Inst{3-0} = opt; 3079} 3080 3081def t2ISB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary, 3082 "isb", "\t$opt", 3083 []>, Requires<[IsThumb, HasDB]> { 3084 bits<4> opt; 3085 let Inst{31-4} = 0xf3bf8f6; 3086 let Inst{3-0} = opt; 3087} 3088 3089class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, int sz, 3090 InstrItinClass itin, string opc, string asm, string cstr, 3091 list<dag> pattern, bits<4> rt2 = 0b1111> 3092 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> { 3093 let Inst{31-27} = 0b11101; 3094 let Inst{26-20} = 0b0001101; 3095 let Inst{11-8} = rt2; 3096 let Inst{7-6} = 0b01; 3097 let Inst{5-4} = opcod; 3098 let Inst{3-0} = 0b1111; 3099 3100 bits<4> addr; 3101 bits<4> Rt; 3102 let Inst{19-16} = addr; 3103 let Inst{15-12} = Rt; 3104} 3105class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, int sz, 3106 InstrItinClass itin, string opc, string asm, string cstr, 3107 list<dag> pattern, bits<4> rt2 = 0b1111> 3108 : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> { 3109 let Inst{31-27} = 0b11101; 3110 let Inst{26-20} = 0b0001100; 3111 let Inst{11-8} = rt2; 3112 let Inst{7-6} = 0b01; 3113 let Inst{5-4} = opcod; 3114 3115 bits<4> Rd; 3116 bits<4> addr; 3117 bits<4> Rt; 3118 let Inst{3-0} = Rd; 3119 let Inst{19-16} = addr; 3120 let Inst{15-12} = Rt; 3121} 3122 3123let mayLoad = 1 in { 3124def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$Rt), (ins addr_offset_none:$addr), 3125 AddrModeNone, 4, NoItinerary, 3126 "ldrexb", "\t$Rt, $addr", "", []>; 3127def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$Rt), (ins addr_offset_none:$addr), 3128 AddrModeNone, 4, NoItinerary, 3129 "ldrexh", "\t$Rt, $addr", "", []>; 3130def t2LDREX : Thumb2I<(outs rGPR:$Rt), (ins t2addrmode_imm0_1020s4:$addr), 3131 AddrModeNone, 4, NoItinerary, 3132 "ldrex", "\t$Rt, $addr", "", []> { 3133 bits<4> Rt; 3134 bits<12> addr; 3135 let Inst{31-27} = 0b11101; 3136 let Inst{26-20} = 0b0000101; 3137 let Inst{19-16} = addr{11-8}; 3138 let Inst{15-12} = Rt; 3139 let Inst{11-8} = 0b1111; 3140 let Inst{7-0} = addr{7-0}; 3141} 3142let hasExtraDefRegAllocReq = 1 in 3143def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$Rt, rGPR:$Rt2), 3144 (ins addr_offset_none:$addr), 3145 AddrModeNone, 4, NoItinerary, 3146 "ldrexd", "\t$Rt, $Rt2, $addr", "", 3147 [], {?, ?, ?, ?}> { 3148 bits<4> Rt2; 3149 let Inst{11-8} = Rt2; 3150} 3151} 3152 3153let mayStore = 1, Constraints = "@earlyclobber $Rd" in { 3154def t2STREXB : T2I_strex<0b00, (outs rGPR:$Rd), 3155 (ins rGPR:$Rt, addr_offset_none:$addr), 3156 AddrModeNone, 4, NoItinerary, 3157 "strexb", "\t$Rd, $Rt, $addr", "", []>; 3158def t2STREXH : T2I_strex<0b01, (outs rGPR:$Rd), 3159 (ins rGPR:$Rt, addr_offset_none:$addr), 3160 AddrModeNone, 4, NoItinerary, 3161 "strexh", "\t$Rd, $Rt, $addr", "", []>; 3162def t2STREX : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, 3163 t2addrmode_imm0_1020s4:$addr), 3164 AddrModeNone, 4, NoItinerary, 3165 "strex", "\t$Rd, $Rt, $addr", "", 3166 []> { 3167 bits<4> Rd; 3168 bits<4> Rt; 3169 bits<12> addr; 3170 let Inst{31-27} = 0b11101; 3171 let Inst{26-20} = 0b0000100; 3172 let Inst{19-16} = addr{11-8}; 3173 let Inst{15-12} = Rt; 3174 let Inst{11-8} = Rd; 3175 let Inst{7-0} = addr{7-0}; 3176} 3177let hasExtraSrcRegAllocReq = 1 in 3178def t2STREXD : T2I_strex<0b11, (outs rGPR:$Rd), 3179 (ins rGPR:$Rt, rGPR:$Rt2, addr_offset_none:$addr), 3180 AddrModeNone, 4, NoItinerary, 3181 "strexd", "\t$Rd, $Rt, $Rt2, $addr", "", [], 3182 {?, ?, ?, ?}> { 3183 bits<4> Rt2; 3184 let Inst{11-8} = Rt2; 3185} 3186} 3187 3188def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "", []>, 3189 Requires<[IsThumb2, HasV7]> { 3190 let Inst{31-16} = 0xf3bf; 3191 let Inst{15-14} = 0b10; 3192 let Inst{13} = 0; 3193 let Inst{12} = 0; 3194 let Inst{11-8} = 0b1111; 3195 let Inst{7-4} = 0b0010; 3196 let Inst{3-0} = 0b1111; 3197} 3198 3199//===----------------------------------------------------------------------===// 3200// SJLJ Exception handling intrinsics 3201// eh_sjlj_setjmp() is an instruction sequence to store the return 3202// address and save #0 in R0 for the non-longjmp case. 3203// Since by its nature we may be coming from some other function to get 3204// here, and we're using the stack frame for the containing function to 3205// save/restore registers, we can't keep anything live in regs across 3206// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 3207// when we get here from a longjmp(). We force everything out of registers 3208// except for our own input by listing the relevant registers in Defs. By 3209// doing so, we also cause the prologue/epilogue code to actively preserve 3210// all of the callee-saved resgisters, which is exactly what we want. 3211// $val is a scratch register for our use. 3212let Defs = 3213 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR, 3214 Q0, Q1, Q2, Q3, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15], 3215 hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, 3216 usesCustomInserter = 1 in { 3217 def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val), 3218 AddrModeNone, 0, NoItinerary, "", "", 3219 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>, 3220 Requires<[IsThumb2, HasVFP2]>; 3221} 3222 3223let Defs = 3224 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ], 3225 hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, 3226 usesCustomInserter = 1 in { 3227 def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val), 3228 AddrModeNone, 0, NoItinerary, "", "", 3229 [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>, 3230 Requires<[IsThumb2, NoVFP]>; 3231} 3232 3233 3234//===----------------------------------------------------------------------===// 3235// Control-Flow Instructions 3236// 3237 3238// FIXME: remove when we have a way to marking a MI with these properties. 3239// FIXME: Should pc be an implicit operand like PICADD, etc? 3240let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 3241 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in 3242def t2LDMIA_RET: t2PseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, 3243 reglist:$regs, variable_ops), 3244 4, IIC_iLoad_mBr, [], 3245 (t2LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>, 3246 RegConstraint<"$Rn = $wb">; 3247 3248let isBranch = 1, isTerminator = 1, isBarrier = 1 in { 3249let isPredicable = 1 in 3250def t2B : T2I<(outs), (ins uncondbrtarget:$target), IIC_Br, 3251 "b", ".w\t$target", 3252 [(br bb:$target)]> { 3253 let Inst{31-27} = 0b11110; 3254 let Inst{15-14} = 0b10; 3255 let Inst{12} = 1; 3256 3257 bits<20> target; 3258 let Inst{26} = target{19}; 3259 let Inst{11} = target{18}; 3260 let Inst{13} = target{17}; 3261 let Inst{21-16} = target{16-11}; 3262 let Inst{10-0} = target{10-0}; 3263 let DecoderMethod = "DecodeT2BInstruction"; 3264} 3265 3266let isNotDuplicable = 1, isIndirectBranch = 1 in { 3267def t2BR_JT : t2PseudoInst<(outs), 3268 (ins GPR:$target, GPR:$index, i32imm:$jt, i32imm:$id), 3269 0, IIC_Br, 3270 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>; 3271 3272// FIXME: Add a non-pc based case that can be predicated. 3273def t2TBB_JT : t2PseudoInst<(outs), 3274 (ins GPR:$index, i32imm:$jt, i32imm:$id), 0, IIC_Br, []>; 3275 3276def t2TBH_JT : t2PseudoInst<(outs), 3277 (ins GPR:$index, i32imm:$jt, i32imm:$id), 0, IIC_Br, []>; 3278 3279def t2TBB : T2I<(outs), (ins addrmode_tbb:$addr), IIC_Br, 3280 "tbb", "\t$addr", []> { 3281 bits<4> Rn; 3282 bits<4> Rm; 3283 let Inst{31-20} = 0b111010001101; 3284 let Inst{19-16} = Rn; 3285 let Inst{15-5} = 0b11110000000; 3286 let Inst{4} = 0; // B form 3287 let Inst{3-0} = Rm; 3288 3289 let DecoderMethod = "DecodeThumbTableBranch"; 3290} 3291 3292def t2TBH : T2I<(outs), (ins addrmode_tbh:$addr), IIC_Br, 3293 "tbh", "\t$addr", []> { 3294 bits<4> Rn; 3295 bits<4> Rm; 3296 let Inst{31-20} = 0b111010001101; 3297 let Inst{19-16} = Rn; 3298 let Inst{15-5} = 0b11110000000; 3299 let Inst{4} = 1; // H form 3300 let Inst{3-0} = Rm; 3301 3302 let DecoderMethod = "DecodeThumbTableBranch"; 3303} 3304} // isNotDuplicable, isIndirectBranch 3305 3306} // isBranch, isTerminator, isBarrier 3307 3308// FIXME: should be able to write a pattern for ARMBrcond, but can't use 3309// a two-value operand where a dag node expects ", "two operands. :( 3310let isBranch = 1, isTerminator = 1 in 3311def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br, 3312 "b", ".w\t$target", 3313 [/*(ARMbrcond bb:$target, imm:$cc)*/]> { 3314 let Inst{31-27} = 0b11110; 3315 let Inst{15-14} = 0b10; 3316 let Inst{12} = 0; 3317 3318 bits<4> p; 3319 let Inst{25-22} = p; 3320 3321 bits<21> target; 3322 let Inst{26} = target{20}; 3323 let Inst{11} = target{19}; 3324 let Inst{13} = target{18}; 3325 let Inst{21-16} = target{17-12}; 3326 let Inst{10-0} = target{11-1}; 3327 3328 let DecoderMethod = "DecodeThumb2BCCInstruction"; 3329} 3330 3331// Tail calls. The IOS version of thumb tail calls uses a t2 branch, so 3332// it goes here. 3333let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { 3334 // IOS version. 3335 let Uses = [SP] in 3336 def tTAILJMPd: tPseudoExpand<(outs), 3337 (ins uncondbrtarget:$dst, pred:$p), 3338 4, IIC_Br, [], 3339 (t2B uncondbrtarget:$dst, pred:$p)>, 3340 Requires<[IsThumb2, IsIOS]>; 3341} 3342 3343let isCall = 1, Defs = [LR], Uses = [SP] in { 3344 // mov lr, pc; b if callee is marked noreturn to avoid confusing the 3345 // return stack predictor. 3346 def t2BMOVPCB_CALL : tPseudoInst<(outs), 3347 (ins t_bltarget:$func), 3348 6, IIC_Br, [(ARMcall_nolink tglobaladdr:$func)]>, 3349 Requires<[IsThumb]>; 3350} 3351 3352// Direct calls 3353def : T2Pat<(ARMcall_nolink texternalsym:$func), 3354 (t2BMOVPCB_CALL texternalsym:$func)>, 3355 Requires<[IsThumb]>; 3356 3357// IT block 3358let Defs = [ITSTATE] in 3359def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask), 3360 AddrModeNone, 2, IIC_iALUx, 3361 "it$mask\t$cc", "", []> { 3362 // 16-bit instruction. 3363 let Inst{31-16} = 0x0000; 3364 let Inst{15-8} = 0b10111111; 3365 3366 bits<4> cc; 3367 bits<4> mask; 3368 let Inst{7-4} = cc; 3369 let Inst{3-0} = mask; 3370 3371 let DecoderMethod = "DecodeIT"; 3372} 3373 3374// Branch and Exchange Jazelle -- for disassembly only 3375// Rm = Inst{19-16} 3376def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func", []> { 3377 bits<4> func; 3378 let Inst{31-27} = 0b11110; 3379 let Inst{26} = 0; 3380 let Inst{25-20} = 0b111100; 3381 let Inst{19-16} = func; 3382 let Inst{15-0} = 0b1000111100000000; 3383} 3384 3385// Compare and branch on zero / non-zero 3386let isBranch = 1, isTerminator = 1 in { 3387 def tCBZ : T1I<(outs), (ins tGPR:$Rn, t_cbtarget:$target), IIC_Br, 3388 "cbz\t$Rn, $target", []>, 3389 T1Misc<{0,0,?,1,?,?,?}>, 3390 Requires<[IsThumb2]> { 3391 // A8.6.27 3392 bits<6> target; 3393 bits<3> Rn; 3394 let Inst{9} = target{5}; 3395 let Inst{7-3} = target{4-0}; 3396 let Inst{2-0} = Rn; 3397 } 3398 3399 def tCBNZ : T1I<(outs), (ins tGPR:$Rn, t_cbtarget:$target), IIC_Br, 3400 "cbnz\t$Rn, $target", []>, 3401 T1Misc<{1,0,?,1,?,?,?}>, 3402 Requires<[IsThumb2]> { 3403 // A8.6.27 3404 bits<6> target; 3405 bits<3> Rn; 3406 let Inst{9} = target{5}; 3407 let Inst{7-3} = target{4-0}; 3408 let Inst{2-0} = Rn; 3409 } 3410} 3411 3412 3413// Change Processor State is a system instruction. 3414// FIXME: Since the asm parser has currently no clean way to handle optional 3415// operands, create 3 versions of the same instruction. Once there's a clean 3416// framework to represent optional operands, change this behavior. 3417class t2CPS<dag iops, string asm_op> : T2XI<(outs), iops, NoItinerary, 3418 !strconcat("cps", asm_op), []> { 3419 bits<2> imod; 3420 bits<3> iflags; 3421 bits<5> mode; 3422 bit M; 3423 3424 let Inst{31-27} = 0b11110; 3425 let Inst{26} = 0; 3426 let Inst{25-20} = 0b111010; 3427 let Inst{19-16} = 0b1111; 3428 let Inst{15-14} = 0b10; 3429 let Inst{12} = 0; 3430 let Inst{10-9} = imod; 3431 let Inst{8} = M; 3432 let Inst{7-5} = iflags; 3433 let Inst{4-0} = mode; 3434 let DecoderMethod = "DecodeT2CPSInstruction"; 3435} 3436 3437let M = 1 in 3438 def t2CPS3p : t2CPS<(ins imod_op:$imod, iflags_op:$iflags, i32imm:$mode), 3439 "$imod.w\t$iflags, $mode">; 3440let mode = 0, M = 0 in 3441 def t2CPS2p : t2CPS<(ins imod_op:$imod, iflags_op:$iflags), 3442 "$imod.w\t$iflags">; 3443let imod = 0, iflags = 0, M = 1 in 3444 def t2CPS1p : t2CPS<(ins imm0_31:$mode), "\t$mode">; 3445 3446// A6.3.4 Branches and miscellaneous control 3447// Table A6-14 Change Processor State, and hint instructions 3448def t2HINT : T2I<(outs), (ins imm0_255:$imm), NoItinerary, "hint", "\t$imm",[]>{ 3449 bits<8> imm; 3450 let Inst{31-8} = 0b111100111010111110000000; 3451 let Inst{7-0} = imm; 3452} 3453 3454def : t2InstAlias<"hint$p.w $imm", (t2HINT imm0_255:$imm, pred:$p)>; 3455def : t2InstAlias<"nop$p.w", (t2HINT 0, pred:$p)>; 3456def : t2InstAlias<"yield$p.w", (t2HINT 1, pred:$p)>; 3457def : t2InstAlias<"wfe$p.w", (t2HINT 2, pred:$p)>; 3458def : t2InstAlias<"wfi$p.w", (t2HINT 3, pred:$p)>; 3459def : t2InstAlias<"sev$p.w", (t2HINT 4, pred:$p)>; 3460 3461def t2DBG : T2I<(outs), (ins imm0_15:$opt), NoItinerary, "dbg", "\t$opt", []> { 3462 bits<4> opt; 3463 let Inst{31-20} = 0b111100111010; 3464 let Inst{19-16} = 0b1111; 3465 let Inst{15-8} = 0b10000000; 3466 let Inst{7-4} = 0b1111; 3467 let Inst{3-0} = opt; 3468} 3469 3470// Secure Monitor Call is a system instruction. 3471// Option = Inst{19-16} 3472def t2SMC : T2I<(outs), (ins imm0_15:$opt), NoItinerary, "smc", "\t$opt", []> { 3473 let Inst{31-27} = 0b11110; 3474 let Inst{26-20} = 0b1111111; 3475 let Inst{15-12} = 0b1000; 3476 3477 bits<4> opt; 3478 let Inst{19-16} = opt; 3479} 3480 3481class T2SRS<bits<2> Op, bit W, dag oops, dag iops, InstrItinClass itin, 3482 string opc, string asm, list<dag> pattern> 3483 : T2I<oops, iops, itin, opc, asm, pattern> { 3484 bits<5> mode; 3485 let Inst{31-25} = 0b1110100; 3486 let Inst{24-23} = Op; 3487 let Inst{22} = 0; 3488 let Inst{21} = W; 3489 let Inst{20-16} = 0b01101; 3490 let Inst{15-5} = 0b11000000000; 3491 let Inst{4-0} = mode{4-0}; 3492} 3493 3494// Store Return State is a system instruction. 3495def t2SRSDB_UPD : T2SRS<0b00, 1, (outs), (ins imm0_31:$mode), NoItinerary, 3496 "srsdb", "\tsp!, $mode", []>; 3497def t2SRSDB : T2SRS<0b00, 0, (outs), (ins imm0_31:$mode), NoItinerary, 3498 "srsdb","\tsp, $mode", []>; 3499def t2SRSIA_UPD : T2SRS<0b11, 1, (outs), (ins imm0_31:$mode), NoItinerary, 3500 "srsia","\tsp!, $mode", []>; 3501def t2SRSIA : T2SRS<0b11, 0, (outs), (ins imm0_31:$mode), NoItinerary, 3502 "srsia","\tsp, $mode", []>; 3503 3504// Return From Exception is a system instruction. 3505class T2RFE<bits<12> op31_20, dag oops, dag iops, InstrItinClass itin, 3506 string opc, string asm, list<dag> pattern> 3507 : T2I<oops, iops, itin, opc, asm, pattern> { 3508 let Inst{31-20} = op31_20{11-0}; 3509 3510 bits<4> Rn; 3511 let Inst{19-16} = Rn; 3512 let Inst{15-0} = 0xc000; 3513} 3514 3515def t2RFEDBW : T2RFE<0b111010000011, 3516 (outs), (ins GPR:$Rn), NoItinerary, "rfedb", "\t$Rn!", 3517 [/* For disassembly only; pattern left blank */]>; 3518def t2RFEDB : T2RFE<0b111010000001, 3519 (outs), (ins GPR:$Rn), NoItinerary, "rfedb", "\t$Rn", 3520 [/* For disassembly only; pattern left blank */]>; 3521def t2RFEIAW : T2RFE<0b111010011011, 3522 (outs), (ins GPR:$Rn), NoItinerary, "rfeia", "\t$Rn!", 3523 [/* For disassembly only; pattern left blank */]>; 3524def t2RFEIA : T2RFE<0b111010011001, 3525 (outs), (ins GPR:$Rn), NoItinerary, "rfeia", "\t$Rn", 3526 [/* For disassembly only; pattern left blank */]>; 3527 3528//===----------------------------------------------------------------------===// 3529// Non-Instruction Patterns 3530// 3531 3532// 32-bit immediate using movw + movt. 3533// This is a single pseudo instruction to make it re-materializable. 3534// FIXME: Remove this when we can do generalized remat. 3535let isReMaterializable = 1, isMoveImm = 1 in 3536def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2, 3537 [(set rGPR:$dst, (i32 imm:$src))]>, 3538 Requires<[IsThumb, HasV6T2]>; 3539 3540// Pseudo instruction that combines movw + movt + add pc (if pic). 3541// It also makes it possible to rematerialize the instructions. 3542// FIXME: Remove this when we can do generalized remat and when machine licm 3543// can properly the instructions. 3544let isReMaterializable = 1 in { 3545def t2MOV_ga_pcrel : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr), 3546 IIC_iMOVix2addpc, 3547 [(set rGPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>, 3548 Requires<[IsThumb2, UseMovt]>; 3549 3550def t2MOV_ga_dyn : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr), 3551 IIC_iMOVix2, 3552 [(set rGPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>, 3553 Requires<[IsThumb2, UseMovt]>; 3554} 3555 3556// ConstantPool, GlobalAddress, and JumpTable 3557def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>, 3558 Requires<[IsThumb2, DontUseMovt]>; 3559def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>; 3560def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>, 3561 Requires<[IsThumb2, UseMovt]>; 3562 3563def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), 3564 (t2LEApcrelJT tjumptable:$dst, imm:$id)>; 3565 3566// Pseudo instruction that combines ldr from constpool and add pc. This should 3567// be expanded into two instructions late to allow if-conversion and 3568// scheduling. 3569let canFoldAsLoad = 1, isReMaterializable = 1 in 3570def t2LDRpci_pic : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr, pclabel:$cp), 3571 IIC_iLoadiALU, 3572 [(set rGPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)), 3573 imm:$cp))]>, 3574 Requires<[IsThumb2]>; 3575 3576// Pseudo isntruction that combines movs + predicated rsbmi 3577// to implement integer ABS 3578let usesCustomInserter = 1, Defs = [CPSR] in { 3579def t2ABS : PseudoInst<(outs rGPR:$dst), (ins rGPR:$src), 3580 NoItinerary, []>, Requires<[IsThumb2]>; 3581} 3582 3583//===----------------------------------------------------------------------===// 3584// Coprocessor load/store -- for disassembly only 3585// 3586class T2CI<bits<4> op31_28, dag oops, dag iops, string opc, string asm> 3587 : T2I<oops, iops, NoItinerary, opc, asm, []> { 3588 let Inst{31-28} = op31_28; 3589 let Inst{27-25} = 0b110; 3590} 3591 3592multiclass t2LdStCop<bits<4> op31_28, bit load, bit Dbit, string asm> { 3593 def _OFFSET : T2CI<op31_28, 3594 (outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), 3595 asm, "\t$cop, $CRd, $addr"> { 3596 bits<13> addr; 3597 bits<4> cop; 3598 bits<4> CRd; 3599 let Inst{24} = 1; // P = 1 3600 let Inst{23} = addr{8}; 3601 let Inst{22} = Dbit; 3602 let Inst{21} = 0; // W = 0 3603 let Inst{20} = load; 3604 let Inst{19-16} = addr{12-9}; 3605 let Inst{15-12} = CRd; 3606 let Inst{11-8} = cop; 3607 let Inst{7-0} = addr{7-0}; 3608 let DecoderMethod = "DecodeCopMemInstruction"; 3609 } 3610 def _PRE : T2CI<op31_28, 3611 (outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), 3612 asm, "\t$cop, $CRd, $addr!"> { 3613 bits<13> addr; 3614 bits<4> cop; 3615 bits<4> CRd; 3616 let Inst{24} = 1; // P = 1 3617 let Inst{23} = addr{8}; 3618 let Inst{22} = Dbit; 3619 let Inst{21} = 1; // W = 1 3620 let Inst{20} = load; 3621 let Inst{19-16} = addr{12-9}; 3622 let Inst{15-12} = CRd; 3623 let Inst{11-8} = cop; 3624 let Inst{7-0} = addr{7-0}; 3625 let DecoderMethod = "DecodeCopMemInstruction"; 3626 } 3627 def _POST: T2CI<op31_28, 3628 (outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 3629 postidx_imm8s4:$offset), 3630 asm, "\t$cop, $CRd, $addr, $offset"> { 3631 bits<9> offset; 3632 bits<4> addr; 3633 bits<4> cop; 3634 bits<4> CRd; 3635 let Inst{24} = 0; // P = 0 3636 let Inst{23} = offset{8}; 3637 let Inst{22} = Dbit; 3638 let Inst{21} = 1; // W = 1 3639 let Inst{20} = load; 3640 let Inst{19-16} = addr; 3641 let Inst{15-12} = CRd; 3642 let Inst{11-8} = cop; 3643 let Inst{7-0} = offset{7-0}; 3644 let DecoderMethod = "DecodeCopMemInstruction"; 3645 } 3646 def _OPTION : T2CI<op31_28, (outs), 3647 (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 3648 coproc_option_imm:$option), 3649 asm, "\t$cop, $CRd, $addr, $option"> { 3650 bits<8> option; 3651 bits<4> addr; 3652 bits<4> cop; 3653 bits<4> CRd; 3654 let Inst{24} = 0; // P = 0 3655 let Inst{23} = 1; // U = 1 3656 let Inst{22} = Dbit; 3657 let Inst{21} = 0; // W = 0 3658 let Inst{20} = load; 3659 let Inst{19-16} = addr; 3660 let Inst{15-12} = CRd; 3661 let Inst{11-8} = cop; 3662 let Inst{7-0} = option; 3663 let DecoderMethod = "DecodeCopMemInstruction"; 3664 } 3665} 3666 3667defm t2LDC : t2LdStCop<0b1110, 1, 0, "ldc">; 3668defm t2LDCL : t2LdStCop<0b1110, 1, 1, "ldcl">; 3669defm t2STC : t2LdStCop<0b1110, 0, 0, "stc">; 3670defm t2STCL : t2LdStCop<0b1110, 0, 1, "stcl">; 3671defm t2LDC2 : t2LdStCop<0b1111, 1, 0, "ldc2">; 3672defm t2LDC2L : t2LdStCop<0b1111, 1, 1, "ldc2l">; 3673defm t2STC2 : t2LdStCop<0b1111, 0, 0, "stc2">; 3674defm t2STC2L : t2LdStCop<0b1111, 0, 1, "stc2l">; 3675 3676 3677//===----------------------------------------------------------------------===// 3678// Move between special register and ARM core register -- for disassembly only 3679// 3680// Move to ARM core register from Special Register 3681 3682// A/R class MRS. 3683// 3684// A/R class can only move from CPSR or SPSR. 3685def t2MRS_AR : T2I<(outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, apsr", 3686 []>, Requires<[IsThumb2,IsARClass]> { 3687 bits<4> Rd; 3688 let Inst{31-12} = 0b11110011111011111000; 3689 let Inst{11-8} = Rd; 3690 let Inst{7-0} = 0b0000; 3691} 3692 3693def : t2InstAlias<"mrs${p} $Rd, cpsr", (t2MRS_AR GPR:$Rd, pred:$p)>; 3694 3695def t2MRSsys_AR: T2I<(outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, spsr", 3696 []>, Requires<[IsThumb2,IsARClass]> { 3697 bits<4> Rd; 3698 let Inst{31-12} = 0b11110011111111111000; 3699 let Inst{11-8} = Rd; 3700 let Inst{7-0} = 0b0000; 3701} 3702 3703// M class MRS. 3704// 3705// This MRS has a mask field in bits 7-0 and can take more values than 3706// the A/R class (a full msr_mask). 3707def t2MRS_M : T2I<(outs rGPR:$Rd), (ins msr_mask:$mask), NoItinerary, 3708 "mrs", "\t$Rd, $mask", []>, 3709 Requires<[IsThumb,IsMClass]> { 3710 bits<4> Rd; 3711 bits<8> mask; 3712 let Inst{31-12} = 0b11110011111011111000; 3713 let Inst{11-8} = Rd; 3714 let Inst{19-16} = 0b1111; 3715 let Inst{7-0} = mask; 3716} 3717 3718 3719// Move from ARM core register to Special Register 3720// 3721// A/R class MSR. 3722// 3723// No need to have both system and application versions, the encodings are the 3724// same and the assembly parser has no way to distinguish between them. The mask 3725// operand contains the special register (R Bit) in bit 4 and bits 3-0 contains 3726// the mask with the fields to be accessed in the special register. 3727def t2MSR_AR : T2I<(outs), (ins msr_mask:$mask, rGPR:$Rn), 3728 NoItinerary, "msr", "\t$mask, $Rn", []>, 3729 Requires<[IsThumb2,IsARClass]> { 3730 bits<5> mask; 3731 bits<4> Rn; 3732 let Inst{31-21} = 0b11110011100; 3733 let Inst{20} = mask{4}; // R Bit 3734 let Inst{19-16} = Rn; 3735 let Inst{15-12} = 0b1000; 3736 let Inst{11-8} = mask{3-0}; 3737 let Inst{7-0} = 0; 3738} 3739 3740// M class MSR. 3741// 3742// Move from ARM core register to Special Register 3743def t2MSR_M : T2I<(outs), (ins msr_mask:$SYSm, rGPR:$Rn), 3744 NoItinerary, "msr", "\t$SYSm, $Rn", []>, 3745 Requires<[IsThumb,IsMClass]> { 3746 bits<12> SYSm; 3747 bits<4> Rn; 3748 let Inst{31-21} = 0b11110011100; 3749 let Inst{20} = 0b0; 3750 let Inst{19-16} = Rn; 3751 let Inst{15-12} = 0b1000; 3752 let Inst{11-0} = SYSm; 3753} 3754 3755 3756//===----------------------------------------------------------------------===// 3757// Move between coprocessor and ARM core register 3758// 3759 3760class t2MovRCopro<bits<4> Op, string opc, bit direction, dag oops, dag iops, 3761 list<dag> pattern> 3762 : T2Cop<Op, oops, iops, 3763 !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"), 3764 pattern> { 3765 let Inst{27-24} = 0b1110; 3766 let Inst{20} = direction; 3767 let Inst{4} = 1; 3768 3769 bits<4> Rt; 3770 bits<4> cop; 3771 bits<3> opc1; 3772 bits<3> opc2; 3773 bits<4> CRm; 3774 bits<4> CRn; 3775 3776 let Inst{15-12} = Rt; 3777 let Inst{11-8} = cop; 3778 let Inst{23-21} = opc1; 3779 let Inst{7-5} = opc2; 3780 let Inst{3-0} = CRm; 3781 let Inst{19-16} = CRn; 3782} 3783 3784class t2MovRRCopro<bits<4> Op, string opc, bit direction, 3785 list<dag> pattern = []> 3786 : T2Cop<Op, (outs), 3787 (ins p_imm:$cop, imm0_15:$opc1, GPR:$Rt, GPR:$Rt2, c_imm:$CRm), 3788 !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"), pattern> { 3789 let Inst{27-24} = 0b1100; 3790 let Inst{23-21} = 0b010; 3791 let Inst{20} = direction; 3792 3793 bits<4> Rt; 3794 bits<4> Rt2; 3795 bits<4> cop; 3796 bits<4> opc1; 3797 bits<4> CRm; 3798 3799 let Inst{15-12} = Rt; 3800 let Inst{19-16} = Rt2; 3801 let Inst{11-8} = cop; 3802 let Inst{7-4} = opc1; 3803 let Inst{3-0} = CRm; 3804} 3805 3806/* from ARM core register to coprocessor */ 3807def t2MCR : t2MovRCopro<0b1110, "mcr", 0, 3808 (outs), 3809 (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 3810 c_imm:$CRm, imm0_7:$opc2), 3811 [(int_arm_mcr imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn, 3812 imm:$CRm, imm:$opc2)]>; 3813def : t2InstAlias<"mcr $cop, $opc1, $Rt, $CRn, $CRm", 3814 (t2MCR p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 3815 c_imm:$CRm, 0)>; 3816def t2MCR2 : t2MovRCopro<0b1111, "mcr2", 0, 3817 (outs), (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 3818 c_imm:$CRm, imm0_7:$opc2), 3819 [(int_arm_mcr2 imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn, 3820 imm:$CRm, imm:$opc2)]>; 3821def : t2InstAlias<"mcr2 $cop, $opc1, $Rt, $CRn, $CRm", 3822 (t2MCR2 p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 3823 c_imm:$CRm, 0)>; 3824 3825/* from coprocessor to ARM core register */ 3826def t2MRC : t2MovRCopro<0b1110, "mrc", 1, 3827 (outs GPR:$Rt), (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 3828 c_imm:$CRm, imm0_7:$opc2), []>; 3829def : t2InstAlias<"mrc $cop, $opc1, $Rt, $CRn, $CRm", 3830 (t2MRC GPR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 3831 c_imm:$CRm, 0)>; 3832 3833def t2MRC2 : t2MovRCopro<0b1111, "mrc2", 1, 3834 (outs GPR:$Rt), (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 3835 c_imm:$CRm, imm0_7:$opc2), []>; 3836def : t2InstAlias<"mrc2 $cop, $opc1, $Rt, $CRn, $CRm", 3837 (t2MRC2 GPR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 3838 c_imm:$CRm, 0)>; 3839 3840def : T2v6Pat<(int_arm_mrc imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2), 3841 (t2MRC imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>; 3842 3843def : T2v6Pat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2), 3844 (t2MRC2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>; 3845 3846 3847/* from ARM core register to coprocessor */ 3848def t2MCRR : t2MovRRCopro<0b1110, "mcrr", 0, 3849 [(int_arm_mcrr imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, 3850 imm:$CRm)]>; 3851def t2MCRR2 : t2MovRRCopro<0b1111, "mcrr2", 0, 3852 [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPR:$Rt, 3853 GPR:$Rt2, imm:$CRm)]>; 3854/* from coprocessor to ARM core register */ 3855def t2MRRC : t2MovRRCopro<0b1110, "mrrc", 1>; 3856 3857def t2MRRC2 : t2MovRRCopro<0b1111, "mrrc2", 1>; 3858 3859//===----------------------------------------------------------------------===// 3860// Other Coprocessor Instructions. 3861// 3862 3863def tCDP : T2Cop<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, 3864 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2), 3865 "cdp\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", 3866 [(int_arm_cdp imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn, 3867 imm:$CRm, imm:$opc2)]> { 3868 let Inst{27-24} = 0b1110; 3869 3870 bits<4> opc1; 3871 bits<4> CRn; 3872 bits<4> CRd; 3873 bits<4> cop; 3874 bits<3> opc2; 3875 bits<4> CRm; 3876 3877 let Inst{3-0} = CRm; 3878 let Inst{4} = 0; 3879 let Inst{7-5} = opc2; 3880 let Inst{11-8} = cop; 3881 let Inst{15-12} = CRd; 3882 let Inst{19-16} = CRn; 3883 let Inst{23-20} = opc1; 3884} 3885 3886def t2CDP2 : T2Cop<0b1111, (outs), (ins p_imm:$cop, imm0_15:$opc1, 3887 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2), 3888 "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", 3889 [(int_arm_cdp2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn, 3890 imm:$CRm, imm:$opc2)]> { 3891 let Inst{27-24} = 0b1110; 3892 3893 bits<4> opc1; 3894 bits<4> CRn; 3895 bits<4> CRd; 3896 bits<4> cop; 3897 bits<3> opc2; 3898 bits<4> CRm; 3899 3900 let Inst{3-0} = CRm; 3901 let Inst{4} = 0; 3902 let Inst{7-5} = opc2; 3903 let Inst{11-8} = cop; 3904 let Inst{15-12} = CRd; 3905 let Inst{19-16} = CRn; 3906 let Inst{23-20} = opc1; 3907} 3908 3909 3910 3911//===----------------------------------------------------------------------===// 3912// Non-Instruction Patterns 3913// 3914 3915// SXT/UXT with no rotate 3916let AddedComplexity = 16 in { 3917def : T2Pat<(and rGPR:$Rm, 0x000000FF), (t2UXTB rGPR:$Rm, 0)>, 3918 Requires<[IsThumb2]>; 3919def : T2Pat<(and rGPR:$Rm, 0x0000FFFF), (t2UXTH rGPR:$Rm, 0)>, 3920 Requires<[IsThumb2]>; 3921def : T2Pat<(and rGPR:$Rm, 0x00FF00FF), (t2UXTB16 rGPR:$Rm, 0)>, 3922 Requires<[HasT2ExtractPack, IsThumb2]>; 3923def : T2Pat<(add rGPR:$Rn, (and rGPR:$Rm, 0x00FF)), 3924 (t2UXTAB rGPR:$Rn, rGPR:$Rm, 0)>, 3925 Requires<[HasT2ExtractPack, IsThumb2]>; 3926def : T2Pat<(add rGPR:$Rn, (and rGPR:$Rm, 0xFFFF)), 3927 (t2UXTAH rGPR:$Rn, rGPR:$Rm, 0)>, 3928 Requires<[HasT2ExtractPack, IsThumb2]>; 3929} 3930 3931def : T2Pat<(sext_inreg rGPR:$Src, i8), (t2SXTB rGPR:$Src, 0)>, 3932 Requires<[IsThumb2]>; 3933def : T2Pat<(sext_inreg rGPR:$Src, i16), (t2SXTH rGPR:$Src, 0)>, 3934 Requires<[IsThumb2]>; 3935def : T2Pat<(add rGPR:$Rn, (sext_inreg rGPR:$Rm, i8)), 3936 (t2SXTAB rGPR:$Rn, rGPR:$Rm, 0)>, 3937 Requires<[HasT2ExtractPack, IsThumb2]>; 3938def : T2Pat<(add rGPR:$Rn, (sext_inreg rGPR:$Rm, i16)), 3939 (t2SXTAH rGPR:$Rn, rGPR:$Rm, 0)>, 3940 Requires<[HasT2ExtractPack, IsThumb2]>; 3941 3942// Atomic load/store patterns 3943def : T2Pat<(atomic_load_8 t2addrmode_imm12:$addr), 3944 (t2LDRBi12 t2addrmode_imm12:$addr)>; 3945def : T2Pat<(atomic_load_8 t2addrmode_negimm8:$addr), 3946 (t2LDRBi8 t2addrmode_negimm8:$addr)>; 3947def : T2Pat<(atomic_load_8 t2addrmode_so_reg:$addr), 3948 (t2LDRBs t2addrmode_so_reg:$addr)>; 3949def : T2Pat<(atomic_load_16 t2addrmode_imm12:$addr), 3950 (t2LDRHi12 t2addrmode_imm12:$addr)>; 3951def : T2Pat<(atomic_load_16 t2addrmode_negimm8:$addr), 3952 (t2LDRHi8 t2addrmode_negimm8:$addr)>; 3953def : T2Pat<(atomic_load_16 t2addrmode_so_reg:$addr), 3954 (t2LDRHs t2addrmode_so_reg:$addr)>; 3955def : T2Pat<(atomic_load_32 t2addrmode_imm12:$addr), 3956 (t2LDRi12 t2addrmode_imm12:$addr)>; 3957def : T2Pat<(atomic_load_32 t2addrmode_negimm8:$addr), 3958 (t2LDRi8 t2addrmode_negimm8:$addr)>; 3959def : T2Pat<(atomic_load_32 t2addrmode_so_reg:$addr), 3960 (t2LDRs t2addrmode_so_reg:$addr)>; 3961def : T2Pat<(atomic_store_8 t2addrmode_imm12:$addr, GPR:$val), 3962 (t2STRBi12 GPR:$val, t2addrmode_imm12:$addr)>; 3963def : T2Pat<(atomic_store_8 t2addrmode_negimm8:$addr, GPR:$val), 3964 (t2STRBi8 GPR:$val, t2addrmode_negimm8:$addr)>; 3965def : T2Pat<(atomic_store_8 t2addrmode_so_reg:$addr, GPR:$val), 3966 (t2STRBs GPR:$val, t2addrmode_so_reg:$addr)>; 3967def : T2Pat<(atomic_store_16 t2addrmode_imm12:$addr, GPR:$val), 3968 (t2STRHi12 GPR:$val, t2addrmode_imm12:$addr)>; 3969def : T2Pat<(atomic_store_16 t2addrmode_negimm8:$addr, GPR:$val), 3970 (t2STRHi8 GPR:$val, t2addrmode_negimm8:$addr)>; 3971def : T2Pat<(atomic_store_16 t2addrmode_so_reg:$addr, GPR:$val), 3972 (t2STRHs GPR:$val, t2addrmode_so_reg:$addr)>; 3973def : T2Pat<(atomic_store_32 t2addrmode_imm12:$addr, GPR:$val), 3974 (t2STRi12 GPR:$val, t2addrmode_imm12:$addr)>; 3975def : T2Pat<(atomic_store_32 t2addrmode_negimm8:$addr, GPR:$val), 3976 (t2STRi8 GPR:$val, t2addrmode_negimm8:$addr)>; 3977def : T2Pat<(atomic_store_32 t2addrmode_so_reg:$addr, GPR:$val), 3978 (t2STRs GPR:$val, t2addrmode_so_reg:$addr)>; 3979 3980 3981//===----------------------------------------------------------------------===// 3982// Assembler aliases 3983// 3984 3985// Aliases for ADC without the ".w" optional width specifier. 3986def : t2InstAlias<"adc${s}${p} $Rd, $Rn, $Rm", 3987 (t2ADCrr rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>; 3988def : t2InstAlias<"adc${s}${p} $Rd, $Rn, $ShiftedRm", 3989 (t2ADCrs rGPR:$Rd, rGPR:$Rn, t2_so_reg:$ShiftedRm, 3990 pred:$p, cc_out:$s)>; 3991 3992// Aliases for SBC without the ".w" optional width specifier. 3993def : t2InstAlias<"sbc${s}${p} $Rd, $Rn, $Rm", 3994 (t2SBCrr rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>; 3995def : t2InstAlias<"sbc${s}${p} $Rd, $Rn, $ShiftedRm", 3996 (t2SBCrs rGPR:$Rd, rGPR:$Rn, t2_so_reg:$ShiftedRm, 3997 pred:$p, cc_out:$s)>; 3998 3999// Aliases for ADD without the ".w" optional width specifier. 4000def : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm", 4001 (t2ADDri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>; 4002def : t2InstAlias<"add${p} $Rd, $Rn, $imm", 4003 (t2ADDri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>; 4004def : t2InstAlias<"add${s}${p} $Rd, $Rn, $Rm", 4005 (t2ADDrr GPRnopc:$Rd, GPRnopc:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>; 4006def : t2InstAlias<"add${s}${p} $Rd, $Rn, $ShiftedRm", 4007 (t2ADDrs GPRnopc:$Rd, GPRnopc:$Rn, t2_so_reg:$ShiftedRm, 4008 pred:$p, cc_out:$s)>; 4009// ... and with the destination and source register combined. 4010def : t2InstAlias<"add${s}${p} $Rdn, $imm", 4011 (t2ADDri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>; 4012def : t2InstAlias<"add${p} $Rdn, $imm", 4013 (t2ADDri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095:$imm, pred:$p)>; 4014def : t2InstAlias<"add${s}${p} $Rdn, $Rm", 4015 (t2ADDrr GPRnopc:$Rdn, GPRnopc:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>; 4016def : t2InstAlias<"add${s}${p} $Rdn, $ShiftedRm", 4017 (t2ADDrs GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_reg:$ShiftedRm, 4018 pred:$p, cc_out:$s)>; 4019 4020// add w/ negative immediates is just a sub. 4021def : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm", 4022 (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p, 4023 cc_out:$s)>; 4024def : t2InstAlias<"add${p} $Rd, $Rn, $imm", 4025 (t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>; 4026def : t2InstAlias<"add${s}${p} $Rdn, $imm", 4027 (t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm_neg:$imm, pred:$p, 4028 cc_out:$s)>; 4029def : t2InstAlias<"add${p} $Rdn, $imm", 4030 (t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095_neg:$imm, pred:$p)>; 4031 4032def : t2InstAlias<"add${s}${p}.w $Rd, $Rn, $imm", 4033 (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p, 4034 cc_out:$s)>; 4035def : t2InstAlias<"addw${p} $Rd, $Rn, $imm", 4036 (t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>; 4037def : t2InstAlias<"add${s}${p}.w $Rdn, $imm", 4038 (t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm_neg:$imm, pred:$p, 4039 cc_out:$s)>; 4040def : t2InstAlias<"addw${p} $Rdn, $imm", 4041 (t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095_neg:$imm, pred:$p)>; 4042 4043 4044// Aliases for SUB without the ".w" optional width specifier. 4045def : t2InstAlias<"sub${s}${p} $Rd, $Rn, $imm", 4046 (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>; 4047def : t2InstAlias<"sub${p} $Rd, $Rn, $imm", 4048 (t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>; 4049def : t2InstAlias<"sub${s}${p} $Rd, $Rn, $Rm", 4050 (t2SUBrr GPRnopc:$Rd, GPRnopc:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>; 4051def : t2InstAlias<"sub${s}${p} $Rd, $Rn, $ShiftedRm", 4052 (t2SUBrs GPRnopc:$Rd, GPRnopc:$Rn, t2_so_reg:$ShiftedRm, 4053 pred:$p, cc_out:$s)>; 4054// ... and with the destination and source register combined. 4055def : t2InstAlias<"sub${s}${p} $Rdn, $imm", 4056 (t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>; 4057def : t2InstAlias<"sub${p} $Rdn, $imm", 4058 (t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095:$imm, pred:$p)>; 4059def : t2InstAlias<"sub${s}${p}.w $Rdn, $Rm", 4060 (t2SUBrr GPRnopc:$Rdn, GPRnopc:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>; 4061def : t2InstAlias<"sub${s}${p} $Rdn, $Rm", 4062 (t2SUBrr GPRnopc:$Rdn, GPRnopc:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>; 4063def : t2InstAlias<"sub${s}${p} $Rdn, $ShiftedRm", 4064 (t2SUBrs GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_reg:$ShiftedRm, 4065 pred:$p, cc_out:$s)>; 4066 4067// Alias for compares without the ".w" optional width specifier. 4068def : t2InstAlias<"cmn${p} $Rn, $Rm", 4069 (t2CMNzrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>; 4070def : t2InstAlias<"teq${p} $Rn, $Rm", 4071 (t2TEQrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>; 4072def : t2InstAlias<"tst${p} $Rn, $Rm", 4073 (t2TSTrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>; 4074 4075// Memory barriers 4076def : InstAlias<"dmb", (t2DMB 0xf)>, Requires<[IsThumb, HasDB]>; 4077def : InstAlias<"dsb", (t2DSB 0xf)>, Requires<[IsThumb, HasDB]>; 4078def : InstAlias<"isb", (t2ISB 0xf)>, Requires<[IsThumb, HasDB]>; 4079 4080// Alias for LDR, LDRB, LDRH, LDRSB, and LDRSH without the ".w" optional 4081// width specifier. 4082def : t2InstAlias<"ldr${p} $Rt, $addr", 4083 (t2LDRi12 GPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4084def : t2InstAlias<"ldrb${p} $Rt, $addr", 4085 (t2LDRBi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4086def : t2InstAlias<"ldrh${p} $Rt, $addr", 4087 (t2LDRHi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4088def : t2InstAlias<"ldrsb${p} $Rt, $addr", 4089 (t2LDRSBi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4090def : t2InstAlias<"ldrsh${p} $Rt, $addr", 4091 (t2LDRSHi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4092 4093def : t2InstAlias<"ldr${p} $Rt, $addr", 4094 (t2LDRs GPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4095def : t2InstAlias<"ldrb${p} $Rt, $addr", 4096 (t2LDRBs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4097def : t2InstAlias<"ldrh${p} $Rt, $addr", 4098 (t2LDRHs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4099def : t2InstAlias<"ldrsb${p} $Rt, $addr", 4100 (t2LDRSBs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4101def : t2InstAlias<"ldrsh${p} $Rt, $addr", 4102 (t2LDRSHs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4103 4104def : t2InstAlias<"ldr${p} $Rt, $addr", 4105 (t2LDRpci GPR:$Rt, t2ldrlabel:$addr, pred:$p)>; 4106def : t2InstAlias<"ldrb${p} $Rt, $addr", 4107 (t2LDRBpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>; 4108def : t2InstAlias<"ldrh${p} $Rt, $addr", 4109 (t2LDRHpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>; 4110def : t2InstAlias<"ldrsb${p} $Rt, $addr", 4111 (t2LDRSBpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>; 4112def : t2InstAlias<"ldrsh${p} $Rt, $addr", 4113 (t2LDRSHpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>; 4114 4115// Alias for MVN with(out) the ".w" optional width specifier. 4116def : t2InstAlias<"mvn${s}${p}.w $Rd, $imm", 4117 (t2MVNi rGPR:$Rd, t2_so_imm:$imm, pred:$p, cc_out:$s)>; 4118def : t2InstAlias<"mvn${s}${p} $Rd, $Rm", 4119 (t2MVNr rGPR:$Rd, rGPR:$Rm, pred:$p, cc_out:$s)>; 4120def : t2InstAlias<"mvn${s}${p} $Rd, $ShiftedRm", 4121 (t2MVNs rGPR:$Rd, t2_so_reg:$ShiftedRm, pred:$p, cc_out:$s)>; 4122 4123// PKHBT/PKHTB with default shift amount. PKHTB is equivalent to PKHBT when the 4124// shift amount is zero (i.e., unspecified). 4125def : InstAlias<"pkhbt${p} $Rd, $Rn, $Rm", 4126 (t2PKHBT rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>, 4127 Requires<[HasT2ExtractPack, IsThumb2]>; 4128def : InstAlias<"pkhtb${p} $Rd, $Rn, $Rm", 4129 (t2PKHBT rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>, 4130 Requires<[HasT2ExtractPack, IsThumb2]>; 4131 4132// PUSH/POP aliases for STM/LDM 4133def : t2InstAlias<"push${p}.w $regs", (t2STMDB_UPD SP, pred:$p, reglist:$regs)>; 4134def : t2InstAlias<"push${p} $regs", (t2STMDB_UPD SP, pred:$p, reglist:$regs)>; 4135def : t2InstAlias<"pop${p}.w $regs", (t2LDMIA_UPD SP, pred:$p, reglist:$regs)>; 4136def : t2InstAlias<"pop${p} $regs", (t2LDMIA_UPD SP, pred:$p, reglist:$regs)>; 4137 4138// STMIA/STMIA_UPD aliases w/o the optional .w suffix 4139def : t2InstAlias<"stm${p} $Rn, $regs", 4140 (t2STMIA GPR:$Rn, pred:$p, reglist:$regs)>; 4141def : t2InstAlias<"stm${p} $Rn!, $regs", 4142 (t2STMIA_UPD GPR:$Rn, pred:$p, reglist:$regs)>; 4143 4144// LDMIA/LDMIA_UPD aliases w/o the optional .w suffix 4145def : t2InstAlias<"ldm${p} $Rn, $regs", 4146 (t2LDMIA GPR:$Rn, pred:$p, reglist:$regs)>; 4147def : t2InstAlias<"ldm${p} $Rn!, $regs", 4148 (t2LDMIA_UPD GPR:$Rn, pred:$p, reglist:$regs)>; 4149 4150// STMDB/STMDB_UPD aliases w/ the optional .w suffix 4151def : t2InstAlias<"stmdb${p}.w $Rn, $regs", 4152 (t2STMDB GPR:$Rn, pred:$p, reglist:$regs)>; 4153def : t2InstAlias<"stmdb${p}.w $Rn!, $regs", 4154 (t2STMDB_UPD GPR:$Rn, pred:$p, reglist:$regs)>; 4155 4156// LDMDB/LDMDB_UPD aliases w/ the optional .w suffix 4157def : t2InstAlias<"ldmdb${p}.w $Rn, $regs", 4158 (t2LDMDB GPR:$Rn, pred:$p, reglist:$regs)>; 4159def : t2InstAlias<"ldmdb${p}.w $Rn!, $regs", 4160 (t2LDMDB_UPD GPR:$Rn, pred:$p, reglist:$regs)>; 4161 4162// Alias for REV/REV16/REVSH without the ".w" optional width specifier. 4163def : t2InstAlias<"rev${p} $Rd, $Rm", (t2REV rGPR:$Rd, rGPR:$Rm, pred:$p)>; 4164def : t2InstAlias<"rev16${p} $Rd, $Rm", (t2REV16 rGPR:$Rd, rGPR:$Rm, pred:$p)>; 4165def : t2InstAlias<"revsh${p} $Rd, $Rm", (t2REVSH rGPR:$Rd, rGPR:$Rm, pred:$p)>; 4166 4167 4168// Alias for RSB without the ".w" optional width specifier, and with optional 4169// implied destination register. 4170def : t2InstAlias<"rsb${s}${p} $Rd, $Rn, $imm", 4171 (t2RSBri rGPR:$Rd, rGPR:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>; 4172def : t2InstAlias<"rsb${s}${p} $Rdn, $imm", 4173 (t2RSBri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>; 4174def : t2InstAlias<"rsb${s}${p} $Rdn, $Rm", 4175 (t2RSBrr rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>; 4176def : t2InstAlias<"rsb${s}${p} $Rdn, $ShiftedRm", 4177 (t2RSBrs rGPR:$Rdn, rGPR:$Rdn, t2_so_reg:$ShiftedRm, pred:$p, 4178 cc_out:$s)>; 4179 4180// SSAT/USAT optional shift operand. 4181def : t2InstAlias<"ssat${p} $Rd, $sat_imm, $Rn", 4182 (t2SSAT rGPR:$Rd, imm1_32:$sat_imm, rGPR:$Rn, 0, pred:$p)>; 4183def : t2InstAlias<"usat${p} $Rd, $sat_imm, $Rn", 4184 (t2USAT rGPR:$Rd, imm0_31:$sat_imm, rGPR:$Rn, 0, pred:$p)>; 4185 4186// STM w/o the .w suffix. 4187def : t2InstAlias<"stm${p} $Rn, $regs", 4188 (t2STMIA GPR:$Rn, pred:$p, reglist:$regs)>; 4189 4190// Alias for STR, STRB, and STRH without the ".w" optional 4191// width specifier. 4192def : t2InstAlias<"str${p} $Rt, $addr", 4193 (t2STRi12 GPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4194def : t2InstAlias<"strb${p} $Rt, $addr", 4195 (t2STRBi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4196def : t2InstAlias<"strh${p} $Rt, $addr", 4197 (t2STRHi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4198 4199def : t2InstAlias<"str${p} $Rt, $addr", 4200 (t2STRs GPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4201def : t2InstAlias<"strb${p} $Rt, $addr", 4202 (t2STRBs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4203def : t2InstAlias<"strh${p} $Rt, $addr", 4204 (t2STRHs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4205 4206// Extend instruction optional rotate operand. 4207def : t2InstAlias<"sxtab${p} $Rd, $Rn, $Rm", 4208 (t2SXTAB rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>; 4209def : t2InstAlias<"sxtah${p} $Rd, $Rn, $Rm", 4210 (t2SXTAH rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>; 4211def : t2InstAlias<"sxtab16${p} $Rd, $Rn, $Rm", 4212 (t2SXTAB16 rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>; 4213 4214def : t2InstAlias<"sxtb${p} $Rd, $Rm", 4215 (t2SXTB rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4216def : t2InstAlias<"sxtb16${p} $Rd, $Rm", 4217 (t2SXTB16 rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4218def : t2InstAlias<"sxth${p} $Rd, $Rm", 4219 (t2SXTH rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4220def : t2InstAlias<"sxtb${p}.w $Rd, $Rm", 4221 (t2SXTB rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4222def : t2InstAlias<"sxth${p}.w $Rd, $Rm", 4223 (t2SXTH rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4224 4225def : t2InstAlias<"uxtab${p} $Rd, $Rn, $Rm", 4226 (t2UXTAB rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>; 4227def : t2InstAlias<"uxtah${p} $Rd, $Rn, $Rm", 4228 (t2UXTAH rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>; 4229def : t2InstAlias<"uxtab16${p} $Rd, $Rn, $Rm", 4230 (t2UXTAB16 rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>; 4231def : t2InstAlias<"uxtb${p} $Rd, $Rm", 4232 (t2UXTB rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4233def : t2InstAlias<"uxtb16${p} $Rd, $Rm", 4234 (t2UXTB16 rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4235def : t2InstAlias<"uxth${p} $Rd, $Rm", 4236 (t2UXTH rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4237 4238def : t2InstAlias<"uxtb${p}.w $Rd, $Rm", 4239 (t2UXTB rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4240def : t2InstAlias<"uxth${p}.w $Rd, $Rm", 4241 (t2UXTH rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4242 4243// Extend instruction w/o the ".w" optional width specifier. 4244def : t2InstAlias<"uxtb${p} $Rd, $Rm$rot", 4245 (t2UXTB rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>; 4246def : t2InstAlias<"uxtb16${p} $Rd, $Rm$rot", 4247 (t2UXTB16 rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>; 4248def : t2InstAlias<"uxth${p} $Rd, $Rm$rot", 4249 (t2UXTH rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>; 4250 4251def : t2InstAlias<"sxtb${p} $Rd, $Rm$rot", 4252 (t2SXTB rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>; 4253def : t2InstAlias<"sxtb16${p} $Rd, $Rm$rot", 4254 (t2SXTB16 rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>; 4255def : t2InstAlias<"sxth${p} $Rd, $Rm$rot", 4256 (t2SXTH rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>; 4257 4258 4259// "mov Rd, t2_so_imm_not" can be handled via "mvn" in assembly, just like 4260// for isel. 4261def : t2InstAlias<"mov${p} $Rd, $imm", 4262 (t2MVNi rGPR:$Rd, t2_so_imm_not:$imm, pred:$p, zero_reg)>; 4263def : t2InstAlias<"mvn${p} $Rd, $imm", 4264 (t2MOVi rGPR:$Rd, t2_so_imm_not:$imm, pred:$p, zero_reg)>; 4265// Same for AND <--> BIC 4266def : t2InstAlias<"bic${s}${p} $Rd, $Rn, $imm", 4267 (t2ANDri rGPR:$Rd, rGPR:$Rn, so_imm_not:$imm, 4268 pred:$p, cc_out:$s)>; 4269def : t2InstAlias<"bic${s}${p} $Rdn, $imm", 4270 (t2ANDri rGPR:$Rdn, rGPR:$Rdn, so_imm_not:$imm, 4271 pred:$p, cc_out:$s)>; 4272def : t2InstAlias<"and${s}${p} $Rd, $Rn, $imm", 4273 (t2BICri rGPR:$Rd, rGPR:$Rn, so_imm_not:$imm, 4274 pred:$p, cc_out:$s)>; 4275def : t2InstAlias<"and${s}${p} $Rdn, $imm", 4276 (t2BICri rGPR:$Rdn, rGPR:$Rdn, so_imm_not:$imm, 4277 pred:$p, cc_out:$s)>; 4278// Likewise, "add Rd, t2_so_imm_neg" -> sub 4279def : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm", 4280 (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, 4281 pred:$p, cc_out:$s)>; 4282def : t2InstAlias<"add${s}${p} $Rd, $imm", 4283 (t2SUBri GPRnopc:$Rd, GPRnopc:$Rd, t2_so_imm_neg:$imm, 4284 pred:$p, cc_out:$s)>; 4285// Same for CMP <--> CMN via t2_so_imm_neg 4286def : t2InstAlias<"cmp${p} $Rd, $imm", 4287 (t2CMNri rGPR:$Rd, t2_so_imm_neg:$imm, pred:$p)>; 4288def : t2InstAlias<"cmn${p} $Rd, $imm", 4289 (t2CMPri rGPR:$Rd, t2_so_imm_neg:$imm, pred:$p)>; 4290 4291 4292// Wide 'mul' encoding can be specified with only two operands. 4293def : t2InstAlias<"mul${p} $Rn, $Rm", 4294 (t2MUL rGPR:$Rn, rGPR:$Rm, rGPR:$Rn, pred:$p)>; 4295 4296// "neg" is and alias for "rsb rd, rn, #0" 4297def : t2InstAlias<"neg${s}${p} $Rd, $Rm", 4298 (t2RSBri rGPR:$Rd, rGPR:$Rm, 0, pred:$p, cc_out:$s)>; 4299 4300// MOV so_reg assembler pseudos. InstAlias isn't expressive enough for 4301// these, unfortunately. 4302def t2MOVsi: t2AsmPseudo<"mov${p} $Rd, $shift", 4303 (ins rGPR:$Rd, t2_so_reg:$shift, pred:$p)>; 4304def t2MOVSsi: t2AsmPseudo<"movs${p} $Rd, $shift", 4305 (ins rGPR:$Rd, t2_so_reg:$shift, pred:$p)>; 4306 4307def t2MOVsr: t2AsmPseudo<"mov${p} $Rd, $shift", 4308 (ins rGPR:$Rd, so_reg_reg:$shift, pred:$p)>; 4309def t2MOVSsr: t2AsmPseudo<"movs${p} $Rd, $shift", 4310 (ins rGPR:$Rd, so_reg_reg:$shift, pred:$p)>; 4311 4312// ADR w/o the .w suffix 4313def : t2InstAlias<"adr${p} $Rd, $addr", 4314 (t2ADR rGPR:$Rd, t2adrlabel:$addr, pred:$p)>; 4315 4316// LDR(literal) w/ alternate [pc, #imm] syntax. 4317def t2LDRpcrel : t2AsmPseudo<"ldr${p} $Rt, $addr", 4318 (ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4319def t2LDRBpcrel : t2AsmPseudo<"ldrb${p} $Rt, $addr", 4320 (ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4321def t2LDRHpcrel : t2AsmPseudo<"ldrh${p} $Rt, $addr", 4322 (ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4323def t2LDRSBpcrel : t2AsmPseudo<"ldrsb${p} $Rt, $addr", 4324 (ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4325def t2LDRSHpcrel : t2AsmPseudo<"ldrsh${p} $Rt, $addr", 4326 (ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4327 // Version w/ the .w suffix. 4328def : t2InstAlias<"ldr${p}.w $Rt, $addr", 4329 (t2LDRpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4330def : t2InstAlias<"ldrb${p}.w $Rt, $addr", 4331 (t2LDRBpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4332def : t2InstAlias<"ldrh${p}.w $Rt, $addr", 4333 (t2LDRHpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4334def : t2InstAlias<"ldrsb${p}.w $Rt, $addr", 4335 (t2LDRSBpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4336def : t2InstAlias<"ldrsh${p}.w $Rt, $addr", 4337 (t2LDRSHpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4338 4339def : t2InstAlias<"add${p} $Rd, pc, $imm", 4340 (t2ADR rGPR:$Rd, imm0_4095:$imm, pred:$p)>; 4341