ARMInstrThumb.td revision b9d5cff0f31c0588f3ca7b77f4c53794995921b0
1//===- ARMInstrThumb.td - Thumb 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 Thumb instruction set. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// Thumb specific DAG Nodes. 16// 17 18def ARMtcall : SDNode<"ARMISD::tCALL", SDT_ARMcall, 19 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; 20 21def imm_neg_XFORM : SDNodeXForm<imm, [{ 22 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32); 23}]>; 24def imm_comp_XFORM : SDNodeXForm<imm, [{ 25 return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32); 26}]>; 27 28 29/// imm0_7 predicate - True if the 32-bit immediate is in the range [0,7]. 30def imm0_7 : PatLeaf<(i32 imm), [{ 31 return (uint32_t)N->getZExtValue() < 8; 32}]>; 33def imm0_7_neg : PatLeaf<(i32 imm), [{ 34 return (uint32_t)-N->getZExtValue() < 8; 35}], imm_neg_XFORM>; 36 37def imm0_255 : PatLeaf<(i32 imm), [{ 38 return (uint32_t)N->getZExtValue() < 256; 39}]>; 40def imm0_255_comp : PatLeaf<(i32 imm), [{ 41 return ~((uint32_t)N->getZExtValue()) < 256; 42}]>; 43 44def imm8_255 : PatLeaf<(i32 imm), [{ 45 return (uint32_t)N->getZExtValue() >= 8 && (uint32_t)N->getZExtValue() < 256; 46}]>; 47def imm8_255_neg : PatLeaf<(i32 imm), [{ 48 unsigned Val = -N->getZExtValue(); 49 return Val >= 8 && Val < 256; 50}], imm_neg_XFORM>; 51 52// Break imm's up into two pieces: an immediate + a left shift. 53// This uses thumb_immshifted to match and thumb_immshifted_val and 54// thumb_immshifted_shamt to get the val/shift pieces. 55def thumb_immshifted : PatLeaf<(imm), [{ 56 return ARM_AM::isThumbImmShiftedVal((unsigned)N->getZExtValue()); 57}]>; 58 59def thumb_immshifted_val : SDNodeXForm<imm, [{ 60 unsigned V = ARM_AM::getThumbImmNonShiftedVal((unsigned)N->getZExtValue()); 61 return CurDAG->getTargetConstant(V, MVT::i32); 62}]>; 63 64def thumb_immshifted_shamt : SDNodeXForm<imm, [{ 65 unsigned V = ARM_AM::getThumbImmValShift((unsigned)N->getZExtValue()); 66 return CurDAG->getTargetConstant(V, MVT::i32); 67}]>; 68 69// Define Thumb specific addressing modes. 70 71// t_addrmode_rr := reg + reg 72// 73def t_addrmode_rr : Operand<i32>, 74 ComplexPattern<i32, 2, "SelectThumbAddrModeRR", []> { 75 let PrintMethod = "printThumbAddrModeRROperand"; 76 let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); 77} 78 79// t_addrmode_s4 := reg + reg 80// reg + imm5 * 4 81// 82def t_addrmode_s4 : Operand<i32>, 83 ComplexPattern<i32, 3, "SelectThumbAddrModeS4", []> { 84 let PrintMethod = "printThumbAddrModeS4Operand"; 85 let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 86} 87 88// t_addrmode_s2 := reg + reg 89// reg + imm5 * 2 90// 91def t_addrmode_s2 : Operand<i32>, 92 ComplexPattern<i32, 3, "SelectThumbAddrModeS2", []> { 93 let PrintMethod = "printThumbAddrModeS2Operand"; 94 let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 95} 96 97// t_addrmode_s1 := reg + reg 98// reg + imm5 99// 100def t_addrmode_s1 : Operand<i32>, 101 ComplexPattern<i32, 3, "SelectThumbAddrModeS1", []> { 102 let PrintMethod = "printThumbAddrModeS1Operand"; 103 let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); 104} 105 106// t_addrmode_sp := sp + imm8 * 4 107// 108def t_addrmode_sp : Operand<i32>, 109 ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> { 110 let PrintMethod = "printThumbAddrModeSPOperand"; 111 let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm); 112} 113 114//===----------------------------------------------------------------------===// 115// Miscellaneous Instructions. 116// 117 118let Defs = [SP], Uses = [SP] in { 119def tADJCALLSTACKUP : 120PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary, 121 "@ tADJCALLSTACKUP $amt1", 122 [(ARMcallseq_end imm:$amt1, imm:$amt2)]>, Requires<[IsThumb1Only]>; 123 124def tADJCALLSTACKDOWN : 125PseudoInst<(outs), (ins i32imm:$amt), NoItinerary, 126 "@ tADJCALLSTACKDOWN $amt", 127 [(ARMcallseq_start imm:$amt)]>, Requires<[IsThumb1Only]>; 128} 129 130// For both thumb1 and thumb2. 131let isNotDuplicable = 1 in 132def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALU, 133 "$cp:\n\tadd $dst, pc", 134 [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>; 135 136// PC relative add. 137def tADDrPCi : T1I<(outs tGPR:$dst), (ins i32imm:$rhs), IIC_iALU, 138 "add $dst, pc, $rhs * 4", []>; 139 140// ADD rd, sp, #imm8 141def tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, i32imm:$rhs), IIC_iALU, 142 "add $dst, $sp, $rhs * 4 @ addrspi", []>; 143 144// ADD sp, sp, #imm7 145def tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU, 146 "add $dst, $rhs * 4", []>; 147 148// SUB sp, sp, #imm7 149def tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU, 150 "sub $dst, $rhs * 4", []>; 151 152// ADD rm, sp 153def tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU, 154 "add $dst, $rhs", []>; 155 156// ADD sp, rm 157def tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU, 158 "add $dst, $rhs", []>; 159 160// Pseudo instruction that will expand into a tSUBspi + a copy. 161let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. 162def tSUBspi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), 163 NoItinerary, "@ sub $dst, $rhs * 4", []>; 164 165def tADDspr_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), 166 NoItinerary, "@ add $dst, $rhs", []>; 167 168let Defs = [CPSR] in 169def tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), 170 NoItinerary, "@ and $dst, $rhs", []>; 171} // usesCustomDAGSchedInserter 172 173//===----------------------------------------------------------------------===// 174// Control Flow Instructions. 175// 176 177let isReturn = 1, isTerminator = 1 in { 178 def tBX_RET : TI<(outs), (ins), IIC_Br, "bx lr", [(ARMretflag)]>; 179 // Alternative return instruction used by vararg functions. 180 def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx $target", []>; 181} 182 183// FIXME: remove when we have a way to marking a MI with these properties. 184let isReturn = 1, isTerminator = 1, mayLoad = 1 in 185def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$dst1, variable_ops), IIC_Br, 186 "pop${p} $dst1", []>; 187 188let isCall = 1, 189 Defs = [R0, R1, R2, R3, R12, LR, 190 D0, D1, D2, D3, D4, D5, D6, D7, 191 D16, D17, D18, D19, D20, D21, D22, D23, 192 D24, D25, D26, D27, D28, D29, D30, D31, CPSR] in { 193 // Also used for Thumb2 194 def tBL : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 195 "bl ${func:call}", 196 [(ARMtcall tglobaladdr:$func)]>, 197 Requires<[IsThumb, IsNotDarwin]>; 198 199 // ARMv5T and above, also used for Thumb2 200 def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 201 "blx ${func:call}", 202 [(ARMcall tglobaladdr:$func)]>, 203 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 204 205 // Also used for Thumb2 206 def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 207 "blx $func", 208 [(ARMtcall GPR:$func)]>, 209 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 210 211 // ARMv4T 212 def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 213 "mov lr, pc\n\tbx $func", 214 [(ARMcall_nolink tGPR:$func)]>, 215 Requires<[IsThumb1Only, IsNotDarwin]>; 216} 217 218// On Darwin R9 is call-clobbered. 219let isCall = 1, 220 Defs = [R0, R1, R2, R3, R9, R12, LR, 221 D0, D1, D2, D3, D4, D5, D6, D7, 222 D16, D17, D18, D19, D20, D21, D22, D23, 223 D24, D25, D26, D27, D28, D29, D30, D31, CPSR] in { 224 // Also used for Thumb2 225 def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 226 "bl ${func:call}", 227 [(ARMtcall tglobaladdr:$func)]>, 228 Requires<[IsThumb, IsDarwin]>; 229 230 // ARMv5T and above, also used for Thumb2 231 def tBLXi_r9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 232 "blx ${func:call}", 233 [(ARMcall tglobaladdr:$func)]>, 234 Requires<[IsThumb, HasV5T, IsDarwin]>; 235 236 // Also used for Thumb2 237 def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 238 "blx $func", 239 [(ARMtcall GPR:$func)]>, 240 Requires<[IsThumb, HasV5T, IsDarwin]>; 241 242 // ARMv4T 243 def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 244 "mov lr, pc\n\tbx $func", 245 [(ARMcall_nolink tGPR:$func)]>, 246 Requires<[IsThumb1Only, IsDarwin]>; 247} 248 249let isBranch = 1, isTerminator = 1 in { 250 let isBarrier = 1 in { 251 let isPredicable = 1 in 252 def tB : T1I<(outs), (ins brtarget:$target), IIC_Br, 253 "b $target", [(br bb:$target)]>; 254 255 // Far jump 256 let Defs = [LR] in 257 def tBfar : TIx2<(outs), (ins brtarget:$target), IIC_Br, 258 "bl $target\t@ far jump",[]>; 259 260 def tBR_JTr : T1JTI<(outs), 261 (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id), 262 IIC_Br, "mov pc, $target\n\t.align\t2\n$jt", 263 [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>; 264 } 265} 266 267// FIXME: should be able to write a pattern for ARMBrcond, but can't use 268// a two-value operand where a dag node expects two operands. :( 269let isBranch = 1, isTerminator = 1 in 270 def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br, 271 "b$cc $target", 272 [/*(ARMbrcond bb:$target, imm:$cc)*/]>; 273 274//===----------------------------------------------------------------------===// 275// Load Store Instructions. 276// 277 278let canFoldAsLoad = 1 in 279def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoad, 280 "ldr", " $dst, $addr", 281 [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>; 282 283def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoad, 284 "ldrb", " $dst, $addr", 285 [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>; 286 287def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoad, 288 "ldrh", " $dst, $addr", 289 [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>; 290 291let AddedComplexity = 10 in 292def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoad, 293 "ldrsb", " $dst, $addr", 294 [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>; 295 296let AddedComplexity = 10 in 297def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoad, 298 "ldrsh", " $dst, $addr", 299 [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>; 300 301let canFoldAsLoad = 1 in 302def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoad, 303 "ldr", " $dst, $addr", 304 [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>; 305 306// Special instruction for restore. It cannot clobber condition register 307// when it's expanded by eliminateCallFramePseudoInstr(). 308let canFoldAsLoad = 1, mayLoad = 1 in 309def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoad, 310 "ldr", " $dst, $addr", []>; 311 312// Load tconstpool 313let canFoldAsLoad = 1 in 314def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoad, 315 "ldr", " $dst, $addr", 316 [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>; 317 318// Special LDR for loads from non-pc-relative constpools. 319let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in 320def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoad, 321 "ldr", " $dst, $addr", []>; 322 323def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStore, 324 "str", " $src, $addr", 325 [(store tGPR:$src, t_addrmode_s4:$addr)]>; 326 327def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStore, 328 "strb", " $src, $addr", 329 [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>; 330 331def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStore, 332 "strh", " $src, $addr", 333 [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>; 334 335def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStore, 336 "str", " $src, $addr", 337 [(store tGPR:$src, t_addrmode_sp:$addr)]>; 338 339let mayStore = 1 in { 340// Special instruction for spill. It cannot clobber condition register 341// when it's expanded by eliminateCallFramePseudoInstr(). 342def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStore, 343 "str", " $src, $addr", []>; 344} 345 346//===----------------------------------------------------------------------===// 347// Load / store multiple Instructions. 348// 349 350// These requires base address to be written back or one of the loaded regs. 351let mayLoad = 1 in 352def tLDM : T1I<(outs), 353 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops), 354 IIC_iLoad, 355 "ldm${addr:submode}${p} $addr, $dst1", []>; 356 357let mayStore = 1 in 358def tSTM : T1I<(outs), 359 (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops), 360 IIC_iStore, 361 "stm${addr:submode}${p} $addr, $src1", []>; 362 363let mayLoad = 1, Uses = [SP], Defs = [SP] in 364def tPOP : T1I<(outs), (ins pred:$p, reglist:$dst1, variable_ops), IIC_Br, 365 "pop${p} $dst1", []>; 366 367let mayStore = 1, Uses = [SP], Defs = [SP] in 368def tPUSH : T1I<(outs), (ins pred:$p, reglist:$src1, variable_ops), IIC_Br, 369 "push${p} $src1", []>; 370 371//===----------------------------------------------------------------------===// 372// Arithmetic Instructions. 373// 374 375// Add with carry register 376let isCommutable = 1, Uses = [CPSR] in 377def tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 378 "adc", " $dst, $rhs", 379 [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>; 380 381// Add immediate 382def tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU, 383 "add", " $dst, $lhs, $rhs", 384 [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>; 385 386def tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU, 387 "add", " $dst, $rhs", 388 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>; 389 390// Add register 391let isCommutable = 1 in 392def tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 393 "add", " $dst, $lhs, $rhs", 394 [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>; 395 396let neverHasSideEffects = 1 in 397def tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU, 398 "add", " $dst, $rhs @ addhirr", []>; 399 400// And register 401let isCommutable = 1 in 402def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 403 "and", " $dst, $rhs", 404 [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>; 405 406// ASR immediate 407def tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU, 408 "asr", " $dst, $lhs, $rhs", 409 [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>; 410 411// ASR register 412def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 413 "asr", " $dst, $rhs", 414 [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>; 415 416// BIC register 417def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 418 "bic", " $dst, $rhs", 419 [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>; 420 421// CMN register 422let Defs = [CPSR] in { 423def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 424 "cmn", " $lhs, $rhs", 425 [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>; 426def tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 427 "cmn", " $lhs, $rhs", 428 [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>; 429} 430 431// CMP immediate 432let Defs = [CPSR] in { 433def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU, 434 "cmp", " $lhs, $rhs", 435 [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>; 436def tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU, 437 "cmp", " $lhs, $rhs", 438 [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>; 439 440} 441 442// CMP register 443let Defs = [CPSR] in { 444def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 445 "cmp", " $lhs, $rhs", 446 [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>; 447def tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 448 "cmp", " $lhs, $rhs", 449 [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>; 450 451def tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iALU, 452 "cmp", " $lhs, $rhs", []>; 453def tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iALU, 454 "cmp", " $lhs, $rhs", []>; 455} 456 457 458// XOR register 459let isCommutable = 1 in 460def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 461 "eor", " $dst, $rhs", 462 [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>; 463 464// LSL immediate 465def tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU, 466 "lsl", " $dst, $lhs, $rhs", 467 [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>; 468 469// LSL register 470def tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 471 "lsl", " $dst, $rhs", 472 [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>; 473 474// LSR immediate 475def tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU, 476 "lsr", " $dst, $lhs, $rhs", 477 [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>; 478 479// LSR register 480def tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 481 "lsr", " $dst, $rhs", 482 [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>; 483 484// move register 485def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iALU, 486 "mov", " $dst, $src", 487 [(set tGPR:$dst, imm0_255:$src)]>; 488 489// TODO: A7-73: MOV(2) - mov setting flag. 490 491 492let neverHasSideEffects = 1 in { 493// FIXME: Make this predicable. 494def tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU, 495 "mov $dst, $src", []>; 496let Defs = [CPSR] in 497def tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU, 498 "movs $dst, $src", []>; 499 500// FIXME: Make these predicable. 501def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iALU, 502 "mov $dst, $src\t@ hir2lor", []>; 503def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iALU, 504 "mov $dst, $src\t@ lor2hir", []>; 505def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU, 506 "mov $dst, $src\t@ hir2hir", []>; 507} // neverHasSideEffects 508 509// multiply register 510let isCommutable = 1 in 511def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 512 "mul", " $dst, $rhs", 513 [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>; 514 515// move inverse register 516def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU, 517 "mvn", " $dst, $src", 518 [(set tGPR:$dst, (not tGPR:$src))]>; 519 520// bitwise or register 521let isCommutable = 1 in 522def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 523 "orr", " $dst, $rhs", 524 [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>; 525 526// swaps 527def tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU, 528 "rev", " $dst, $src", 529 [(set tGPR:$dst, (bswap tGPR:$src))]>, 530 Requires<[IsThumb1Only, HasV6]>; 531 532def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU, 533 "rev16", " $dst, $src", 534 [(set tGPR:$dst, 535 (or (and (srl tGPR:$src, (i32 8)), 0xFF), 536 (or (and (shl tGPR:$src, (i32 8)), 0xFF00), 537 (or (and (srl tGPR:$src, (i32 8)), 0xFF0000), 538 (and (shl tGPR:$src, (i32 8)), 0xFF000000)))))]>, 539 Requires<[IsThumb1Only, HasV6]>; 540 541def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU, 542 "revsh", " $dst, $src", 543 [(set tGPR:$dst, 544 (sext_inreg 545 (or (srl (and tGPR:$src, 0xFFFF), (i32 8)), 546 (shl tGPR:$src, (i32 8))), i16))]>, 547 Requires<[IsThumb1Only, HasV6]>; 548 549// rotate right register 550def tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 551 "ror", " $dst, $rhs", 552 [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>; 553 554// negate register 555def tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU, 556 "rsb", " $dst, $src, #0", 557 [(set tGPR:$dst, (ineg tGPR:$src))]>; 558 559// Subtract with carry register 560let Uses = [CPSR] in 561def tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 562 "sbc", " $dst, $rhs", 563 [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>; 564 565// Subtract immediate 566def tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU, 567 "sub", " $dst, $lhs, $rhs", 568 [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>; 569 570def tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU, 571 "sub", " $dst, $rhs", 572 [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>; 573 574// subtract register 575def tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 576 "sub", " $dst, $lhs, $rhs", 577 [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>; 578 579// TODO: A7-96: STMIA - store multiple. 580 581// sign-extend byte 582def tSXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU, 583 "sxtb", " $dst, $src", 584 [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>, 585 Requires<[IsThumb1Only, HasV6]>; 586 587// sign-extend short 588def tSXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU, 589 "sxth", " $dst, $src", 590 [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>, 591 Requires<[IsThumb1Only, HasV6]>; 592 593// test 594let isCommutable = 1, Defs = [CPSR] in 595def tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU, 596 "tst", " $lhs, $rhs", 597 [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>; 598 599// zero-extend byte 600def tUXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU, 601 "uxtb", " $dst, $src", 602 [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>, 603 Requires<[IsThumb1Only, HasV6]>; 604 605// zero-extend short 606def tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU, 607 "uxth", " $dst, $src", 608 [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>, 609 Requires<[IsThumb1Only, HasV6]>; 610 611 612// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation. 613// Expanded by the scheduler into a branch sequence. 614// FIXME: Add actual movcc in IT blocks for Thumb2. 615let usesCustomDAGSchedInserter = 1 in // Expanded by the scheduler. 616 def tMOVCCr : 617 PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc), 618 NoItinerary, "@ tMOVCCr $cc", 619 [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>; 620 621// tLEApcrel - Load a pc-relative address into a register without offending the 622// assembler. 623def tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label), IIC_iALU, 624 "adr $dst, #$label", []>; 625 626def tLEApcrelJT : T1I<(outs tGPR:$dst), (ins i32imm:$label, lane_cst:$id), 627 IIC_iALU, "adr $dst, #${label}_${id}", []>; 628 629//===----------------------------------------------------------------------===// 630// TLS Instructions 631// 632 633// __aeabi_read_tp preserves the registers r1-r3. 634let isCall = 1, 635 Defs = [R0, LR] in { 636 def tTPsoft : TIx2<(outs), (ins), IIC_Br, 637 "bl __aeabi_read_tp", 638 [(set R0, ARMthread_pointer)]>; 639} 640 641//===----------------------------------------------------------------------===// 642// Non-Instruction Patterns 643// 644 645// Add with carry 646def : T1Pat<(addc tGPR:$lhs, imm0_7:$rhs), 647 (tADDi3 tGPR:$lhs, imm0_7:$rhs)>; 648def : T1Pat<(addc tGPR:$lhs, imm8_255:$rhs), 649 (tADDi3 tGPR:$lhs, imm8_255:$rhs)>; 650def : T1Pat<(addc tGPR:$lhs, tGPR:$rhs), 651 (tADDrr tGPR:$lhs, tGPR:$rhs)>; 652 653// Subtract with carry 654def : T1Pat<(addc tGPR:$lhs, imm0_7_neg:$rhs), 655 (tSUBi3 tGPR:$lhs, imm0_7_neg:$rhs)>; 656def : T1Pat<(addc tGPR:$lhs, imm8_255_neg:$rhs), 657 (tSUBi8 tGPR:$lhs, imm8_255_neg:$rhs)>; 658def : T1Pat<(subc tGPR:$lhs, tGPR:$rhs), 659 (tSUBrr tGPR:$lhs, tGPR:$rhs)>; 660 661// ConstantPool, GlobalAddress 662def : T1Pat<(ARMWrapper tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>; 663def : T1Pat<(ARMWrapper tconstpool :$dst), (tLEApcrel tconstpool :$dst)>; 664 665// JumpTable 666def : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), 667 (tLEApcrelJT tjumptable:$dst, imm:$id)>; 668 669// Direct calls 670def : T1Pat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>, 671 Requires<[IsThumb, IsNotDarwin]>; 672def : T1Pat<(ARMtcall texternalsym:$func), (tBLr9 texternalsym:$func)>, 673 Requires<[IsThumb, IsDarwin]>; 674 675def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>, 676 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 677def : Tv5Pat<(ARMcall texternalsym:$func), (tBLXi_r9 texternalsym:$func)>, 678 Requires<[IsThumb, HasV5T, IsDarwin]>; 679 680// Indirect calls to ARM routines 681def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr GPR:$dst)>, 682 Requires<[IsThumb, HasV5T, IsNotDarwin]>; 683def : Tv5Pat<(ARMcall GPR:$dst), (tBLXr_r9 GPR:$dst)>, 684 Requires<[IsThumb, HasV5T, IsDarwin]>; 685 686// zextload i1 -> zextload i8 687def : T1Pat<(zextloadi1 t_addrmode_s1:$addr), 688 (tLDRB t_addrmode_s1:$addr)>; 689 690// extload -> zextload 691def : T1Pat<(extloadi1 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 692def : T1Pat<(extloadi8 t_addrmode_s1:$addr), (tLDRB t_addrmode_s1:$addr)>; 693def : T1Pat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>; 694 695// If it's possible to use [r,r] address mode for sextload, select to 696// ldr{b|h} + sxt{b|h} instead. 697def : T1Pat<(sextloadi8 t_addrmode_s1:$addr), 698 (tSXTB (tLDRB t_addrmode_s1:$addr))>; 699def : T1Pat<(sextloadi16 t_addrmode_s2:$addr), 700 (tSXTH (tLDRH t_addrmode_s2:$addr))>; 701 702 703// Large immediate handling. 704 705// Two piece imms. 706def : T1Pat<(i32 thumb_immshifted:$src), 707 (tLSLri (tMOVi8 (thumb_immshifted_val imm:$src)), 708 (thumb_immshifted_shamt imm:$src))>; 709 710def : T1Pat<(i32 imm0_255_comp:$src), 711 (tMVN (tMOVi8 (imm_comp_XFORM imm:$src)))>; 712