ARMInstrThumb2.td revision 2889ccea625942348ea74f51ae2f67d084f44850
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// Shifted operands. No register controlled shifts for Thumb2. 15// Note: We do not support rrx shifted operands yet. 16def t2_so_reg : Operand<i32>, // reg imm 17 ComplexPattern<i32, 2, "SelectT2ShifterOperandReg", 18 [shl,srl,sra,rotr]> { 19 let PrintMethod = "printT2SOOperand"; 20 let MIOperandInfo = (ops GPR, i32imm); 21} 22 23// t2_so_imm_XFORM - Return a t2_so_imm value packed into the format 24// described for t2_so_imm def below. 25def t2_so_imm_XFORM : SDNodeXForm<imm, [{ 26 return CurDAG->getTargetConstant( 27 ARM_AM::getT2SOImmVal(N->getZExtValue()), MVT::i32); 28}]>; 29 30// t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value 31def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{ 32 return CurDAG->getTargetConstant( 33 ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())), MVT::i32); 34}]>; 35 36// t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value 37def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{ 38 return CurDAG->getTargetConstant( 39 ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())), MVT::i32); 40}]>; 41 42// t2_so_imm - Match a 32-bit immediate operand, which is an 43// 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit 44// immediate splatted into multiple bytes of the word. t2_so_imm values are 45// represented in the imm field in the same 12-bit form that they are encoded 46// into t2_so_imm instructions: the 8-bit immediate is the least significant bits 47// [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11]. 48def t2_so_imm : Operand<i32>, 49 PatLeaf<(imm), [{ 50 return ARM_AM::getT2SOImmVal((uint32_t)N->getZExtValue()) != -1; 51 }], t2_so_imm_XFORM> { 52 let PrintMethod = "printT2SOImmOperand"; 53} 54 55// t2_so_imm_not - Match an immediate that is a complement 56// of a t2_so_imm. 57def t2_so_imm_not : Operand<i32>, 58 PatLeaf<(imm), [{ 59 return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1; 60 }], t2_so_imm_not_XFORM> { 61 let PrintMethod = "printT2SOImmOperand"; 62} 63 64// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm. 65def t2_so_imm_neg : Operand<i32>, 66 PatLeaf<(imm), [{ 67 return ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())) != -1; 68 }], t2_so_imm_neg_XFORM> { 69 let PrintMethod = "printT2SOImmOperand"; 70} 71 72/// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31]. 73def imm1_31 : PatLeaf<(i32 imm), [{ 74 return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32; 75}]>; 76 77/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095]. 78def imm0_4095 : PatLeaf<(i32 imm), [{ 79 return (uint32_t)N->getZExtValue() < 4096; 80}]>; 81 82def imm0_4095_neg : PatLeaf<(i32 imm), [{ 83 return (uint32_t)(-N->getZExtValue()) < 4096; 84}], imm_neg_XFORM>; 85 86/// imm0_65535 predicate - True if the 32-bit immediate is in the range 87/// [0.65535]. 88def imm0_65535 : PatLeaf<(i32 imm), [{ 89 return (uint32_t)N->getZExtValue() < 65536; 90}]>; 91 92/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield 93/// e.g., 0xf000ffff 94def bf_inv_mask_imm : Operand<i32>, 95 PatLeaf<(imm), [{ 96 uint32_t v = (uint32_t)N->getZExtValue(); 97 if (v == 0xffffffff) 98 return 0; 99 // naive checker. should do better, but simple is best for now since it's 100 // more likely to be correct. 101 while (v & 1) v >>= 1; // shift off the leading 1's 102 if (v) 103 { 104 while (!(v & 1)) v >>=1; // shift off the mask 105 while (v & 1) v >>= 1; // shift off the trailing 1's 106 } 107 // if this is a mask for clearing a bitfield, what's left should be zero. 108 return (v == 0); 109}] > { 110 let PrintMethod = "printBitfieldInvMaskImmOperand"; 111} 112 113/// Split a 32-bit immediate into two 16 bit parts. 114def t2_lo16 : SDNodeXForm<imm, [{ 115 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff, 116 MVT::i32); 117}]>; 118 119def t2_hi16 : SDNodeXForm<imm, [{ 120 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32); 121}]>; 122 123def t2_lo16AllZero : PatLeaf<(i32 imm), [{ 124 // Returns true if all low 16-bits are 0. 125 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0; 126 }], t2_hi16>; 127 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 = "printT2AddrModeImm8Operand"; 154 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 155} 156 157// t2addrmode_so_reg := reg + reg << imm2 158def t2addrmode_so_reg : Operand<i32>, 159 ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> { 160 let PrintMethod = "printT2AddrModeSoRegOperand"; 161 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 162} 163 164 165//===----------------------------------------------------------------------===// 166// Multiclass helpers... 167// 168 169/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a 170/// unary operation that produces a value. These are predicable and can be 171/// changed to modify CPSR. 172multiclass T2I_un_irs<string opc, PatFrag opnode, bit Cheap = 0, bit ReMat = 0>{ 173 // shifted imm 174 def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), 175 opc, " $dst, $src", 176 [(set GPR:$dst, (opnode t2_so_imm:$src))]> { 177 let isAsCheapAsAMove = Cheap; 178 let isReMaterializable = ReMat; 179 } 180 // register 181 def r : T2I<(outs GPR:$dst), (ins GPR:$src), 182 opc, " $dst, $src", 183 [(set GPR:$dst, (opnode GPR:$src))]>; 184 // shifted register 185 def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), 186 opc, " $dst, $src", 187 [(set GPR:$dst, (opnode t2_so_reg:$src))]>; 188} 189 190/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a 191// binary operation that produces a value. These are predicable and can be 192/// changed to modify CPSR. 193multiclass T2I_bin_irs<string opc, PatFrag opnode, bit Commutable = 0> { 194 // shifted imm 195 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), 196 opc, " $dst, $lhs, $rhs", 197 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; 198 // register 199 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 200 opc, " $dst, $lhs, $rhs", 201 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { 202 let isCommutable = Commutable; 203 } 204 // shifted register 205 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), 206 opc, " $dst, $lhs, $rhs", 207 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; 208} 209 210/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are 211/// reversed. It doesn't define the 'rr' form since it's handled by its 212/// T2I_bin_irs counterpart. 213multiclass T2I_rbin_is<string opc, PatFrag opnode> { 214 // shifted imm 215 def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), 216 opc, " $dst, $rhs, $lhs", 217 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; 218 // shifted register 219 def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), 220 opc, " $dst, $rhs, $lhs", 221 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>; 222} 223 224/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the 225/// instruction modifies the CPSR register. 226let Defs = [CPSR] in { 227multiclass T2I_bin_s_irs<string opc, PatFrag opnode, bit Commutable = 0> { 228 // shifted imm 229 def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), 230 !strconcat(opc, "s"), " $dst, $lhs, $rhs", 231 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; 232 // register 233 def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 234 !strconcat(opc, "s"), " $dst, $lhs, $rhs", 235 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { 236 let isCommutable = Commutable; 237 } 238 // shifted register 239 def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), 240 !strconcat(opc, "s"), " $dst, $lhs, $rhs", 241 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; 242} 243} 244 245/// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg}) 246/// patterns for a binary operation that produces a value. 247multiclass T2I_bin_ii12rs<string opc, PatFrag opnode, bit Commutable = 0> { 248 // shifted imm 249 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), 250 opc, " $dst, $lhs, $rhs", 251 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; 252 // 12-bit imm 253 def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), 254 !strconcat(opc, "w"), " $dst, $lhs, $rhs", 255 [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]>; 256 // register 257 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 258 opc, " $dst, $lhs, $rhs", 259 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { 260 let isCommutable = Commutable; 261 } 262 // shifted register 263 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), 264 opc, " $dst, $lhs, $rhs", 265 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; 266} 267 268/// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a 269/// binary operation that produces a value and use and define the carry bit. 270/// It's not predicable. 271let Uses = [CPSR] in { 272multiclass T2I_adde_sube_irs<string opc, PatFrag opnode, bit Commutable = 0> { 273 // shifted imm 274 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), 275 opc, " $dst, $lhs, $rhs", 276 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>, 277 Requires<[IsThumb2, CarryDefIsUnused]>; 278 // register 279 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 280 opc, " $dst, $lhs, $rhs", 281 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>, 282 Requires<[IsThumb2, CarryDefIsUnused]> { 283 let isCommutable = Commutable; 284 } 285 // shifted register 286 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), 287 opc, " $dst, $lhs, $rhs", 288 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>, 289 Requires<[IsThumb2, CarryDefIsUnused]>; 290 // Carry setting variants 291 // shifted imm 292 def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), 293 !strconcat(opc, "s $dst, $lhs, $rhs"), 294 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>, 295 Requires<[IsThumb2, CarryDefIsUsed]> { 296 let Defs = [CPSR]; 297 } 298 // register 299 def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 300 !strconcat(opc, "s $dst, $lhs, $rhs"), 301 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>, 302 Requires<[IsThumb2, CarryDefIsUsed]> { 303 let Defs = [CPSR]; 304 let isCommutable = Commutable; 305 } 306 // shifted register 307 def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), 308 !strconcat(opc, "s $dst, $lhs, $rhs"), 309 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>, 310 Requires<[IsThumb2, CarryDefIsUsed]> { 311 let Defs = [CPSR]; 312 } 313} 314} 315 316/// T2I_rsc_is - Same as T2I_adde_sube_irs except the order of operands are 317/// reversed. It doesn't define the 'rr' form since it's handled by its 318/// T2I_adde_sube_irs counterpart. 319let Defs = [CPSR], Uses = [CPSR] in { 320multiclass T2I_rsc_is<string opc, PatFrag opnode> { 321 // shifted imm 322 def ri : T2sI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), 323 opc, " $dst, $rhs, $lhs", 324 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>, 325 Requires<[IsThumb2, CarryDefIsUnused]>; 326 // shifted register 327 def rs : T2sI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), 328 opc, " $dst, $rhs, $lhs", 329 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>, 330 Requires<[IsThumb2, CarryDefIsUnused]>; 331 // shifted imm 332 def Sri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), 333 !strconcat(opc, "s $dst, $rhs, $lhs"), 334 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>, 335 Requires<[IsThumb2, CarryDefIsUsed]> { 336 let Defs = [CPSR]; 337 } 338 // shifted register 339 def Srs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), 340 !strconcat(opc, "s $dst, $rhs, $lhs"), 341 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>, 342 Requires<[IsThumb2, CarryDefIsUsed]> { 343 let Defs = [CPSR]; 344 } 345} 346} 347 348/// T2I_rbin_s_is - Same as T2I_bin_s_irs except the order of operands are 349/// reversed. It doesn't define the 'rr' form since it's handled by its 350/// T2I_bin_s_irs counterpart. 351let Defs = [CPSR] in { 352multiclass T2I_rbin_s_is<string opc, PatFrag opnode> { 353 // shifted imm 354 def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s), 355 !strconcat(opc, "${s} $dst, $rhs, $lhs"), 356 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; 357 // shifted register 358 def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s), 359 !strconcat(opc, "${s} $dst, $rhs, $lhs"), 360 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>; 361} 362} 363 364/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift / 365// rotate operation that produces a value. 366multiclass T2I_sh_ir<string opc, PatFrag opnode> { 367 // 5-bit imm 368 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), 369 opc, " $dst, $lhs, $rhs", 370 [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]>; 371 // register 372 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 373 opc, " $dst, $lhs, $rhs", 374 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>; 375} 376 377/// T21_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test 378/// patterns. Similar to T2I_bin_irs except the instruction does not produce 379/// a explicit result, only implicitly set CPSR. 380let Uses = [CPSR] in { 381multiclass T2I_cmp_is<string opc, PatFrag opnode> { 382 // shifted imm 383 def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), 384 opc, " $lhs, $rhs", 385 [(opnode GPR:$lhs, t2_so_imm:$rhs)]>; 386 // register 387 def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), 388 opc, " $lhs, $rhs", 389 [(opnode GPR:$lhs, GPR:$rhs)]>; 390 // shifted register 391 def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), 392 opc, " $lhs, $rhs", 393 [(opnode GPR:$lhs, t2_so_reg:$rhs)]>; 394} 395} 396 397/// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns. 398multiclass T2I_ld<string opc, PatFrag opnode> { 399 def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), 400 opc, " $dst, $addr", 401 [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]>; 402 def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), 403 opc, " $dst, $addr", 404 [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]>; 405 def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), 406 opc, " $dst, $addr", 407 [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]>; 408 def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), 409 opc, " $dst, $addr", 410 [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]>; 411} 412 413/// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns. 414multiclass T2I_st<string opc, PatFrag opnode> { 415 def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), 416 opc, " $src, $addr", 417 [(opnode GPR:$src, t2addrmode_imm12:$addr)]>; 418 def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), 419 opc, " $src, $addr", 420 [(opnode GPR:$src, t2addrmode_imm8:$addr)]>; 421 def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), 422 opc, " $src, $addr", 423 [(opnode GPR:$src, t2addrmode_so_reg:$addr)]>; 424} 425 426/// T2I_picld - Defines the PIC load pattern. 427class T2I_picld<string opc, PatFrag opnode> : 428 T2I<(outs GPR:$dst), (ins addrmodepc:$addr), 429 !strconcat("${addr:label}:\n\t", opc), " $dst, $addr", 430 [(set GPR:$dst, (opnode addrmodepc:$addr))]>; 431 432/// T2I_picst - Defines the PIC store pattern. 433class T2I_picst<string opc, PatFrag opnode> : 434 T2I<(outs), (ins GPR:$src, addrmodepc:$addr), 435 !strconcat("${addr:label}:\n\t", opc), " $src, $addr", 436 [(opnode GPR:$src, addrmodepc:$addr)]>; 437 438//===----------------------------------------------------------------------===// 439// Instructions 440//===----------------------------------------------------------------------===// 441 442//===----------------------------------------------------------------------===// 443// Miscellaneous Instructions. 444// 445 446let isNotDuplicable = 1 in 447def t2PICADD : T2XI<(outs tGPR:$dst), (ins tGPR:$lhs, pclabel:$cp), 448 "$cp:\n\tadd $dst, pc", 449 [(set tGPR:$dst, (ARMpic_add tGPR:$lhs, imm:$cp))]>; 450 451 452// LEApcrel - Load a pc-relative address into a register without offending the 453// assembler. 454def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p), 455 !strconcat(!strconcat(".set PCRELV${:uid}, ($label-(", 456 "${:private}PCRELL${:uid}+8))\n"), 457 !strconcat("${:private}PCRELL${:uid}:\n\t", 458 "add$p $dst, pc, #PCRELV${:uid}")), 459 []>; 460 461def t2LEApcrelJT : T2XI<(outs GPR:$dst), 462 (ins i32imm:$label, i32imm:$id, pred:$p), 463 !strconcat(!strconcat(".set PCRELV${:uid}, (${label}_${id:no_hash}-(", 464 "${:private}PCRELL${:uid}+8))\n"), 465 !strconcat("${:private}PCRELL${:uid}:\n\t", 466 "add$p $dst, pc, #PCRELV${:uid}")), 467 []>; 468 469// ADD rd, sp, #so_imm 470def t2ADDrSPi : T2XI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm), 471 "add $dst, $sp, $imm", 472 []>; 473 474// ADD rd, sp, #imm12 475def t2ADDrSPi12 : T2XI<(outs GPR:$dst), (ins GPR:$sp, i32imm:$imm), 476 "addw $dst, $sp, $imm", 477 []>; 478 479def t2ADDrSPs : T2XI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs), 480 "addw $dst, $sp, $rhs", 481 []>; 482 483 484//===----------------------------------------------------------------------===// 485// Load / store Instructions. 486// 487 488// Load 489let canFoldAsLoad = 1 in 490defm t2LDR : T2I_ld<"ldr", UnOpFrag<(load node:$Src)>>; 491 492// Loads with zero extension 493defm t2LDRH : T2I_ld<"ldrh", UnOpFrag<(zextloadi16 node:$Src)>>; 494defm t2LDRB : T2I_ld<"ldrb", UnOpFrag<(zextloadi8 node:$Src)>>; 495 496// Loads with sign extension 497defm t2LDRSH : T2I_ld<"ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>; 498defm t2LDRSB : T2I_ld<"ldrsb", UnOpFrag<(sextloadi8 node:$Src)>>; 499 500let mayLoad = 1 in { 501// Load doubleword 502def t2LDRDi8 : T2Ii8s4<(outs GPR:$dst), (ins t2addrmode_imm8s4:$addr), 503 "ldrd", " $dst, $addr", []>; 504def t2LDRDpci : T2Ii8s4<(outs GPR:$dst), (ins i32imm:$addr), 505 "ldrd", " $dst, $addr", []>; 506} 507 508// zextload i1 -> zextload i8 509def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr), 510 (t2LDRBi12 t2addrmode_imm12:$addr)>; 511def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr), 512 (t2LDRBi8 t2addrmode_imm8:$addr)>; 513def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr), 514 (t2LDRBs t2addrmode_so_reg:$addr)>; 515def : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)), 516 (t2LDRBpci tconstpool:$addr)>; 517 518// extload -> zextload 519// FIXME: Reduce the number of patterns by legalizing extload to zextload 520// earlier? 521def : T2Pat<(extloadi1 t2addrmode_imm12:$addr), 522 (t2LDRBi12 t2addrmode_imm12:$addr)>; 523def : T2Pat<(extloadi1 t2addrmode_imm8:$addr), 524 (t2LDRBi8 t2addrmode_imm8:$addr)>; 525def : T2Pat<(extloadi1 t2addrmode_so_reg:$addr), 526 (t2LDRBs t2addrmode_so_reg:$addr)>; 527def : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)), 528 (t2LDRBpci tconstpool:$addr)>; 529 530def : T2Pat<(extloadi8 t2addrmode_imm12:$addr), 531 (t2LDRBi12 t2addrmode_imm12:$addr)>; 532def : T2Pat<(extloadi8 t2addrmode_imm8:$addr), 533 (t2LDRBi8 t2addrmode_imm8:$addr)>; 534def : T2Pat<(extloadi8 t2addrmode_so_reg:$addr), 535 (t2LDRBs t2addrmode_so_reg:$addr)>; 536def : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)), 537 (t2LDRBpci tconstpool:$addr)>; 538 539def : T2Pat<(extloadi16 t2addrmode_imm12:$addr), 540 (t2LDRHi12 t2addrmode_imm12:$addr)>; 541def : T2Pat<(extloadi16 t2addrmode_imm8:$addr), 542 (t2LDRHi8 t2addrmode_imm8:$addr)>; 543def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr), 544 (t2LDRHs t2addrmode_so_reg:$addr)>; 545def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)), 546 (t2LDRHpci tconstpool:$addr)>; 547 548// Indexed loads 549let mayLoad = 1 in { 550def t2LDR_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), 551 (ins t2addrmode_imm8:$addr), 552 AddrModeT2_i8, IndexModePre, 553 "ldr", " $dst, $addr!", "$addr.base = $base_wb", 554 []>; 555 556def t2LDR_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), 557 (ins GPR:$base, t2am_imm8_offset:$offset), 558 AddrModeT2_i8, IndexModePost, 559 "ldr", " $dst, [$base], $offset", "$base = $base_wb", 560 []>; 561 562def t2LDRB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), 563 (ins t2addrmode_imm8:$addr), 564 AddrModeT2_i8, IndexModePre, 565 "ldrb", " $dst, $addr!", "$addr.base = $base_wb", 566 []>; 567def t2LDRB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), 568 (ins GPR:$base, t2am_imm8_offset:$offset), 569 AddrModeT2_i8, IndexModePost, 570 "ldrb", " $dst, [$base], $offset", "$base = $base_wb", 571 []>; 572 573def t2LDRH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), 574 (ins t2addrmode_imm8:$addr), 575 AddrModeT2_i8, IndexModePre, 576 "ldrh", " $dst, $addr!", "$addr.base = $base_wb", 577 []>; 578def t2LDRH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), 579 (ins GPR:$base, t2am_imm8_offset:$offset), 580 AddrModeT2_i8, IndexModePost, 581 "ldrh", " $dst, [$base], $offset", "$base = $base_wb", 582 []>; 583 584def t2LDRSB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), 585 (ins t2addrmode_imm8:$addr), 586 AddrModeT2_i8, IndexModePre, 587 "ldrsb", " $dst, $addr!", "$addr.base = $base_wb", 588 []>; 589def t2LDRSB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), 590 (ins GPR:$base, t2am_imm8_offset:$offset), 591 AddrModeT2_i8, IndexModePost, 592 "ldrsb", " $dst, [$base], $offset", "$base = $base_wb", 593 []>; 594 595def t2LDRSH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), 596 (ins t2addrmode_imm8:$addr), 597 AddrModeT2_i8, IndexModePre, 598 "ldrsh", " $dst, $addr!", "$addr.base = $base_wb", 599 []>; 600def t2LDRSH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb), 601 (ins GPR:$base, t2am_imm8_offset:$offset), 602 AddrModeT2_i8, IndexModePost, 603 "ldrsh", " $dst, [$base], $offset", "$base = $base_wb", 604 []>; 605} 606 607// Store 608defm t2STR : T2I_st<"str", BinOpFrag<(store node:$LHS, node:$RHS)>>; 609defm t2STRB : T2I_st<"strb", BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>; 610defm t2STRH : T2I_st<"strh", BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>; 611 612// Store doubleword 613let mayLoad = 1 in 614def t2STRDi8 : T2Ii8s4<(outs), (ins GPR:$src, t2addrmode_imm8s4:$addr), 615 "strd", " $src, $addr", []>; 616 617// Indexed stores 618def t2STR_PRE : T2Iidxldst<(outs GPR:$base_wb), 619 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), 620 AddrModeT2_i8, IndexModePre, 621 "str", " $src, [$base, $offset]!", "$base = $base_wb", 622 [(set GPR:$base_wb, 623 (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; 624 625def t2STR_POST : T2Iidxldst<(outs GPR:$base_wb), 626 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), 627 AddrModeT2_i8, IndexModePost, 628 "str", " $src, [$base], $offset", "$base = $base_wb", 629 [(set GPR:$base_wb, 630 (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; 631 632def t2STRH_PRE : T2Iidxldst<(outs GPR:$base_wb), 633 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), 634 AddrModeT2_i8, IndexModePre, 635 "strh", " $src, [$base, $offset]!", "$base = $base_wb", 636 [(set GPR:$base_wb, 637 (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; 638 639def t2STRH_POST : T2Iidxldst<(outs GPR:$base_wb), 640 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), 641 AddrModeT2_i8, IndexModePost, 642 "strh", " $src, [$base], $offset", "$base = $base_wb", 643 [(set GPR:$base_wb, 644 (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; 645 646def t2STRB_PRE : T2Iidxldst<(outs GPR:$base_wb), 647 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), 648 AddrModeT2_i8, IndexModePre, 649 "strb", " $src, [$base, $offset]!", "$base = $base_wb", 650 [(set GPR:$base_wb, 651 (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; 652 653def t2STRB_POST : T2Iidxldst<(outs GPR:$base_wb), 654 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset), 655 AddrModeT2_i8, IndexModePost, 656 "strb", " $src, [$base], $offset", "$base = $base_wb", 657 [(set GPR:$base_wb, 658 (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>; 659 660 661// Address computation and loads and stores in PIC mode. 662let isNotDuplicable = 1, AddedComplexity = 10 in { 663let canFoldAsLoad = 1 in 664def t2PICLDR : T2I_picld<"ldr", UnOpFrag<(load node:$Src)>>; 665 666def t2PICLDRH : T2I_picld<"ldrh", UnOpFrag<(zextloadi16 node:$Src)>>; 667def t2PICLDRB : T2I_picld<"ldrb", UnOpFrag<(zextloadi8 node:$Src)>>; 668def t2PICLDRSH : T2I_picld<"ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>; 669def t2PICLDRSB : T2I_picld<"ldrsb", UnOpFrag<(sextloadi8 node:$Src)>>; 670 671def t2PICSTR : T2I_picst<"str", BinOpFrag<(store node:$LHS, node:$RHS)>>; 672def t2PICSTRH : T2I_picst<"strh", BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>; 673def t2PICSTRB : T2I_picst<"strb", BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>; 674} // isNotDuplicable = 1, AddedComplexity = 10 675 676 677//===----------------------------------------------------------------------===// 678// Load / store multiple Instructions. 679// 680 681let mayLoad = 1 in 682def t2LDM : T2XI<(outs), 683 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops), 684 "ldm${p}${addr:submode} $addr, $dst1", []>; 685 686let mayStore = 1 in 687def t2STM : T2XI<(outs), 688 (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops), 689 "stm${p}${addr:submode} $addr, $src1", []>; 690 691//===----------------------------------------------------------------------===// 692// Move Instructions. 693// 694 695let neverHasSideEffects = 1 in 696def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), 697 "mov", " $dst, $src", []>; 698 699let isReMaterializable = 1, isAsCheapAsAMove = 1 in 700def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), 701 "mov", " $dst, $src", 702 [(set GPR:$dst, t2_so_imm:$src)]>; 703 704let isReMaterializable = 1, isAsCheapAsAMove = 1 in 705def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), 706 "movw", " $dst, $src", 707 [(set GPR:$dst, imm0_65535:$src)]>; 708 709// FIXME: Also available in ARM mode. 710let Constraints = "$src = $dst" in 711def t2MOVTi16 : T2sI<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), 712 "movt", " $dst, $imm", 713 [(set GPR:$dst, 714 (or (and GPR:$src, 0xffff), t2_lo16AllZero:$imm))]>; 715 716//===----------------------------------------------------------------------===// 717// Arithmetic Instructions. 718// 719 720defm t2ADD : T2I_bin_ii12rs<"add", BinOpFrag<(add node:$LHS, node:$RHS)>, 1>; 721defm t2SUB : T2I_bin_ii12rs<"sub", BinOpFrag<(sub node:$LHS, node:$RHS)>>; 722 723// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants. 724defm t2ADDS : T2I_bin_s_irs <"add", BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>; 725defm t2SUBS : T2I_bin_s_irs <"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>; 726 727defm t2ADC : T2I_adde_sube_irs<"adc",BinOpFrag<(adde node:$LHS, node:$RHS)>,1>; 728defm t2SBC : T2I_adde_sube_irs<"sbc",BinOpFrag<(sube node:$LHS, node:$RHS)>>; 729 730// RSB, RSC 731defm t2RSB : T2I_rbin_is <"rsb", BinOpFrag<(sub node:$LHS, node:$RHS)>>; 732defm t2RSBS : T2I_rbin_s_is <"rsb", BinOpFrag<(subc node:$LHS, node:$RHS)>>; 733defm t2RSC : T2I_rsc_is <"rsc", BinOpFrag<(sube node:$LHS, node:$RHS)>>; 734 735// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 736def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm), 737 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>; 738def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm), 739 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>; 740 741 742//===----------------------------------------------------------------------===// 743// Shift and rotate Instructions. 744// 745 746defm t2LSL : T2I_sh_ir<"lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>; 747defm t2LSR : T2I_sh_ir<"lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>; 748defm t2ASR : T2I_sh_ir<"asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>; 749defm t2ROR : T2I_sh_ir<"ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>; 750 751def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), 752 "mov", " $dst, $src, rrx", 753 [(set GPR:$dst, (ARMrrx GPR:$src))]>; 754 755//===----------------------------------------------------------------------===// 756// Bitwise Instructions. 757// 758 759defm t2AND : T2I_bin_irs<"and", BinOpFrag<(and node:$LHS, node:$RHS)>, 1>; 760defm t2ORR : T2I_bin_irs<"orr", BinOpFrag<(or node:$LHS, node:$RHS)>, 1>; 761defm t2EOR : T2I_bin_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>; 762 763defm t2BIC : T2I_bin_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>; 764 765def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm), 766 (t2BICri GPR:$src, t2_so_imm_not:$imm)>; 767 768defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>; 769 770def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm), 771 (t2ORNri GPR:$src, t2_so_imm_not:$imm)>; 772 773// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version 774let AddedComplexity = 1 in 775defm t2MVN : T2I_un_irs <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>; 776 777def : T2Pat<(t2_so_imm_not:$src), 778 (t2MVNi t2_so_imm_not:$src)>; 779 780// A8.6.17 BFC - Bitfield clear 781// FIXME: Also available in ARM mode. 782let Constraints = "$src = $dst" in 783def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm), 784 "bfc", " $dst, $imm", 785 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>; 786 787// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1) 788 789//===----------------------------------------------------------------------===// 790// Multiply Instructions. 791// 792let isCommutable = 1 in 793def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), 794 "mul", " $dst, $a, $b", 795 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>; 796 797def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 798 "mla", " $dst, $a, $b, $c", 799 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>; 800 801def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 802 "mls", " $dst, $a, $b, $c", 803 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>; 804 805// FIXME: SMULL, etc. 806 807//===----------------------------------------------------------------------===// 808// Misc. Arithmetic Instructions. 809// 810 811def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src), 812 "clz", " $dst, $src", 813 [(set GPR:$dst, (ctlz GPR:$src))]>; 814 815def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src), 816 "rev", " $dst, $src", 817 [(set GPR:$dst, (bswap GPR:$src))]>; 818 819def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src), 820 "rev16", " $dst, $src", 821 [(set GPR:$dst, 822 (or (and (srl GPR:$src, (i32 8)), 0xFF), 823 (or (and (shl GPR:$src, (i32 8)), 0xFF00), 824 (or (and (srl GPR:$src, (i32 8)), 0xFF0000), 825 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>; 826 827///// 828/// A8.6.137 REVSH 829///// 830def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src), 831 "revsh", " $dst, $src", 832 [(set GPR:$dst, 833 (sext_inreg 834 (or (srl (and GPR:$src, 0xFFFF), (i32 8)), 835 (shl GPR:$src, (i32 8))), i16))]>; 836 837// FIXME: PKHxx etc. 838 839//===----------------------------------------------------------------------===// 840// Comparison Instructions... 841// 842 843defm t2CMP : T2I_cmp_is<"cmp", 844 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>; 845defm t2CMPz : T2I_cmp_is<"cmp", 846 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>; 847 848defm t2CMN : T2I_cmp_is<"cmn", 849 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>; 850defm t2CMNz : T2I_cmp_is<"cmn", 851 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>; 852 853def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm), 854 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>; 855 856def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm), 857 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>; 858 859defm t2TST : T2I_cmp_is<"tst", 860 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>; 861defm t2TEQ : T2I_cmp_is<"teq", 862 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>; 863 864// A8.6.27 CBNZ, CBZ - Compare and branch on (non)zero. 865// Short range conditional branch. Looks awesome for loops. Need to figure 866// out how to use this one. 867 868// FIXME: Conditional moves 869 870//===----------------------------------------------------------------------===// 871// Control-Flow Instructions 872// 873 874let isBranch = 1, isTerminator = 1, isBarrier = 1 in { 875let isPredicable = 1 in 876def t2B : T2XI<(outs), (ins brtarget:$target), 877 "b $target", 878 [(br bb:$target)]>; 879 880let isNotDuplicable = 1, isIndirectBranch = 1 in { 881def t2BR_JTr : T2JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id), 882 "mov pc, $target \n$jt", 883 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>; 884 885def t2BR_JTm : 886 T2JTI<(outs), 887 (ins t2addrmode_so_reg:$target, jtblock_operand:$jt, i32imm:$id), 888 "ldr pc, $target \n$jt", 889 [(ARMbrjt (i32 (load t2addrmode_so_reg:$target)), tjumptable:$jt, 890 imm:$id)]>; 891 892def t2BR_JTadd : 893 T2JTI<(outs), 894 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id), 895 "add pc, $target, $idx \n$jt", 896 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, imm:$id)]>; 897} // isNotDuplicate, isIndirectBranch 898} // isBranch, isTerminator, isBarrier 899 900// FIXME: should be able to write a pattern for ARMBrcond, but can't use 901// a two-value operand where a dag node expects two operands. :( 902let isBranch = 1, isTerminator = 1 in 903def t2Bcc : T2I<(outs), (ins brtarget:$target), 904 "b", " $target", 905 [/*(ARMbrcond bb:$target, imm:$cc)*/]>; 906 907//===----------------------------------------------------------------------===// 908// Non-Instruction Patterns 909// 910 911// ConstantPool, GlobalAddress, and JumpTable 912def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>; 913def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>; 914def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), 915 (t2LEApcrelJT tjumptable:$dst, imm:$id)>; 916 917// Large immediate handling. 918 919def : T2Pat<(i32 imm:$src), 920 (t2MOVTi16 (t2MOVi16 (t2_lo16 imm:$src)), (t2_hi16 imm:$src))>; 921