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