ARMInstrThumb2.td revision 83b3593478406b020b7af6ba5402a14507d7d713
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, "SelectThumb2ShifterOperandReg", 18 [shl,srl,sra,rotr]> { 19 let PrintMethod = "printSOOperand"; 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 93/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield 94/// e.g., 0xf000ffff 95def bf_inv_mask_imm : Operand<i32>, 96 PatLeaf<(imm), [{ 97 uint32_t v = (uint32_t)N->getZExtValue(); 98 if (v == 0xffffffff) 99 return 0; 100 // naive checker. should do better, but simple is best for now since it's 101 // more likely to be correct. 102 while (v & 1) v >>= 1; // shift off the leading 1's 103 if (v) 104 { 105 while (!(v & 1)) v >>=1; // shift off the mask 106 while (v & 1) v >>= 1; // shift off the trailing 1's 107 } 108 // if this is a mask for clearing a bitfield, what's left should be zero. 109 return (v == 0); 110}] > { 111 let PrintMethod = "printBitfieldInvMaskImmOperand"; 112} 113 114/// Split a 32-bit immediate into two 16 bit parts. 115def t2_lo16 : SDNodeXForm<imm, [{ 116 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff, 117 MVT::i32); 118}]>; 119 120def t2_hi16 : SDNodeXForm<imm, [{ 121 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32); 122}]>; 123 124def t2_lo16AllZero : PatLeaf<(i32 imm), [{ 125 // Returns true if all low 16-bits are 0. 126 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0; 127 }], t2_hi16>; 128 129//===----------------------------------------------------------------------===// 130// Thumb2 to cover the functionality of the ARM instruction set. 131// 132 133/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a 134/// unary operation that produces a value. These are predicable and can be 135/// changed to modify CPSR. 136multiclass T2I_un_irs<string opc, PatFrag opnode, bit Cheap = 0, bit ReMat = 0>{ 137 // shifted imm 138 def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), 139 opc, " $dst, $src", 140 [(set GPR:$dst, (opnode t2_so_imm:$src))]> { 141 let isAsCheapAsAMove = Cheap; 142 let isReMaterializable = ReMat; 143 } 144 // register 145 def r : T2I<(outs GPR:$dst), (ins GPR:$src), 146 opc, " $dst, $src", 147 [(set GPR:$dst, (opnode GPR:$src))]>; 148 // shifted register 149 def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), 150 opc, " $dst, $src", 151 [(set GPR:$dst, (opnode t2_so_reg:$src))]>; 152} 153 154/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a 155// binary operation that produces a value. These are predicable and can be 156/// changed to modify CPSR. 157multiclass T2I_bin_irs<string opc, PatFrag opnode, bit Commutable = 0> { 158 // shifted imm 159 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), 160 opc, " $dst, $lhs, $rhs", 161 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; 162 // register 163 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 164 opc, " $dst, $lhs, $rhs", 165 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { 166 let isCommutable = Commutable; 167 } 168 // shifted register 169 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), 170 opc, " $dst, $lhs, $rhs", 171 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; 172} 173 174/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are 175/// reversed. It doesn't define the 'rr' form since it's handled by its 176/// T2I_bin_irs counterpart. 177multiclass T2I_rbin_is<string opc, PatFrag opnode> { 178 // shifted imm 179 def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), 180 opc, " $dst, $rhs, $lhs", 181 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; 182 // shifted register 183 def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), 184 opc, " $dst, $rhs, $lhs", 185 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>; 186} 187 188/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the 189/// instruction modifies the CPSR register. 190let Defs = [CPSR] in { 191multiclass T2I_bin_s_irs<string opc, PatFrag opnode, bit Commutable = 0> { 192 // shifted imm 193 def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), 194 !strconcat(opc, "s"), " $dst, $lhs, $rhs", 195 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; 196 // register 197 def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 198 !strconcat(opc, "s"), " $dst, $lhs, $rhs", 199 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { 200 let isCommutable = Commutable; 201 } 202 // shifted register 203 def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), 204 !strconcat(opc, "s"), " $dst, $lhs, $rhs", 205 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; 206} 207} 208 209/// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg}) 210/// patterns for a binary operation that produces a value. 211multiclass T2I_bin_ii12rs<string opc, PatFrag opnode, bit Commutable = 0> { 212 // shifted imm 213 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), 214 opc, " $dst, $lhs, $rhs", 215 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>; 216 // 12-bit imm 217 def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), 218 !strconcat(opc, "w"), " $dst, $lhs, $rhs", 219 [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]>; 220 // register 221 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 222 opc, " $dst, $lhs, $rhs", 223 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> { 224 let isCommutable = Commutable; 225 } 226 // shifted register 227 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), 228 opc, " $dst, $lhs, $rhs", 229 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>; 230} 231 232/// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a 233/// binary operation that produces a value and use and define the carry bit. 234/// It's not predicable. 235let Uses = [CPSR] in { 236multiclass T2I_adde_sube_irs<string opc, PatFrag opnode, bit Commutable = 0> { 237 // shifted imm 238 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), 239 opc, " $dst, $lhs, $rhs", 240 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>, 241 Requires<[IsThumb, HasThumb2, CarryDefIsUnused]>; 242 // register 243 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 244 opc, " $dst, $lhs, $rhs", 245 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>, 246 Requires<[IsThumb, HasThumb2, CarryDefIsUnused]> { 247 let isCommutable = Commutable; 248 } 249 // shifted register 250 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), 251 opc, "s $dst, $lhs, $rhs", 252 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>, 253 Requires<[IsThumb, HasThumb2, CarryDefIsUnused]>; 254 // Carry setting variants 255 // shifted imm 256 def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), 257 !strconcat(opc, "s $dst, $lhs, $rhs"), 258 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>, 259 Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> { 260 let Defs = [CPSR]; 261 } 262 // register 263 def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 264 !strconcat(opc, "s $dst, $lhs, $rhs"), 265 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>, 266 Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> { 267 let Defs = [CPSR]; 268 let isCommutable = Commutable; 269 } 270 // shifted register 271 def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), 272 !strconcat(opc, "s $dst, $lhs, $rhs"), 273 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>, 274 Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> { 275 let Defs = [CPSR]; 276 } 277} 278} 279 280/// T2I_rsc_is - Same as T2I_adde_sube_irs except the order of operands are 281/// reversed. It doesn't define the 'rr' form since it's handled by its 282/// T2I_adde_sube_irs counterpart. 283let Defs = [CPSR], Uses = [CPSR] in { 284multiclass T2I_rsc_is<string opc, PatFrag opnode> { 285 // shifted imm 286 def ri : T2sI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), 287 opc, " $dst, $rhs, $lhs", 288 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>, 289 Requires<[IsThumb, HasThumb2, CarryDefIsUnused]>; 290 // shifted register 291 def rs : T2sI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), 292 opc, " $dst, $rhs, $lhs", 293 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>, 294 Requires<[IsThumb, HasThumb2, CarryDefIsUnused]>; 295 // shifted imm 296 def Sri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), 297 !strconcat(opc, "s $dst, $rhs, $lhs"), 298 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>, 299 Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> { 300 let Defs = [CPSR]; 301 } 302 // shifted register 303 def Srs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), 304 !strconcat(opc, "s $dst, $rhs, $lhs"), 305 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>, 306 Requires<[IsThumb, HasThumb2, CarryDefIsUsed]> { 307 let Defs = [CPSR]; 308 } 309} 310} 311 312/// T2I_rbin_s_is - Same as T2I_bin_s_irs except the order of operands are 313/// reversed. It doesn't define the 'rr' form since it's handled by its 314/// T2I_bin_s_irs counterpart. 315let Defs = [CPSR] in { 316multiclass T2I_rbin_s_is<string opc, PatFrag opnode> { 317 // shifted imm 318 def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s), 319 !strconcat(opc, "${s} $dst, $rhs, $lhs"), 320 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>; 321 // shifted register 322 def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s), 323 !strconcat(opc, "${s} $dst, $rhs, $lhs"), 324 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>; 325} 326} 327 328/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift / 329// rotate operation that produces a value. 330multiclass T2I_sh_ir<string opc, PatFrag opnode> { 331 // 5-bit imm 332 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), 333 opc, " $dst, $lhs, $rhs", 334 [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]>; 335 // register 336 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 337 opc, " $dst, $lhs, $rhs", 338 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>; 339} 340 341/// T21_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test 342/// patterns. Similar to T2I_bin_irs except the instruction does not produce 343/// a explicit result, only implicitly set CPSR. 344let Uses = [CPSR] in { 345multiclass T2I_cmp_is<string opc, PatFrag opnode> { 346 // shifted imm 347 def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), 348 opc, " $lhs, $rhs", 349 [(opnode GPR:$lhs, t2_so_imm:$rhs)]>; 350 // register 351 def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), 352 opc, " $lhs, $rhs", 353 [(opnode GPR:$lhs, GPR:$rhs)]>; 354 // shifted register 355 def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), 356 opc, " $lhs, $rhs", 357 [(opnode GPR:$lhs, t2_so_reg:$rhs)]>; 358} 359} 360 361//===----------------------------------------------------------------------===// 362// Miscellaneous Instructions. 363// 364 365let isNotDuplicable = 1 in 366def t2PICADD : T2XI<(outs tGPR:$dst), (ins tGPR:$lhs, pclabel:$cp), 367 "$cp:\n\tadd $dst, pc", 368 [(set tGPR:$dst, (ARMpic_add tGPR:$lhs, imm:$cp))]>; 369 370 371// LEApcrel - Load a pc-relative address into a register without offending the 372// assembler. 373def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p), 374 !strconcat(!strconcat(".set PCRELV${:uid}, ($label-(", 375 "${:private}PCRELL${:uid}+8))\n"), 376 !strconcat("${:private}PCRELL${:uid}:\n\t", 377 "add$p $dst, pc, #PCRELV${:uid}")), 378 []>; 379 380def t2LEApcrelJT : T2XI<(outs GPR:$dst), 381 (ins i32imm:$label, i32imm:$id, pred:$p), 382 !strconcat(!strconcat(".set PCRELV${:uid}, (${label}_${id:no_hash}-(", 383 "${:private}PCRELL${:uid}+8))\n"), 384 !strconcat("${:private}PCRELL${:uid}:\n\t", 385 "add$p $dst, pc, #PCRELV${:uid}")), 386 []>; 387 388// ADD rd, sp, #so_imm 389def t2ADDrSPi : T2XI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm), 390 "add $dst, $sp, $imm", 391 []>; 392 393// ADD rd, sp, #imm12 394def t2ADDrSPi12 : T2XI<(outs GPR:$dst), (ins GPR:$sp, i32imm:$imm), 395 "addw $dst, $sp, $imm", 396 []>; 397 398def t2ADDrSPs : T2XI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs), 399 "addw $dst, $sp, $rhs", 400 []>; 401 402 403//===----------------------------------------------------------------------===// 404// Move Instructions. 405// 406 407let neverHasSideEffects = 1 in 408def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), 409 "mov", " $dst, $src", []>; 410 411let isReMaterializable = 1, isAsCheapAsAMove = 1 in 412def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), 413 "mov", " $dst, $src", 414 [(set GPR:$dst, t2_so_imm:$src)]>; 415 416let isReMaterializable = 1, isAsCheapAsAMove = 1 in 417def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), 418 "movw", " $dst, $src", 419 [(set GPR:$dst, imm0_65535:$src)]>; 420 421// FIXME: Also available in ARM mode. 422let Constraints = "$src = $dst" in 423def t2MOVTi16 : T2sI<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), 424 "movt", " $dst, $imm", 425 [(set GPR:$dst, 426 (or (and GPR:$src, 0xffff), t2_lo16AllZero:$imm))]>; 427 428//===----------------------------------------------------------------------===// 429// Arithmetic Instructions. 430// 431 432defm t2ADD : T2I_bin_ii12rs<"add", BinOpFrag<(add node:$LHS, node:$RHS)>, 1>; 433defm t2SUB : T2I_bin_ii12rs<"sub", BinOpFrag<(sub node:$LHS, node:$RHS)>>; 434 435// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants. 436defm t2ADDS : T2I_bin_s_irs <"add", BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>; 437defm t2SUBS : T2I_bin_s_irs <"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>; 438 439defm t2ADC : T2I_adde_sube_irs<"adc",BinOpFrag<(adde node:$LHS, node:$RHS)>,1>; 440defm t2SBC : T2I_adde_sube_irs<"sbc",BinOpFrag<(sube node:$LHS, node:$RHS)>>; 441 442// RSB, RSC 443defm t2RSB : T2I_rbin_is <"rsb", BinOpFrag<(sub node:$LHS, node:$RHS)>>; 444defm t2RSBS : T2I_rbin_s_is <"rsb", BinOpFrag<(subc node:$LHS, node:$RHS)>>; 445defm t2RSC : T2I_rsc_is <"rsc", BinOpFrag<(sube node:$LHS, node:$RHS)>>; 446 447// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 448def : Thumb2Pat<(add GPR:$src, t2_so_imm_neg:$imm), 449 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>; 450def : Thumb2Pat<(add GPR:$src, imm0_4095_neg:$imm), 451 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>; 452 453 454//===----------------------------------------------------------------------===// 455// Shift and rotate Instructions. 456// 457 458defm t2LSL : T2I_sh_ir<"lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>; 459defm t2LSR : T2I_sh_ir<"lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>; 460defm t2ASR : T2I_sh_ir<"asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>; 461defm t2ROR : T2I_sh_ir<"ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>; 462 463def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), 464 "mov", " $dst, $src, rrx", 465 [(set GPR:$dst, (ARMrrx GPR:$src))]>; 466 467//===----------------------------------------------------------------------===// 468// Bitwise Instructions. 469// 470 471defm t2AND : T2I_bin_irs<"and", BinOpFrag<(and node:$LHS, node:$RHS)>, 1>; 472defm t2ORR : T2I_bin_irs<"orr", BinOpFrag<(or node:$LHS, node:$RHS)>, 1>; 473defm t2EOR : T2I_bin_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>; 474 475defm t2BIC : T2I_bin_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>; 476 477def : Thumb2Pat<(and GPR:$src, t2_so_imm_not:$imm), 478 (t2BICri GPR:$src, t2_so_imm_not:$imm)>; 479 480defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>; 481 482def : Thumb2Pat<(or GPR:$src, t2_so_imm_not:$imm), 483 (t2ORNri GPR:$src, t2_so_imm_not:$imm)>; 484 485defm t2MVN : T2I_un_irs <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>; 486 487def : Thumb2Pat<(t2_so_imm_not:$src), 488 (t2MVNi t2_so_imm_not:$src)>; 489 490// A8.6.17 BFC - Bitfield clear 491// FIXME: Also available in ARM mode. 492let Constraints = "$src = $dst" in 493def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm), 494 "bfc", " $dst, $imm", 495 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>; 496 497// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1) 498 499//===----------------------------------------------------------------------===// 500// Multiply Instructions. 501// 502let isCommutable = 1 in 503def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), 504 "mul", " $dst, $a, $b", 505 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>; 506 507def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 508 "mla", " $dst, $a, $b, $c", 509 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>; 510 511def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 512 "mls", " $dst, $a, $b, $c", 513 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>; 514 515// FIXME: SMULL, etc. 516 517//===----------------------------------------------------------------------===// 518// Misc. Arithmetic Instructions. 519// 520 521///// 522/// A8.6.31 CLZ 523///// 524// FIXME not firing? but ARM version does... 525def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src), 526 "clz", " $dst, $src", 527 [(set GPR:$dst, (ctlz GPR:$src))]>; 528 529def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src), 530 "rev", " $dst, $src", 531 [(set GPR:$dst, (bswap GPR:$src))]>; 532 533def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src), 534 "rev16", " $dst, $src", 535 [(set GPR:$dst, 536 (or (and (srl GPR:$src, (i32 8)), 0xFF), 537 (or (and (shl GPR:$src, (i32 8)), 0xFF00), 538 (or (and (srl GPR:$src, (i32 8)), 0xFF0000), 539 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>; 540 541///// 542/// A8.6.137 REVSH 543///// 544def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src), 545 "revsh", " $dst, $src", 546 [(set GPR:$dst, 547 (sext_inreg 548 (or (srl (and GPR:$src, 0xFFFF), (i32 8)), 549 (shl GPR:$src, (i32 8))), i16))]>; 550 551// FIXME: PKHxx etc. 552 553//===----------------------------------------------------------------------===// 554// Comparison Instructions... 555// 556 557defm t2CMP : T2I_cmp_is<"cmp", 558 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>; 559defm t2CMPnz : T2I_cmp_is<"cmp", 560 BinOpFrag<(ARMcmpNZ node:$LHS, node:$RHS)>>; 561 562defm t2CMN : T2I_cmp_is<"cmn", 563 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>; 564defm t2CMNnz : T2I_cmp_is<"cmn", 565 BinOpFrag<(ARMcmpNZ node:$LHS,(ineg node:$RHS))>>; 566 567def : Thumb2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm), 568 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>; 569 570def : Thumb2Pat<(ARMcmpNZ GPR:$src, t2_so_imm_neg:$imm), 571 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>; 572 573// FIXME: TST, TEQ, etc. 574 575// A8.6.27 CBNZ, CBZ - Compare and branch on (non)zero. 576// Short range conditional branch. Looks awesome for loops. Need to figure 577// out how to use this one. 578 579// FIXME: Conditional moves 580 581 582//===----------------------------------------------------------------------===// 583// Non-Instruction Patterns 584// 585 586// ConstantPool, GlobalAddress, and JumpTable 587def : Thumb2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>; 588def : Thumb2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>; 589def : Thumb2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), 590 (t2LEApcrelJT tjumptable:$dst, imm:$id)>; 591 592// Large immediate handling. 593 594def : Thumb2Pat<(i32 imm:$src), 595 (t2MOVTi16 (t2MOVi16 (t2_lo16 imm:$src)), 596 (t2_hi16 imm:$src))>; 597