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