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