1234353Sdim//===-- ARMInstrThumb2.td - Thumb2 support for ARM ---------*- tablegen -*-===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file describes the Thumb2 instruction set. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13194612Sed 14198090Srdivacky// IT block predicate field 15226633Sdimdef it_pred_asmoperand : AsmOperandClass { 16226633Sdim let Name = "ITCondCode"; 17226633Sdim let ParserMethod = "parseITCondCode"; 18226633Sdim} 19198090Srdivackydef it_pred : Operand<i32> { 20204642Srdivacky let PrintMethod = "printMandatoryPredicateOperand"; 21226633Sdim let ParserMatchClass = it_pred_asmoperand; 22198090Srdivacky} 23198090Srdivacky 24198090Srdivacky// IT block condition mask 25226633Sdimdef it_mask_asmoperand : AsmOperandClass { let Name = "ITMask"; } 26198090Srdivackydef it_mask : Operand<i32> { 27198090Srdivacky let PrintMethod = "printThumbITMask"; 28226633Sdim let ParserMatchClass = it_mask_asmoperand; 29198090Srdivacky} 30198090Srdivacky 31226633Sdim// t2_shift_imm: An integer that encodes a shift amount and the type of shift 32226633Sdim// (asr or lsl). The 6-bit immediate encodes as: 33226633Sdim// {5} 0 ==> lsl 34226633Sdim// 1 asr 35226633Sdim// {4-0} imm5 shift amount. 36226633Sdim// asr #32 not allowed 37226633Sdimdef t2_shift_imm : Operand<i32> { 38226633Sdim let PrintMethod = "printShiftImmOperand"; 39226633Sdim let ParserMatchClass = ShifterImmAsmOperand; 40226633Sdim let DecoderMethod = "DecodeT2ShifterImmOperand"; 41226633Sdim} 42226633Sdim 43194612Sed// Shifted operands. No register controlled shifts for Thumb2. 44194612Sed// Note: We do not support rrx shifted operands yet. 45194612Seddef t2_so_reg : Operand<i32>, // reg imm 46195098Sed ComplexPattern<i32, 2, "SelectT2ShifterOperandReg", 47194612Sed [shl,srl,sra,rotr]> { 48218893Sdim let EncoderMethod = "getT2SORegOpValue"; 49195098Sed let PrintMethod = "printT2SOOperand"; 50226633Sdim let DecoderMethod = "DecodeSORegImmOperand"; 51226633Sdim let ParserMatchClass = ShiftedImmAsmOperand; 52212904Sdim let MIOperandInfo = (ops rGPR, i32imm); 53194612Sed} 54194612Sed 55194754Sed// t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value 56194754Seddef t2_so_imm_not_XFORM : SDNodeXForm<imm, [{ 57198090Srdivacky return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32); 58194612Sed}]>; 59194612Sed 60194754Sed// t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value 61194754Seddef t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{ 62198090Srdivacky return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32); 63194754Sed}]>; 64194612Sed 65239462Sdim// so_imm_notSext_XFORM - Return a so_imm value packed into the format 66239462Sdim// described for so_imm_notSext def below, with sign extension from 16 67239462Sdim// bits. 68239462Sdimdef t2_so_imm_notSext16_XFORM : SDNodeXForm<imm, [{ 69239462Sdim APInt apIntN = N->getAPIntValue(); 70239462Sdim unsigned N16bitSignExt = apIntN.trunc(16).sext(32).getZExtValue(); 71239462Sdim return CurDAG->getTargetConstant(~N16bitSignExt, MVT::i32); 72239462Sdim}]>; 73239462Sdim 74194754Sed// t2_so_imm - Match a 32-bit immediate operand, which is an 75194754Sed// 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit 76218893Sdim// immediate splatted into multiple bytes of the word. 77234353Sdimdef t2_so_imm_asmoperand : ImmAsmOperand { let Name = "T2SOImm"; } 78221345Sdimdef t2_so_imm : Operand<i32>, ImmLeaf<i32, [{ 79221345Sdim return ARM_AM::getT2SOImmVal(Imm) != -1; 80221345Sdim }]> { 81224145Sdim let ParserMatchClass = t2_so_imm_asmoperand; 82218893Sdim let EncoderMethod = "getT2SOImmOpValue"; 83226633Sdim let DecoderMethod = "DecodeT2SOImm"; 84218893Sdim} 85194612Sed 86204642Srdivacky// t2_so_imm_not - Match an immediate that is a complement 87194754Sed// of a t2_so_imm. 88234353Sdim// Note: this pattern doesn't require an encoder method and such, as it's 89234353Sdim// only used on aliases (Pat<> and InstAlias<>). The actual encoding 90234353Sdim// is handled by the destination instructions, which use t2_so_imm. 91234353Sdimdef t2_so_imm_not_asmoperand : AsmOperandClass { let Name = "T2SOImmNot"; } 92234353Sdimdef t2_so_imm_not : Operand<i32>, PatLeaf<(imm), [{ 93198090Srdivacky return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1; 94234353Sdim}], t2_so_imm_not_XFORM> { 95234353Sdim let ParserMatchClass = t2_so_imm_not_asmoperand; 96234353Sdim} 97194612Sed 98239462Sdim// t2_so_imm_notSext - match an immediate that is a complement of a t2_so_imm 99239462Sdim// if the upper 16 bits are zero. 100239462Sdimdef t2_so_imm_notSext : Operand<i32>, PatLeaf<(imm), [{ 101239462Sdim APInt apIntN = N->getAPIntValue(); 102239462Sdim if (!apIntN.isIntN(16)) return false; 103239462Sdim unsigned N16bitSignExt = apIntN.trunc(16).sext(32).getZExtValue(); 104239462Sdim return ARM_AM::getT2SOImmVal(~N16bitSignExt) != -1; 105239462Sdim }], t2_so_imm_notSext16_XFORM> { 106239462Sdim let ParserMatchClass = t2_so_imm_not_asmoperand; 107239462Sdim} 108239462Sdim 109194754Sed// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm. 110234353Sdimdef t2_so_imm_neg_asmoperand : AsmOperandClass { let Name = "T2SOImmNeg"; } 111234353Sdimdef t2_so_imm_neg : Operand<i32>, PatLeaf<(imm), [{ 112234353Sdim int64_t Value = -(int)N->getZExtValue(); 113234353Sdim return Value && ARM_AM::getT2SOImmVal(Value) != -1; 114234353Sdim}], t2_so_imm_neg_XFORM> { 115234353Sdim let ParserMatchClass = t2_so_imm_neg_asmoperand; 116234353Sdim} 117194754Sed 118194754Sed/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095]. 119234353Sdimdef imm0_4095_asmoperand: ImmAsmOperand { let Name = "Imm0_4095"; } 120234353Sdimdef imm0_4095 : Operand<i32>, ImmLeaf<i32, [{ 121221345Sdim return Imm >= 0 && Imm < 4096; 122234353Sdim}]> { 123234353Sdim let ParserMatchClass = imm0_4095_asmoperand; 124234353Sdim} 125194754Sed 126234353Sdimdef imm0_4095_neg_asmoperand: AsmOperandClass { let Name = "Imm0_4095Neg"; } 127234353Sdimdef imm0_4095_neg : Operand<i32>, PatLeaf<(i32 imm), [{ 128204642Srdivacky return (uint32_t)(-N->getZExtValue()) < 4096; 129234353Sdim}], imm_neg_XFORM> { 130234353Sdim let ParserMatchClass = imm0_4095_neg_asmoperand; 131234353Sdim} 132194612Sed 133249423Sdimdef imm1_255_neg : PatLeaf<(i32 imm), [{ 134249423Sdim uint32_t Val = -N->getZExtValue(); 135249423Sdim return (Val > 0 && Val < 255); 136204642Srdivacky}], imm_neg_XFORM>; 137194612Sed 138210299Seddef imm0_255_not : PatLeaf<(i32 imm), [{ 139210299Sed return (uint32_t)(~N->getZExtValue()) < 255; 140210299Sed}], imm_comp_XFORM>; 141210299Sed 142221345Sdimdef lo5AllOne : PatLeaf<(i32 imm), [{ 143221345Sdim // Returns true if all low 5-bits are 1. 144221345Sdim return (((uint32_t)N->getZExtValue()) & 0x1FUL) == 0x1FUL; 145221345Sdim}]>; 146221345Sdim 147195340Sed// Define Thumb2 specific addressing modes. 148195340Sed 149195340Sed// t2addrmode_imm12 := reg + imm12 150226633Sdimdef t2addrmode_imm12_asmoperand : AsmOperandClass {let Name="MemUImm12Offset";} 151195340Seddef t2addrmode_imm12 : Operand<i32>, 152195340Sed ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> { 153251662Sdim let PrintMethod = "printAddrModeImm12Operand<false>"; 154218893Sdim let EncoderMethod = "getAddrModeImm12OpValue"; 155226633Sdim let DecoderMethod = "DecodeT2AddrModeImm12"; 156226633Sdim let ParserMatchClass = t2addrmode_imm12_asmoperand; 157195340Sed let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 158195340Sed} 159195340Sed 160221345Sdim// t2ldrlabel := imm12 161221345Sdimdef t2ldrlabel : Operand<i32> { 162221345Sdim let EncoderMethod = "getAddrModeImm12OpValue"; 163243830Sdim let PrintMethod = "printThumbLdrLabelOperand"; 164221345Sdim} 165221345Sdim 166234353Sdimdef t2ldr_pcrel_imm12_asmoperand : AsmOperandClass {let Name = "MemPCRelImm12";} 167234353Sdimdef t2ldr_pcrel_imm12 : Operand<i32> { 168234353Sdim let ParserMatchClass = t2ldr_pcrel_imm12_asmoperand; 169234353Sdim // used for assembler pseudo instruction and maps to t2ldrlabel, so 170234353Sdim // doesn't need encoder or print methods of its own. 171234353Sdim} 172221345Sdim 173218893Sdim// ADR instruction labels. 174218893Sdimdef t2adrlabel : Operand<i32> { 175218893Sdim let EncoderMethod = "getT2AdrLabelOpValue"; 176263508Sdim let PrintMethod = "printAdrLabelOperand<0>"; 177218893Sdim} 178218893Sdim 179226633Sdim// t2addrmode_posimm8 := reg + imm8 180226633Sdimdef MemPosImm8OffsetAsmOperand : AsmOperandClass {let Name="MemPosImm8Offset";} 181226633Sdimdef t2addrmode_posimm8 : Operand<i32> { 182263508Sdim let PrintMethod = "printT2AddrModeImm8Operand<false>"; 183226633Sdim let EncoderMethod = "getT2AddrModeImm8OpValue"; 184226633Sdim let DecoderMethod = "DecodeT2AddrModeImm8"; 185226633Sdim let ParserMatchClass = MemPosImm8OffsetAsmOperand; 186226633Sdim let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 187226633Sdim} 188226633Sdim 189226633Sdim// t2addrmode_negimm8 := reg - imm8 190226633Sdimdef MemNegImm8OffsetAsmOperand : AsmOperandClass {let Name="MemNegImm8Offset";} 191226633Sdimdef t2addrmode_negimm8 : Operand<i32>, 192226633Sdim ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> { 193263508Sdim let PrintMethod = "printT2AddrModeImm8Operand<false>"; 194226633Sdim let EncoderMethod = "getT2AddrModeImm8OpValue"; 195226633Sdim let DecoderMethod = "DecodeT2AddrModeImm8"; 196226633Sdim let ParserMatchClass = MemNegImm8OffsetAsmOperand; 197226633Sdim let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 198226633Sdim} 199226633Sdim 200204792Srdivacky// t2addrmode_imm8 := reg +/- imm8 201226633Sdimdef MemImm8OffsetAsmOperand : AsmOperandClass { let Name = "MemImm8Offset"; } 202263508Sdimclass T2AddrMode_Imm8 : Operand<i32>, 203263508Sdim ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> { 204218893Sdim let EncoderMethod = "getT2AddrModeImm8OpValue"; 205226633Sdim let DecoderMethod = "DecodeT2AddrModeImm8"; 206226633Sdim let ParserMatchClass = MemImm8OffsetAsmOperand; 207195340Sed let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 208195340Sed} 209195340Sed 210263508Sdimdef t2addrmode_imm8 : T2AddrMode_Imm8 { 211263508Sdim let PrintMethod = "printT2AddrModeImm8Operand<false>"; 212263508Sdim} 213263508Sdim 214263508Sdimdef t2addrmode_imm8_pre : T2AddrMode_Imm8 { 215263508Sdim let PrintMethod = "printT2AddrModeImm8Operand<true>"; 216263508Sdim} 217263508Sdim 218195340Seddef t2am_imm8_offset : Operand<i32>, 219218893Sdim ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", 220218893Sdim [], [SDNPWantRoot]> { 221195340Sed let PrintMethod = "printT2AddrModeImm8OffsetOperand"; 222218893Sdim let EncoderMethod = "getT2AddrModeImm8OffsetOpValue"; 223226633Sdim let DecoderMethod = "DecodeT2Imm8"; 224195340Sed} 225195340Sed 226198090Srdivacky// t2addrmode_imm8s4 := reg +/- (imm8 << 2) 227226633Sdimdef MemImm8s4OffsetAsmOperand : AsmOperandClass {let Name = "MemImm8s4Offset";} 228263508Sdimclass T2AddrMode_Imm8s4 : Operand<i32> { 229218893Sdim let EncoderMethod = "getT2AddrModeImm8s4OpValue"; 230226633Sdim let DecoderMethod = "DecodeT2AddrModeImm8s4"; 231226633Sdim let ParserMatchClass = MemImm8s4OffsetAsmOperand; 232195340Sed let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 233195340Sed} 234195340Sed 235263508Sdimdef t2addrmode_imm8s4 : T2AddrMode_Imm8s4 { 236263508Sdim let PrintMethod = "printT2AddrModeImm8s4Operand<false>"; 237263508Sdim} 238263508Sdim 239263508Sdimdef t2addrmode_imm8s4_pre : T2AddrMode_Imm8s4 { 240263508Sdim let PrintMethod = "printT2AddrModeImm8s4Operand<true>"; 241263508Sdim} 242263508Sdim 243226633Sdimdef t2am_imm8s4_offset_asmoperand : AsmOperandClass { let Name = "Imm8s4"; } 244205218Srdivackydef t2am_imm8s4_offset : Operand<i32> { 245205218Srdivacky let PrintMethod = "printT2AddrModeImm8s4OffsetOperand"; 246226633Sdim let EncoderMethod = "getT2Imm8s4OpValue"; 247226633Sdim let DecoderMethod = "DecodeT2Imm8S4"; 248205218Srdivacky} 249205218Srdivacky 250226633Sdim// t2addrmode_imm0_1020s4 := reg + (imm8 << 2) 251226633Sdimdef MemImm0_1020s4OffsetAsmOperand : AsmOperandClass { 252226633Sdim let Name = "MemImm0_1020s4Offset"; 253226633Sdim} 254263508Sdimdef t2addrmode_imm0_1020s4 : Operand<i32>, 255263508Sdim ComplexPattern<i32, 2, "SelectT2AddrModeExclusive"> { 256226633Sdim let PrintMethod = "printT2AddrModeImm0_1020s4Operand"; 257226633Sdim let EncoderMethod = "getT2AddrModeImm0_1020s4OpValue"; 258226633Sdim let DecoderMethod = "DecodeT2AddrModeImm0_1020s4"; 259226633Sdim let ParserMatchClass = MemImm0_1020s4OffsetAsmOperand; 260226633Sdim let MIOperandInfo = (ops GPRnopc:$base, i32imm:$offsimm); 261226633Sdim} 262226633Sdim 263198090Srdivacky// t2addrmode_so_reg := reg + (reg << imm2) 264226633Sdimdef t2addrmode_so_reg_asmoperand : AsmOperandClass {let Name="T2MemRegOffset";} 265195340Seddef t2addrmode_so_reg : Operand<i32>, 266195340Sed ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> { 267195340Sed let PrintMethod = "printT2AddrModeSoRegOperand"; 268218893Sdim let EncoderMethod = "getT2AddrModeSORegOpValue"; 269226633Sdim let DecoderMethod = "DecodeT2AddrModeSOReg"; 270226633Sdim let ParserMatchClass = t2addrmode_so_reg_asmoperand; 271212904Sdim let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm); 272195340Sed} 273195340Sed 274226633Sdim// Addresses for the TBB/TBH instructions. 275226633Sdimdef addrmode_tbb_asmoperand : AsmOperandClass { let Name = "MemTBB"; } 276226633Sdimdef addrmode_tbb : Operand<i32> { 277226633Sdim let PrintMethod = "printAddrModeTBB"; 278226633Sdim let ParserMatchClass = addrmode_tbb_asmoperand; 279226633Sdim let MIOperandInfo = (ops GPR:$Rn, rGPR:$Rm); 280221345Sdim} 281226633Sdimdef addrmode_tbh_asmoperand : AsmOperandClass { let Name = "MemTBH"; } 282226633Sdimdef addrmode_tbh : Operand<i32> { 283226633Sdim let PrintMethod = "printAddrModeTBH"; 284226633Sdim let ParserMatchClass = addrmode_tbh_asmoperand; 285226633Sdim let MIOperandInfo = (ops GPR:$Rn, rGPR:$Rm); 286226633Sdim} 287195340Sed 288194612Sed//===----------------------------------------------------------------------===// 289195098Sed// Multiclass helpers... 290194612Sed// 291194612Sed 292218893Sdim 293218893Sdimclass T2OneRegImm<dag oops, dag iops, InstrItinClass itin, 294218893Sdim string opc, string asm, list<dag> pattern> 295218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 296218893Sdim bits<4> Rd; 297218893Sdim bits<12> imm; 298218893Sdim 299218893Sdim let Inst{11-8} = Rd; 300218893Sdim let Inst{26} = imm{11}; 301218893Sdim let Inst{14-12} = imm{10-8}; 302218893Sdim let Inst{7-0} = imm{7-0}; 303218893Sdim} 304218893Sdim 305218893Sdim 306218893Sdimclass T2sOneRegImm<dag oops, dag iops, InstrItinClass itin, 307218893Sdim string opc, string asm, list<dag> pattern> 308218893Sdim : T2sI<oops, iops, itin, opc, asm, pattern> { 309218893Sdim bits<4> Rd; 310218893Sdim bits<4> Rn; 311218893Sdim bits<12> imm; 312218893Sdim 313218893Sdim let Inst{11-8} = Rd; 314218893Sdim let Inst{26} = imm{11}; 315218893Sdim let Inst{14-12} = imm{10-8}; 316218893Sdim let Inst{7-0} = imm{7-0}; 317218893Sdim} 318218893Sdim 319218893Sdimclass T2OneRegCmpImm<dag oops, dag iops, InstrItinClass itin, 320218893Sdim string opc, string asm, list<dag> pattern> 321218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 322218893Sdim bits<4> Rn; 323218893Sdim bits<12> imm; 324218893Sdim 325218893Sdim let Inst{19-16} = Rn; 326218893Sdim let Inst{26} = imm{11}; 327218893Sdim let Inst{14-12} = imm{10-8}; 328218893Sdim let Inst{7-0} = imm{7-0}; 329218893Sdim} 330218893Sdim 331218893Sdim 332218893Sdimclass T2OneRegShiftedReg<dag oops, dag iops, InstrItinClass itin, 333218893Sdim string opc, string asm, list<dag> pattern> 334218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 335218893Sdim bits<4> Rd; 336218893Sdim bits<12> ShiftedRm; 337218893Sdim 338218893Sdim let Inst{11-8} = Rd; 339218893Sdim let Inst{3-0} = ShiftedRm{3-0}; 340218893Sdim let Inst{5-4} = ShiftedRm{6-5}; 341218893Sdim let Inst{14-12} = ShiftedRm{11-9}; 342218893Sdim let Inst{7-6} = ShiftedRm{8-7}; 343218893Sdim} 344218893Sdim 345218893Sdimclass T2sOneRegShiftedReg<dag oops, dag iops, InstrItinClass itin, 346218893Sdim string opc, string asm, list<dag> pattern> 347218893Sdim : T2sI<oops, iops, itin, opc, asm, pattern> { 348218893Sdim bits<4> Rd; 349218893Sdim bits<12> ShiftedRm; 350218893Sdim 351218893Sdim let Inst{11-8} = Rd; 352218893Sdim let Inst{3-0} = ShiftedRm{3-0}; 353218893Sdim let Inst{5-4} = ShiftedRm{6-5}; 354218893Sdim let Inst{14-12} = ShiftedRm{11-9}; 355218893Sdim let Inst{7-6} = ShiftedRm{8-7}; 356218893Sdim} 357218893Sdim 358218893Sdimclass T2OneRegCmpShiftedReg<dag oops, dag iops, InstrItinClass itin, 359218893Sdim string opc, string asm, list<dag> pattern> 360218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 361218893Sdim bits<4> Rn; 362218893Sdim bits<12> ShiftedRm; 363218893Sdim 364218893Sdim let Inst{19-16} = Rn; 365218893Sdim let Inst{3-0} = ShiftedRm{3-0}; 366218893Sdim let Inst{5-4} = ShiftedRm{6-5}; 367218893Sdim let Inst{14-12} = ShiftedRm{11-9}; 368218893Sdim let Inst{7-6} = ShiftedRm{8-7}; 369218893Sdim} 370218893Sdim 371218893Sdimclass T2TwoReg<dag oops, dag iops, InstrItinClass itin, 372218893Sdim string opc, string asm, list<dag> pattern> 373218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 374218893Sdim bits<4> Rd; 375218893Sdim bits<4> Rm; 376218893Sdim 377218893Sdim let Inst{11-8} = Rd; 378218893Sdim let Inst{3-0} = Rm; 379218893Sdim} 380218893Sdim 381218893Sdimclass T2sTwoReg<dag oops, dag iops, InstrItinClass itin, 382218893Sdim string opc, string asm, list<dag> pattern> 383218893Sdim : T2sI<oops, iops, itin, opc, asm, pattern> { 384218893Sdim bits<4> Rd; 385218893Sdim bits<4> Rm; 386218893Sdim 387218893Sdim let Inst{11-8} = Rd; 388218893Sdim let Inst{3-0} = Rm; 389218893Sdim} 390218893Sdim 391218893Sdimclass T2TwoRegCmp<dag oops, dag iops, InstrItinClass itin, 392218893Sdim string opc, string asm, list<dag> pattern> 393218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 394218893Sdim bits<4> Rn; 395218893Sdim bits<4> Rm; 396218893Sdim 397218893Sdim let Inst{19-16} = Rn; 398218893Sdim let Inst{3-0} = Rm; 399218893Sdim} 400218893Sdim 401218893Sdim 402218893Sdimclass T2TwoRegImm<dag oops, dag iops, InstrItinClass itin, 403218893Sdim string opc, string asm, list<dag> pattern> 404218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 405218893Sdim bits<4> Rd; 406218893Sdim bits<4> Rn; 407218893Sdim bits<12> imm; 408218893Sdim 409218893Sdim let Inst{11-8} = Rd; 410218893Sdim let Inst{19-16} = Rn; 411218893Sdim let Inst{26} = imm{11}; 412218893Sdim let Inst{14-12} = imm{10-8}; 413218893Sdim let Inst{7-0} = imm{7-0}; 414218893Sdim} 415218893Sdim 416218893Sdimclass T2sTwoRegImm<dag oops, dag iops, InstrItinClass itin, 417218893Sdim string opc, string asm, list<dag> pattern> 418218893Sdim : T2sI<oops, iops, itin, opc, asm, pattern> { 419218893Sdim bits<4> Rd; 420218893Sdim bits<4> Rn; 421218893Sdim bits<12> imm; 422218893Sdim 423218893Sdim let Inst{11-8} = Rd; 424218893Sdim let Inst{19-16} = Rn; 425218893Sdim let Inst{26} = imm{11}; 426218893Sdim let Inst{14-12} = imm{10-8}; 427218893Sdim let Inst{7-0} = imm{7-0}; 428218893Sdim} 429218893Sdim 430218893Sdimclass T2TwoRegShiftImm<dag oops, dag iops, InstrItinClass itin, 431218893Sdim string opc, string asm, list<dag> pattern> 432218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 433218893Sdim bits<4> Rd; 434218893Sdim bits<4> Rm; 435218893Sdim bits<5> imm; 436218893Sdim 437218893Sdim let Inst{11-8} = Rd; 438218893Sdim let Inst{3-0} = Rm; 439218893Sdim let Inst{14-12} = imm{4-2}; 440218893Sdim let Inst{7-6} = imm{1-0}; 441218893Sdim} 442218893Sdim 443218893Sdimclass T2sTwoRegShiftImm<dag oops, dag iops, InstrItinClass itin, 444218893Sdim string opc, string asm, list<dag> pattern> 445218893Sdim : T2sI<oops, iops, itin, opc, asm, pattern> { 446218893Sdim bits<4> Rd; 447218893Sdim bits<4> Rm; 448218893Sdim bits<5> imm; 449218893Sdim 450218893Sdim let Inst{11-8} = Rd; 451218893Sdim let Inst{3-0} = Rm; 452218893Sdim let Inst{14-12} = imm{4-2}; 453218893Sdim let Inst{7-6} = imm{1-0}; 454218893Sdim} 455218893Sdim 456218893Sdimclass T2ThreeReg<dag oops, dag iops, InstrItinClass itin, 457218893Sdim string opc, string asm, list<dag> pattern> 458218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 459218893Sdim bits<4> Rd; 460218893Sdim bits<4> Rn; 461218893Sdim bits<4> Rm; 462218893Sdim 463218893Sdim let Inst{11-8} = Rd; 464218893Sdim let Inst{19-16} = Rn; 465218893Sdim let Inst{3-0} = Rm; 466218893Sdim} 467218893Sdim 468263508Sdimclass T2ThreeRegNoP<dag oops, dag iops, InstrItinClass itin, 469263508Sdim string asm, list<dag> pattern> 470263508Sdim : T2XI<oops, iops, itin, asm, pattern> { 471263508Sdim bits<4> Rd; 472263508Sdim bits<4> Rn; 473263508Sdim bits<4> Rm; 474263508Sdim 475263508Sdim let Inst{11-8} = Rd; 476263508Sdim let Inst{19-16} = Rn; 477263508Sdim let Inst{3-0} = Rm; 478263508Sdim} 479263508Sdim 480218893Sdimclass T2sThreeReg<dag oops, dag iops, InstrItinClass itin, 481218893Sdim string opc, string asm, list<dag> pattern> 482218893Sdim : T2sI<oops, iops, itin, opc, asm, pattern> { 483218893Sdim bits<4> Rd; 484218893Sdim bits<4> Rn; 485218893Sdim bits<4> Rm; 486218893Sdim 487218893Sdim let Inst{11-8} = Rd; 488218893Sdim let Inst{19-16} = Rn; 489218893Sdim let Inst{3-0} = Rm; 490218893Sdim} 491218893Sdim 492218893Sdimclass T2TwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin, 493218893Sdim string opc, string asm, list<dag> pattern> 494218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 495218893Sdim bits<4> Rd; 496218893Sdim bits<4> Rn; 497218893Sdim bits<12> ShiftedRm; 498218893Sdim 499218893Sdim let Inst{11-8} = Rd; 500218893Sdim let Inst{19-16} = Rn; 501218893Sdim let Inst{3-0} = ShiftedRm{3-0}; 502218893Sdim let Inst{5-4} = ShiftedRm{6-5}; 503218893Sdim let Inst{14-12} = ShiftedRm{11-9}; 504218893Sdim let Inst{7-6} = ShiftedRm{8-7}; 505218893Sdim} 506218893Sdim 507218893Sdimclass T2sTwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin, 508218893Sdim string opc, string asm, list<dag> pattern> 509218893Sdim : T2sI<oops, iops, itin, opc, asm, pattern> { 510218893Sdim bits<4> Rd; 511218893Sdim bits<4> Rn; 512218893Sdim bits<12> ShiftedRm; 513218893Sdim 514218893Sdim let Inst{11-8} = Rd; 515218893Sdim let Inst{19-16} = Rn; 516218893Sdim let Inst{3-0} = ShiftedRm{3-0}; 517218893Sdim let Inst{5-4} = ShiftedRm{6-5}; 518218893Sdim let Inst{14-12} = ShiftedRm{11-9}; 519218893Sdim let Inst{7-6} = ShiftedRm{8-7}; 520218893Sdim} 521218893Sdim 522218893Sdimclass T2FourReg<dag oops, dag iops, InstrItinClass itin, 523218893Sdim string opc, string asm, list<dag> pattern> 524218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 525218893Sdim bits<4> Rd; 526218893Sdim bits<4> Rn; 527218893Sdim bits<4> Rm; 528218893Sdim bits<4> Ra; 529218893Sdim 530218893Sdim let Inst{19-16} = Rn; 531218893Sdim let Inst{15-12} = Ra; 532218893Sdim let Inst{11-8} = Rd; 533218893Sdim let Inst{3-0} = Rm; 534218893Sdim} 535218893Sdim 536218893Sdimclass T2MulLong<bits<3> opc22_20, bits<4> opc7_4, 537218893Sdim dag oops, dag iops, InstrItinClass itin, 538218893Sdim string opc, string asm, list<dag> pattern> 539218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 540218893Sdim bits<4> RdLo; 541218893Sdim bits<4> RdHi; 542218893Sdim bits<4> Rn; 543218893Sdim bits<4> Rm; 544218893Sdim 545218893Sdim let Inst{31-23} = 0b111110111; 546218893Sdim let Inst{22-20} = opc22_20; 547218893Sdim let Inst{19-16} = Rn; 548218893Sdim let Inst{15-12} = RdLo; 549218893Sdim let Inst{11-8} = RdHi; 550218893Sdim let Inst{7-4} = opc7_4; 551218893Sdim let Inst{3-0} = Rm; 552218893Sdim} 553243830Sdimclass T2MlaLong<bits<3> opc22_20, bits<4> opc7_4, 554243830Sdim dag oops, dag iops, InstrItinClass itin, 555243830Sdim string opc, string asm, list<dag> pattern> 556243830Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 557243830Sdim bits<4> RdLo; 558243830Sdim bits<4> RdHi; 559243830Sdim bits<4> Rn; 560243830Sdim bits<4> Rm; 561218893Sdim 562243830Sdim let Inst{31-23} = 0b111110111; 563243830Sdim let Inst{22-20} = opc22_20; 564243830Sdim let Inst{19-16} = Rn; 565243830Sdim let Inst{15-12} = RdLo; 566243830Sdim let Inst{11-8} = RdHi; 567243830Sdim let Inst{7-4} = opc7_4; 568243830Sdim let Inst{3-0} = Rm; 569243830Sdim} 570218893Sdim 571243830Sdim 572195098Sed/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a 573208599Srdivacky/// binary operation that produces a value. These are predicable and can be 574195098Sed/// changed to modify CPSR. 575218893Sdimmulticlass T2I_bin_irs<bits<4> opcod, string opc, 576218893Sdim InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 577239462Sdim PatFrag opnode, bit Commutable = 0, 578224145Sdim string wide = ""> { 579195098Sed // shifted imm 580218893Sdim def ri : T2sTwoRegImm< 581218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), iii, 582218893Sdim opc, "\t$Rd, $Rn, $imm", 583263508Sdim [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_imm:$imm))]>, 584263508Sdim Sched<[WriteALU, ReadALU]> { 585201360Srdivacky let Inst{31-27} = 0b11110; 586201360Srdivacky let Inst{25} = 0; 587201360Srdivacky let Inst{24-21} = opcod; 588201360Srdivacky let Inst{15} = 0; 589201360Srdivacky } 590195098Sed // register 591218893Sdim def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), iir, 592218893Sdim opc, !strconcat(wide, "\t$Rd, $Rn, $Rm"), 593263508Sdim [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>, 594263508Sdim Sched<[WriteALU, ReadALU, ReadALU]> { 595195098Sed let isCommutable = Commutable; 596201360Srdivacky let Inst{31-27} = 0b11101; 597201360Srdivacky let Inst{26-25} = 0b01; 598201360Srdivacky let Inst{24-21} = opcod; 599201360Srdivacky let Inst{14-12} = 0b000; // imm3 600201360Srdivacky let Inst{7-6} = 0b00; // imm2 601201360Srdivacky let Inst{5-4} = 0b00; // type 602195098Sed } 603195098Sed // shifted register 604218893Sdim def rs : T2sTwoRegShiftedReg< 605218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), iis, 606218893Sdim opc, !strconcat(wide, "\t$Rd, $Rn, $ShiftedRm"), 607263508Sdim [(set rGPR:$Rd, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm))]>, 608263508Sdim Sched<[WriteALUsi, ReadALU]> { 609201360Srdivacky let Inst{31-27} = 0b11101; 610201360Srdivacky let Inst{26-25} = 0b01; 611201360Srdivacky let Inst{24-21} = opcod; 612201360Srdivacky } 613224145Sdim // Assembly aliases for optional destination operand when it's the same 614224145Sdim // as the source operand. 615226633Sdim def : t2InstAlias<!strconcat(opc, "${s}${p} $Rdn, $imm"), 616239462Sdim (!cast<Instruction>(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, 617224145Sdim t2_so_imm:$imm, pred:$p, 618226633Sdim cc_out:$s)>; 619226633Sdim def : t2InstAlias<!strconcat(opc, "${s}${p}", wide, " $Rdn, $Rm"), 620239462Sdim (!cast<Instruction>(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, 621224145Sdim rGPR:$Rm, pred:$p, 622226633Sdim cc_out:$s)>; 623226633Sdim def : t2InstAlias<!strconcat(opc, "${s}${p}", wide, " $Rdn, $shift"), 624239462Sdim (!cast<Instruction>(NAME#"rs") rGPR:$Rdn, rGPR:$Rdn, 625224145Sdim t2_so_reg:$shift, pred:$p, 626226633Sdim cc_out:$s)>; 627195098Sed} 628195098Sed 629198090Srdivacky/// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need 630224145Sdim// the ".w" suffix to indicate that they are wide. 631218893Sdimmulticlass T2I_bin_w_irs<bits<4> opcod, string opc, 632218893Sdim InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 633239462Sdim PatFrag opnode, bit Commutable = 0> : 634239462Sdim T2I_bin_irs<opcod, opc, iii, iir, iis, opnode, Commutable, ".w"> { 635234353Sdim // Assembler aliases w/ the ".w" suffix. 636234353Sdim def : t2InstAlias<!strconcat(opc, "${s}${p}.w", " $Rd, $Rn, $imm"), 637239462Sdim (!cast<Instruction>(NAME#"ri") rGPR:$Rd, rGPR:$Rn, t2_so_imm:$imm, pred:$p, 638239462Sdim cc_out:$s)>; 639226633Sdim // Assembler aliases w/o the ".w" suffix. 640226633Sdim def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rd, $Rn, $Rm"), 641239462Sdim (!cast<Instruction>(NAME#"rr") rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p, 642239462Sdim cc_out:$s)>; 643226633Sdim def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rd, $Rn, $shift"), 644239462Sdim (!cast<Instruction>(NAME#"rs") rGPR:$Rd, rGPR:$Rn, t2_so_reg:$shift, 645239462Sdim pred:$p, cc_out:$s)>; 646198090Srdivacky 647226633Sdim // and with the optional destination operand, too. 648234353Sdim def : t2InstAlias<!strconcat(opc, "${s}${p}.w", " $Rdn, $imm"), 649239462Sdim (!cast<Instruction>(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, t2_so_imm:$imm, 650239462Sdim pred:$p, cc_out:$s)>; 651226633Sdim def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rdn, $Rm"), 652239462Sdim (!cast<Instruction>(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p, 653239462Sdim cc_out:$s)>; 654226633Sdim def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rdn, $shift"), 655239462Sdim (!cast<Instruction>(NAME#"rs") rGPR:$Rdn, rGPR:$Rdn, t2_so_reg:$shift, 656239462Sdim pred:$p, cc_out:$s)>; 657226633Sdim} 658226633Sdim 659195098Sed/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are 660212904Sdim/// reversed. The 'rr' form is only defined for the disassembler; for codegen 661212904Sdim/// it is equivalent to the T2I_bin_irs counterpart. 662212904Sdimmulticlass T2I_rbin_irs<bits<4> opcod, string opc, PatFrag opnode> { 663194754Sed // shifted imm 664218893Sdim def ri : T2sTwoRegImm< 665218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), IIC_iALUi, 666218893Sdim opc, ".w\t$Rd, $Rn, $imm", 667263508Sdim [(set rGPR:$Rd, (opnode t2_so_imm:$imm, rGPR:$Rn))]>, 668263508Sdim Sched<[WriteALU, ReadALU]> { 669201360Srdivacky let Inst{31-27} = 0b11110; 670201360Srdivacky let Inst{25} = 0; 671201360Srdivacky let Inst{24-21} = opcod; 672201360Srdivacky let Inst{15} = 0; 673201360Srdivacky } 674212904Sdim // register 675218893Sdim def rr : T2sThreeReg< 676218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr, 677218893Sdim opc, "\t$Rd, $Rn, $Rm", 678263508Sdim [/* For disassembly only; pattern left blank */]>, 679263508Sdim Sched<[WriteALU, ReadALU, ReadALU]> { 680212904Sdim let Inst{31-27} = 0b11101; 681212904Sdim let Inst{26-25} = 0b01; 682212904Sdim let Inst{24-21} = opcod; 683212904Sdim let Inst{14-12} = 0b000; // imm3 684212904Sdim let Inst{7-6} = 0b00; // imm2 685212904Sdim let Inst{5-4} = 0b00; // type 686212904Sdim } 687194754Sed // shifted register 688218893Sdim def rs : T2sTwoRegShiftedReg< 689218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), 690218893Sdim IIC_iALUsir, opc, "\t$Rd, $Rn, $ShiftedRm", 691263508Sdim [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm, rGPR:$Rn))]>, 692263508Sdim Sched<[WriteALUsi, ReadALU]> { 693201360Srdivacky let Inst{31-27} = 0b11101; 694201360Srdivacky let Inst{26-25} = 0b01; 695201360Srdivacky let Inst{24-21} = opcod; 696201360Srdivacky } 697194754Sed} 698194754Sed 699195098Sed/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the 700194612Sed/// instruction modifies the CPSR register. 701226633Sdim/// 702226633Sdim/// These opcodes will be converted to the real non-S opcodes by 703226633Sdim/// AdjustInstrPostInstrSelection after giving then an optional CPSR operand. 704234353Sdimlet hasPostISelHook = 1, Defs = [CPSR] in { 705234353Sdimmulticlass T2I_bin_s_irs<InstrItinClass iii, InstrItinClass iir, 706234353Sdim InstrItinClass iis, PatFrag opnode, 707234353Sdim bit Commutable = 0> { 708194612Sed // shifted imm 709234353Sdim def ri : t2PseudoInst<(outs rGPR:$Rd), 710234353Sdim (ins GPRnopc:$Rn, t2_so_imm:$imm, pred:$p), 711234353Sdim 4, iii, 712234353Sdim [(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn, 713263508Sdim t2_so_imm:$imm))]>, 714263508Sdim Sched<[WriteALU, ReadALU]>; 715195098Sed // register 716234353Sdim def rr : t2PseudoInst<(outs rGPR:$Rd), (ins GPRnopc:$Rn, rGPR:$Rm, pred:$p), 717234353Sdim 4, iir, 718234353Sdim [(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn, 719263508Sdim rGPR:$Rm))]>, 720263508Sdim Sched<[WriteALU, ReadALU, ReadALU]> { 721234353Sdim let isCommutable = Commutable; 722234353Sdim } 723194754Sed // shifted register 724234353Sdim def rs : t2PseudoInst<(outs rGPR:$Rd), 725234353Sdim (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm, pred:$p), 726234353Sdim 4, iis, 727234353Sdim [(set rGPR:$Rd, CPSR, (opnode GPRnopc:$Rn, 728263508Sdim t2_so_reg:$ShiftedRm))]>, 729263508Sdim Sched<[WriteALUsi, ReadALUsr]>; 730194754Sed} 731194754Sed} 732194612Sed 733234353Sdim/// T2I_rbin_s_is - Same as T2I_bin_s_irs, except selection DAG 734234353Sdim/// operands are reversed. 735234353Sdimlet hasPostISelHook = 1, Defs = [CPSR] in { 736234353Sdimmulticlass T2I_rbin_s_is<PatFrag opnode> { 737234353Sdim // shifted imm 738234353Sdim def ri : t2PseudoInst<(outs rGPR:$Rd), 739239462Sdim (ins rGPR:$Rn, t2_so_imm:$imm, pred:$p), 740234353Sdim 4, IIC_iALUi, 741234353Sdim [(set rGPR:$Rd, CPSR, (opnode t2_so_imm:$imm, 742263508Sdim rGPR:$Rn))]>, 743263508Sdim Sched<[WriteALU, ReadALU]>; 744234353Sdim // shifted register 745234353Sdim def rs : t2PseudoInst<(outs rGPR:$Rd), 746239462Sdim (ins rGPR:$Rn, t2_so_reg:$ShiftedRm, pred:$p), 747234353Sdim 4, IIC_iALUsi, 748234353Sdim [(set rGPR:$Rd, CPSR, (opnode t2_so_reg:$ShiftedRm, 749263508Sdim rGPR:$Rn))]>, 750263508Sdim Sched<[WriteALUsi, ReadALU]>; 751234353Sdim} 752234353Sdim} 753234353Sdim 754195098Sed/// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg}) 755195098Sed/// patterns for a binary operation that produces a value. 756201360Srdivackymulticlass T2I_bin_ii12rs<bits<3> op23_21, string opc, PatFrag opnode, 757201360Srdivacky bit Commutable = 0> { 758194754Sed // shifted imm 759212904Sdim // The register-immediate version is re-materializable. This is useful 760212904Sdim // in particular for taking the address of a local. 761212904Sdim let isReMaterializable = 1 in { 762218893Sdim def ri : T2sTwoRegImm< 763226633Sdim (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, t2_so_imm:$imm), IIC_iALUi, 764226633Sdim opc, ".w\t$Rd, $Rn, $imm", 765263508Sdim [(set GPRnopc:$Rd, (opnode GPRnopc:$Rn, t2_so_imm:$imm))]>, 766263508Sdim Sched<[WriteALU, ReadALU]> { 767201360Srdivacky let Inst{31-27} = 0b11110; 768201360Srdivacky let Inst{25} = 0; 769201360Srdivacky let Inst{24} = 1; 770201360Srdivacky let Inst{23-21} = op23_21; 771201360Srdivacky let Inst{15} = 0; 772201360Srdivacky } 773212904Sdim } 774195098Sed // 12-bit imm 775218893Sdim def ri12 : T2I< 776226633Sdim (outs GPRnopc:$Rd), (ins GPR:$Rn, imm0_4095:$imm), IIC_iALUi, 777218893Sdim !strconcat(opc, "w"), "\t$Rd, $Rn, $imm", 778263508Sdim [(set GPRnopc:$Rd, (opnode GPR:$Rn, imm0_4095:$imm))]>, 779263508Sdim Sched<[WriteALU, ReadALU]> { 780218893Sdim bits<4> Rd; 781218893Sdim bits<4> Rn; 782218893Sdim bits<12> imm; 783201360Srdivacky let Inst{31-27} = 0b11110; 784218893Sdim let Inst{26} = imm{11}; 785218893Sdim let Inst{25-24} = 0b10; 786201360Srdivacky let Inst{23-21} = op23_21; 787201360Srdivacky let Inst{20} = 0; // The S bit. 788218893Sdim let Inst{19-16} = Rn; 789201360Srdivacky let Inst{15} = 0; 790218893Sdim let Inst{14-12} = imm{10-8}; 791218893Sdim let Inst{11-8} = Rd; 792218893Sdim let Inst{7-0} = imm{7-0}; 793201360Srdivacky } 794195098Sed // register 795226633Sdim def rr : T2sThreeReg<(outs GPRnopc:$Rd), (ins GPRnopc:$Rn, rGPR:$Rm), 796226633Sdim IIC_iALUr, opc, ".w\t$Rd, $Rn, $Rm", 797263508Sdim [(set GPRnopc:$Rd, (opnode GPRnopc:$Rn, rGPR:$Rm))]>, 798263508Sdim Sched<[WriteALU, ReadALU, ReadALU]> { 799195098Sed let isCommutable = Commutable; 800201360Srdivacky let Inst{31-27} = 0b11101; 801201360Srdivacky let Inst{26-25} = 0b01; 802201360Srdivacky let Inst{24} = 1; 803201360Srdivacky let Inst{23-21} = op23_21; 804201360Srdivacky let Inst{14-12} = 0b000; // imm3 805201360Srdivacky let Inst{7-6} = 0b00; // imm2 806201360Srdivacky let Inst{5-4} = 0b00; // type 807195098Sed } 808194612Sed // shifted register 809218893Sdim def rs : T2sTwoRegShiftedReg< 810226633Sdim (outs GPRnopc:$Rd), (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm), 811218893Sdim IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm", 812263508Sdim [(set GPRnopc:$Rd, (opnode GPRnopc:$Rn, t2_so_reg:$ShiftedRm))]>, 813263508Sdim Sched<[WriteALUsi, ReadALU]> { 814201360Srdivacky let Inst{31-27} = 0b11101; 815202375Srdivacky let Inst{26-25} = 0b01; 816201360Srdivacky let Inst{24} = 1; 817201360Srdivacky let Inst{23-21} = op23_21; 818201360Srdivacky } 819194612Sed} 820194612Sed 821199989Srdivacky/// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns 822204642Srdivacky/// for a binary operation that produces a value and use the carry 823199989Srdivacky/// bit. It's not predicable. 824226633Sdimlet Defs = [CPSR], Uses = [CPSR] in { 825204642Srdivackymulticlass T2I_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, 826204642Srdivacky bit Commutable = 0> { 827194754Sed // shifted imm 828218893Sdim def ri : T2sTwoRegImm<(outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_imm:$imm), 829218893Sdim IIC_iALUi, opc, "\t$Rd, $Rn, $imm", 830226633Sdim [(set rGPR:$Rd, CPSR, (opnode rGPR:$Rn, t2_so_imm:$imm, CPSR))]>, 831263508Sdim Requires<[IsThumb2]>, Sched<[WriteALU, ReadALU]> { 832201360Srdivacky let Inst{31-27} = 0b11110; 833201360Srdivacky let Inst{25} = 0; 834201360Srdivacky let Inst{24-21} = opcod; 835201360Srdivacky let Inst{15} = 0; 836201360Srdivacky } 837195098Sed // register 838218893Sdim def rr : T2sThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iALUr, 839218893Sdim opc, ".w\t$Rd, $Rn, $Rm", 840226633Sdim [(set rGPR:$Rd, CPSR, (opnode rGPR:$Rn, rGPR:$Rm, CPSR))]>, 841263508Sdim Requires<[IsThumb2]>, Sched<[WriteALU, ReadALU, ReadALU]> { 842195098Sed let isCommutable = Commutable; 843201360Srdivacky let Inst{31-27} = 0b11101; 844201360Srdivacky let Inst{26-25} = 0b01; 845201360Srdivacky let Inst{24-21} = opcod; 846201360Srdivacky let Inst{14-12} = 0b000; // imm3 847201360Srdivacky let Inst{7-6} = 0b00; // imm2 848201360Srdivacky let Inst{5-4} = 0b00; // type 849195098Sed } 850194754Sed // shifted register 851218893Sdim def rs : T2sTwoRegShiftedReg< 852218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, t2_so_reg:$ShiftedRm), 853218893Sdim IIC_iALUsi, opc, ".w\t$Rd, $Rn, $ShiftedRm", 854226633Sdim [(set rGPR:$Rd, CPSR, (opnode rGPR:$Rn, t2_so_reg:$ShiftedRm, CPSR))]>, 855263508Sdim Requires<[IsThumb2]>, Sched<[WriteALUsi, ReadALU]> { 856201360Srdivacky let Inst{31-27} = 0b11101; 857201360Srdivacky let Inst{26-25} = 0b01; 858201360Srdivacky let Inst{24-21} = opcod; 859201360Srdivacky } 860204642Srdivacky} 861221345Sdim} 862204642Srdivacky 863195098Sed/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift / 864195098Sed// rotate operation that produces a value. 865239462Sdimmulticlass T2I_sh_ir<bits<2> opcod, string opc, Operand ty, PatFrag opnode> { 866195098Sed // 5-bit imm 867218893Sdim def ri : T2sTwoRegShiftImm< 868226633Sdim (outs rGPR:$Rd), (ins rGPR:$Rm, ty:$imm), IIC_iMOVsi, 869218893Sdim opc, ".w\t$Rd, $Rm, $imm", 870263508Sdim [(set rGPR:$Rd, (opnode rGPR:$Rm, (i32 ty:$imm)))]>, 871263508Sdim Sched<[WriteALU]> { 872201360Srdivacky let Inst{31-27} = 0b11101; 873201360Srdivacky let Inst{26-21} = 0b010010; 874201360Srdivacky let Inst{19-16} = 0b1111; // Rn 875201360Srdivacky let Inst{5-4} = opcod; 876201360Srdivacky } 877195098Sed // register 878218893Sdim def rr : T2sThreeReg< 879218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMOVsr, 880218893Sdim opc, ".w\t$Rd, $Rn, $Rm", 881263508Sdim [(set rGPR:$Rd, (opnode rGPR:$Rn, rGPR:$Rm))]>, 882263508Sdim Sched<[WriteALU]> { 883201360Srdivacky let Inst{31-27} = 0b11111; 884201360Srdivacky let Inst{26-23} = 0b0100; 885201360Srdivacky let Inst{22-21} = opcod; 886201360Srdivacky let Inst{15-12} = 0b1111; 887201360Srdivacky let Inst{7-4} = 0b0000; 888201360Srdivacky } 889226633Sdim 890226633Sdim // Optional destination register 891226633Sdim def : t2InstAlias<!strconcat(opc, "${s}${p}", ".w $Rdn, $imm"), 892239462Sdim (!cast<Instruction>(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, ty:$imm, pred:$p, 893239462Sdim cc_out:$s)>; 894226633Sdim def : t2InstAlias<!strconcat(opc, "${s}${p}", ".w $Rdn, $Rm"), 895239462Sdim (!cast<Instruction>(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p, 896239462Sdim cc_out:$s)>; 897226633Sdim 898226633Sdim // Assembler aliases w/o the ".w" suffix. 899226633Sdim def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rd, $Rn, $imm"), 900239462Sdim (!cast<Instruction>(NAME#"ri") rGPR:$Rd, rGPR:$Rn, ty:$imm, pred:$p, 901239462Sdim cc_out:$s)>; 902226633Sdim def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rd, $Rn, $Rm"), 903239462Sdim (!cast<Instruction>(NAME#"rr") rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p, 904239462Sdim cc_out:$s)>; 905226633Sdim 906226633Sdim // and with the optional destination operand, too. 907226633Sdim def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rdn, $imm"), 908239462Sdim (!cast<Instruction>(NAME#"ri") rGPR:$Rdn, rGPR:$Rdn, ty:$imm, pred:$p, 909239462Sdim cc_out:$s)>; 910226633Sdim def : t2InstAlias<!strconcat(opc, "${s}${p}", " $Rdn, $Rm"), 911239462Sdim (!cast<Instruction>(NAME#"rr") rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p, 912239462Sdim cc_out:$s)>; 913195098Sed} 914194754Sed 915201360Srdivacky/// T2I_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test 916195098Sed/// patterns. Similar to T2I_bin_irs except the instruction does not produce 917194754Sed/// a explicit result, only implicitly set CPSR. 918218893Sdimmulticlass T2I_cmp_irs<bits<4> opcod, string opc, 919218893Sdim InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 920239462Sdim PatFrag opnode> { 921226633Sdimlet isCompare = 1, Defs = [CPSR] in { 922194754Sed // shifted imm 923218893Sdim def ri : T2OneRegCmpImm< 924226633Sdim (outs), (ins GPRnopc:$Rn, t2_so_imm:$imm), iii, 925218893Sdim opc, ".w\t$Rn, $imm", 926263508Sdim [(opnode GPRnopc:$Rn, t2_so_imm:$imm)]>, Sched<[WriteCMP]> { 927201360Srdivacky let Inst{31-27} = 0b11110; 928201360Srdivacky let Inst{25} = 0; 929201360Srdivacky let Inst{24-21} = opcod; 930201360Srdivacky let Inst{20} = 1; // The S bit. 931201360Srdivacky let Inst{15} = 0; 932201360Srdivacky let Inst{11-8} = 0b1111; // Rd 933201360Srdivacky } 934195098Sed // register 935218893Sdim def rr : T2TwoRegCmp< 936226633Sdim (outs), (ins GPRnopc:$Rn, rGPR:$Rm), iir, 937226633Sdim opc, ".w\t$Rn, $Rm", 938263508Sdim [(opnode GPRnopc:$Rn, rGPR:$Rm)]>, Sched<[WriteCMP]> { 939201360Srdivacky let Inst{31-27} = 0b11101; 940201360Srdivacky let Inst{26-25} = 0b01; 941201360Srdivacky let Inst{24-21} = opcod; 942201360Srdivacky let Inst{20} = 1; // The S bit. 943201360Srdivacky let Inst{14-12} = 0b000; // imm3 944201360Srdivacky let Inst{11-8} = 0b1111; // Rd 945201360Srdivacky let Inst{7-6} = 0b00; // imm2 946201360Srdivacky let Inst{5-4} = 0b00; // type 947201360Srdivacky } 948194754Sed // shifted register 949218893Sdim def rs : T2OneRegCmpShiftedReg< 950226633Sdim (outs), (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm), iis, 951218893Sdim opc, ".w\t$Rn, $ShiftedRm", 952263508Sdim [(opnode GPRnopc:$Rn, t2_so_reg:$ShiftedRm)]>, 953263508Sdim Sched<[WriteCMPsi]> { 954201360Srdivacky let Inst{31-27} = 0b11101; 955201360Srdivacky let Inst{26-25} = 0b01; 956201360Srdivacky let Inst{24-21} = opcod; 957201360Srdivacky let Inst{20} = 1; // The S bit. 958201360Srdivacky let Inst{11-8} = 0b1111; // Rd 959201360Srdivacky } 960194754Sed} 961226633Sdim 962226633Sdim // Assembler aliases w/o the ".w" suffix. 963226633Sdim // No alias here for 'rr' version as not all instantiations of this 964226633Sdim // multiclass want one (CMP in particular, does not). 965226633Sdim def : t2InstAlias<!strconcat(opc, "${p}", " $Rn, $imm"), 966239462Sdim (!cast<Instruction>(NAME#"ri") GPRnopc:$Rn, t2_so_imm:$imm, pred:$p)>; 967226633Sdim def : t2InstAlias<!strconcat(opc, "${p}", " $Rn, $shift"), 968239462Sdim (!cast<Instruction>(NAME#"rs") GPRnopc:$Rn, t2_so_reg:$shift, pred:$p)>; 969194754Sed} 970194754Sed 971195340Sed/// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns. 972218893Sdimmulticlass T2I_ld<bit signed, bits<2> opcod, string opc, 973226633Sdim InstrItinClass iii, InstrItinClass iis, RegisterClass target, 974226633Sdim PatFrag opnode> { 975226633Sdim def i12 : T2Ii12<(outs target:$Rt), (ins t2addrmode_imm12:$addr), iii, 976218893Sdim opc, ".w\t$Rt, $addr", 977226633Sdim [(set target:$Rt, (opnode t2addrmode_imm12:$addr))]> { 978226633Sdim bits<4> Rt; 979226633Sdim bits<17> addr; 980226633Sdim let Inst{31-25} = 0b1111100; 981201360Srdivacky let Inst{24} = signed; 982201360Srdivacky let Inst{23} = 1; 983201360Srdivacky let Inst{22-21} = opcod; 984201360Srdivacky let Inst{20} = 1; // load 985226633Sdim let Inst{19-16} = addr{16-13}; // Rn 986218893Sdim let Inst{15-12} = Rt; 987218893Sdim let Inst{11-0} = addr{11-0}; // imm 988263508Sdim 989263508Sdim let DecoderMethod = "DecodeT2LoadImm12"; 990201360Srdivacky } 991226633Sdim def i8 : T2Ii8 <(outs target:$Rt), (ins t2addrmode_negimm8:$addr), iii, 992218893Sdim opc, "\t$Rt, $addr", 993226633Sdim [(set target:$Rt, (opnode t2addrmode_negimm8:$addr))]> { 994226633Sdim bits<4> Rt; 995226633Sdim bits<13> addr; 996201360Srdivacky let Inst{31-27} = 0b11111; 997201360Srdivacky let Inst{26-25} = 0b00; 998201360Srdivacky let Inst{24} = signed; 999201360Srdivacky let Inst{23} = 0; 1000201360Srdivacky let Inst{22-21} = opcod; 1001201360Srdivacky let Inst{20} = 1; // load 1002226633Sdim let Inst{19-16} = addr{12-9}; // Rn 1003226633Sdim let Inst{15-12} = Rt; 1004201360Srdivacky let Inst{11} = 1; 1005201360Srdivacky // Offset: index==TRUE, wback==FALSE 1006201360Srdivacky let Inst{10} = 1; // The P bit. 1007226633Sdim let Inst{9} = addr{8}; // U 1008201360Srdivacky let Inst{8} = 0; // The W bit. 1009218893Sdim let Inst{7-0} = addr{7-0}; // imm 1010263508Sdim 1011263508Sdim let DecoderMethod = "DecodeT2LoadImm8"; 1012201360Srdivacky } 1013226633Sdim def s : T2Iso <(outs target:$Rt), (ins t2addrmode_so_reg:$addr), iis, 1014218893Sdim opc, ".w\t$Rt, $addr", 1015226633Sdim [(set target:$Rt, (opnode t2addrmode_so_reg:$addr))]> { 1016201360Srdivacky let Inst{31-27} = 0b11111; 1017201360Srdivacky let Inst{26-25} = 0b00; 1018201360Srdivacky let Inst{24} = signed; 1019201360Srdivacky let Inst{23} = 0; 1020201360Srdivacky let Inst{22-21} = opcod; 1021201360Srdivacky let Inst{20} = 1; // load 1022201360Srdivacky let Inst{11-6} = 0b000000; 1023218893Sdim 1024218893Sdim bits<4> Rt; 1025218893Sdim let Inst{15-12} = Rt; 1026218893Sdim 1027218893Sdim bits<10> addr; 1028218893Sdim let Inst{19-16} = addr{9-6}; // Rn 1029218893Sdim let Inst{3-0} = addr{5-2}; // Rm 1030218893Sdim let Inst{5-4} = addr{1-0}; // imm 1031226633Sdim 1032226633Sdim let DecoderMethod = "DecodeT2LoadShift"; 1033201360Srdivacky } 1034218893Sdim 1035234353Sdim // pci variant is very similar to i12, but supports negative offsets 1036234353Sdim // from the PC. 1037226633Sdim def pci : T2Ipc <(outs target:$Rt), (ins t2ldrlabel:$addr), iii, 1038218893Sdim opc, ".w\t$Rt, $addr", 1039226633Sdim [(set target:$Rt, (opnode (ARMWrapper tconstpool:$addr)))]> { 1040198892Srdivacky let isReMaterializable = 1; 1041201360Srdivacky let Inst{31-27} = 0b11111; 1042201360Srdivacky let Inst{26-25} = 0b00; 1043201360Srdivacky let Inst{24} = signed; 1044201360Srdivacky let Inst{22-21} = opcod; 1045201360Srdivacky let Inst{20} = 1; // load 1046201360Srdivacky let Inst{19-16} = 0b1111; // Rn 1047263508Sdim 1048218893Sdim bits<4> Rt; 1049218893Sdim let Inst{15-12} = Rt{3-0}; 1050263508Sdim 1051263508Sdim bits<13> addr; 1052263508Sdim let Inst{23} = addr{12}; // add = (U == '1') 1053218893Sdim let Inst{11-0} = addr{11-0}; 1054263508Sdim 1055263508Sdim let DecoderMethod = "DecodeT2LoadLabel"; 1056198892Srdivacky } 1057195340Sed} 1058195340Sed 1059195340Sed/// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns. 1060218893Sdimmulticlass T2I_st<bits<2> opcod, string opc, 1061226633Sdim InstrItinClass iii, InstrItinClass iis, RegisterClass target, 1062226633Sdim PatFrag opnode> { 1063226633Sdim def i12 : T2Ii12<(outs), (ins target:$Rt, t2addrmode_imm12:$addr), iii, 1064218893Sdim opc, ".w\t$Rt, $addr", 1065226633Sdim [(opnode target:$Rt, t2addrmode_imm12:$addr)]> { 1066201360Srdivacky let Inst{31-27} = 0b11111; 1067201360Srdivacky let Inst{26-23} = 0b0001; 1068201360Srdivacky let Inst{22-21} = opcod; 1069201360Srdivacky let Inst{20} = 0; // !load 1070218893Sdim 1071218893Sdim bits<4> Rt; 1072218893Sdim let Inst{15-12} = Rt; 1073218893Sdim 1074218893Sdim bits<17> addr; 1075221345Sdim let addr{12} = 1; // add = TRUE 1076218893Sdim let Inst{19-16} = addr{16-13}; // Rn 1077218893Sdim let Inst{23} = addr{12}; // U 1078218893Sdim let Inst{11-0} = addr{11-0}; // imm 1079201360Srdivacky } 1080226633Sdim def i8 : T2Ii8 <(outs), (ins target:$Rt, t2addrmode_negimm8:$addr), iii, 1081218893Sdim opc, "\t$Rt, $addr", 1082226633Sdim [(opnode target:$Rt, t2addrmode_negimm8:$addr)]> { 1083201360Srdivacky let Inst{31-27} = 0b11111; 1084201360Srdivacky let Inst{26-23} = 0b0000; 1085201360Srdivacky let Inst{22-21} = opcod; 1086201360Srdivacky let Inst{20} = 0; // !load 1087201360Srdivacky let Inst{11} = 1; 1088201360Srdivacky // Offset: index==TRUE, wback==FALSE 1089201360Srdivacky let Inst{10} = 1; // The P bit. 1090201360Srdivacky let Inst{8} = 0; // The W bit. 1091218893Sdim 1092218893Sdim bits<4> Rt; 1093218893Sdim let Inst{15-12} = Rt; 1094218893Sdim 1095218893Sdim bits<13> addr; 1096218893Sdim let Inst{19-16} = addr{12-9}; // Rn 1097218893Sdim let Inst{9} = addr{8}; // U 1098218893Sdim let Inst{7-0} = addr{7-0}; // imm 1099201360Srdivacky } 1100226633Sdim def s : T2Iso <(outs), (ins target:$Rt, t2addrmode_so_reg:$addr), iis, 1101218893Sdim opc, ".w\t$Rt, $addr", 1102226633Sdim [(opnode target:$Rt, t2addrmode_so_reg:$addr)]> { 1103201360Srdivacky let Inst{31-27} = 0b11111; 1104201360Srdivacky let Inst{26-23} = 0b0000; 1105201360Srdivacky let Inst{22-21} = opcod; 1106201360Srdivacky let Inst{20} = 0; // !load 1107201360Srdivacky let Inst{11-6} = 0b000000; 1108218893Sdim 1109218893Sdim bits<4> Rt; 1110218893Sdim let Inst{15-12} = Rt; 1111218893Sdim 1112218893Sdim bits<10> addr; 1113218893Sdim let Inst{19-16} = addr{9-6}; // Rn 1114218893Sdim let Inst{3-0} = addr{5-2}; // Rm 1115218893Sdim let Inst{5-4} = addr{1-0}; // imm 1116201360Srdivacky } 1117195340Sed} 1118195340Sed 1119218893Sdim/// T2I_ext_rrot - A unary operation with two forms: one whose operand is a 1120195340Sed/// register and one whose operand is a register rotated by 8/16/24. 1121226633Sdimclass T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode> 1122226633Sdim : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), IIC_iEXTr, 1123226633Sdim opc, ".w\t$Rd, $Rm$rot", 1124226633Sdim [(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>, 1125226633Sdim Requires<[IsThumb2]> { 1126226633Sdim let Inst{31-27} = 0b11111; 1127226633Sdim let Inst{26-23} = 0b0100; 1128226633Sdim let Inst{22-20} = opcod; 1129226633Sdim let Inst{19-16} = 0b1111; // Rn 1130226633Sdim let Inst{15-12} = 0b1111; 1131226633Sdim let Inst{7} = 1; 1132218893Sdim 1133226633Sdim bits<2> rot; 1134226633Sdim let Inst{5-4} = rot{1-0}; // rotate 1135195340Sed} 1136195340Sed 1137210299Sed// UXTB16 - Requres T2ExtractPack, does not need the .w qualifier. 1138226633Sdimclass T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode> 1139226633Sdim : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), 1140226633Sdim IIC_iEXTr, opc, "\t$Rd, $Rm$rot", 1141226633Sdim [(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>, 1142226633Sdim Requires<[HasT2ExtractPack, IsThumb2]> { 1143226633Sdim bits<2> rot; 1144226633Sdim let Inst{31-27} = 0b11111; 1145226633Sdim let Inst{26-23} = 0b0100; 1146226633Sdim let Inst{22-20} = opcod; 1147226633Sdim let Inst{19-16} = 0b1111; // Rn 1148226633Sdim let Inst{15-12} = 0b1111; 1149226633Sdim let Inst{7} = 1; 1150226633Sdim let Inst{5-4} = rot; 1151204792Srdivacky} 1152204792Srdivacky 1153210299Sed// SXTB16 - Requres T2ExtractPack, does not need the .w qualifier, no pattern 1154210299Sed// supported yet. 1155226633Sdimclass T2I_ext_rrot_sxtb16<bits<3> opcod, string opc> 1156226633Sdim : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), IIC_iEXTr, 1157226633Sdim opc, "\t$Rd, $Rm$rot", []>, 1158224145Sdim Requires<[IsThumb2, HasT2ExtractPack]> { 1159226633Sdim bits<2> rot; 1160226633Sdim let Inst{31-27} = 0b11111; 1161226633Sdim let Inst{26-23} = 0b0100; 1162226633Sdim let Inst{22-20} = opcod; 1163226633Sdim let Inst{19-16} = 0b1111; // Rn 1164226633Sdim let Inst{15-12} = 0b1111; 1165226633Sdim let Inst{7} = 1; 1166226633Sdim let Inst{5-4} = rot; 1167204642Srdivacky} 1168204642Srdivacky 1169218893Sdim/// T2I_exta_rrot - A binary operation with two forms: one whose operand is a 1170195340Sed/// register and one whose operand is a register rotated by 8/16/24. 1171226633Sdimclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> 1172226633Sdim : T2ThreeReg<(outs rGPR:$Rd), 1173226633Sdim (ins rGPR:$Rn, rGPR:$Rm, rot_imm:$rot), 1174226633Sdim IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm$rot", 1175226633Sdim [(set rGPR:$Rd, (opnode rGPR:$Rn, (rotr rGPR:$Rm,rot_imm:$rot)))]>, 1176226633Sdim Requires<[HasT2ExtractPack, IsThumb2]> { 1177226633Sdim bits<2> rot; 1178226633Sdim let Inst{31-27} = 0b11111; 1179226633Sdim let Inst{26-23} = 0b0100; 1180226633Sdim let Inst{22-20} = opcod; 1181226633Sdim let Inst{15-12} = 0b1111; 1182226633Sdim let Inst{7} = 1; 1183226633Sdim let Inst{5-4} = rot; 1184195340Sed} 1185195340Sed 1186226633Sdimclass T2I_exta_rrot_np<bits<3> opcod, string opc> 1187226633Sdim : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm,rot_imm:$rot), 1188226633Sdim IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm$rot", []> { 1189226633Sdim bits<2> rot; 1190226633Sdim let Inst{31-27} = 0b11111; 1191226633Sdim let Inst{26-23} = 0b0100; 1192226633Sdim let Inst{22-20} = opcod; 1193226633Sdim let Inst{15-12} = 0b1111; 1194226633Sdim let Inst{7} = 1; 1195226633Sdim let Inst{5-4} = rot; 1196204642Srdivacky} 1197204642Srdivacky 1198194612Sed//===----------------------------------------------------------------------===// 1199195098Sed// Instructions 1200195098Sed//===----------------------------------------------------------------------===// 1201195098Sed 1202195098Sed//===----------------------------------------------------------------------===// 1203195098Sed// Miscellaneous Instructions. 1204194612Sed// 1205194612Sed 1206218893Sdimclass T2PCOneRegImm<dag oops, dag iops, InstrItinClass itin, 1207218893Sdim string asm, list<dag> pattern> 1208218893Sdim : T2XI<oops, iops, itin, asm, pattern> { 1209218893Sdim bits<4> Rd; 1210218893Sdim bits<12> label; 1211218893Sdim 1212218893Sdim let Inst{11-8} = Rd; 1213218893Sdim let Inst{26} = label{11}; 1214218893Sdim let Inst{14-12} = label{10-8}; 1215218893Sdim let Inst{7-0} = label{7-0}; 1216218893Sdim} 1217218893Sdim 1218195098Sed// LEApcrel - Load a pc-relative address into a register without offending the 1219195098Sed// assembler. 1220218893Sdimdef t2ADR : T2PCOneRegImm<(outs rGPR:$Rd), 1221218893Sdim (ins t2adrlabel:$addr, pred:$p), 1222263508Sdim IIC_iALUi, "adr{$p}.w\t$Rd, $addr", []>, 1223263508Sdim Sched<[WriteALU, ReadALU]> { 1224201360Srdivacky let Inst{31-27} = 0b11110; 1225201360Srdivacky let Inst{25-24} = 0b10; 1226201360Srdivacky // Inst{23:21} = '11' (add = FALSE) or '00' (add = TRUE) 1227201360Srdivacky let Inst{22} = 0; 1228201360Srdivacky let Inst{20} = 0; 1229201360Srdivacky let Inst{19-16} = 0b1111; // Rn 1230201360Srdivacky let Inst{15} = 0; 1231218893Sdim 1232218893Sdim bits<4> Rd; 1233218893Sdim bits<13> addr; 1234218893Sdim let Inst{11-8} = Rd; 1235218893Sdim let Inst{23} = addr{12}; 1236218893Sdim let Inst{21} = addr{12}; 1237218893Sdim let Inst{26} = addr{11}; 1238218893Sdim let Inst{14-12} = addr{10-8}; 1239218893Sdim let Inst{7-0} = addr{7-0}; 1240226633Sdim 1241226633Sdim let DecoderMethod = "DecodeT2Adr"; 1242201360Srdivacky} 1243195098Sed 1244218893Sdimlet neverHasSideEffects = 1, isReMaterializable = 1 in 1245218893Sdimdef t2LEApcrel : t2PseudoInst<(outs rGPR:$Rd), (ins i32imm:$label, pred:$p), 1246263508Sdim 4, IIC_iALUi, []>, Sched<[WriteALU, ReadALU]>; 1247243830Sdimlet hasSideEffects = 1 in 1248218893Sdimdef t2LEApcrelJT : t2PseudoInst<(outs rGPR:$Rd), 1249218893Sdim (ins i32imm:$label, nohash_imm:$id, pred:$p), 1250224145Sdim 4, IIC_iALUi, 1251263508Sdim []>, Sched<[WriteALU, ReadALU]>; 1252218893Sdim 1253218893Sdim 1254194612Sed//===----------------------------------------------------------------------===// 1255195098Sed// Load / store Instructions. 1256195098Sed// 1257195098Sed 1258195340Sed// Load 1259204642Srdivackylet canFoldAsLoad = 1, isReMaterializable = 1 in 1260226633Sdimdefm t2LDR : T2I_ld<0, 0b10, "ldr", IIC_iLoad_i, IIC_iLoad_si, GPR, 1261218893Sdim UnOpFrag<(load node:$Src)>>; 1262195340Sed 1263195340Sed// Loads with zero extension 1264218893Sdimdefm t2LDRH : T2I_ld<0, 0b01, "ldrh", IIC_iLoad_bh_i, IIC_iLoad_bh_si, 1265263508Sdim GPR, UnOpFrag<(zextloadi16 node:$Src)>>; 1266218893Sdimdefm t2LDRB : T2I_ld<0, 0b00, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_si, 1267263508Sdim GPR, UnOpFrag<(zextloadi8 node:$Src)>>; 1268195340Sed 1269195340Sed// Loads with sign extension 1270218893Sdimdefm t2LDRSH : T2I_ld<1, 0b01, "ldrsh", IIC_iLoad_bh_i, IIC_iLoad_bh_si, 1271263508Sdim GPR, UnOpFrag<(sextloadi16 node:$Src)>>; 1272218893Sdimdefm t2LDRSB : T2I_ld<1, 0b00, "ldrsb", IIC_iLoad_bh_i, IIC_iLoad_bh_si, 1273263508Sdim GPR, UnOpFrag<(sextloadi8 node:$Src)>>; 1274195340Sed 1275208599Srdivackylet mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in { 1276195340Sed// Load doubleword 1277218893Sdimdef t2LDRDi8 : T2Ii8s4<1, 0, 1, (outs rGPR:$Rt, rGPR:$Rt2), 1278198090Srdivacky (ins t2addrmode_imm8s4:$addr), 1279226633Sdim IIC_iLoad_d_i, "ldrd", "\t$Rt, $Rt2, $addr", "", []>; 1280208599Srdivacky} // mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 1281195340Sed 1282195340Sed// zextload i1 -> zextload i8 1283195340Seddef : T2Pat<(zextloadi1 t2addrmode_imm12:$addr), 1284195340Sed (t2LDRBi12 t2addrmode_imm12:$addr)>; 1285226633Sdimdef : T2Pat<(zextloadi1 t2addrmode_negimm8:$addr), 1286226633Sdim (t2LDRBi8 t2addrmode_negimm8:$addr)>; 1287195340Seddef : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr), 1288195340Sed (t2LDRBs t2addrmode_so_reg:$addr)>; 1289195340Seddef : T2Pat<(zextloadi1 (ARMWrapper tconstpool:$addr)), 1290195340Sed (t2LDRBpci tconstpool:$addr)>; 1291195340Sed 1292195340Sed// extload -> zextload 1293195340Sed// FIXME: Reduce the number of patterns by legalizing extload to zextload 1294195340Sed// earlier? 1295195340Seddef : T2Pat<(extloadi1 t2addrmode_imm12:$addr), 1296195340Sed (t2LDRBi12 t2addrmode_imm12:$addr)>; 1297226633Sdimdef : T2Pat<(extloadi1 t2addrmode_negimm8:$addr), 1298226633Sdim (t2LDRBi8 t2addrmode_negimm8:$addr)>; 1299195340Seddef : T2Pat<(extloadi1 t2addrmode_so_reg:$addr), 1300195340Sed (t2LDRBs t2addrmode_so_reg:$addr)>; 1301195340Seddef : T2Pat<(extloadi1 (ARMWrapper tconstpool:$addr)), 1302195340Sed (t2LDRBpci tconstpool:$addr)>; 1303195340Sed 1304195340Seddef : T2Pat<(extloadi8 t2addrmode_imm12:$addr), 1305195340Sed (t2LDRBi12 t2addrmode_imm12:$addr)>; 1306226633Sdimdef : T2Pat<(extloadi8 t2addrmode_negimm8:$addr), 1307226633Sdim (t2LDRBi8 t2addrmode_negimm8:$addr)>; 1308195340Seddef : T2Pat<(extloadi8 t2addrmode_so_reg:$addr), 1309195340Sed (t2LDRBs t2addrmode_so_reg:$addr)>; 1310195340Seddef : T2Pat<(extloadi8 (ARMWrapper tconstpool:$addr)), 1311195340Sed (t2LDRBpci tconstpool:$addr)>; 1312195340Sed 1313195340Seddef : T2Pat<(extloadi16 t2addrmode_imm12:$addr), 1314195340Sed (t2LDRHi12 t2addrmode_imm12:$addr)>; 1315226633Sdimdef : T2Pat<(extloadi16 t2addrmode_negimm8:$addr), 1316226633Sdim (t2LDRHi8 t2addrmode_negimm8:$addr)>; 1317195340Seddef : T2Pat<(extloadi16 t2addrmode_so_reg:$addr), 1318195340Sed (t2LDRHs t2addrmode_so_reg:$addr)>; 1319195340Seddef : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)), 1320195340Sed (t2LDRHpci tconstpool:$addr)>; 1321195340Sed 1322212904Sdim// FIXME: The destination register of the loads and stores can't be PC, but 1323212904Sdim// can be SP. We need another regclass (similar to rGPR) to represent 1324212904Sdim// that. Not a pressing issue since these are selected manually, 1325212904Sdim// not via pattern. 1326212904Sdim 1327195340Sed// Indexed loads 1328218893Sdim 1329208599Srdivackylet mayLoad = 1, neverHasSideEffects = 1 in { 1330226633Sdimdef t2LDR_PRE : T2Ipreldst<0, 0b10, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), 1331263508Sdim (ins t2addrmode_imm8_pre:$addr), 1332218893Sdim AddrModeT2_i8, IndexModePre, IIC_iLoad_iu, 1333263508Sdim "ldr", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>; 1334195340Sed 1335226633Sdimdef t2LDR_POST : T2Ipostldst<0, 0b10, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 1336226633Sdim (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset), 1337226633Sdim AddrModeT2_i8, IndexModePost, IIC_iLoad_iu, 1338226633Sdim "ldr", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>; 1339195340Sed 1340226633Sdimdef t2LDRB_PRE : T2Ipreldst<0, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), 1341263508Sdim (ins t2addrmode_imm8_pre:$addr), 1342218893Sdim AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, 1343263508Sdim "ldrb", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>; 1344263508Sdim 1345226633Sdimdef t2LDRB_POST : T2Ipostldst<0, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 1346226633Sdim (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset), 1347226633Sdim AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, 1348226633Sdim "ldrb", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>; 1349195340Sed 1350226633Sdimdef t2LDRH_PRE : T2Ipreldst<0, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), 1351263508Sdim (ins t2addrmode_imm8_pre:$addr), 1352218893Sdim AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, 1353263508Sdim "ldrh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", []>; 1354263508Sdim 1355226633Sdimdef t2LDRH_POST : T2Ipostldst<0, 0b01, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 1356226633Sdim (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset), 1357226633Sdim AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, 1358226633Sdim "ldrh", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>; 1359195340Sed 1360226633Sdimdef t2LDRSB_PRE : T2Ipreldst<1, 0b00, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), 1361263508Sdim (ins t2addrmode_imm8_pre:$addr), 1362218893Sdim AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, 1363226633Sdim "ldrsb", "\t$Rt, $addr!", "$addr.base = $Rn_wb", 1364263508Sdim []>; 1365263508Sdim 1366226633Sdimdef t2LDRSB_POST : T2Ipostldst<1, 0b00, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 1367226633Sdim (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset), 1368226633Sdim AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, 1369226633Sdim "ldrsb", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>; 1370195340Sed 1371226633Sdimdef t2LDRSH_PRE : T2Ipreldst<1, 0b01, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), 1372263508Sdim (ins t2addrmode_imm8_pre:$addr), 1373218893Sdim AddrModeT2_i8, IndexModePre, IIC_iLoad_bh_iu, 1374226633Sdim "ldrsh", "\t$Rt, $addr!", "$addr.base = $Rn_wb", 1375263508Sdim []>; 1376263508Sdim 1377226633Sdimdef t2LDRSH_POST : T2Ipostldst<1, 0b01, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 1378226633Sdim (ins addr_offset_none:$Rn, t2am_imm8_offset:$offset), 1379226633Sdim AddrModeT2_i8, IndexModePost, IIC_iLoad_bh_iu, 1380226633Sdim "ldrsh", "\t$Rt, $Rn$offset", "$Rn = $Rn_wb", []>; 1381218893Sdim} // mayLoad = 1, neverHasSideEffects = 1 1382195340Sed 1383226633Sdim// LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110). 1384204792Srdivacky// Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4 1385218893Sdimclass T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii> 1386226633Sdim : T2Ii8<(outs rGPR:$Rt), (ins t2addrmode_posimm8:$addr), ii, opc, 1387218893Sdim "\t$Rt, $addr", []> { 1388226633Sdim bits<4> Rt; 1389226633Sdim bits<13> addr; 1390204792Srdivacky let Inst{31-27} = 0b11111; 1391204792Srdivacky let Inst{26-25} = 0b00; 1392204792Srdivacky let Inst{24} = signed; 1393204792Srdivacky let Inst{23} = 0; 1394204792Srdivacky let Inst{22-21} = type; 1395204792Srdivacky let Inst{20} = 1; // load 1396226633Sdim let Inst{19-16} = addr{12-9}; 1397226633Sdim let Inst{15-12} = Rt; 1398204792Srdivacky let Inst{11} = 1; 1399204792Srdivacky let Inst{10-8} = 0b110; // PUW. 1400226633Sdim let Inst{7-0} = addr{7-0}; 1401263508Sdim 1402263508Sdim let DecoderMethod = "DecodeT2LoadT"; 1403204792Srdivacky} 1404204792Srdivacky 1405218893Sdimdef t2LDRT : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>; 1406218893Sdimdef t2LDRBT : T2IldT<0, 0b00, "ldrbt", IIC_iLoad_bh_i>; 1407218893Sdimdef t2LDRHT : T2IldT<0, 0b01, "ldrht", IIC_iLoad_bh_i>; 1408218893Sdimdef t2LDRSBT : T2IldT<1, 0b00, "ldrsbt", IIC_iLoad_bh_i>; 1409218893Sdimdef t2LDRSHT : T2IldT<1, 0b01, "ldrsht", IIC_iLoad_bh_i>; 1410204792Srdivacky 1411263508Sdimclass T2Ildacq<bits<4> bits23_20, bits<2> bit54, dag oops, dag iops, 1412263508Sdim string opc, string asm, list<dag> pattern> 1413263508Sdim : Thumb2I<oops, iops, AddrModeNone, 4, NoItinerary, 1414263508Sdim opc, asm, "", pattern>, Requires<[IsThumb, HasV8]> { 1415263508Sdim bits<4> Rt; 1416263508Sdim bits<4> addr; 1417263508Sdim 1418263508Sdim let Inst{31-27} = 0b11101; 1419263508Sdim let Inst{26-24} = 0b000; 1420263508Sdim let Inst{23-20} = bits23_20; 1421263508Sdim let Inst{11-6} = 0b111110; 1422263508Sdim let Inst{5-4} = bit54; 1423263508Sdim let Inst{3-0} = 0b1111; 1424263508Sdim 1425263508Sdim // Encode instruction operands 1426263508Sdim let Inst{19-16} = addr; 1427263508Sdim let Inst{15-12} = Rt; 1428263508Sdim} 1429263508Sdim 1430263508Sdimdef t2LDA : T2Ildacq<0b1101, 0b10, (outs rGPR:$Rt), 1431263508Sdim (ins addr_offset_none:$addr), "lda", "\t$Rt, $addr", []>; 1432263508Sdimdef t2LDAB : T2Ildacq<0b1101, 0b00, (outs rGPR:$Rt), 1433263508Sdim (ins addr_offset_none:$addr), "ldab", "\t$Rt, $addr", []>; 1434263508Sdimdef t2LDAH : T2Ildacq<0b1101, 0b01, (outs rGPR:$Rt), 1435263508Sdim (ins addr_offset_none:$addr), "ldah", "\t$Rt, $addr", []>; 1436263508Sdim 1437195340Sed// Store 1438226633Sdimdefm t2STR :T2I_st<0b10,"str", IIC_iStore_i, IIC_iStore_si, GPR, 1439218893Sdim BinOpFrag<(store node:$LHS, node:$RHS)>>; 1440218893Sdimdefm t2STRB:T2I_st<0b00,"strb", IIC_iStore_bh_i, IIC_iStore_bh_si, 1441226633Sdim rGPR, BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>; 1442218893Sdimdefm t2STRH:T2I_st<0b01,"strh", IIC_iStore_bh_i, IIC_iStore_bh_si, 1443226633Sdim rGPR, BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>; 1444195340Sed 1445195340Sed// Store doubleword 1446234353Sdimlet mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in 1447201360Srdivackydef t2STRDi8 : T2Ii8s4<1, 0, 0, (outs), 1448218893Sdim (ins GPR:$Rt, GPR:$Rt2, t2addrmode_imm8s4:$addr), 1449226633Sdim IIC_iStore_d_r, "strd", "\t$Rt, $Rt2, $addr", "", []>; 1450195340Sed 1451195340Sed// Indexed stores 1452234353Sdim 1453234353Sdimlet mayStore = 1, neverHasSideEffects = 1 in { 1454226633Sdimdef t2STR_PRE : T2Ipreldst<0, 0b10, 0, 1, (outs GPRnopc:$Rn_wb), 1455263508Sdim (ins GPRnopc:$Rt, t2addrmode_imm8_pre:$addr), 1456218893Sdim AddrModeT2_i8, IndexModePre, IIC_iStore_iu, 1457226633Sdim "str", "\t$Rt, $addr!", 1458263508Sdim "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []>; 1459263508Sdim 1460226633Sdimdef t2STRH_PRE : T2Ipreldst<0, 0b01, 0, 1, (outs GPRnopc:$Rn_wb), 1461263508Sdim (ins rGPR:$Rt, t2addrmode_imm8_pre:$addr), 1462226633Sdim AddrModeT2_i8, IndexModePre, IIC_iStore_iu, 1463226633Sdim "strh", "\t$Rt, $addr!", 1464263508Sdim "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []>; 1465195340Sed 1466226633Sdimdef t2STRB_PRE : T2Ipreldst<0, 0b00, 0, 1, (outs GPRnopc:$Rn_wb), 1467263508Sdim (ins rGPR:$Rt, t2addrmode_imm8_pre:$addr), 1468226633Sdim AddrModeT2_i8, IndexModePre, IIC_iStore_bh_iu, 1469226633Sdim "strb", "\t$Rt, $addr!", 1470263508Sdim "$addr.base = $Rn_wb,@earlyclobber $Rn_wb", []>; 1471234353Sdim} // mayStore = 1, neverHasSideEffects = 1 1472226633Sdim 1473226633Sdimdef t2STR_POST : T2Ipostldst<0, 0b10, 0, 0, (outs GPRnopc:$Rn_wb), 1474234353Sdim (ins GPRnopc:$Rt, addr_offset_none:$Rn, 1475226633Sdim t2am_imm8_offset:$offset), 1476218893Sdim AddrModeT2_i8, IndexModePost, IIC_iStore_iu, 1477226633Sdim "str", "\t$Rt, $Rn$offset", 1478226633Sdim "$Rn = $Rn_wb,@earlyclobber $Rn_wb", 1479226633Sdim [(set GPRnopc:$Rn_wb, 1480234353Sdim (post_store GPRnopc:$Rt, addr_offset_none:$Rn, 1481226633Sdim t2am_imm8_offset:$offset))]>; 1482195340Sed 1483226633Sdimdef t2STRH_POST : T2Ipostldst<0, 0b01, 0, 0, (outs GPRnopc:$Rn_wb), 1484226633Sdim (ins rGPR:$Rt, addr_offset_none:$Rn, 1485226633Sdim t2am_imm8_offset:$offset), 1486226633Sdim AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu, 1487226633Sdim "strh", "\t$Rt, $Rn$offset", 1488226633Sdim "$Rn = $Rn_wb,@earlyclobber $Rn_wb", 1489226633Sdim [(set GPRnopc:$Rn_wb, 1490226633Sdim (post_truncsti16 rGPR:$Rt, addr_offset_none:$Rn, 1491226633Sdim t2am_imm8_offset:$offset))]>; 1492195340Sed 1493226633Sdimdef t2STRB_POST : T2Ipostldst<0, 0b00, 0, 0, (outs GPRnopc:$Rn_wb), 1494226633Sdim (ins rGPR:$Rt, addr_offset_none:$Rn, 1495226633Sdim t2am_imm8_offset:$offset), 1496218893Sdim AddrModeT2_i8, IndexModePost, IIC_iStore_bh_iu, 1497226633Sdim "strb", "\t$Rt, $Rn$offset", 1498226633Sdim "$Rn = $Rn_wb,@earlyclobber $Rn_wb", 1499226633Sdim [(set GPRnopc:$Rn_wb, 1500226633Sdim (post_truncsti8 rGPR:$Rt, addr_offset_none:$Rn, 1501226633Sdim t2am_imm8_offset:$offset))]>; 1502195340Sed 1503226633Sdim// Pseudo-instructions for pattern matching the pre-indexed stores. We can't 1504226633Sdim// put the patterns on the instruction definitions directly as ISel wants 1505226633Sdim// the address base and offset to be separate operands, not a single 1506226633Sdim// complex operand like we represent the instructions themselves. The 1507226633Sdim// pseudos map between the two. 1508226633Sdimlet usesCustomInserter = 1, 1509226633Sdim Constraints = "$Rn = $Rn_wb,@earlyclobber $Rn_wb" in { 1510226633Sdimdef t2STR_preidx: t2PseudoInst<(outs GPRnopc:$Rn_wb), 1511226633Sdim (ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset, pred:$p), 1512226633Sdim 4, IIC_iStore_ru, 1513226633Sdim [(set GPRnopc:$Rn_wb, 1514226633Sdim (pre_store rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset))]>; 1515226633Sdimdef t2STRB_preidx: t2PseudoInst<(outs GPRnopc:$Rn_wb), 1516226633Sdim (ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset, pred:$p), 1517226633Sdim 4, IIC_iStore_ru, 1518226633Sdim [(set GPRnopc:$Rn_wb, 1519226633Sdim (pre_truncsti8 rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset))]>; 1520226633Sdimdef t2STRH_preidx: t2PseudoInst<(outs GPRnopc:$Rn_wb), 1521226633Sdim (ins rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset, pred:$p), 1522226633Sdim 4, IIC_iStore_ru, 1523226633Sdim [(set GPRnopc:$Rn_wb, 1524226633Sdim (pre_truncsti16 rGPR:$Rt, GPRnopc:$Rn, t2am_imm8_offset:$offset))]>; 1525226633Sdim} 1526195340Sed 1527204792Srdivacky// STRT, STRBT, STRHT all have offset mode (PUW=0b110) and are for disassembly 1528204792Srdivacky// only. 1529204792Srdivacky// Ref: A8.6.193 STR (immediate, Thumb) Encoding T4 1530218893Sdimclass T2IstT<bits<2> type, string opc, InstrItinClass ii> 1531221345Sdim : T2Ii8<(outs rGPR:$Rt), (ins t2addrmode_imm8:$addr), ii, opc, 1532218893Sdim "\t$Rt, $addr", []> { 1533204792Srdivacky let Inst{31-27} = 0b11111; 1534204792Srdivacky let Inst{26-25} = 0b00; 1535204792Srdivacky let Inst{24} = 0; // not signed 1536204792Srdivacky let Inst{23} = 0; 1537204792Srdivacky let Inst{22-21} = type; 1538204792Srdivacky let Inst{20} = 0; // store 1539204792Srdivacky let Inst{11} = 1; 1540204792Srdivacky let Inst{10-8} = 0b110; // PUW 1541218893Sdim 1542218893Sdim bits<4> Rt; 1543218893Sdim bits<13> addr; 1544218893Sdim let Inst{15-12} = Rt; 1545218893Sdim let Inst{19-16} = addr{12-9}; 1546218893Sdim let Inst{7-0} = addr{7-0}; 1547204792Srdivacky} 1548195340Sed 1549218893Sdimdef t2STRT : T2IstT<0b10, "strt", IIC_iStore_i>; 1550218893Sdimdef t2STRBT : T2IstT<0b00, "strbt", IIC_iStore_bh_i>; 1551218893Sdimdef t2STRHT : T2IstT<0b01, "strht", IIC_iStore_bh_i>; 1552204792Srdivacky 1553205218Srdivacky// ldrd / strd pre / post variants 1554205218Srdivacky// For disassembly only. 1555195340Sed 1556226633Sdimdef t2LDRD_PRE : T2Ii8s4<1, 1, 1, (outs rGPR:$Rt, rGPR:$Rt2, GPR:$wb), 1557263508Sdim (ins t2addrmode_imm8s4_pre:$addr), IIC_iLoad_d_ru, 1558226633Sdim "ldrd", "\t$Rt, $Rt2, $addr!", "$addr.base = $wb", []> { 1559226633Sdim let DecoderMethod = "DecodeT2LDRDPreInstruction"; 1560226633Sdim} 1561205218Srdivacky 1562226633Sdimdef t2LDRD_POST : T2Ii8s4post<0, 1, 1, (outs rGPR:$Rt, rGPR:$Rt2, GPR:$wb), 1563226633Sdim (ins addr_offset_none:$addr, t2am_imm8s4_offset:$imm), 1564226633Sdim IIC_iLoad_d_ru, "ldrd", "\t$Rt, $Rt2, $addr$imm", 1565226633Sdim "$addr.base = $wb", []>; 1566205218Srdivacky 1567226633Sdimdef t2STRD_PRE : T2Ii8s4<1, 1, 0, (outs GPR:$wb), 1568263508Sdim (ins rGPR:$Rt, rGPR:$Rt2, t2addrmode_imm8s4_pre:$addr), 1569226633Sdim IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, $addr!", 1570226633Sdim "$addr.base = $wb", []> { 1571226633Sdim let DecoderMethod = "DecodeT2STRDPreInstruction"; 1572226633Sdim} 1573205218Srdivacky 1574226633Sdimdef t2STRD_POST : T2Ii8s4post<0, 1, 0, (outs GPR:$wb), 1575226633Sdim (ins rGPR:$Rt, rGPR:$Rt2, addr_offset_none:$addr, 1576226633Sdim t2am_imm8s4_offset:$imm), 1577226633Sdim IIC_iStore_d_ru, "strd", "\t$Rt, $Rt2, $addr$imm", 1578226633Sdim "$addr.base = $wb", []>; 1579205218Srdivacky 1580263508Sdimclass T2Istrrel<bits<2> bit54, dag oops, dag iops, 1581263508Sdim string opc, string asm, list<dag> pattern> 1582263508Sdim : Thumb2I<oops, iops, AddrModeNone, 4, NoItinerary, opc, 1583263508Sdim asm, "", pattern>, Requires<[IsThumb, HasV8]> { 1584263508Sdim bits<4> Rt; 1585263508Sdim bits<4> addr; 1586263508Sdim 1587263508Sdim let Inst{31-27} = 0b11101; 1588263508Sdim let Inst{26-20} = 0b0001100; 1589263508Sdim let Inst{11-6} = 0b111110; 1590263508Sdim let Inst{5-4} = bit54; 1591263508Sdim let Inst{3-0} = 0b1111; 1592263508Sdim 1593263508Sdim // Encode instruction operands 1594263508Sdim let Inst{19-16} = addr; 1595263508Sdim let Inst{15-12} = Rt; 1596263508Sdim} 1597263508Sdim 1598263508Sdimdef t2STL : T2Istrrel<0b10, (outs), (ins rGPR:$Rt, addr_offset_none:$addr), 1599263508Sdim "stl", "\t$Rt, $addr", []>; 1600263508Sdimdef t2STLB : T2Istrrel<0b00, (outs), (ins rGPR:$Rt, addr_offset_none:$addr), 1601263508Sdim "stlb", "\t$Rt, $addr", []>; 1602263508Sdimdef t2STLH : T2Istrrel<0b01, (outs), (ins rGPR:$Rt, addr_offset_none:$addr), 1603263508Sdim "stlh", "\t$Rt, $addr", []>; 1604263508Sdim 1605204792Srdivacky// T2Ipl (Preload Data/Instruction) signals the memory system of possible future 1606234353Sdim// data/instruction access. 1607218893Sdim// instr_write is inverted for Thumb mode: (prefetch 3) -> (preload 0), 1608218893Sdim// (prefetch 1) -> (preload 2), (prefetch 2) -> (preload 1). 1609218893Sdimmulticlass T2Ipl<bits<1> write, bits<1> instr, string opc> { 1610204792Srdivacky 1611218893Sdim def i12 : T2Ii12<(outs), (ins t2addrmode_imm12:$addr), IIC_Preload, opc, 1612218893Sdim "\t$addr", 1613263508Sdim [(ARMPreload t2addrmode_imm12:$addr, (i32 write), (i32 instr))]>, 1614263508Sdim Sched<[WritePreLd]> { 1615204792Srdivacky let Inst{31-25} = 0b1111100; 1616204792Srdivacky let Inst{24} = instr; 1617263508Sdim let Inst{23} = 1; 1618204792Srdivacky let Inst{22} = 0; 1619204792Srdivacky let Inst{21} = write; 1620204792Srdivacky let Inst{20} = 1; 1621204792Srdivacky let Inst{15-12} = 0b1111; 1622218893Sdim 1623218893Sdim bits<17> addr; 1624218893Sdim let Inst{19-16} = addr{16-13}; // Rn 1625218893Sdim let Inst{11-0} = addr{11-0}; // imm12 1626263508Sdim 1627263508Sdim let DecoderMethod = "DecodeT2LoadImm12"; 1628204792Srdivacky } 1629204792Srdivacky 1630226633Sdim def i8 : T2Ii8<(outs), (ins t2addrmode_negimm8:$addr), IIC_Preload, opc, 1631218893Sdim "\t$addr", 1632263508Sdim [(ARMPreload t2addrmode_negimm8:$addr, (i32 write), (i32 instr))]>, 1633263508Sdim Sched<[WritePreLd]> { 1634204792Srdivacky let Inst{31-25} = 0b1111100; 1635204792Srdivacky let Inst{24} = instr; 1636204792Srdivacky let Inst{23} = 0; // U = 0 1637204792Srdivacky let Inst{22} = 0; 1638204792Srdivacky let Inst{21} = write; 1639204792Srdivacky let Inst{20} = 1; 1640204792Srdivacky let Inst{15-12} = 0b1111; 1641204792Srdivacky let Inst{11-8} = 0b1100; 1642204792Srdivacky 1643218893Sdim bits<13> addr; 1644218893Sdim let Inst{19-16} = addr{12-9}; // Rn 1645218893Sdim let Inst{7-0} = addr{7-0}; // imm8 1646263508Sdim 1647263508Sdim let DecoderMethod = "DecodeT2LoadImm8"; 1648204792Srdivacky } 1649204792Srdivacky 1650218893Sdim def s : T2Iso<(outs), (ins t2addrmode_so_reg:$addr), IIC_Preload, opc, 1651218893Sdim "\t$addr", 1652263508Sdim [(ARMPreload t2addrmode_so_reg:$addr, (i32 write), (i32 instr))]>, 1653263508Sdim Sched<[WritePreLd]> { 1654204792Srdivacky let Inst{31-25} = 0b1111100; 1655204792Srdivacky let Inst{24} = instr; 1656204792Srdivacky let Inst{23} = 0; // add = TRUE for T1 1657204792Srdivacky let Inst{22} = 0; 1658204792Srdivacky let Inst{21} = write; 1659204792Srdivacky let Inst{20} = 1; 1660204792Srdivacky let Inst{15-12} = 0b1111; 1661263508Sdim let Inst{11-6} = 0b000000; 1662204792Srdivacky 1663218893Sdim bits<10> addr; 1664218893Sdim let Inst{19-16} = addr{9-6}; // Rn 1665218893Sdim let Inst{3-0} = addr{5-2}; // Rm 1666218893Sdim let Inst{5-4} = addr{1-0}; // imm2 1667226633Sdim 1668226633Sdim let DecoderMethod = "DecodeT2LoadShift"; 1669204792Srdivacky } 1670204792Srdivacky} 1671204792Srdivacky 1672263508Sdimdefm t2PLD : T2Ipl<0, 0, "pld">, Requires<[IsThumb2]>; 1673263508Sdimdefm t2PLDW : T2Ipl<1, 0, "pldw">, Requires<[IsThumb2,HasV7,HasMP]>; 1674263508Sdimdefm t2PLI : T2Ipl<0, 1, "pli">, Requires<[IsThumb2,HasV7]>; 1675204792Srdivacky 1676263508Sdim// pci variant is very similar to i12, but supports negative offsets 1677263508Sdim// from the PC. Only PLD and PLI have pci variants (not PLDW) 1678263508Sdimclass T2Iplpci<bits<1> inst, string opc> : T2Iso<(outs), (ins t2ldrlabel:$addr), 1679263508Sdim IIC_Preload, opc, "\t$addr", 1680263508Sdim [(ARMPreload (ARMWrapper tconstpool:$addr), 1681263508Sdim (i32 0), (i32 inst))]>, Sched<[WritePreLd]> { 1682263508Sdim let Inst{31-25} = 0b1111100; 1683263508Sdim let Inst{24} = inst; 1684263508Sdim let Inst{22-20} = 0b001; 1685263508Sdim let Inst{19-16} = 0b1111; 1686263508Sdim let Inst{15-12} = 0b1111; 1687263508Sdim 1688263508Sdim bits<13> addr; 1689263508Sdim let Inst{23} = addr{12}; // add = (U == '1') 1690263508Sdim let Inst{11-0} = addr{11-0}; // imm12 1691263508Sdim 1692263508Sdim let DecoderMethod = "DecodeT2LoadLabel"; 1693263508Sdim} 1694263508Sdim 1695263508Sdimdef t2PLDpci : T2Iplpci<0, "pld">, Requires<[IsThumb2]>; 1696263508Sdimdef t2PLIpci : T2Iplpci<1, "pli">, Requires<[IsThumb2,HasV7]>; 1697263508Sdim 1698195098Sed//===----------------------------------------------------------------------===// 1699195340Sed// Load / store multiple Instructions. 1700195340Sed// 1701195340Sed 1702226633Sdimmulticlass thumb2_ld_mult<string asm, InstrItinClass itin, 1703218893Sdim InstrItinClass itin_upd, bit L_bit> { 1704218893Sdim def IA : 1705218893Sdim T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1706226633Sdim itin, !strconcat(asm, "${p}.w\t$Rn, $regs"), []> { 1707218893Sdim bits<4> Rn; 1708218893Sdim bits<16> regs; 1709195340Sed 1710218893Sdim let Inst{31-27} = 0b11101; 1711218893Sdim let Inst{26-25} = 0b00; 1712218893Sdim let Inst{24-23} = 0b01; // Increment After 1713218893Sdim let Inst{22} = 0; 1714218893Sdim let Inst{21} = 0; // No writeback 1715218893Sdim let Inst{20} = L_bit; 1716218893Sdim let Inst{19-16} = Rn; 1717228379Sdim let Inst{15-0} = regs; 1718218893Sdim } 1719218893Sdim def IA_UPD : 1720218893Sdim T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1721226633Sdim itin_upd, !strconcat(asm, "${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> { 1722218893Sdim bits<4> Rn; 1723218893Sdim bits<16> regs; 1724205218Srdivacky 1725218893Sdim let Inst{31-27} = 0b11101; 1726218893Sdim let Inst{26-25} = 0b00; 1727218893Sdim let Inst{24-23} = 0b01; // Increment After 1728218893Sdim let Inst{22} = 0; 1729218893Sdim let Inst{21} = 1; // Writeback 1730218893Sdim let Inst{20} = L_bit; 1731218893Sdim let Inst{19-16} = Rn; 1732228379Sdim let Inst{15-0} = regs; 1733218893Sdim } 1734218893Sdim def DB : 1735218893Sdim T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1736226633Sdim itin, !strconcat(asm, "db${p}\t$Rn, $regs"), []> { 1737218893Sdim bits<4> Rn; 1738218893Sdim bits<16> regs; 1739195340Sed 1740218893Sdim let Inst{31-27} = 0b11101; 1741218893Sdim let Inst{26-25} = 0b00; 1742218893Sdim let Inst{24-23} = 0b10; // Decrement Before 1743218893Sdim let Inst{22} = 0; 1744218893Sdim let Inst{21} = 0; // No writeback 1745218893Sdim let Inst{20} = L_bit; 1746218893Sdim let Inst{19-16} = Rn; 1747228379Sdim let Inst{15-0} = regs; 1748218893Sdim } 1749218893Sdim def DB_UPD : 1750218893Sdim T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1751226633Sdim itin_upd, !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 1752218893Sdim bits<4> Rn; 1753218893Sdim bits<16> regs; 1754218893Sdim 1755218893Sdim let Inst{31-27} = 0b11101; 1756218893Sdim let Inst{26-25} = 0b00; 1757218893Sdim let Inst{24-23} = 0b10; // Decrement Before 1758218893Sdim let Inst{22} = 0; 1759218893Sdim let Inst{21} = 1; // Writeback 1760218893Sdim let Inst{20} = L_bit; 1761218893Sdim let Inst{19-16} = Rn; 1762228379Sdim let Inst{15-0} = regs; 1763218893Sdim } 1764205218Srdivacky} 1765205218Srdivacky 1766218893Sdimlet neverHasSideEffects = 1 in { 1767218893Sdim 1768218893Sdimlet mayLoad = 1, hasExtraDefRegAllocReq = 1 in 1769226633Sdimdefm t2LDM : thumb2_ld_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu, 1>; 1770218893Sdim 1771226633Sdimmulticlass thumb2_st_mult<string asm, InstrItinClass itin, 1772226633Sdim InstrItinClass itin_upd, bit L_bit> { 1773226633Sdim def IA : 1774226633Sdim T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1775226633Sdim itin, !strconcat(asm, "${p}.w\t$Rn, $regs"), []> { 1776226633Sdim bits<4> Rn; 1777226633Sdim bits<16> regs; 1778226633Sdim 1779226633Sdim let Inst{31-27} = 0b11101; 1780226633Sdim let Inst{26-25} = 0b00; 1781226633Sdim let Inst{24-23} = 0b01; // Increment After 1782226633Sdim let Inst{22} = 0; 1783226633Sdim let Inst{21} = 0; // No writeback 1784226633Sdim let Inst{20} = L_bit; 1785226633Sdim let Inst{19-16} = Rn; 1786226633Sdim let Inst{15} = 0; 1787226633Sdim let Inst{14} = regs{14}; 1788226633Sdim let Inst{13} = 0; 1789226633Sdim let Inst{12-0} = regs{12-0}; 1790226633Sdim } 1791226633Sdim def IA_UPD : 1792226633Sdim T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1793226633Sdim itin_upd, !strconcat(asm, "${p}.w\t$Rn!, $regs"), "$Rn = $wb", []> { 1794226633Sdim bits<4> Rn; 1795226633Sdim bits<16> regs; 1796226633Sdim 1797226633Sdim let Inst{31-27} = 0b11101; 1798226633Sdim let Inst{26-25} = 0b00; 1799226633Sdim let Inst{24-23} = 0b01; // Increment After 1800226633Sdim let Inst{22} = 0; 1801226633Sdim let Inst{21} = 1; // Writeback 1802226633Sdim let Inst{20} = L_bit; 1803226633Sdim let Inst{19-16} = Rn; 1804226633Sdim let Inst{15} = 0; 1805226633Sdim let Inst{14} = regs{14}; 1806226633Sdim let Inst{13} = 0; 1807226633Sdim let Inst{12-0} = regs{12-0}; 1808226633Sdim } 1809226633Sdim def DB : 1810226633Sdim T2XI<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1811226633Sdim itin, !strconcat(asm, "db${p}\t$Rn, $regs"), []> { 1812226633Sdim bits<4> Rn; 1813226633Sdim bits<16> regs; 1814226633Sdim 1815226633Sdim let Inst{31-27} = 0b11101; 1816226633Sdim let Inst{26-25} = 0b00; 1817226633Sdim let Inst{24-23} = 0b10; // Decrement Before 1818226633Sdim let Inst{22} = 0; 1819226633Sdim let Inst{21} = 0; // No writeback 1820226633Sdim let Inst{20} = L_bit; 1821226633Sdim let Inst{19-16} = Rn; 1822226633Sdim let Inst{15} = 0; 1823226633Sdim let Inst{14} = regs{14}; 1824226633Sdim let Inst{13} = 0; 1825226633Sdim let Inst{12-0} = regs{12-0}; 1826226633Sdim } 1827226633Sdim def DB_UPD : 1828226633Sdim T2XIt<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1829226633Sdim itin_upd, !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 1830226633Sdim bits<4> Rn; 1831226633Sdim bits<16> regs; 1832226633Sdim 1833226633Sdim let Inst{31-27} = 0b11101; 1834226633Sdim let Inst{26-25} = 0b00; 1835226633Sdim let Inst{24-23} = 0b10; // Decrement Before 1836226633Sdim let Inst{22} = 0; 1837226633Sdim let Inst{21} = 1; // Writeback 1838226633Sdim let Inst{20} = L_bit; 1839226633Sdim let Inst{19-16} = Rn; 1840226633Sdim let Inst{15} = 0; 1841226633Sdim let Inst{14} = regs{14}; 1842226633Sdim let Inst{13} = 0; 1843226633Sdim let Inst{12-0} = regs{12-0}; 1844226633Sdim } 1845226633Sdim} 1846226633Sdim 1847226633Sdim 1848218893Sdimlet mayStore = 1, hasExtraSrcRegAllocReq = 1 in 1849226633Sdimdefm t2STM : thumb2_st_mult<"stm", IIC_iStore_m, IIC_iStore_mu, 0>; 1850218893Sdim 1851218893Sdim} // neverHasSideEffects 1852218893Sdim 1853218893Sdim 1854195340Sed//===----------------------------------------------------------------------===// 1855194612Sed// Move Instructions. 1856194612Sed// 1857194612Sed 1858194754Sedlet neverHasSideEffects = 1 in 1859226633Sdimdef t2MOVr : T2sTwoReg<(outs GPRnopc:$Rd), (ins GPR:$Rm), IIC_iMOVr, 1860263508Sdim "mov", ".w\t$Rd, $Rm", []>, Sched<[WriteALU]> { 1861201360Srdivacky let Inst{31-27} = 0b11101; 1862201360Srdivacky let Inst{26-25} = 0b01; 1863201360Srdivacky let Inst{24-21} = 0b0010; 1864201360Srdivacky let Inst{19-16} = 0b1111; // Rn 1865201360Srdivacky let Inst{14-12} = 0b000; 1866201360Srdivacky let Inst{7-4} = 0b0000; 1867201360Srdivacky} 1868234353Sdimdef : t2InstAlias<"mov${p}.w $Rd, $Rm", (t2MOVr GPRnopc:$Rd, GPR:$Rm, 1869234353Sdim pred:$p, zero_reg)>; 1870226633Sdimdef : t2InstAlias<"movs${p}.w $Rd, $Rm", (t2MOVr GPRnopc:$Rd, GPR:$Rm, 1871226633Sdim pred:$p, CPSR)>; 1872226633Sdimdef : t2InstAlias<"movs${p} $Rd, $Rm", (t2MOVr GPRnopc:$Rd, GPR:$Rm, 1873226633Sdim pred:$p, CPSR)>; 1874194612Sed 1875198090Srdivacky// AddedComplexity to ensure isel tries t2MOVi before t2MOVi16. 1876218893Sdimlet isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1, 1877218893Sdim AddedComplexity = 1 in 1878218893Sdimdef t2MOVi : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), IIC_iMOVi, 1879218893Sdim "mov", ".w\t$Rd, $imm", 1880263508Sdim [(set rGPR:$Rd, t2_so_imm:$imm)]>, Sched<[WriteALU]> { 1881201360Srdivacky let Inst{31-27} = 0b11110; 1882201360Srdivacky let Inst{25} = 0; 1883201360Srdivacky let Inst{24-21} = 0b0010; 1884201360Srdivacky let Inst{19-16} = 0b1111; // Rn 1885201360Srdivacky let Inst{15} = 0; 1886201360Srdivacky} 1887195098Sed 1888226633Sdim// cc_out is handled as part of the explicit mnemonic in the parser for 'mov'. 1889226633Sdim// Use aliases to get that to play nice here. 1890226633Sdimdef : t2InstAlias<"movs${p}.w $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm, 1891226633Sdim pred:$p, CPSR)>; 1892226633Sdimdef : t2InstAlias<"movs${p} $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm, 1893226633Sdim pred:$p, CPSR)>; 1894224145Sdim 1895226633Sdimdef : t2InstAlias<"mov${p}.w $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm, 1896226633Sdim pred:$p, zero_reg)>; 1897226633Sdimdef : t2InstAlias<"mov${p} $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm, 1898226633Sdim pred:$p, zero_reg)>; 1899226633Sdim 1900218893Sdimlet isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 1901226633Sdimdef t2MOVi16 : T2I<(outs rGPR:$Rd), (ins imm0_65535_expr:$imm), IIC_iMOVi, 1902218893Sdim "movw", "\t$Rd, $imm", 1903263508Sdim [(set rGPR:$Rd, imm0_65535:$imm)]>, Sched<[WriteALU]> { 1904201360Srdivacky let Inst{31-27} = 0b11110; 1905201360Srdivacky let Inst{25} = 1; 1906201360Srdivacky let Inst{24-21} = 0b0010; 1907201360Srdivacky let Inst{20} = 0; // The S bit. 1908201360Srdivacky let Inst{15} = 0; 1909218893Sdim 1910218893Sdim bits<4> Rd; 1911218893Sdim bits<16> imm; 1912218893Sdim 1913218893Sdim let Inst{11-8} = Rd; 1914218893Sdim let Inst{19-16} = imm{15-12}; 1915218893Sdim let Inst{26} = imm{11}; 1916218893Sdim let Inst{14-12} = imm{10-8}; 1917218893Sdim let Inst{7-0} = imm{7-0}; 1918226633Sdim let DecoderMethod = "DecodeT2MOVTWInstruction"; 1919201360Srdivacky} 1920194612Sed 1921263508Sdimdef : t2InstAlias<"mov${p} $Rd, $imm", 1922263508Sdim (t2MOVi16 rGPR:$Rd, imm256_65535_expr:$imm, pred:$p)>; 1923263508Sdim 1924218893Sdimdef t2MOVi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd), 1925218893Sdim (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>; 1926218893Sdim 1927218893Sdimlet Constraints = "$src = $Rd" in { 1928218893Sdimdef t2MOVTi16 : T2I<(outs rGPR:$Rd), 1929226633Sdim (ins rGPR:$src, imm0_65535_expr:$imm), IIC_iMOVi, 1930218893Sdim "movt", "\t$Rd, $imm", 1931218893Sdim [(set rGPR:$Rd, 1932263508Sdim (or (and rGPR:$src, 0xffff), lo16AllZero:$imm))]>, 1933263508Sdim Sched<[WriteALU]> { 1934201360Srdivacky let Inst{31-27} = 0b11110; 1935201360Srdivacky let Inst{25} = 1; 1936201360Srdivacky let Inst{24-21} = 0b0110; 1937201360Srdivacky let Inst{20} = 0; // The S bit. 1938201360Srdivacky let Inst{15} = 0; 1939218893Sdim 1940218893Sdim bits<4> Rd; 1941218893Sdim bits<16> imm; 1942218893Sdim 1943218893Sdim let Inst{11-8} = Rd; 1944218893Sdim let Inst{19-16} = imm{15-12}; 1945218893Sdim let Inst{26} = imm{11}; 1946218893Sdim let Inst{14-12} = imm{10-8}; 1947218893Sdim let Inst{7-0} = imm{7-0}; 1948226633Sdim let DecoderMethod = "DecodeT2MOVTWInstruction"; 1949201360Srdivacky} 1950194754Sed 1951218893Sdimdef t2MOVTi16_ga_pcrel : PseudoInst<(outs rGPR:$Rd), 1952263508Sdim (ins rGPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>, 1953263508Sdim Sched<[WriteALU]>; 1954218893Sdim} // Constraints 1955218893Sdim 1956212904Sdimdef : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>; 1957198396Srdivacky 1958194612Sed//===----------------------------------------------------------------------===// 1959195340Sed// Extend Instructions. 1960195340Sed// 1961195340Sed 1962195340Sed// Sign extenders 1963195340Sed 1964226633Sdimdef t2SXTB : T2I_ext_rrot<0b100, "sxtb", 1965201360Srdivacky UnOpFrag<(sext_inreg node:$Src, i8)>>; 1966226633Sdimdef t2SXTH : T2I_ext_rrot<0b000, "sxth", 1967201360Srdivacky UnOpFrag<(sext_inreg node:$Src, i16)>>; 1968226633Sdimdef t2SXTB16 : T2I_ext_rrot_sxtb16<0b010, "sxtb16">; 1969195340Sed 1970226633Sdimdef t2SXTAB : T2I_exta_rrot<0b100, "sxtab", 1971195340Sed BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>; 1972226633Sdimdef t2SXTAH : T2I_exta_rrot<0b000, "sxtah", 1973195340Sed BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>; 1974226633Sdimdef t2SXTAB16 : T2I_exta_rrot_np<0b010, "sxtab16">; 1975195340Sed 1976195340Sed// Zero extenders 1977195340Sed 1978195340Sedlet AddedComplexity = 16 in { 1979226633Sdimdef t2UXTB : T2I_ext_rrot<0b101, "uxtb", 1980201360Srdivacky UnOpFrag<(and node:$Src, 0x000000FF)>>; 1981226633Sdimdef t2UXTH : T2I_ext_rrot<0b001, "uxth", 1982201360Srdivacky UnOpFrag<(and node:$Src, 0x0000FFFF)>>; 1983226633Sdimdef t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16", 1984201360Srdivacky UnOpFrag<(and node:$Src, 0x00FF00FF)>>; 1985195340Sed 1986212904Sdim// FIXME: This pattern incorrectly assumes the shl operator is a rotate. 1987212904Sdim// The transformation should probably be done as a combiner action 1988212904Sdim// instead so we can include a check for masking back in the upper 1989212904Sdim// eight bits of the source into the lower eight bits of the result. 1990212904Sdim//def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF), 1991226633Sdim// (t2UXTB16 rGPR:$Src, 3)>, 1992218893Sdim// Requires<[HasT2ExtractPack, IsThumb2]>; 1993212904Sdimdef : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF), 1994226633Sdim (t2UXTB16 rGPR:$Src, 1)>, 1995218893Sdim Requires<[HasT2ExtractPack, IsThumb2]>; 1996195340Sed 1997226633Sdimdef t2UXTAB : T2I_exta_rrot<0b101, "uxtab", 1998199989Srdivacky BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; 1999226633Sdimdef t2UXTAH : T2I_exta_rrot<0b001, "uxtah", 2000199989Srdivacky BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; 2001226633Sdimdef t2UXTAB16 : T2I_exta_rrot_np<0b011, "uxtab16">; 2002195340Sed} 2003195340Sed 2004195340Sed//===----------------------------------------------------------------------===// 2005194612Sed// Arithmetic Instructions. 2006194612Sed// 2007194612Sed 2008201360Srdivackydefm t2ADD : T2I_bin_ii12rs<0b000, "add", 2009201360Srdivacky BinOpFrag<(add node:$LHS, node:$RHS)>, 1>; 2010201360Srdivackydefm t2SUB : T2I_bin_ii12rs<0b101, "sub", 2011201360Srdivacky BinOpFrag<(sub node:$LHS, node:$RHS)>>; 2012194612Sed 2013194754Sed// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants. 2014226633Sdim// 2015226633Sdim// Currently, t2ADDS/t2SUBS are pseudo opcodes that exist only in the 2016226633Sdim// selection DAG. They are "lowered" to real t2ADD/t2SUB opcodes by 2017226633Sdim// AdjustInstrPostInstrSelection where we determine whether or not to 2018226633Sdim// set the "s" bit based on CPSR liveness. 2019226633Sdim// 2020226633Sdim// FIXME: Eliminate t2ADDS/t2SUBS pseudo opcodes after adding tablegen 2021226633Sdim// support for an optional CPSR definition that corresponds to the DAG 2022226633Sdim// node's second value. We can then eliminate the implicit def of CPSR. 2023234353Sdimdefm t2ADDS : T2I_bin_s_irs <IIC_iALUi, IIC_iALUr, IIC_iALUsi, 2024226633Sdim BinOpFrag<(ARMaddc node:$LHS, node:$RHS)>, 1>; 2025234353Sdimdefm t2SUBS : T2I_bin_s_irs <IIC_iALUi, IIC_iALUr, IIC_iALUsi, 2026226633Sdim BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>; 2027194612Sed 2028226633Sdimlet hasPostISelHook = 1 in { 2029201360Srdivackydefm t2ADC : T2I_adde_sube_irs<0b1010, "adc", 2030226633Sdim BinOpWithFlagFrag<(ARMadde node:$LHS, node:$RHS, node:$FLAG)>, 1>; 2031201360Srdivackydefm t2SBC : T2I_adde_sube_irs<0b1011, "sbc", 2032226633Sdim BinOpWithFlagFrag<(ARMsube node:$LHS, node:$RHS, node:$FLAG)>>; 2033226633Sdim} 2034194612Sed 2035198090Srdivacky// RSB 2036212904Sdimdefm t2RSB : T2I_rbin_irs <0b1110, "rsb", 2037201360Srdivacky BinOpFrag<(sub node:$LHS, node:$RHS)>>; 2038226633Sdim 2039226633Sdim// FIXME: Eliminate them if we can write def : Pat patterns which defines 2040226633Sdim// CPSR and the implicit def of CPSR is not needed. 2041234353Sdimdefm t2RSBS : T2I_rbin_s_is <BinOpFrag<(ARMsubc node:$LHS, node:$RHS)>>; 2042194612Sed 2043194754Sed// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 2044210299Sed// The assume-no-carry-in form uses the negation of the input since add/sub 2045210299Sed// assume opposite meanings of the carry flag (i.e., carry == !borrow). 2046210299Sed// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory 2047210299Sed// details. 2048210299Sed// The AddedComplexity preferences the first variant over the others since 2049210299Sed// it can be shrunk to a 16-bit wide encoding, while the others cannot. 2050198090Srdivackylet AddedComplexity = 1 in 2051249423Sdimdef : T2Pat<(add GPR:$src, imm1_255_neg:$imm), 2052249423Sdim (t2SUBri GPR:$src, imm1_255_neg:$imm)>; 2053210299Seddef : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm), 2054210299Sed (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>; 2055210299Seddef : T2Pat<(add GPR:$src, imm0_4095_neg:$imm), 2056210299Sed (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>; 2057239462Sdimdef : T2Pat<(add GPR:$src, imm0_65535_neg:$imm), 2058239462Sdim (t2SUBrr GPR:$src, (t2MOVi16 (imm_neg_XFORM imm:$imm)))>; 2059239462Sdim 2060210299Sedlet AddedComplexity = 1 in 2061249423Sdimdef : T2Pat<(ARMaddc rGPR:$src, imm1_255_neg:$imm), 2062249423Sdim (t2SUBSri rGPR:$src, imm1_255_neg:$imm)>; 2063226633Sdimdef : T2Pat<(ARMaddc rGPR:$src, t2_so_imm_neg:$imm), 2064212904Sdim (t2SUBSri rGPR:$src, t2_so_imm_neg:$imm)>; 2065239462Sdimdef : T2Pat<(ARMaddc rGPR:$src, imm0_65535_neg:$imm), 2066239462Sdim (t2SUBSrr rGPR:$src, (t2MOVi16 (imm_neg_XFORM imm:$imm)))>; 2067210299Sed// The with-carry-in form matches bitwise not instead of the negation. 2068210299Sed// Effectively, the inverse interpretation of the carry flag already accounts 2069210299Sed// for part of the negation. 2070210299Sedlet AddedComplexity = 1 in 2071226633Sdimdef : T2Pat<(ARMadde rGPR:$src, imm0_255_not:$imm, CPSR), 2072221345Sdim (t2SBCri rGPR:$src, imm0_255_not:$imm)>; 2073226633Sdimdef : T2Pat<(ARMadde rGPR:$src, t2_so_imm_not:$imm, CPSR), 2074221345Sdim (t2SBCri rGPR:$src, t2_so_imm_not:$imm)>; 2075239462Sdimdef : T2Pat<(ARMadde rGPR:$src, imm0_65535_neg:$imm, CPSR), 2076243830Sdim (t2SBCrr rGPR:$src, (t2MOVi16 (imm_not_XFORM imm:$imm)))>; 2077194612Sed 2078204642Srdivacky// Select Bytes -- for disassembly only 2079194754Sed 2080218893Sdimdef t2SEL : T2ThreeReg<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2081224145Sdim NoItinerary, "sel", "\t$Rd, $Rn, $Rm", []>, 2082224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2083204642Srdivacky let Inst{31-27} = 0b11111; 2084204642Srdivacky let Inst{26-24} = 0b010; 2085204642Srdivacky let Inst{23} = 0b1; 2086204642Srdivacky let Inst{22-20} = 0b010; 2087204642Srdivacky let Inst{15-12} = 0b1111; 2088204642Srdivacky let Inst{7} = 0b1; 2089204642Srdivacky let Inst{6-4} = 0b000; 2090204642Srdivacky} 2091204642Srdivacky 2092204642Srdivacky// A6.3.13, A6.3.14, A6.3.15 Parallel addition and subtraction (signed/unsigned) 2093204642Srdivacky// And Miscellaneous operations -- for disassembly only 2094212904Sdimclass T2I_pam<bits<3> op22_20, bits<4> op7_4, string opc, 2095218893Sdim list<dag> pat = [/* For disassembly only; pattern left blank */], 2096218893Sdim dag iops = (ins rGPR:$Rn, rGPR:$Rm), 2097218893Sdim string asm = "\t$Rd, $Rn, $Rm"> 2098224145Sdim : T2I<(outs rGPR:$Rd), iops, NoItinerary, opc, asm, pat>, 2099224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2100204642Srdivacky let Inst{31-27} = 0b11111; 2101204642Srdivacky let Inst{26-23} = 0b0101; 2102204642Srdivacky let Inst{22-20} = op22_20; 2103204642Srdivacky let Inst{15-12} = 0b1111; 2104204642Srdivacky let Inst{7-4} = op7_4; 2105218893Sdim 2106218893Sdim bits<4> Rd; 2107218893Sdim bits<4> Rn; 2108218893Sdim bits<4> Rm; 2109218893Sdim 2110218893Sdim let Inst{11-8} = Rd; 2111218893Sdim let Inst{19-16} = Rn; 2112218893Sdim let Inst{3-0} = Rm; 2113204642Srdivacky} 2114204642Srdivacky 2115204642Srdivacky// Saturating add/subtract -- for disassembly only 2116204642Srdivacky 2117212904Sdimdef t2QADD : T2I_pam<0b000, 0b1000, "qadd", 2118218893Sdim [(set rGPR:$Rd, (int_arm_qadd rGPR:$Rn, rGPR:$Rm))], 2119218893Sdim (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">; 2120204642Srdivackydef t2QADD16 : T2I_pam<0b001, 0b0001, "qadd16">; 2121204642Srdivackydef t2QADD8 : T2I_pam<0b000, 0b0001, "qadd8">; 2122204642Srdivackydef t2QASX : T2I_pam<0b010, 0b0001, "qasx">; 2123218893Sdimdef t2QDADD : T2I_pam<0b000, 0b1001, "qdadd", [], 2124218893Sdim (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">; 2125218893Sdimdef t2QDSUB : T2I_pam<0b000, 0b1011, "qdsub", [], 2126218893Sdim (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">; 2127204642Srdivackydef t2QSAX : T2I_pam<0b110, 0b0001, "qsax">; 2128212904Sdimdef t2QSUB : T2I_pam<0b000, 0b1010, "qsub", 2129218893Sdim [(set rGPR:$Rd, (int_arm_qsub rGPR:$Rn, rGPR:$Rm))], 2130218893Sdim (ins rGPR:$Rm, rGPR:$Rn), "\t$Rd, $Rm, $Rn">; 2131204642Srdivackydef t2QSUB16 : T2I_pam<0b101, 0b0001, "qsub16">; 2132204642Srdivackydef t2QSUB8 : T2I_pam<0b100, 0b0001, "qsub8">; 2133204642Srdivackydef t2UQADD16 : T2I_pam<0b001, 0b0101, "uqadd16">; 2134204642Srdivackydef t2UQADD8 : T2I_pam<0b000, 0b0101, "uqadd8">; 2135204642Srdivackydef t2UQASX : T2I_pam<0b010, 0b0101, "uqasx">; 2136204642Srdivackydef t2UQSAX : T2I_pam<0b110, 0b0101, "uqsax">; 2137204642Srdivackydef t2UQSUB16 : T2I_pam<0b101, 0b0101, "uqsub16">; 2138204642Srdivackydef t2UQSUB8 : T2I_pam<0b100, 0b0101, "uqsub8">; 2139204642Srdivacky 2140204642Srdivacky// Signed/Unsigned add/subtract -- for disassembly only 2141204642Srdivacky 2142204642Srdivackydef t2SASX : T2I_pam<0b010, 0b0000, "sasx">; 2143204642Srdivackydef t2SADD16 : T2I_pam<0b001, 0b0000, "sadd16">; 2144204642Srdivackydef t2SADD8 : T2I_pam<0b000, 0b0000, "sadd8">; 2145204642Srdivackydef t2SSAX : T2I_pam<0b110, 0b0000, "ssax">; 2146204642Srdivackydef t2SSUB16 : T2I_pam<0b101, 0b0000, "ssub16">; 2147204642Srdivackydef t2SSUB8 : T2I_pam<0b100, 0b0000, "ssub8">; 2148204642Srdivackydef t2UASX : T2I_pam<0b010, 0b0100, "uasx">; 2149204642Srdivackydef t2UADD16 : T2I_pam<0b001, 0b0100, "uadd16">; 2150204642Srdivackydef t2UADD8 : T2I_pam<0b000, 0b0100, "uadd8">; 2151204642Srdivackydef t2USAX : T2I_pam<0b110, 0b0100, "usax">; 2152204642Srdivackydef t2USUB16 : T2I_pam<0b101, 0b0100, "usub16">; 2153204642Srdivackydef t2USUB8 : T2I_pam<0b100, 0b0100, "usub8">; 2154204642Srdivacky 2155204642Srdivacky// Signed/Unsigned halving add/subtract -- for disassembly only 2156204642Srdivacky 2157204642Srdivackydef t2SHASX : T2I_pam<0b010, 0b0010, "shasx">; 2158204642Srdivackydef t2SHADD16 : T2I_pam<0b001, 0b0010, "shadd16">; 2159204642Srdivackydef t2SHADD8 : T2I_pam<0b000, 0b0010, "shadd8">; 2160204642Srdivackydef t2SHSAX : T2I_pam<0b110, 0b0010, "shsax">; 2161204642Srdivackydef t2SHSUB16 : T2I_pam<0b101, 0b0010, "shsub16">; 2162204642Srdivackydef t2SHSUB8 : T2I_pam<0b100, 0b0010, "shsub8">; 2163204642Srdivackydef t2UHASX : T2I_pam<0b010, 0b0110, "uhasx">; 2164204642Srdivackydef t2UHADD16 : T2I_pam<0b001, 0b0110, "uhadd16">; 2165204642Srdivackydef t2UHADD8 : T2I_pam<0b000, 0b0110, "uhadd8">; 2166204642Srdivackydef t2UHSAX : T2I_pam<0b110, 0b0110, "uhsax">; 2167204642Srdivackydef t2UHSUB16 : T2I_pam<0b101, 0b0110, "uhsub16">; 2168204642Srdivackydef t2UHSUB8 : T2I_pam<0b100, 0b0110, "uhsub8">; 2169204642Srdivacky 2170218893Sdim// Helper class for disassembly only 2171218893Sdim// A6.3.16 & A6.3.17 2172218893Sdim// T2Imac - Thumb2 multiply [accumulate, and absolute difference] instructions. 2173218893Sdimclass T2ThreeReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops, 2174218893Sdim dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern> 2175218893Sdim : T2ThreeReg<oops, iops, itin, opc, asm, pattern> { 2176218893Sdim let Inst{31-27} = 0b11111; 2177218893Sdim let Inst{26-24} = 0b011; 2178218893Sdim let Inst{23} = long; 2179218893Sdim let Inst{22-20} = op22_20; 2180218893Sdim let Inst{7-4} = op7_4; 2181218893Sdim} 2182218893Sdim 2183218893Sdimclass T2FourReg_mac<bit long, bits<3> op22_20, bits<4> op7_4, dag oops, 2184218893Sdim dag iops, InstrItinClass itin, string opc, string asm, list<dag> pattern> 2185218893Sdim : T2FourReg<oops, iops, itin, opc, asm, pattern> { 2186218893Sdim let Inst{31-27} = 0b11111; 2187218893Sdim let Inst{26-24} = 0b011; 2188218893Sdim let Inst{23} = long; 2189218893Sdim let Inst{22-20} = op22_20; 2190218893Sdim let Inst{7-4} = op7_4; 2191218893Sdim} 2192218893Sdim 2193226633Sdim// Unsigned Sum of Absolute Differences [and Accumulate]. 2194218893Sdimdef t2USAD8 : T2ThreeReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd), 2195218893Sdim (ins rGPR:$Rn, rGPR:$Rm), 2196224145Sdim NoItinerary, "usad8", "\t$Rd, $Rn, $Rm", []>, 2197224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2198204642Srdivacky let Inst{15-12} = 0b1111; 2199204642Srdivacky} 2200218893Sdimdef t2USADA8 : T2FourReg_mac<0, 0b111, 0b0000, (outs rGPR:$Rd), 2201218893Sdim (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), NoItinerary, 2202224145Sdim "usada8", "\t$Rd, $Rn, $Rm, $Ra", []>, 2203224145Sdim Requires<[IsThumb2, HasThumb2DSP]>; 2204204642Srdivacky 2205226633Sdim// Signed/Unsigned saturate. 2206218893Sdimclass T2SatI<dag oops, dag iops, InstrItinClass itin, 2207218893Sdim string opc, string asm, list<dag> pattern> 2208218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 2209218893Sdim bits<4> Rd; 2210218893Sdim bits<4> Rn; 2211218893Sdim bits<5> sat_imm; 2212218893Sdim bits<7> sh; 2213218893Sdim 2214218893Sdim let Inst{11-8} = Rd; 2215218893Sdim let Inst{19-16} = Rn; 2216226633Sdim let Inst{4-0} = sat_imm; 2217226633Sdim let Inst{21} = sh{5}; 2218218893Sdim let Inst{14-12} = sh{4-2}; 2219218893Sdim let Inst{7-6} = sh{1-0}; 2220218893Sdim} 2221218893Sdim 2222218893Sdimdef t2SSAT: T2SatI< 2223226633Sdim (outs rGPR:$Rd), 2224226633Sdim (ins imm1_32:$sat_imm, rGPR:$Rn, t2_shift_imm:$sh), 2225226633Sdim NoItinerary, "ssat", "\t$Rd, $sat_imm, $Rn$sh", []> { 2226204642Srdivacky let Inst{31-27} = 0b11110; 2227204642Srdivacky let Inst{25-22} = 0b1100; 2228204642Srdivacky let Inst{20} = 0; 2229204642Srdivacky let Inst{15} = 0; 2230226633Sdim let Inst{5} = 0; 2231204642Srdivacky} 2232204642Srdivacky 2233218893Sdimdef t2SSAT16: T2SatI< 2234226633Sdim (outs rGPR:$Rd), (ins imm1_16:$sat_imm, rGPR:$Rn), NoItinerary, 2235226633Sdim "ssat16", "\t$Rd, $sat_imm, $Rn", []>, 2236224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2237204642Srdivacky let Inst{31-27} = 0b11110; 2238204642Srdivacky let Inst{25-22} = 0b1100; 2239204642Srdivacky let Inst{20} = 0; 2240204642Srdivacky let Inst{15} = 0; 2241204642Srdivacky let Inst{21} = 1; // sh = '1' 2242204642Srdivacky let Inst{14-12} = 0b000; // imm3 = '000' 2243204642Srdivacky let Inst{7-6} = 0b00; // imm2 = '00' 2244226633Sdim let Inst{5-4} = 0b00; 2245204642Srdivacky} 2246204642Srdivacky 2247218893Sdimdef t2USAT: T2SatI< 2248226633Sdim (outs rGPR:$Rd), 2249226633Sdim (ins imm0_31:$sat_imm, rGPR:$Rn, t2_shift_imm:$sh), 2250226633Sdim NoItinerary, "usat", "\t$Rd, $sat_imm, $Rn$sh", []> { 2251204642Srdivacky let Inst{31-27} = 0b11110; 2252204642Srdivacky let Inst{25-22} = 0b1110; 2253204642Srdivacky let Inst{20} = 0; 2254204642Srdivacky let Inst{15} = 0; 2255204642Srdivacky} 2256204642Srdivacky 2257226633Sdimdef t2USAT16: T2SatI<(outs rGPR:$Rd), (ins imm0_15:$sat_imm, rGPR:$Rn), 2258224145Sdim NoItinerary, 2259226633Sdim "usat16", "\t$Rd, $sat_imm, $Rn", []>, 2260224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2261226633Sdim let Inst{31-22} = 0b1111001110; 2262204642Srdivacky let Inst{20} = 0; 2263204642Srdivacky let Inst{15} = 0; 2264204642Srdivacky let Inst{21} = 1; // sh = '1' 2265204642Srdivacky let Inst{14-12} = 0b000; // imm3 = '000' 2266204642Srdivacky let Inst{7-6} = 0b00; // imm2 = '00' 2267226633Sdim let Inst{5-4} = 0b00; 2268204642Srdivacky} 2269204642Srdivacky 2270212904Sdimdef : T2Pat<(int_arm_ssat GPR:$a, imm:$pos), (t2SSAT imm:$pos, GPR:$a, 0)>; 2271212904Sdimdef : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>; 2272212904Sdim 2273194754Sed//===----------------------------------------------------------------------===// 2274195098Sed// Shift and rotate Instructions. 2275195098Sed// 2276195098Sed 2277226633Sdimdefm t2LSL : T2I_sh_ir<0b00, "lsl", imm0_31, 2278239462Sdim BinOpFrag<(shl node:$LHS, node:$RHS)>>; 2279226633Sdimdefm t2LSR : T2I_sh_ir<0b01, "lsr", imm_sr, 2280239462Sdim BinOpFrag<(srl node:$LHS, node:$RHS)>>; 2281226633Sdimdefm t2ASR : T2I_sh_ir<0b10, "asr", imm_sr, 2282239462Sdim BinOpFrag<(sra node:$LHS, node:$RHS)>>; 2283226633Sdimdefm t2ROR : T2I_sh_ir<0b11, "ror", imm0_31, 2284239462Sdim BinOpFrag<(rotr node:$LHS, node:$RHS)>>; 2285195098Sed 2286221345Sdim// (rotr x, (and y, 0x...1f)) ==> (ROR x, y) 2287239462Sdimdef : T2Pat<(rotr rGPR:$lhs, (and rGPR:$rhs, lo5AllOne)), 2288239462Sdim (t2RORrr rGPR:$lhs, rGPR:$rhs)>; 2289221345Sdim 2290198090Srdivackylet Uses = [CPSR] in { 2291218893Sdimdef t2RRX : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi, 2292218893Sdim "rrx", "\t$Rd, $Rm", 2293263508Sdim [(set rGPR:$Rd, (ARMrrx rGPR:$Rm))]>, Sched<[WriteALU]> { 2294201360Srdivacky let Inst{31-27} = 0b11101; 2295201360Srdivacky let Inst{26-25} = 0b01; 2296201360Srdivacky let Inst{24-21} = 0b0010; 2297201360Srdivacky let Inst{19-16} = 0b1111; // Rn 2298201360Srdivacky let Inst{14-12} = 0b000; 2299201360Srdivacky let Inst{7-4} = 0b0011; 2300198090Srdivacky} 2301201360Srdivacky} 2302195098Sed 2303218893Sdimlet isCodeGenOnly = 1, Defs = [CPSR] in { 2304218893Sdimdef t2MOVsrl_flag : T2TwoRegShiftImm< 2305218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi, 2306218893Sdim "lsrs", ".w\t$Rd, $Rm, #1", 2307263508Sdim [(set rGPR:$Rd, (ARMsrl_flag rGPR:$Rm))]>, 2308263508Sdim Sched<[WriteALU]> { 2309201360Srdivacky let Inst{31-27} = 0b11101; 2310201360Srdivacky let Inst{26-25} = 0b01; 2311201360Srdivacky let Inst{24-21} = 0b0010; 2312201360Srdivacky let Inst{20} = 1; // The S bit. 2313201360Srdivacky let Inst{19-16} = 0b1111; // Rn 2314201360Srdivacky let Inst{5-4} = 0b01; // Shift type. 2315201360Srdivacky // Shift amount = Inst{14-12:7-6} = 1. 2316201360Srdivacky let Inst{14-12} = 0b000; 2317201360Srdivacky let Inst{7-6} = 0b01; 2318201360Srdivacky} 2319218893Sdimdef t2MOVsra_flag : T2TwoRegShiftImm< 2320218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iMOVsi, 2321218893Sdim "asrs", ".w\t$Rd, $Rm, #1", 2322263508Sdim [(set rGPR:$Rd, (ARMsra_flag rGPR:$Rm))]>, 2323263508Sdim Sched<[WriteALU]> { 2324201360Srdivacky let Inst{31-27} = 0b11101; 2325201360Srdivacky let Inst{26-25} = 0b01; 2326201360Srdivacky let Inst{24-21} = 0b0010; 2327201360Srdivacky let Inst{20} = 1; // The S bit. 2328201360Srdivacky let Inst{19-16} = 0b1111; // Rn 2329201360Srdivacky let Inst{5-4} = 0b10; // Shift type. 2330201360Srdivacky // Shift amount = Inst{14-12:7-6} = 1. 2331201360Srdivacky let Inst{14-12} = 0b000; 2332201360Srdivacky let Inst{7-6} = 0b01; 2333198090Srdivacky} 2334201360Srdivacky} 2335198090Srdivacky 2336195098Sed//===----------------------------------------------------------------------===// 2337194754Sed// Bitwise Instructions. 2338194754Sed// 2339194754Sed 2340201360Srdivackydefm t2AND : T2I_bin_w_irs<0b0000, "and", 2341218893Sdim IIC_iBITi, IIC_iBITr, IIC_iBITsi, 2342239462Sdim BinOpFrag<(and node:$LHS, node:$RHS)>, 1>; 2343201360Srdivackydefm t2ORR : T2I_bin_w_irs<0b0010, "orr", 2344218893Sdim IIC_iBITi, IIC_iBITr, IIC_iBITsi, 2345239462Sdim BinOpFrag<(or node:$LHS, node:$RHS)>, 1>; 2346201360Srdivackydefm t2EOR : T2I_bin_w_irs<0b0100, "eor", 2347218893Sdim IIC_iBITi, IIC_iBITr, IIC_iBITsi, 2348239462Sdim BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>; 2349194754Sed 2350201360Srdivackydefm t2BIC : T2I_bin_w_irs<0b0001, "bic", 2351218893Sdim IIC_iBITi, IIC_iBITr, IIC_iBITsi, 2352239462Sdim BinOpFrag<(and node:$LHS, (not node:$RHS))>>; 2353194754Sed 2354218893Sdimclass T2BitFI<dag oops, dag iops, InstrItinClass itin, 2355218893Sdim string opc, string asm, list<dag> pattern> 2356218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 2357218893Sdim bits<4> Rd; 2358218893Sdim bits<5> msb; 2359218893Sdim bits<5> lsb; 2360212904Sdim 2361218893Sdim let Inst{11-8} = Rd; 2362218893Sdim let Inst{4-0} = msb{4-0}; 2363218893Sdim let Inst{14-12} = lsb{4-2}; 2364218893Sdim let Inst{7-6} = lsb{1-0}; 2365218893Sdim} 2366218893Sdim 2367218893Sdimclass T2TwoRegBitFI<dag oops, dag iops, InstrItinClass itin, 2368218893Sdim string opc, string asm, list<dag> pattern> 2369218893Sdim : T2BitFI<oops, iops, itin, opc, asm, pattern> { 2370218893Sdim bits<4> Rn; 2371218893Sdim 2372218893Sdim let Inst{19-16} = Rn; 2373218893Sdim} 2374218893Sdim 2375218893Sdimlet Constraints = "$src = $Rd" in 2376218893Sdimdef t2BFC : T2BitFI<(outs rGPR:$Rd), (ins rGPR:$src, bf_inv_mask_imm:$imm), 2377218893Sdim IIC_iUNAsi, "bfc", "\t$Rd, $imm", 2378218893Sdim [(set rGPR:$Rd, (and rGPR:$src, bf_inv_mask_imm:$imm))]> { 2379201360Srdivacky let Inst{31-27} = 0b11110; 2380221345Sdim let Inst{26} = 0; // should be 0. 2381201360Srdivacky let Inst{25} = 1; 2382201360Srdivacky let Inst{24-20} = 0b10110; 2383201360Srdivacky let Inst{19-16} = 0b1111; // Rn 2384201360Srdivacky let Inst{15} = 0; 2385221345Sdim let Inst{5} = 0; // should be 0. 2386218893Sdim 2387218893Sdim bits<10> imm; 2388218893Sdim let msb{4-0} = imm{9-5}; 2389218893Sdim let lsb{4-0} = imm{4-0}; 2390201360Srdivacky} 2391194754Sed 2392218893Sdimdef t2SBFX: T2TwoRegBitFI< 2393226633Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm1_32:$msb), 2394218893Sdim IIC_iUNAsi, "sbfx", "\t$Rd, $Rn, $lsb, $msb", []> { 2395201360Srdivacky let Inst{31-27} = 0b11110; 2396201360Srdivacky let Inst{25} = 1; 2397201360Srdivacky let Inst{24-20} = 0b10100; 2398201360Srdivacky let Inst{15} = 0; 2399201360Srdivacky} 2400198090Srdivacky 2401218893Sdimdef t2UBFX: T2TwoRegBitFI< 2402226633Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm1_32:$msb), 2403218893Sdim IIC_iUNAsi, "ubfx", "\t$Rd, $Rn, $lsb, $msb", []> { 2404201360Srdivacky let Inst{31-27} = 0b11110; 2405201360Srdivacky let Inst{25} = 1; 2406201360Srdivacky let Inst{24-20} = 0b11100; 2407201360Srdivacky let Inst{15} = 0; 2408201360Srdivacky} 2409198090Srdivacky 2410203954Srdivacky// A8.6.18 BFI - Bitfield insert (Encoding T1) 2411218893Sdimlet Constraints = "$src = $Rd" in { 2412218893Sdim def t2BFI : T2TwoRegBitFI<(outs rGPR:$Rd), 2413218893Sdim (ins rGPR:$src, rGPR:$Rn, bf_inv_mask_imm:$imm), 2414218893Sdim IIC_iBITi, "bfi", "\t$Rd, $Rn, $imm", 2415218893Sdim [(set rGPR:$Rd, (ARMbfi rGPR:$src, rGPR:$Rn, 2416218893Sdim bf_inv_mask_imm:$imm))]> { 2417218893Sdim let Inst{31-27} = 0b11110; 2418221345Sdim let Inst{26} = 0; // should be 0. 2419218893Sdim let Inst{25} = 1; 2420218893Sdim let Inst{24-20} = 0b10110; 2421218893Sdim let Inst{15} = 0; 2422221345Sdim let Inst{5} = 0; // should be 0. 2423218893Sdim 2424218893Sdim bits<10> imm; 2425218893Sdim let msb{4-0} = imm{9-5}; 2426218893Sdim let lsb{4-0} = imm{4-0}; 2427218893Sdim } 2428203954Srdivacky} 2429198090Srdivacky 2430218893Sdimdefm t2ORN : T2I_bin_irs<0b0011, "orn", 2431218893Sdim IIC_iBITi, IIC_iBITr, IIC_iBITsi, 2432239462Sdim BinOpFrag<(or node:$LHS, (not node:$RHS))>, 0, "">; 2433194754Sed 2434226633Sdim/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a 2435226633Sdim/// unary operation that produces a value. These are predicable and can be 2436226633Sdim/// changed to modify CPSR. 2437226633Sdimmulticlass T2I_un_irs<bits<4> opcod, string opc, 2438226633Sdim InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 2439249423Sdim PatFrag opnode, 2440249423Sdim bit Cheap = 0, bit ReMat = 0, bit MoveImm = 0> { 2441226633Sdim // shifted imm 2442226633Sdim def i : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), iii, 2443226633Sdim opc, "\t$Rd, $imm", 2444263508Sdim [(set rGPR:$Rd, (opnode t2_so_imm:$imm))]>, Sched<[WriteALU]> { 2445226633Sdim let isAsCheapAsAMove = Cheap; 2446226633Sdim let isReMaterializable = ReMat; 2447249423Sdim let isMoveImm = MoveImm; 2448226633Sdim let Inst{31-27} = 0b11110; 2449226633Sdim let Inst{25} = 0; 2450226633Sdim let Inst{24-21} = opcod; 2451226633Sdim let Inst{19-16} = 0b1111; // Rn 2452226633Sdim let Inst{15} = 0; 2453226633Sdim } 2454226633Sdim // register 2455226633Sdim def r : T2sTwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm), iir, 2456226633Sdim opc, ".w\t$Rd, $Rm", 2457263508Sdim [(set rGPR:$Rd, (opnode rGPR:$Rm))]>, Sched<[WriteALU]> { 2458226633Sdim let Inst{31-27} = 0b11101; 2459226633Sdim let Inst{26-25} = 0b01; 2460226633Sdim let Inst{24-21} = opcod; 2461226633Sdim let Inst{19-16} = 0b1111; // Rn 2462226633Sdim let Inst{14-12} = 0b000; // imm3 2463226633Sdim let Inst{7-6} = 0b00; // imm2 2464226633Sdim let Inst{5-4} = 0b00; // type 2465226633Sdim } 2466226633Sdim // shifted register 2467226633Sdim def s : T2sOneRegShiftedReg<(outs rGPR:$Rd), (ins t2_so_reg:$ShiftedRm), iis, 2468226633Sdim opc, ".w\t$Rd, $ShiftedRm", 2469263508Sdim [(set rGPR:$Rd, (opnode t2_so_reg:$ShiftedRm))]>, 2470263508Sdim Sched<[WriteALU]> { 2471226633Sdim let Inst{31-27} = 0b11101; 2472226633Sdim let Inst{26-25} = 0b01; 2473226633Sdim let Inst{24-21} = opcod; 2474226633Sdim let Inst{19-16} = 0b1111; // Rn 2475226633Sdim } 2476226633Sdim} 2477226633Sdim 2478195098Sed// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version 2479195098Sedlet AddedComplexity = 1 in 2480218893Sdimdefm t2MVN : T2I_un_irs <0b0011, "mvn", 2481218893Sdim IIC_iMVNi, IIC_iMVNr, IIC_iMVNsi, 2482249423Sdim UnOpFrag<(not node:$Src)>, 1, 1, 1>; 2483194754Sed 2484212904Sdimlet AddedComplexity = 1 in 2485212904Sdimdef : T2Pat<(and rGPR:$src, t2_so_imm_not:$imm), 2486212904Sdim (t2BICri rGPR:$src, t2_so_imm_not:$imm)>; 2487198090Srdivacky 2488239462Sdim// top16Zero - answer true if the upper 16 bits of $src are 0, false otherwise 2489239462Sdimdef top16Zero: PatLeaf<(i32 rGPR:$src), [{ 2490239462Sdim return CurDAG->MaskedValueIsZero(SDValue(N,0), APInt::getHighBitsSet(32, 16)); 2491239462Sdim }]>; 2492239462Sdim 2493239462Sdim// so_imm_notSext is needed instead of so_imm_not, as the value of imm 2494239462Sdim// will match the extended, not the original bitWidth for $src. 2495239462Sdimdef : T2Pat<(and top16Zero:$src, t2_so_imm_notSext:$imm), 2496239462Sdim (t2BICri rGPR:$src, t2_so_imm_notSext:$imm)>; 2497239462Sdim 2498239462Sdim 2499198090Srdivacky// FIXME: Disable this pattern on Darwin to workaround an assembler bug. 2500212904Sdimdef : T2Pat<(or rGPR:$src, t2_so_imm_not:$imm), 2501212904Sdim (t2ORNri rGPR:$src, t2_so_imm_not:$imm)>, 2502198090Srdivacky Requires<[IsThumb2]>; 2503198090Srdivacky 2504195098Seddef : T2Pat<(t2_so_imm_not:$src), 2505195098Sed (t2MVNi t2_so_imm_not:$src)>; 2506194754Sed 2507194754Sed//===----------------------------------------------------------------------===// 2508194754Sed// Multiply Instructions. 2509194754Sed// 2510195098Sedlet isCommutable = 1 in 2511218893Sdimdef t2MUL: T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32, 2512218893Sdim "mul", "\t$Rd, $Rn, $Rm", 2513218893Sdim [(set rGPR:$Rd, (mul rGPR:$Rn, rGPR:$Rm))]> { 2514201360Srdivacky let Inst{31-27} = 0b11111; 2515201360Srdivacky let Inst{26-23} = 0b0110; 2516201360Srdivacky let Inst{22-20} = 0b000; 2517201360Srdivacky let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2518201360Srdivacky let Inst{7-4} = 0b0000; // Multiply 2519201360Srdivacky} 2520194754Sed 2521218893Sdimdef t2MLA: T2FourReg< 2522218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, 2523218893Sdim "mla", "\t$Rd, $Rn, $Rm, $Ra", 2524243830Sdim [(set rGPR:$Rd, (add (mul rGPR:$Rn, rGPR:$Rm), rGPR:$Ra))]>, 2525243830Sdim Requires<[IsThumb2, UseMulOps]> { 2526201360Srdivacky let Inst{31-27} = 0b11111; 2527201360Srdivacky let Inst{26-23} = 0b0110; 2528201360Srdivacky let Inst{22-20} = 0b000; 2529201360Srdivacky let Inst{7-4} = 0b0000; // Multiply 2530201360Srdivacky} 2531194754Sed 2532218893Sdimdef t2MLS: T2FourReg< 2533218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, 2534218893Sdim "mls", "\t$Rd, $Rn, $Rm, $Ra", 2535243830Sdim [(set rGPR:$Rd, (sub rGPR:$Ra, (mul rGPR:$Rn, rGPR:$Rm)))]>, 2536243830Sdim Requires<[IsThumb2, UseMulOps]> { 2537201360Srdivacky let Inst{31-27} = 0b11111; 2538201360Srdivacky let Inst{26-23} = 0b0110; 2539201360Srdivacky let Inst{22-20} = 0b000; 2540201360Srdivacky let Inst{7-4} = 0b0001; // Multiply and Subtract 2541201360Srdivacky} 2542194754Sed 2543198090Srdivacky// Extra precision multiplies with low / high results 2544198090Srdivackylet neverHasSideEffects = 1 in { 2545198090Srdivackylet isCommutable = 1 in { 2546218893Sdimdef t2SMULL : T2MulLong<0b000, 0b0000, 2547226633Sdim (outs rGPR:$RdLo, rGPR:$RdHi), 2548218893Sdim (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64, 2549226633Sdim "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>; 2550194754Sed 2551218893Sdimdef t2UMULL : T2MulLong<0b010, 0b0000, 2552218893Sdim (outs rGPR:$RdLo, rGPR:$RdHi), 2553218893Sdim (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL64, 2554218893Sdim "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>; 2555201360Srdivacky} // isCommutable 2556198090Srdivacky 2557198090Srdivacky// Multiply + accumulate 2558243830Sdimdef t2SMLAL : T2MlaLong<0b100, 0b0000, 2559218893Sdim (outs rGPR:$RdLo, rGPR:$RdHi), 2560243830Sdim (ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64, 2561243830Sdim "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 2562243830Sdim RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">; 2563198090Srdivacky 2564243830Sdimdef t2UMLAL : T2MlaLong<0b110, 0b0000, 2565218893Sdim (outs rGPR:$RdLo, rGPR:$RdHi), 2566243830Sdim (ins rGPR:$Rn, rGPR:$Rm, rGPR:$RLo, rGPR:$RHi), IIC_iMAC64, 2567243830Sdim "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 2568243830Sdim RegConstraint<"$RLo = $RdLo, $RHi = $RdHi">; 2569198090Srdivacky 2570218893Sdimdef t2UMAAL : T2MulLong<0b110, 0b0110, 2571218893Sdim (outs rGPR:$RdLo, rGPR:$RdHi), 2572218893Sdim (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64, 2573224145Sdim "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 2574224145Sdim Requires<[IsThumb2, HasThumb2DSP]>; 2575198090Srdivacky} // neverHasSideEffects 2576198090Srdivacky 2577204642Srdivacky// Rounding variants of the below included for disassembly only 2578204642Srdivacky 2579198090Srdivacky// Most significant word multiply 2580218893Sdimdef t2SMMUL : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32, 2581218893Sdim "smmul", "\t$Rd, $Rn, $Rm", 2582224145Sdim [(set rGPR:$Rd, (mulhs rGPR:$Rn, rGPR:$Rm))]>, 2583224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2584201360Srdivacky let Inst{31-27} = 0b11111; 2585201360Srdivacky let Inst{26-23} = 0b0110; 2586201360Srdivacky let Inst{22-20} = 0b101; 2587201360Srdivacky let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2588201360Srdivacky let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) 2589201360Srdivacky} 2590198090Srdivacky 2591218893Sdimdef t2SMMULR : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL32, 2592224145Sdim "smmulr", "\t$Rd, $Rn, $Rm", []>, 2593224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2594204642Srdivacky let Inst{31-27} = 0b11111; 2595204642Srdivacky let Inst{26-23} = 0b0110; 2596204642Srdivacky let Inst{22-20} = 0b101; 2597204642Srdivacky let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2598204642Srdivacky let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) 2599204642Srdivacky} 2600204642Srdivacky 2601218893Sdimdef t2SMMLA : T2FourReg< 2602218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, 2603218893Sdim "smmla", "\t$Rd, $Rn, $Rm, $Ra", 2604224145Sdim [(set rGPR:$Rd, (add (mulhs rGPR:$Rm, rGPR:$Rn), rGPR:$Ra))]>, 2605243830Sdim Requires<[IsThumb2, HasThumb2DSP, UseMulOps]> { 2606201360Srdivacky let Inst{31-27} = 0b11111; 2607201360Srdivacky let Inst{26-23} = 0b0110; 2608201360Srdivacky let Inst{22-20} = 0b101; 2609201360Srdivacky let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) 2610201360Srdivacky} 2611198090Srdivacky 2612218893Sdimdef t2SMMLAR: T2FourReg< 2613218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, 2614224145Sdim "smmlar", "\t$Rd, $Rn, $Rm, $Ra", []>, 2615224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2616204642Srdivacky let Inst{31-27} = 0b11111; 2617204642Srdivacky let Inst{26-23} = 0b0110; 2618204642Srdivacky let Inst{22-20} = 0b101; 2619204642Srdivacky let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) 2620204642Srdivacky} 2621198090Srdivacky 2622218893Sdimdef t2SMMLS: T2FourReg< 2623218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, 2624218893Sdim "smmls", "\t$Rd, $Rn, $Rm, $Ra", 2625224145Sdim [(set rGPR:$Rd, (sub rGPR:$Ra, (mulhs rGPR:$Rn, rGPR:$Rm)))]>, 2626243830Sdim Requires<[IsThumb2, HasThumb2DSP, UseMulOps]> { 2627201360Srdivacky let Inst{31-27} = 0b11111; 2628201360Srdivacky let Inst{26-23} = 0b0110; 2629201360Srdivacky let Inst{22-20} = 0b110; 2630201360Srdivacky let Inst{7-4} = 0b0000; // No Rounding (Inst{4} = 0) 2631201360Srdivacky} 2632198090Srdivacky 2633218893Sdimdef t2SMMLSR:T2FourReg< 2634218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, 2635224145Sdim "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", []>, 2636224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2637204642Srdivacky let Inst{31-27} = 0b11111; 2638204642Srdivacky let Inst{26-23} = 0b0110; 2639204642Srdivacky let Inst{22-20} = 0b110; 2640204642Srdivacky let Inst{7-4} = 0b0001; // Rounding (Inst{4} = 1) 2641204642Srdivacky} 2642204642Srdivacky 2643198090Srdivackymulticlass T2I_smul<string opc, PatFrag opnode> { 2644218893Sdim def BB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, 2645218893Sdim !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm", 2646218893Sdim [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16), 2647224145Sdim (sext_inreg rGPR:$Rm, i16)))]>, 2648224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2649201360Srdivacky let Inst{31-27} = 0b11111; 2650201360Srdivacky let Inst{26-23} = 0b0110; 2651201360Srdivacky let Inst{22-20} = 0b001; 2652201360Srdivacky let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2653201360Srdivacky let Inst{7-6} = 0b00; 2654201360Srdivacky let Inst{5-4} = 0b00; 2655201360Srdivacky } 2656198090Srdivacky 2657218893Sdim def BT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, 2658218893Sdim !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm", 2659218893Sdim [(set rGPR:$Rd, (opnode (sext_inreg rGPR:$Rn, i16), 2660224145Sdim (sra rGPR:$Rm, (i32 16))))]>, 2661224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2662201360Srdivacky let Inst{31-27} = 0b11111; 2663201360Srdivacky let Inst{26-23} = 0b0110; 2664201360Srdivacky let Inst{22-20} = 0b001; 2665201360Srdivacky let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2666201360Srdivacky let Inst{7-6} = 0b00; 2667201360Srdivacky let Inst{5-4} = 0b01; 2668201360Srdivacky } 2669198090Srdivacky 2670218893Sdim def TB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, 2671218893Sdim !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm", 2672218893Sdim [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)), 2673224145Sdim (sext_inreg rGPR:$Rm, i16)))]>, 2674224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2675201360Srdivacky let Inst{31-27} = 0b11111; 2676201360Srdivacky let Inst{26-23} = 0b0110; 2677201360Srdivacky let Inst{22-20} = 0b001; 2678201360Srdivacky let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2679201360Srdivacky let Inst{7-6} = 0b00; 2680201360Srdivacky let Inst{5-4} = 0b10; 2681201360Srdivacky } 2682198090Srdivacky 2683218893Sdim def TT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, 2684218893Sdim !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm", 2685218893Sdim [(set rGPR:$Rd, (opnode (sra rGPR:$Rn, (i32 16)), 2686224145Sdim (sra rGPR:$Rm, (i32 16))))]>, 2687224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2688201360Srdivacky let Inst{31-27} = 0b11111; 2689201360Srdivacky let Inst{26-23} = 0b0110; 2690201360Srdivacky let Inst{22-20} = 0b001; 2691201360Srdivacky let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2692201360Srdivacky let Inst{7-6} = 0b00; 2693201360Srdivacky let Inst{5-4} = 0b11; 2694201360Srdivacky } 2695198090Srdivacky 2696218893Sdim def WB : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, 2697218893Sdim !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm", 2698218893Sdim [(set rGPR:$Rd, (sra (opnode rGPR:$Rn, 2699224145Sdim (sext_inreg rGPR:$Rm, i16)), (i32 16)))]>, 2700224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2701201360Srdivacky let Inst{31-27} = 0b11111; 2702201360Srdivacky let Inst{26-23} = 0b0110; 2703201360Srdivacky let Inst{22-20} = 0b011; 2704201360Srdivacky let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2705201360Srdivacky let Inst{7-6} = 0b00; 2706201360Srdivacky let Inst{5-4} = 0b00; 2707201360Srdivacky } 2708198090Srdivacky 2709218893Sdim def WT : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iMUL16, 2710218893Sdim !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm", 2711218893Sdim [(set rGPR:$Rd, (sra (opnode rGPR:$Rn, 2712224145Sdim (sra rGPR:$Rm, (i32 16))), (i32 16)))]>, 2713224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2714201360Srdivacky let Inst{31-27} = 0b11111; 2715201360Srdivacky let Inst{26-23} = 0b0110; 2716201360Srdivacky let Inst{22-20} = 0b011; 2717201360Srdivacky let Inst{15-12} = 0b1111; // Ra = 0b1111 (no accumulate) 2718201360Srdivacky let Inst{7-6} = 0b00; 2719201360Srdivacky let Inst{5-4} = 0b01; 2720201360Srdivacky } 2721198090Srdivacky} 2722198090Srdivacky 2723198090Srdivacky 2724198090Srdivackymulticlass T2I_smla<string opc, PatFrag opnode> { 2725218893Sdim def BB : T2FourReg< 2726218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, 2727218893Sdim !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra", 2728218893Sdim [(set rGPR:$Rd, (add rGPR:$Ra, 2729218893Sdim (opnode (sext_inreg rGPR:$Rn, i16), 2730224145Sdim (sext_inreg rGPR:$Rm, i16))))]>, 2731243830Sdim Requires<[IsThumb2, HasThumb2DSP, UseMulOps]> { 2732201360Srdivacky let Inst{31-27} = 0b11111; 2733201360Srdivacky let Inst{26-23} = 0b0110; 2734201360Srdivacky let Inst{22-20} = 0b001; 2735201360Srdivacky let Inst{7-6} = 0b00; 2736201360Srdivacky let Inst{5-4} = 0b00; 2737201360Srdivacky } 2738198090Srdivacky 2739218893Sdim def BT : T2FourReg< 2740218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, 2741218893Sdim !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra", 2742218893Sdim [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sext_inreg rGPR:$Rn, i16), 2743224145Sdim (sra rGPR:$Rm, (i32 16)))))]>, 2744243830Sdim Requires<[IsThumb2, HasThumb2DSP, UseMulOps]> { 2745201360Srdivacky let Inst{31-27} = 0b11111; 2746201360Srdivacky let Inst{26-23} = 0b0110; 2747201360Srdivacky let Inst{22-20} = 0b001; 2748201360Srdivacky let Inst{7-6} = 0b00; 2749201360Srdivacky let Inst{5-4} = 0b01; 2750201360Srdivacky } 2751198090Srdivacky 2752218893Sdim def TB : T2FourReg< 2753218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, 2754218893Sdim !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra", 2755218893Sdim [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)), 2756224145Sdim (sext_inreg rGPR:$Rm, i16))))]>, 2757243830Sdim Requires<[IsThumb2, HasThumb2DSP, UseMulOps]> { 2758201360Srdivacky let Inst{31-27} = 0b11111; 2759201360Srdivacky let Inst{26-23} = 0b0110; 2760201360Srdivacky let Inst{22-20} = 0b001; 2761201360Srdivacky let Inst{7-6} = 0b00; 2762201360Srdivacky let Inst{5-4} = 0b10; 2763201360Srdivacky } 2764198090Srdivacky 2765218893Sdim def TT : T2FourReg< 2766218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, 2767218893Sdim !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra", 2768218893Sdim [(set rGPR:$Rd, (add rGPR:$Ra, (opnode (sra rGPR:$Rn, (i32 16)), 2769224145Sdim (sra rGPR:$Rm, (i32 16)))))]>, 2770243830Sdim Requires<[IsThumb2, HasThumb2DSP, UseMulOps]> { 2771201360Srdivacky let Inst{31-27} = 0b11111; 2772201360Srdivacky let Inst{26-23} = 0b0110; 2773201360Srdivacky let Inst{22-20} = 0b001; 2774201360Srdivacky let Inst{7-6} = 0b00; 2775201360Srdivacky let Inst{5-4} = 0b11; 2776201360Srdivacky } 2777198090Srdivacky 2778218893Sdim def WB : T2FourReg< 2779218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, 2780218893Sdim !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra", 2781218893Sdim [(set rGPR:$Rd, (add rGPR:$Ra, (sra (opnode rGPR:$Rn, 2782224145Sdim (sext_inreg rGPR:$Rm, i16)), (i32 16))))]>, 2783243830Sdim Requires<[IsThumb2, HasThumb2DSP, UseMulOps]> { 2784201360Srdivacky let Inst{31-27} = 0b11111; 2785201360Srdivacky let Inst{26-23} = 0b0110; 2786201360Srdivacky let Inst{22-20} = 0b011; 2787201360Srdivacky let Inst{7-6} = 0b00; 2788201360Srdivacky let Inst{5-4} = 0b00; 2789201360Srdivacky } 2790198090Srdivacky 2791218893Sdim def WT : T2FourReg< 2792218893Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC16, 2793218893Sdim !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra", 2794218893Sdim [(set rGPR:$Rd, (add rGPR:$Ra, (sra (opnode rGPR:$Rn, 2795224145Sdim (sra rGPR:$Rm, (i32 16))), (i32 16))))]>, 2796243830Sdim Requires<[IsThumb2, HasThumb2DSP, UseMulOps]> { 2797201360Srdivacky let Inst{31-27} = 0b11111; 2798201360Srdivacky let Inst{26-23} = 0b0110; 2799201360Srdivacky let Inst{22-20} = 0b011; 2800201360Srdivacky let Inst{7-6} = 0b00; 2801201360Srdivacky let Inst{5-4} = 0b01; 2802201360Srdivacky } 2803198090Srdivacky} 2804198090Srdivacky 2805198090Srdivackydefm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 2806198090Srdivackydefm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 2807198090Srdivacky 2808226633Sdim// Halfword multiple accumulate long: SMLAL<x><y> 2809218893Sdimdef t2SMLALBB : T2FourReg_mac<1, 0b100, 0b1000, (outs rGPR:$Ra,rGPR:$Rd), 2810218893Sdim (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbb", "\t$Ra, $Rd, $Rn, $Rm", 2811224145Sdim [/* For disassembly only; pattern left blank */]>, 2812224145Sdim Requires<[IsThumb2, HasThumb2DSP]>; 2813218893Sdimdef t2SMLALBT : T2FourReg_mac<1, 0b100, 0b1001, (outs rGPR:$Ra,rGPR:$Rd), 2814218893Sdim (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlalbt", "\t$Ra, $Rd, $Rn, $Rm", 2815224145Sdim [/* For disassembly only; pattern left blank */]>, 2816224145Sdim Requires<[IsThumb2, HasThumb2DSP]>; 2817218893Sdimdef t2SMLALTB : T2FourReg_mac<1, 0b100, 0b1010, (outs rGPR:$Ra,rGPR:$Rd), 2818218893Sdim (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltb", "\t$Ra, $Rd, $Rn, $Rm", 2819224145Sdim [/* For disassembly only; pattern left blank */]>, 2820224145Sdim Requires<[IsThumb2, HasThumb2DSP]>; 2821218893Sdimdef t2SMLALTT : T2FourReg_mac<1, 0b100, 0b1011, (outs rGPR:$Ra,rGPR:$Rd), 2822218893Sdim (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaltt", "\t$Ra, $Rd, $Rn, $Rm", 2823224145Sdim [/* For disassembly only; pattern left blank */]>, 2824224145Sdim Requires<[IsThumb2, HasThumb2DSP]>; 2825198090Srdivacky 2826204642Srdivacky// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD 2827218893Sdimdef t2SMUAD: T2ThreeReg_mac< 2828218893Sdim 0, 0b010, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), 2829224145Sdim IIC_iMAC32, "smuad", "\t$Rd, $Rn, $Rm", []>, 2830224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2831204642Srdivacky let Inst{15-12} = 0b1111; 2832204642Srdivacky} 2833218893Sdimdef t2SMUADX:T2ThreeReg_mac< 2834218893Sdim 0, 0b010, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), 2835224145Sdim IIC_iMAC32, "smuadx", "\t$Rd, $Rn, $Rm", []>, 2836224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2837204642Srdivacky let Inst{15-12} = 0b1111; 2838204642Srdivacky} 2839218893Sdimdef t2SMUSD: T2ThreeReg_mac< 2840218893Sdim 0, 0b100, 0b0000, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), 2841224145Sdim IIC_iMAC32, "smusd", "\t$Rd, $Rn, $Rm", []>, 2842224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2843204642Srdivacky let Inst{15-12} = 0b1111; 2844204642Srdivacky} 2845218893Sdimdef t2SMUSDX:T2ThreeReg_mac< 2846218893Sdim 0, 0b100, 0b0001, (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), 2847224145Sdim IIC_iMAC32, "smusdx", "\t$Rd, $Rn, $Rm", []>, 2848224145Sdim Requires<[IsThumb2, HasThumb2DSP]> { 2849204642Srdivacky let Inst{15-12} = 0b1111; 2850204642Srdivacky} 2851226633Sdimdef t2SMLAD : T2FourReg_mac< 2852218893Sdim 0, 0b010, 0b0000, (outs rGPR:$Rd), 2853218893Sdim (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlad", 2854224145Sdim "\t$Rd, $Rn, $Rm, $Ra", []>, 2855224145Sdim Requires<[IsThumb2, HasThumb2DSP]>; 2856218893Sdimdef t2SMLADX : T2FourReg_mac< 2857218893Sdim 0, 0b010, 0b0001, (outs rGPR:$Rd), 2858218893Sdim (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smladx", 2859224145Sdim "\t$Rd, $Rn, $Rm, $Ra", []>, 2860224145Sdim Requires<[IsThumb2, HasThumb2DSP]>; 2861218893Sdimdef t2SMLSD : T2FourReg_mac<0, 0b100, 0b0000, (outs rGPR:$Rd), 2862218893Sdim (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsd", 2863224145Sdim "\t$Rd, $Rn, $Rm, $Ra", []>, 2864224145Sdim Requires<[IsThumb2, HasThumb2DSP]>; 2865218893Sdimdef t2SMLSDX : T2FourReg_mac<0, 0b100, 0b0001, (outs rGPR:$Rd), 2866218893Sdim (ins rGPR:$Rn, rGPR:$Rm, rGPR:$Ra), IIC_iMAC32, "smlsdx", 2867224145Sdim "\t$Rd, $Rn, $Rm, $Ra", []>, 2868224145Sdim Requires<[IsThumb2, HasThumb2DSP]>; 2869218893Sdimdef t2SMLALD : T2FourReg_mac<1, 0b100, 0b1100, (outs rGPR:$Ra,rGPR:$Rd), 2870226633Sdim (ins rGPR:$Rn, rGPR:$Rm), IIC_iMAC64, "smlald", 2871226633Sdim "\t$Ra, $Rd, $Rn, $Rm", []>, 2872224145Sdim Requires<[IsThumb2, HasThumb2DSP]>; 2873218893Sdimdef t2SMLALDX : T2FourReg_mac<1, 0b100, 0b1101, (outs rGPR:$Ra,rGPR:$Rd), 2874226633Sdim (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlaldx", 2875226633Sdim "\t$Ra, $Rd, $Rn, $Rm", []>, 2876224145Sdim Requires<[IsThumb2, HasThumb2DSP]>; 2877218893Sdimdef t2SMLSLD : T2FourReg_mac<1, 0b101, 0b1100, (outs rGPR:$Ra,rGPR:$Rd), 2878226633Sdim (ins rGPR:$Rn,rGPR:$Rm), IIC_iMAC64, "smlsld", 2879226633Sdim "\t$Ra, $Rd, $Rn, $Rm", []>, 2880224145Sdim Requires<[IsThumb2, HasThumb2DSP]>; 2881218893Sdimdef t2SMLSLDX : T2FourReg_mac<1, 0b101, 0b1101, (outs rGPR:$Ra,rGPR:$Rd), 2882218893Sdim (ins rGPR:$Rm,rGPR:$Rn), IIC_iMAC64, "smlsldx", 2883226633Sdim "\t$Ra, $Rd, $Rn, $Rm", []>, 2884224145Sdim Requires<[IsThumb2, HasThumb2DSP]>; 2885204642Srdivacky 2886194754Sed//===----------------------------------------------------------------------===// 2887224145Sdim// Division Instructions. 2888224145Sdim// Signed and unsigned division on v7-M 2889224145Sdim// 2890243830Sdimdef t2SDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iDIV, 2891224145Sdim "sdiv", "\t$Rd, $Rn, $Rm", 2892224145Sdim [(set rGPR:$Rd, (sdiv rGPR:$Rn, rGPR:$Rm))]>, 2893224145Sdim Requires<[HasDivide, IsThumb2]> { 2894224145Sdim let Inst{31-27} = 0b11111; 2895224145Sdim let Inst{26-21} = 0b011100; 2896224145Sdim let Inst{20} = 0b1; 2897224145Sdim let Inst{15-12} = 0b1111; 2898224145Sdim let Inst{7-4} = 0b1111; 2899224145Sdim} 2900224145Sdim 2901243830Sdimdef t2UDIV : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iDIV, 2902224145Sdim "udiv", "\t$Rd, $Rn, $Rm", 2903224145Sdim [(set rGPR:$Rd, (udiv rGPR:$Rn, rGPR:$Rm))]>, 2904224145Sdim Requires<[HasDivide, IsThumb2]> { 2905224145Sdim let Inst{31-27} = 0b11111; 2906224145Sdim let Inst{26-21} = 0b011101; 2907224145Sdim let Inst{20} = 0b1; 2908224145Sdim let Inst{15-12} = 0b1111; 2909224145Sdim let Inst{7-4} = 0b1111; 2910224145Sdim} 2911224145Sdim 2912224145Sdim//===----------------------------------------------------------------------===// 2913194754Sed// Misc. Arithmetic Instructions. 2914194754Sed// 2915194754Sed 2916204642Srdivackyclass T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops, 2917204642Srdivacky InstrItinClass itin, string opc, string asm, list<dag> pattern> 2918218893Sdim : T2ThreeReg<oops, iops, itin, opc, asm, pattern> { 2919201360Srdivacky let Inst{31-27} = 0b11111; 2920201360Srdivacky let Inst{26-22} = 0b01010; 2921201360Srdivacky let Inst{21-20} = op1; 2922201360Srdivacky let Inst{15-12} = 0b1111; 2923201360Srdivacky let Inst{7-6} = 0b10; 2924201360Srdivacky let Inst{5-4} = op2; 2925218893Sdim let Rn{3-0} = Rm; 2926201360Srdivacky} 2927194754Sed 2928218893Sdimdef t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr, 2929263508Sdim "clz", "\t$Rd, $Rm", [(set rGPR:$Rd, (ctlz rGPR:$Rm))]>, 2930263508Sdim Sched<[WriteALU]>; 2931194754Sed 2932218893Sdimdef t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr, 2933218893Sdim "rbit", "\t$Rd, $Rm", 2934263508Sdim [(set rGPR:$Rd, (ARMrbit rGPR:$Rm))]>, 2935263508Sdim Sched<[WriteALU]>; 2936202878Srdivacky 2937218893Sdimdef t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr, 2938263508Sdim "rev", ".w\t$Rd, $Rm", [(set rGPR:$Rd, (bswap rGPR:$Rm))]>, 2939263508Sdim Sched<[WriteALU]>; 2940201360Srdivacky 2941218893Sdimdef t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr, 2942218893Sdim "rev16", ".w\t$Rd, $Rm", 2943263508Sdim [(set rGPR:$Rd, (rotr (bswap rGPR:$Rm), (i32 16)))]>, 2944263508Sdim Sched<[WriteALU]>; 2945194754Sed 2946218893Sdimdef t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$Rd), (ins rGPR:$Rm), IIC_iUNAr, 2947218893Sdim "revsh", ".w\t$Rd, $Rm", 2948263508Sdim [(set rGPR:$Rd, (sra (bswap rGPR:$Rm), (i32 16)))]>, 2949263508Sdim Sched<[WriteALU]>; 2950194754Sed 2951224145Sdimdef : T2Pat<(or (sra (shl rGPR:$Rm, (i32 24)), (i32 16)), 2952224145Sdim (and (srl rGPR:$Rm, (i32 8)), 0xFF)), 2953221345Sdim (t2REVSH rGPR:$Rm)>; 2954221345Sdim 2955218893Sdimdef t2PKHBT : T2ThreeReg< 2956226633Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, pkh_lsl_amt:$sh), 2957218893Sdim IIC_iBITsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh", 2958218893Sdim [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF), 2959226633Sdim (and (shl rGPR:$Rm, pkh_lsl_amt:$sh), 2960208599Srdivacky 0xFFFF0000)))]>, 2961263508Sdim Requires<[HasT2ExtractPack, IsThumb2]>, 2962263508Sdim Sched<[WriteALUsi, ReadALU]> { 2963201360Srdivacky let Inst{31-27} = 0b11101; 2964201360Srdivacky let Inst{26-25} = 0b01; 2965201360Srdivacky let Inst{24-20} = 0b01100; 2966201360Srdivacky let Inst{5} = 0; // BT form 2967201360Srdivacky let Inst{4} = 0; 2968218893Sdim 2969226633Sdim bits<5> sh; 2970226633Sdim let Inst{14-12} = sh{4-2}; 2971226633Sdim let Inst{7-6} = sh{1-0}; 2972201360Srdivacky} 2973194754Sed 2974198090Srdivacky// Alternate cases for PKHBT where identities eliminate some nodes. 2975212904Sdimdef : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)), 2976212904Sdim (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>, 2977218893Sdim Requires<[HasT2ExtractPack, IsThumb2]>; 2978212904Sdimdef : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)), 2979226633Sdim (t2PKHBT rGPR:$src1, rGPR:$src2, imm16_31:$sh)>, 2980218893Sdim Requires<[HasT2ExtractPack, IsThumb2]>; 2981198090Srdivacky 2982212904Sdim// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and 2983212904Sdim// will match the pattern below. 2984218893Sdimdef t2PKHTB : T2ThreeReg< 2985226633Sdim (outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, pkh_asr_amt:$sh), 2986218893Sdim IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh", 2987218893Sdim [(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF0000), 2988226633Sdim (and (sra rGPR:$Rm, pkh_asr_amt:$sh), 2989212904Sdim 0xFFFF)))]>, 2990263508Sdim Requires<[HasT2ExtractPack, IsThumb2]>, 2991263508Sdim Sched<[WriteALUsi, ReadALU]> { 2992201360Srdivacky let Inst{31-27} = 0b11101; 2993201360Srdivacky let Inst{26-25} = 0b01; 2994201360Srdivacky let Inst{24-20} = 0b01100; 2995201360Srdivacky let Inst{5} = 1; // TB form 2996201360Srdivacky let Inst{4} = 0; 2997218893Sdim 2998226633Sdim bits<5> sh; 2999226633Sdim let Inst{14-12} = sh{4-2}; 3000226633Sdim let Inst{7-6} = sh{1-0}; 3001201360Srdivacky} 3002198090Srdivacky 3003198090Srdivacky// Alternate cases for PKHTB where identities eliminate some nodes. Note that 3004198090Srdivacky// a shift amount of 0 is *not legal* here, it is PKHBT instead. 3005263508Sdim// We also can not replace a srl (17..31) by an arithmetic shift we would use in 3006263508Sdim// pkhtb src1, src2, asr (17..31). 3007263508Sdimdef : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16:$sh)), 3008263508Sdim (t2PKHTB rGPR:$src1, rGPR:$src2, imm16:$sh)>, 3009263508Sdim Requires<[HasT2ExtractPack, IsThumb2]>; 3010263508Sdimdef : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (sra rGPR:$src2, imm16_31:$sh)), 3011226633Sdim (t2PKHTB rGPR:$src1, rGPR:$src2, imm16_31:$sh)>, 3012218893Sdim Requires<[HasT2ExtractPack, IsThumb2]>; 3013212904Sdimdef : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), 3014212904Sdim (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)), 3015226633Sdim (t2PKHTB rGPR:$src1, rGPR:$src2, imm1_15:$sh)>, 3016218893Sdim Requires<[HasT2ExtractPack, IsThumb2]>; 3017198090Srdivacky 3018194754Sed//===----------------------------------------------------------------------===// 3019263508Sdim// CRC32 Instructions 3020263508Sdim// 3021263508Sdim// Polynomials: 3022263508Sdim// + CRC32{B,H,W} 0x04C11DB7 3023263508Sdim// + CRC32C{B,H,W} 0x1EDC6F41 3024263508Sdim// 3025263508Sdim 3026263508Sdimclass T2I_crc32<bit C, bits<2> sz, string suffix, SDPatternOperator builtin> 3027263508Sdim : T2ThreeRegNoP<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), NoItinerary, 3028263508Sdim !strconcat("crc32", suffix, "\t$Rd, $Rn, $Rm"), 3029263508Sdim [(set rGPR:$Rd, (builtin rGPR:$Rn, rGPR:$Rm))]>, 3030263508Sdim Requires<[IsThumb2, HasV8, HasCRC]> { 3031263508Sdim let Inst{31-27} = 0b11111; 3032263508Sdim let Inst{26-21} = 0b010110; 3033263508Sdim let Inst{20} = C; 3034263508Sdim let Inst{15-12} = 0b1111; 3035263508Sdim let Inst{7-6} = 0b10; 3036263508Sdim let Inst{5-4} = sz; 3037263508Sdim} 3038263508Sdim 3039263508Sdimdef t2CRC32B : T2I_crc32<0, 0b00, "b", int_arm_crc32b>; 3040263508Sdimdef t2CRC32CB : T2I_crc32<1, 0b00, "cb", int_arm_crc32cb>; 3041263508Sdimdef t2CRC32H : T2I_crc32<0, 0b01, "h", int_arm_crc32h>; 3042263508Sdimdef t2CRC32CH : T2I_crc32<1, 0b01, "ch", int_arm_crc32ch>; 3043263508Sdimdef t2CRC32W : T2I_crc32<0, 0b10, "w", int_arm_crc32w>; 3044263508Sdimdef t2CRC32CW : T2I_crc32<1, 0b10, "cw", int_arm_crc32cw>; 3045263508Sdim 3046263508Sdim//===----------------------------------------------------------------------===// 3047194754Sed// Comparison Instructions... 3048194754Sed// 3049201360Srdivackydefm t2CMP : T2I_cmp_irs<0b1101, "cmp", 3050218893Sdim IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi, 3051239462Sdim BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>; 3052194754Sed 3053226633Sdimdef : T2Pat<(ARMcmpZ GPRnopc:$lhs, t2_so_imm:$imm), 3054226633Sdim (t2CMPri GPRnopc:$lhs, t2_so_imm:$imm)>; 3055226633Sdimdef : T2Pat<(ARMcmpZ GPRnopc:$lhs, rGPR:$rhs), 3056226633Sdim (t2CMPrr GPRnopc:$lhs, rGPR:$rhs)>; 3057226633Sdimdef : T2Pat<(ARMcmpZ GPRnopc:$lhs, t2_so_reg:$rhs), 3058226633Sdim (t2CMPrs GPRnopc:$lhs, t2_so_reg:$rhs)>; 3059218893Sdim 3060239462Sdimlet isCompare = 1, Defs = [CPSR] in { 3061239462Sdim // shifted imm 3062239462Sdim def t2CMNri : T2OneRegCmpImm< 3063239462Sdim (outs), (ins GPRnopc:$Rn, t2_so_imm:$imm), IIC_iCMPi, 3064239462Sdim "cmn", ".w\t$Rn, $imm", 3065263508Sdim [(ARMcmn GPRnopc:$Rn, (ineg t2_so_imm:$imm))]>, 3066263508Sdim Sched<[WriteCMP, ReadALU]> { 3067239462Sdim let Inst{31-27} = 0b11110; 3068239462Sdim let Inst{25} = 0; 3069239462Sdim let Inst{24-21} = 0b1000; 3070239462Sdim let Inst{20} = 1; // The S bit. 3071239462Sdim let Inst{15} = 0; 3072239462Sdim let Inst{11-8} = 0b1111; // Rd 3073239462Sdim } 3074239462Sdim // register 3075239462Sdim def t2CMNzrr : T2TwoRegCmp< 3076239462Sdim (outs), (ins GPRnopc:$Rn, rGPR:$Rm), IIC_iCMPr, 3077239462Sdim "cmn", ".w\t$Rn, $Rm", 3078239462Sdim [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 3079263508Sdim GPRnopc:$Rn, rGPR:$Rm)]>, Sched<[WriteCMP, ReadALU, ReadALU]> { 3080239462Sdim let Inst{31-27} = 0b11101; 3081239462Sdim let Inst{26-25} = 0b01; 3082239462Sdim let Inst{24-21} = 0b1000; 3083239462Sdim let Inst{20} = 1; // The S bit. 3084239462Sdim let Inst{14-12} = 0b000; // imm3 3085239462Sdim let Inst{11-8} = 0b1111; // Rd 3086239462Sdim let Inst{7-6} = 0b00; // imm2 3087239462Sdim let Inst{5-4} = 0b00; // type 3088239462Sdim } 3089239462Sdim // shifted register 3090239462Sdim def t2CMNzrs : T2OneRegCmpShiftedReg< 3091239462Sdim (outs), (ins GPRnopc:$Rn, t2_so_reg:$ShiftedRm), IIC_iCMPsi, 3092239462Sdim "cmn", ".w\t$Rn, $ShiftedRm", 3093239462Sdim [(BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))> 3094263508Sdim GPRnopc:$Rn, t2_so_reg:$ShiftedRm)]>, 3095263508Sdim Sched<[WriteCMPsi, ReadALU, ReadALU]> { 3096239462Sdim let Inst{31-27} = 0b11101; 3097239462Sdim let Inst{26-25} = 0b01; 3098239462Sdim let Inst{24-21} = 0b1000; 3099239462Sdim let Inst{20} = 1; // The S bit. 3100239462Sdim let Inst{11-8} = 0b1111; // Rd 3101239462Sdim } 3102239462Sdim} 3103194754Sed 3104239462Sdim// Assembler aliases w/o the ".w" suffix. 3105239462Sdim// No alias here for 'rr' version as not all instantiations of this multiclass 3106239462Sdim// want one (CMP in particular, does not). 3107239462Sdimdef : t2InstAlias<"cmn${p} $Rn, $imm", 3108239462Sdim (t2CMNri GPRnopc:$Rn, t2_so_imm:$imm, pred:$p)>; 3109239462Sdimdef : t2InstAlias<"cmn${p} $Rn, $shift", 3110239462Sdim (t2CMNzrs GPRnopc:$Rn, t2_so_reg:$shift, pred:$p)>; 3111194754Sed 3112239462Sdimdef : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm), 3113239462Sdim (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>; 3114194754Sed 3115239462Sdimdef : T2Pat<(ARMcmpZ GPRnopc:$src, t2_so_imm_neg:$imm), 3116239462Sdim (t2CMNri GPRnopc:$src, t2_so_imm_neg:$imm)>; 3117239462Sdim 3118201360Srdivackydefm t2TST : T2I_cmp_irs<0b0000, "tst", 3119218893Sdim IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi, 3120239462Sdim BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>>; 3121201360Srdivackydefm t2TEQ : T2I_cmp_irs<0b0100, "teq", 3122218893Sdim IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi, 3123239462Sdim BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>>; 3124194754Sed 3125198090Srdivacky// Conditional moves 3126208599Srdivackylet neverHasSideEffects = 1 in { 3127234353Sdim 3128239462Sdimlet isCommutable = 1, isSelect = 1 in 3129224145Sdimdef t2MOVCCr : t2PseudoInst<(outs rGPR:$Rd), 3130263508Sdim (ins rGPR:$false, rGPR:$Rm, cmovpred:$p), 3131224145Sdim 4, IIC_iCMOVr, 3132263508Sdim [(set rGPR:$Rd, (ARMcmov rGPR:$false, rGPR:$Rm, 3133263508Sdim cmovpred:$p))]>, 3134263508Sdim RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 3135198090Srdivacky 3136218893Sdimlet isMoveImm = 1 in 3137263508Sdimdef t2MOVCCi 3138263508Sdim : t2PseudoInst<(outs rGPR:$Rd), 3139263508Sdim (ins rGPR:$false, t2_so_imm:$imm, cmovpred:$p), 3140224145Sdim 4, IIC_iCMOVi, 3141263508Sdim [(set rGPR:$Rd, (ARMcmov rGPR:$false,t2_so_imm:$imm, 3142263508Sdim cmovpred:$p))]>, 3143263508Sdim RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 3144198090Srdivacky 3145224145Sdimlet isCodeGenOnly = 1 in { 3146218893Sdimlet isMoveImm = 1 in 3147263508Sdimdef t2MOVCCi16 3148263508Sdim : t2PseudoInst<(outs rGPR:$Rd), 3149263508Sdim (ins rGPR:$false, imm0_65535_expr:$imm, cmovpred:$p), 3150263508Sdim 4, IIC_iCMOVi, 3151263508Sdim [(set rGPR:$Rd, (ARMcmov rGPR:$false, imm0_65535:$imm, 3152263508Sdim cmovpred:$p))]>, 3153263508Sdim RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 3154218893Sdim 3155263508Sdimlet isMoveImm = 1 in 3156263508Sdimdef t2MVNCCi 3157263508Sdim : t2PseudoInst<(outs rGPR:$Rd), 3158263508Sdim (ins rGPR:$false, t2_so_imm:$imm, cmovpred:$p), 3159263508Sdim 4, IIC_iCMOVi, 3160263508Sdim [(set rGPR:$Rd, 3161263508Sdim (ARMcmov rGPR:$false, t2_so_imm_not:$imm, 3162263508Sdim cmovpred:$p))]>, 3163263508Sdim RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 3164218893Sdim 3165263508Sdimclass MOVCCShPseudo<SDPatternOperator opnode, Operand ty> 3166263508Sdim : t2PseudoInst<(outs rGPR:$Rd), 3167263508Sdim (ins rGPR:$false, rGPR:$Rm, i32imm:$imm, cmovpred:$p), 3168263508Sdim 4, IIC_iCMOVsi, 3169263508Sdim [(set rGPR:$Rd, (ARMcmov rGPR:$false, 3170263508Sdim (opnode rGPR:$Rm, (i32 ty:$imm)), 3171263508Sdim cmovpred:$p))]>, 3172263508Sdim RegConstraint<"$false = $Rd">, Sched<[WriteALU]>; 3173218893Sdim 3174263508Sdimdef t2MOVCClsl : MOVCCShPseudo<shl, imm0_31>; 3175263508Sdimdef t2MOVCClsr : MOVCCShPseudo<srl, imm_sr>; 3176263508Sdimdef t2MOVCCasr : MOVCCShPseudo<sra, imm_sr>; 3177263508Sdimdef t2MOVCCror : MOVCCShPseudo<rotr, imm0_31>; 3178218893Sdim 3179218893Sdimlet isMoveImm = 1 in 3180263508Sdimdef t2MOVCCi32imm 3181263508Sdim : t2PseudoInst<(outs rGPR:$dst), 3182263508Sdim (ins rGPR:$false, i32imm:$src, cmovpred:$p), 3183263508Sdim 8, IIC_iCMOVix2, 3184263508Sdim [(set rGPR:$dst, (ARMcmov rGPR:$false, imm:$src, 3185263508Sdim cmovpred:$p))]>, 3186263508Sdim RegConstraint<"$false = $dst">; 3187224145Sdim} // isCodeGenOnly = 1 3188234353Sdim 3189208599Srdivacky} // neverHasSideEffects 3190198090Srdivacky 3191195340Sed//===----------------------------------------------------------------------===// 3192200581Srdivacky// Atomic operations intrinsics 3193200581Srdivacky// 3194200581Srdivacky 3195200581Srdivacky// memory barriers protect the atomic sequences 3196200581Srdivackylet hasSideEffects = 1 in { 3197263508Sdimdef t2DMB : T2I<(outs), (ins memb_opt:$opt), NoItinerary, 3198263508Sdim "dmb", "\t$opt", [(int_arm_dmb (i32 imm0_15:$opt))]>, 3199263508Sdim Requires<[HasDB]> { 3200218893Sdim bits<4> opt; 3201218893Sdim let Inst{31-4} = 0xf3bf8f5; 3202218893Sdim let Inst{3-0} = opt; 3203200581Srdivacky} 3204200581Srdivacky} 3205200581Srdivacky 3206263508Sdimdef t2DSB : T2I<(outs), (ins memb_opt:$opt), NoItinerary, 3207263508Sdim "dsb", "\t$opt", [(int_arm_dsb (i32 imm0_15:$opt))]>, 3208263508Sdim Requires<[HasDB]> { 3209218893Sdim bits<4> opt; 3210218893Sdim let Inst{31-4} = 0xf3bf8f4; 3211218893Sdim let Inst{3-0} = opt; 3212204642Srdivacky} 3213204642Srdivacky 3214263508Sdimdef t2ISB : T2I<(outs), (ins instsyncb_opt:$opt), NoItinerary, 3215263508Sdim "isb", "\t$opt", []>, Requires<[HasDB]> { 3216226633Sdim bits<4> opt; 3217218893Sdim let Inst{31-4} = 0xf3bf8f6; 3218226633Sdim let Inst{3-0} = opt; 3219204642Srdivacky} 3220204642Srdivacky 3221263508Sdimclass T2I_ldrex<bits<4> opcod, dag oops, dag iops, AddrMode am, int sz, 3222201360Srdivacky InstrItinClass itin, string opc, string asm, string cstr, 3223201360Srdivacky list<dag> pattern, bits<4> rt2 = 0b1111> 3224201360Srdivacky : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> { 3225201360Srdivacky let Inst{31-27} = 0b11101; 3226201360Srdivacky let Inst{26-20} = 0b0001101; 3227201360Srdivacky let Inst{11-8} = rt2; 3228263508Sdim let Inst{7-4} = opcod; 3229201360Srdivacky let Inst{3-0} = 0b1111; 3230218893Sdim 3231221345Sdim bits<4> addr; 3232218893Sdim bits<4> Rt; 3233221345Sdim let Inst{19-16} = addr; 3234218893Sdim let Inst{15-12} = Rt; 3235201360Srdivacky} 3236263508Sdimclass T2I_strex<bits<4> opcod, dag oops, dag iops, AddrMode am, int sz, 3237201360Srdivacky InstrItinClass itin, string opc, string asm, string cstr, 3238201360Srdivacky list<dag> pattern, bits<4> rt2 = 0b1111> 3239201360Srdivacky : Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> { 3240201360Srdivacky let Inst{31-27} = 0b11101; 3241201360Srdivacky let Inst{26-20} = 0b0001100; 3242201360Srdivacky let Inst{11-8} = rt2; 3243263508Sdim let Inst{7-4} = opcod; 3244218893Sdim 3245218893Sdim bits<4> Rd; 3246221345Sdim bits<4> addr; 3247218893Sdim bits<4> Rt; 3248221345Sdim let Inst{3-0} = Rd; 3249221345Sdim let Inst{19-16} = addr; 3250218893Sdim let Inst{15-12} = Rt; 3251201360Srdivacky} 3252201360Srdivacky 3253200581Srdivackylet mayLoad = 1 in { 3254263508Sdimdef t2LDREXB : T2I_ldrex<0b0100, (outs rGPR:$Rt), (ins addr_offset_none:$addr), 3255224145Sdim AddrModeNone, 4, NoItinerary, 3256263508Sdim "ldrexb", "\t$Rt, $addr", "", 3257263508Sdim [(set rGPR:$Rt, (ldrex_1 addr_offset_none:$addr))]>; 3258263508Sdimdef t2LDREXH : T2I_ldrex<0b0101, (outs rGPR:$Rt), (ins addr_offset_none:$addr), 3259224145Sdim AddrModeNone, 4, NoItinerary, 3260263508Sdim "ldrexh", "\t$Rt, $addr", "", 3261263508Sdim [(set rGPR:$Rt, (ldrex_2 addr_offset_none:$addr))]>; 3262226633Sdimdef t2LDREX : Thumb2I<(outs rGPR:$Rt), (ins t2addrmode_imm0_1020s4:$addr), 3263224145Sdim AddrModeNone, 4, NoItinerary, 3264263508Sdim "ldrex", "\t$Rt, $addr", "", 3265263508Sdim [(set rGPR:$Rt, (ldrex_4 t2addrmode_imm0_1020s4:$addr))]> { 3266226633Sdim bits<4> Rt; 3267226633Sdim bits<12> addr; 3268201360Srdivacky let Inst{31-27} = 0b11101; 3269201360Srdivacky let Inst{26-20} = 0b0000101; 3270226633Sdim let Inst{19-16} = addr{11-8}; 3271226633Sdim let Inst{15-12} = Rt; 3272201360Srdivacky let Inst{11-8} = 0b1111; 3273226633Sdim let Inst{7-0} = addr{7-0}; 3274200581Srdivacky} 3275223017Sdimlet hasExtraDefRegAllocReq = 1 in 3276263508Sdimdef t2LDREXD : T2I_ldrex<0b0111, (outs rGPR:$Rt, rGPR:$Rt2), 3277226633Sdim (ins addr_offset_none:$addr), 3278224145Sdim AddrModeNone, 4, NoItinerary, 3279221345Sdim "ldrexd", "\t$Rt, $Rt2, $addr", "", 3280218893Sdim [], {?, ?, ?, ?}> { 3281218893Sdim bits<4> Rt2; 3282218893Sdim let Inst{11-8} = Rt2; 3283201360Srdivacky} 3284263508Sdimdef t2LDAEXB : T2I_ldrex<0b1100, (outs rGPR:$Rt), (ins addr_offset_none:$addr), 3285263508Sdim AddrModeNone, 4, NoItinerary, 3286263508Sdim "ldaexb", "\t$Rt, $addr", "", 3287263508Sdim []>, Requires<[IsThumb, HasV8]>; 3288263508Sdimdef t2LDAEXH : T2I_ldrex<0b1101, (outs rGPR:$Rt), (ins addr_offset_none:$addr), 3289263508Sdim AddrModeNone, 4, NoItinerary, 3290263508Sdim "ldaexh", "\t$Rt, $addr", "", 3291263508Sdim []>, Requires<[IsThumb, HasV8]>; 3292263508Sdimdef t2LDAEX : Thumb2I<(outs rGPR:$Rt), (ins addr_offset_none:$addr), 3293263508Sdim AddrModeNone, 4, NoItinerary, 3294263508Sdim "ldaex", "\t$Rt, $addr", "", 3295263508Sdim []>, Requires<[IsThumb, HasV8]> { 3296263508Sdim bits<4> Rt; 3297263508Sdim bits<4> addr; 3298263508Sdim let Inst{31-27} = 0b11101; 3299263508Sdim let Inst{26-20} = 0b0001101; 3300263508Sdim let Inst{19-16} = addr; 3301263508Sdim let Inst{15-12} = Rt; 3302263508Sdim let Inst{11-8} = 0b1111; 3303263508Sdim let Inst{7-0} = 0b11101111; 3304218893Sdim} 3305263508Sdimlet hasExtraDefRegAllocReq = 1 in 3306263508Sdimdef t2LDAEXD : T2I_ldrex<0b1111, (outs rGPR:$Rt, rGPR:$Rt2), 3307263508Sdim (ins addr_offset_none:$addr), 3308263508Sdim AddrModeNone, 4, NoItinerary, 3309263508Sdim "ldaexd", "\t$Rt, $Rt2, $addr", "", 3310263508Sdim [], {?, ?, ?, ?}>, Requires<[IsThumb, HasV8]> { 3311263508Sdim bits<4> Rt2; 3312263508Sdim let Inst{11-8} = Rt2; 3313200581Srdivacky 3314263508Sdim let Inst{7} = 1; 3315263508Sdim} 3316263508Sdim} 3317263508Sdim 3318218893Sdimlet mayStore = 1, Constraints = "@earlyclobber $Rd" in { 3319263508Sdimdef t2STREXB : T2I_strex<0b0100, (outs rGPR:$Rd), 3320226633Sdim (ins rGPR:$Rt, addr_offset_none:$addr), 3321224145Sdim AddrModeNone, 4, NoItinerary, 3322263508Sdim "strexb", "\t$Rd, $Rt, $addr", "", 3323263508Sdim [(set rGPR:$Rd, (strex_1 rGPR:$Rt, 3324263508Sdim addr_offset_none:$addr))]>; 3325263508Sdimdef t2STREXH : T2I_strex<0b0101, (outs rGPR:$Rd), 3326226633Sdim (ins rGPR:$Rt, addr_offset_none:$addr), 3327224145Sdim AddrModeNone, 4, NoItinerary, 3328263508Sdim "strexh", "\t$Rd, $Rt, $addr", "", 3329263508Sdim [(set rGPR:$Rd, (strex_2 rGPR:$Rt, 3330263508Sdim addr_offset_none:$addr))]>; 3331263508Sdim 3332226633Sdimdef t2STREX : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, 3333226633Sdim t2addrmode_imm0_1020s4:$addr), 3334224145Sdim AddrModeNone, 4, NoItinerary, 3335221345Sdim "strex", "\t$Rd, $Rt, $addr", "", 3336263508Sdim [(set rGPR:$Rd, (strex_4 rGPR:$Rt, 3337263508Sdim t2addrmode_imm0_1020s4:$addr))]> { 3338226633Sdim bits<4> Rd; 3339226633Sdim bits<4> Rt; 3340226633Sdim bits<12> addr; 3341201360Srdivacky let Inst{31-27} = 0b11101; 3342201360Srdivacky let Inst{26-20} = 0b0000100; 3343226633Sdim let Inst{19-16} = addr{11-8}; 3344226633Sdim let Inst{15-12} = Rt; 3345218893Sdim let Inst{11-8} = Rd; 3346226633Sdim let Inst{7-0} = addr{7-0}; 3347200581Srdivacky} 3348234353Sdimlet hasExtraSrcRegAllocReq = 1 in 3349263508Sdimdef t2STREXD : T2I_strex<0b0111, (outs rGPR:$Rd), 3350226633Sdim (ins rGPR:$Rt, rGPR:$Rt2, addr_offset_none:$addr), 3351224145Sdim AddrModeNone, 4, NoItinerary, 3352221345Sdim "strexd", "\t$Rd, $Rt, $Rt2, $addr", "", [], 3353218893Sdim {?, ?, ?, ?}> { 3354218893Sdim bits<4> Rt2; 3355218893Sdim let Inst{11-8} = Rt2; 3356201360Srdivacky} 3357263508Sdimdef t2STLEXB : T2I_strex<0b1100, (outs rGPR:$Rd), 3358263508Sdim (ins rGPR:$Rt, addr_offset_none:$addr), 3359263508Sdim AddrModeNone, 4, NoItinerary, 3360263508Sdim "stlexb", "\t$Rd, $Rt, $addr", "", 3361263508Sdim []>, Requires<[IsThumb, HasV8]>; 3362263508Sdim 3363263508Sdimdef t2STLEXH : T2I_strex<0b1101, (outs rGPR:$Rd), 3364263508Sdim (ins rGPR:$Rt, addr_offset_none:$addr), 3365263508Sdim AddrModeNone, 4, NoItinerary, 3366263508Sdim "stlexh", "\t$Rd, $Rt, $addr", "", 3367263508Sdim []>, Requires<[IsThumb, HasV8]>; 3368263508Sdim 3369263508Sdimdef t2STLEX : Thumb2I<(outs rGPR:$Rd), (ins rGPR:$Rt, 3370263508Sdim addr_offset_none:$addr), 3371263508Sdim AddrModeNone, 4, NoItinerary, 3372263508Sdim "stlex", "\t$Rd, $Rt, $addr", "", 3373263508Sdim []>, Requires<[IsThumb, HasV8]> { 3374263508Sdim bits<4> Rd; 3375263508Sdim bits<4> Rt; 3376263508Sdim bits<4> addr; 3377263508Sdim let Inst{31-27} = 0b11101; 3378263508Sdim let Inst{26-20} = 0b0001100; 3379263508Sdim let Inst{19-16} = addr; 3380263508Sdim let Inst{15-12} = Rt; 3381263508Sdim let Inst{11-4} = 0b11111110; 3382263508Sdim let Inst{3-0} = Rd; 3383234353Sdim} 3384263508Sdimlet hasExtraSrcRegAllocReq = 1 in 3385263508Sdimdef t2STLEXD : T2I_strex<0b1111, (outs rGPR:$Rd), 3386263508Sdim (ins rGPR:$Rt, rGPR:$Rt2, addr_offset_none:$addr), 3387263508Sdim AddrModeNone, 4, NoItinerary, 3388263508Sdim "stlexd", "\t$Rd, $Rt, $Rt2, $addr", "", [], 3389263508Sdim {?, ?, ?, ?}>, Requires<[IsThumb, HasV8]> { 3390263508Sdim bits<4> Rt2; 3391263508Sdim let Inst{11-8} = Rt2; 3392263508Sdim} 3393263508Sdim} 3394200581Srdivacky 3395263508Sdimdef t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "", [(int_arm_clrex)]>, 3396218893Sdim Requires<[IsThumb2, HasV7]> { 3397218893Sdim let Inst{31-16} = 0xf3bf; 3398204642Srdivacky let Inst{15-14} = 0b10; 3399218893Sdim let Inst{13} = 0; 3400204642Srdivacky let Inst{12} = 0; 3401218893Sdim let Inst{11-8} = 0b1111; 3402204642Srdivacky let Inst{7-4} = 0b0010; 3403218893Sdim let Inst{3-0} = 0b1111; 3404204642Srdivacky} 3405204642Srdivacky 3406263508Sdimdef : T2Pat<(and (ldrex_1 addr_offset_none:$addr), 0xff), 3407263508Sdim (t2LDREXB addr_offset_none:$addr)>; 3408263508Sdimdef : T2Pat<(and (ldrex_2 addr_offset_none:$addr), 0xffff), 3409263508Sdim (t2LDREXH addr_offset_none:$addr)>; 3410263508Sdimdef : T2Pat<(strex_1 (and GPR:$Rt, 0xff), addr_offset_none:$addr), 3411263508Sdim (t2STREXB GPR:$Rt, addr_offset_none:$addr)>; 3412263508Sdimdef : T2Pat<(strex_2 (and GPR:$Rt, 0xffff), addr_offset_none:$addr), 3413263508Sdim (t2STREXH GPR:$Rt, addr_offset_none:$addr)>; 3414263508Sdim 3415200581Srdivacky//===----------------------------------------------------------------------===// 3416198090Srdivacky// SJLJ Exception handling intrinsics 3417198090Srdivacky// eh_sjlj_setjmp() is an instruction sequence to store the return 3418198090Srdivacky// address and save #0 in R0 for the non-longjmp case. 3419198090Srdivacky// Since by its nature we may be coming from some other function to get 3420198090Srdivacky// here, and we're using the stack frame for the containing function to 3421198090Srdivacky// save/restore registers, we can't keep anything live in regs across 3422198090Srdivacky// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 3423221345Sdim// when we get here from a longjmp(). We force everything out of registers 3424198090Srdivacky// except for our own input by listing the relevant registers in Defs. By 3425198090Srdivacky// doing so, we also cause the prologue/epilogue code to actively preserve 3426198090Srdivacky// all of the callee-saved resgisters, which is exactly what we want. 3427210299Sed// $val is a scratch register for our use. 3428203954Srdivackylet Defs = 3429223017Sdim [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR, 3430234353Sdim Q0, Q1, Q2, Q3, Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15], 3431234353Sdim hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, 3432234353Sdim usesCustomInserter = 1 in { 3433212904Sdim def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val), 3434224145Sdim AddrModeNone, 0, NoItinerary, "", "", 3435212904Sdim [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>, 3436207618Srdivacky Requires<[IsThumb2, HasVFP2]>; 3437198090Srdivacky} 3438198090Srdivacky 3439207618Srdivackylet Defs = 3440223017Sdim [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ], 3441234353Sdim hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, 3442234353Sdim usesCustomInserter = 1 in { 3443212904Sdim def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val), 3444224145Sdim AddrModeNone, 0, NoItinerary, "", "", 3445212904Sdim [(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>, 3446207618Srdivacky Requires<[IsThumb2, NoVFP]>; 3447207618Srdivacky} 3448198090Srdivacky 3449198090Srdivacky 3450198090Srdivacky//===----------------------------------------------------------------------===// 3451195340Sed// Control-Flow Instructions 3452195340Sed// 3453194754Sed 3454198090Srdivacky// FIXME: remove when we have a way to marking a MI with these properties. 3455198090Srdivacky// FIXME: Should pc be an implicit operand like PICADD, etc? 3456198090Srdivackylet isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 3457218893Sdim hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in 3458224145Sdimdef t2LDMIA_RET: t2PseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, 3459224145Sdim reglist:$regs, variable_ops), 3460224145Sdim 4, IIC_iLoad_mBr, [], 3461224145Sdim (t2LDMIA_UPD GPR:$wb, GPR:$Rn, pred:$p, reglist:$regs)>, 3462224145Sdim RegConstraint<"$Rn = $wb">; 3463218893Sdim 3464195340Sedlet isBranch = 1, isTerminator = 1, isBarrier = 1 in { 3465195340Sedlet isPredicable = 1 in 3466226633Sdimdef t2B : T2I<(outs), (ins uncondbrtarget:$target), IIC_Br, 3467226633Sdim "b", ".w\t$target", 3468263508Sdim [(br bb:$target)]>, Sched<[WriteBr]> { 3469201360Srdivacky let Inst{31-27} = 0b11110; 3470201360Srdivacky let Inst{15-14} = 0b10; 3471201360Srdivacky let Inst{12} = 1; 3472218893Sdim 3473243830Sdim bits<24> target; 3474263508Sdim let Inst{26} = target{23}; 3475263508Sdim let Inst{13} = target{22}; 3476263508Sdim let Inst{11} = target{21}; 3477243830Sdim let Inst{25-16} = target{20-11}; 3478218893Sdim let Inst{10-0} = target{10-0}; 3479234353Sdim let DecoderMethod = "DecodeT2BInstruction"; 3480263508Sdim let AsmMatchConverter = "cvtThumbBranches"; 3481263508Sdim} 3482195340Sed 3483195340Sedlet isNotDuplicable = 1, isIndirectBranch = 1 in { 3484218893Sdimdef t2BR_JT : t2PseudoInst<(outs), 3485218893Sdim (ins GPR:$target, GPR:$index, i32imm:$jt, i32imm:$id), 3486224145Sdim 0, IIC_Br, 3487263508Sdim [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>, 3488263508Sdim Sched<[WriteBr]>; 3489195340Sed 3490198090Srdivacky// FIXME: Add a non-pc based case that can be predicated. 3491218893Sdimdef t2TBB_JT : t2PseudoInst<(outs), 3492263508Sdim (ins GPR:$index, i32imm:$jt, i32imm:$id), 0, IIC_Br, []>, 3493263508Sdim Sched<[WriteBr]>; 3494195340Sed 3495218893Sdimdef t2TBH_JT : t2PseudoInst<(outs), 3496263508Sdim (ins GPR:$index, i32imm:$jt, i32imm:$id), 0, IIC_Br, []>, 3497263508Sdim Sched<[WriteBr]>; 3498204642Srdivacky 3499226633Sdimdef t2TBB : T2I<(outs), (ins addrmode_tbb:$addr), IIC_Br, 3500263508Sdim "tbb", "\t$addr", []>, Sched<[WriteBrTbl]> { 3501218893Sdim bits<4> Rn; 3502218893Sdim bits<4> Rm; 3503218893Sdim let Inst{31-20} = 0b111010001101; 3504218893Sdim let Inst{19-16} = Rn; 3505218893Sdim let Inst{15-5} = 0b11110000000; 3506218893Sdim let Inst{4} = 0; // B form 3507218893Sdim let Inst{3-0} = Rm; 3508226633Sdim 3509226633Sdim let DecoderMethod = "DecodeThumbTableBranch"; 3510204642Srdivacky} 3511204642Srdivacky 3512226633Sdimdef t2TBH : T2I<(outs), (ins addrmode_tbh:$addr), IIC_Br, 3513263508Sdim "tbh", "\t$addr", []>, Sched<[WriteBrTbl]> { 3514218893Sdim bits<4> Rn; 3515218893Sdim bits<4> Rm; 3516218893Sdim let Inst{31-20} = 0b111010001101; 3517218893Sdim let Inst{19-16} = Rn; 3518218893Sdim let Inst{15-5} = 0b11110000000; 3519218893Sdim let Inst{4} = 1; // H form 3520218893Sdim let Inst{3-0} = Rm; 3521226633Sdim 3522226633Sdim let DecoderMethod = "DecodeThumbTableBranch"; 3523204642Srdivacky} 3524198090Srdivacky} // isNotDuplicable, isIndirectBranch 3525198090Srdivacky 3526195340Sed} // isBranch, isTerminator, isBarrier 3527195340Sed 3528195340Sed// FIXME: should be able to write a pattern for ARMBrcond, but can't use 3529226633Sdim// a two-value operand where a dag node expects ", "two operands. :( 3530195340Sedlet isBranch = 1, isTerminator = 1 in 3531198090Srdivackydef t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br, 3532198892Srdivacky "b", ".w\t$target", 3533263508Sdim [/*(ARMbrcond bb:$target, imm:$cc)*/]>, Sched<[WriteBr]> { 3534201360Srdivacky let Inst{31-27} = 0b11110; 3535201360Srdivacky let Inst{15-14} = 0b10; 3536201360Srdivacky let Inst{12} = 0; 3537218893Sdim 3538218893Sdim bits<4> p; 3539218893Sdim let Inst{25-22} = p; 3540218893Sdim 3541218893Sdim bits<21> target; 3542218893Sdim let Inst{26} = target{20}; 3543218893Sdim let Inst{11} = target{19}; 3544218893Sdim let Inst{13} = target{18}; 3545218893Sdim let Inst{21-16} = target{17-12}; 3546218893Sdim let Inst{10-0} = target{11-1}; 3547226633Sdim 3548226633Sdim let DecoderMethod = "DecodeThumb2BCCInstruction"; 3549263508Sdim let AsmMatchConverter = "cvtThumbBranches"; 3550201360Srdivacky} 3551195340Sed 3552234353Sdim// Tail calls. The IOS version of thumb tail calls uses a t2 branch, so 3553224145Sdim// it goes here. 3554224145Sdimlet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { 3555234353Sdim // IOS version. 3556234353Sdim let Uses = [SP] in 3557226633Sdim def tTAILJMPd: tPseudoExpand<(outs), 3558239462Sdim (ins uncondbrtarget:$dst, pred:$p), 3559224145Sdim 4, IIC_Br, [], 3560226633Sdim (t2B uncondbrtarget:$dst, pred:$p)>, 3561263508Sdim Requires<[IsThumb2, IsIOS]>, Sched<[WriteBr]>; 3562224145Sdim} 3563198090Srdivacky 3564198090Srdivacky// IT block 3565210299Sedlet Defs = [ITSTATE] in 3566198090Srdivackydef t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask), 3567224145Sdim AddrModeNone, 2, IIC_iALUx, 3568263508Sdim "it$mask\t$cc", "", []>, 3569263508Sdim ComplexDeprecationPredicate<"IT"> { 3570201360Srdivacky // 16-bit instruction. 3571201360Srdivacky let Inst{31-16} = 0x0000; 3572201360Srdivacky let Inst{15-8} = 0b10111111; 3573218893Sdim 3574218893Sdim bits<4> cc; 3575218893Sdim bits<4> mask; 3576218893Sdim let Inst{7-4} = cc; 3577218893Sdim let Inst{3-0} = mask; 3578226633Sdim 3579226633Sdim let DecoderMethod = "DecodeIT"; 3580201360Srdivacky} 3581198090Srdivacky 3582204642Srdivacky// Branch and Exchange Jazelle -- for disassembly only 3583204642Srdivacky// Rm = Inst{19-16} 3584263508Sdimdef t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func", []>, 3585263508Sdim Sched<[WriteBr]> { 3586226633Sdim bits<4> func; 3587204642Srdivacky let Inst{31-27} = 0b11110; 3588204642Srdivacky let Inst{26} = 0; 3589204642Srdivacky let Inst{25-20} = 0b111100; 3590218893Sdim let Inst{19-16} = func; 3591226633Sdim let Inst{15-0} = 0b1000111100000000; 3592204642Srdivacky} 3593204642Srdivacky 3594226633Sdim// Compare and branch on zero / non-zero 3595226633Sdimlet isBranch = 1, isTerminator = 1 in { 3596226633Sdim def tCBZ : T1I<(outs), (ins tGPR:$Rn, t_cbtarget:$target), IIC_Br, 3597226633Sdim "cbz\t$Rn, $target", []>, 3598226633Sdim T1Misc<{0,0,?,1,?,?,?}>, 3599263508Sdim Requires<[IsThumb2]>, Sched<[WriteBr]> { 3600226633Sdim // A8.6.27 3601226633Sdim bits<6> target; 3602226633Sdim bits<3> Rn; 3603226633Sdim let Inst{9} = target{5}; 3604226633Sdim let Inst{7-3} = target{4-0}; 3605226633Sdim let Inst{2-0} = Rn; 3606226633Sdim } 3607226633Sdim 3608226633Sdim def tCBNZ : T1I<(outs), (ins tGPR:$Rn, t_cbtarget:$target), IIC_Br, 3609226633Sdim "cbnz\t$Rn, $target", []>, 3610226633Sdim T1Misc<{1,0,?,1,?,?,?}>, 3611263508Sdim Requires<[IsThumb2]>, Sched<[WriteBr]> { 3612226633Sdim // A8.6.27 3613226633Sdim bits<6> target; 3614226633Sdim bits<3> Rn; 3615226633Sdim let Inst{9} = target{5}; 3616226633Sdim let Inst{7-3} = target{4-0}; 3617226633Sdim let Inst{2-0} = Rn; 3618226633Sdim } 3619226633Sdim} 3620226633Sdim 3621226633Sdim 3622226633Sdim// Change Processor State is a system instruction. 3623218893Sdim// FIXME: Since the asm parser has currently no clean way to handle optional 3624218893Sdim// operands, create 3 versions of the same instruction. Once there's a clean 3625218893Sdim// framework to represent optional operands, change this behavior. 3626218893Sdimclass t2CPS<dag iops, string asm_op> : T2XI<(outs), iops, NoItinerary, 3627226633Sdim !strconcat("cps", asm_op), []> { 3628218893Sdim bits<2> imod; 3629218893Sdim bits<3> iflags; 3630218893Sdim bits<5> mode; 3631218893Sdim bit M; 3632218893Sdim 3633251662Sdim let Inst{31-11} = 0b111100111010111110000; 3634218893Sdim let Inst{10-9} = imod; 3635218893Sdim let Inst{8} = M; 3636218893Sdim let Inst{7-5} = iflags; 3637218893Sdim let Inst{4-0} = mode; 3638226633Sdim let DecoderMethod = "DecodeT2CPSInstruction"; 3639204642Srdivacky} 3640204642Srdivacky 3641218893Sdimlet M = 1 in 3642218893Sdim def t2CPS3p : t2CPS<(ins imod_op:$imod, iflags_op:$iflags, i32imm:$mode), 3643263508Sdim "$imod\t$iflags, $mode">; 3644218893Sdimlet mode = 0, M = 0 in 3645218893Sdim def t2CPS2p : t2CPS<(ins imod_op:$imod, iflags_op:$iflags), 3646218893Sdim "$imod.w\t$iflags">; 3647218893Sdimlet imod = 0, iflags = 0, M = 1 in 3648226633Sdim def t2CPS1p : t2CPS<(ins imm0_31:$mode), "\t$mode">; 3649218893Sdim 3650263508Sdimdef : t2InstAlias<"cps$imod.w $iflags, $mode", 3651263508Sdim (t2CPS3p imod_op:$imod, iflags_op:$iflags, i32imm:$mode), 0>; 3652263508Sdimdef : t2InstAlias<"cps.w $mode", (t2CPS1p imm0_31:$mode), 0>; 3653263508Sdim 3654204642Srdivacky// A6.3.4 Branches and miscellaneous control 3655204642Srdivacky// Table A6-14 Change Processor State, and hint instructions 3656263508Sdimdef t2HINT : T2I<(outs), (ins imm0_239:$imm), NoItinerary, "hint", ".w\t$imm",[]> { 3657263508Sdim bits<8> imm; 3658251662Sdim let Inst{31-3} = 0b11110011101011111000000000000; 3659263508Sdim let Inst{7-0} = imm; 3660204642Srdivacky} 3661204642Srdivacky 3662263508Sdimdef : t2InstAlias<"hint$p $imm", (t2HINT imm0_239:$imm, pred:$p)>; 3663239462Sdimdef : t2InstAlias<"nop$p.w", (t2HINT 0, pred:$p)>; 3664239462Sdimdef : t2InstAlias<"yield$p.w", (t2HINT 1, pred:$p)>; 3665239462Sdimdef : t2InstAlias<"wfe$p.w", (t2HINT 2, pred:$p)>; 3666239462Sdimdef : t2InstAlias<"wfi$p.w", (t2HINT 3, pred:$p)>; 3667239462Sdimdef : t2InstAlias<"sev$p.w", (t2HINT 4, pred:$p)>; 3668263508Sdimdef : t2InstAlias<"sevl$p.w", (t2HINT 5, pred:$p)> { 3669263508Sdim let Predicates = [IsThumb2, HasV8]; 3670263508Sdim} 3671204642Srdivacky 3672224145Sdimdef t2DBG : T2I<(outs), (ins imm0_15:$opt), NoItinerary, "dbg", "\t$opt", []> { 3673226633Sdim bits<4> opt; 3674226633Sdim let Inst{31-20} = 0b111100111010; 3675226633Sdim let Inst{19-16} = 0b1111; 3676226633Sdim let Inst{15-8} = 0b10000000; 3677204642Srdivacky let Inst{7-4} = 0b1111; 3678218893Sdim let Inst{3-0} = opt; 3679204642Srdivacky} 3680204642Srdivacky 3681226633Sdim// Secure Monitor Call is a system instruction. 3682204642Srdivacky// Option = Inst{19-16} 3683251662Sdimdef t2SMC : T2I<(outs), (ins imm0_15:$opt), NoItinerary, "smc", "\t$opt", 3684251662Sdim []>, Requires<[IsThumb2, HasTrustZone]> { 3685204642Srdivacky let Inst{31-27} = 0b11110; 3686204642Srdivacky let Inst{26-20} = 0b1111111; 3687204642Srdivacky let Inst{15-12} = 0b1000; 3688204642Srdivacky 3689218893Sdim bits<4> opt; 3690218893Sdim let Inst{19-16} = opt; 3691204642Srdivacky} 3692204642Srdivacky 3693263508Sdimclass T2DCPS<bits<2> opt, string opc> 3694263508Sdim : T2I<(outs), (ins), NoItinerary, opc, "", []>, Requires<[IsThumb2, HasV8]> { 3695263508Sdim let Inst{31-27} = 0b11110; 3696263508Sdim let Inst{26-20} = 0b1111000; 3697263508Sdim let Inst{19-16} = 0b1111; 3698263508Sdim let Inst{15-12} = 0b1000; 3699263508Sdim let Inst{11-2} = 0b0000000000; 3700263508Sdim let Inst{1-0} = opt; 3701263508Sdim} 3702263508Sdim 3703263508Sdimdef t2DCPS1 : T2DCPS<0b01, "dcps1">; 3704263508Sdimdef t2DCPS2 : T2DCPS<0b10, "dcps2">; 3705263508Sdimdef t2DCPS3 : T2DCPS<0b11, "dcps3">; 3706263508Sdim 3707226633Sdimclass T2SRS<bits<2> Op, bit W, dag oops, dag iops, InstrItinClass itin, 3708226633Sdim string opc, string asm, list<dag> pattern> 3709218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 3710218893Sdim bits<5> mode; 3711226633Sdim let Inst{31-25} = 0b1110100; 3712226633Sdim let Inst{24-23} = Op; 3713226633Sdim let Inst{22} = 0; 3714226633Sdim let Inst{21} = W; 3715226633Sdim let Inst{20-16} = 0b01101; 3716226633Sdim let Inst{15-5} = 0b11000000000; 3717218893Sdim let Inst{4-0} = mode{4-0}; 3718204642Srdivacky} 3719204642Srdivacky 3720226633Sdim// Store Return State is a system instruction. 3721226633Sdimdef t2SRSDB_UPD : T2SRS<0b00, 1, (outs), (ins imm0_31:$mode), NoItinerary, 3722226633Sdim "srsdb", "\tsp!, $mode", []>; 3723226633Sdimdef t2SRSDB : T2SRS<0b00, 0, (outs), (ins imm0_31:$mode), NoItinerary, 3724226633Sdim "srsdb","\tsp, $mode", []>; 3725226633Sdimdef t2SRSIA_UPD : T2SRS<0b11, 1, (outs), (ins imm0_31:$mode), NoItinerary, 3726226633Sdim "srsia","\tsp!, $mode", []>; 3727226633Sdimdef t2SRSIA : T2SRS<0b11, 0, (outs), (ins imm0_31:$mode), NoItinerary, 3728226633Sdim "srsia","\tsp, $mode", []>; 3729204642Srdivacky 3730249423Sdim 3731249423Sdimdef : t2InstAlias<"srsdb${p} $mode", (t2SRSDB imm0_31:$mode, pred:$p)>; 3732249423Sdimdef : t2InstAlias<"srsdb${p} $mode!", (t2SRSDB_UPD imm0_31:$mode, pred:$p)>; 3733249423Sdim 3734249423Sdimdef : t2InstAlias<"srsia${p} $mode", (t2SRSIA imm0_31:$mode, pred:$p)>; 3735249423Sdimdef : t2InstAlias<"srsia${p} $mode!", (t2SRSIA_UPD imm0_31:$mode, pred:$p)>; 3736249423Sdim 3737226633Sdim// Return From Exception is a system instruction. 3738218893Sdimclass T2RFE<bits<12> op31_20, dag oops, dag iops, InstrItinClass itin, 3739218893Sdim string opc, string asm, list<dag> pattern> 3740218893Sdim : T2I<oops, iops, itin, opc, asm, pattern> { 3741218893Sdim let Inst{31-20} = op31_20{11-0}; 3742204642Srdivacky 3743218893Sdim bits<4> Rn; 3744218893Sdim let Inst{19-16} = Rn; 3745221345Sdim let Inst{15-0} = 0xc000; 3746204642Srdivacky} 3747204642Srdivacky 3748218893Sdimdef t2RFEDBW : T2RFE<0b111010000011, 3749221345Sdim (outs), (ins GPR:$Rn), NoItinerary, "rfedb", "\t$Rn!", 3750218893Sdim [/* For disassembly only; pattern left blank */]>; 3751218893Sdimdef t2RFEDB : T2RFE<0b111010000001, 3752221345Sdim (outs), (ins GPR:$Rn), NoItinerary, "rfedb", "\t$Rn", 3753218893Sdim [/* For disassembly only; pattern left blank */]>; 3754218893Sdimdef t2RFEIAW : T2RFE<0b111010011011, 3755221345Sdim (outs), (ins GPR:$Rn), NoItinerary, "rfeia", "\t$Rn!", 3756218893Sdim [/* For disassembly only; pattern left blank */]>; 3757218893Sdimdef t2RFEIA : T2RFE<0b111010011001, 3758221345Sdim (outs), (ins GPR:$Rn), NoItinerary, "rfeia", "\t$Rn", 3759218893Sdim [/* For disassembly only; pattern left blank */]>; 3760204642Srdivacky 3761263508Sdim// B9.3.19 SUBS PC, LR, #imm (Thumb2) system instruction. 3762263508Sdim// Exception return instruction is "subs pc, lr, #imm". 3763263508Sdimlet isReturn = 1, isBarrier = 1, isTerminator = 1, Defs = [PC] in 3764263508Sdimdef t2SUBS_PC_LR : T2I <(outs), (ins imm0_255:$imm), NoItinerary, 3765263508Sdim "subs", "\tpc, lr, $imm", 3766263508Sdim [(ARMintretflag imm0_255:$imm)]>, 3767263508Sdim Requires<[IsThumb2]> { 3768263508Sdim let Inst{31-8} = 0b111100111101111010001111; 3769263508Sdim 3770263508Sdim bits<8> imm; 3771263508Sdim let Inst{7-0} = imm; 3772263508Sdim} 3773263508Sdim 3774194754Sed//===----------------------------------------------------------------------===// 3775194754Sed// Non-Instruction Patterns 3776194754Sed// 3777194754Sed 3778198090Srdivacky// 32-bit immediate using movw + movt. 3779218893Sdim// This is a single pseudo instruction to make it re-materializable. 3780218893Sdim// FIXME: Remove this when we can do generalized remat. 3781218893Sdimlet isReMaterializable = 1, isMoveImm = 1 in 3782218893Sdimdef t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2, 3783218893Sdim [(set rGPR:$dst, (i32 imm:$src))]>, 3784218893Sdim Requires<[IsThumb, HasV6T2]>; 3785199481Srdivacky 3786218893Sdim// Pseudo instruction that combines movw + movt + add pc (if pic). 3787218893Sdim// It also makes it possible to rematerialize the instructions. 3788218893Sdim// FIXME: Remove this when we can do generalized remat and when machine licm 3789218893Sdim// can properly the instructions. 3790218893Sdimlet isReMaterializable = 1 in { 3791218893Sdimdef t2MOV_ga_pcrel : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr), 3792218893Sdim IIC_iMOVix2addpc, 3793218893Sdim [(set rGPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>, 3794218893Sdim Requires<[IsThumb2, UseMovt]>; 3795218893Sdim 3796218893Sdimdef t2MOV_ga_dyn : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr), 3797218893Sdim IIC_iMOVix2, 3798218893Sdim [(set rGPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>, 3799218893Sdim Requires<[IsThumb2, UseMovt]>; 3800218893Sdim} 3801218893Sdim 3802199989Srdivacky// ConstantPool, GlobalAddress, and JumpTable 3803199989Srdivackydef : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>, 3804199989Srdivacky Requires<[IsThumb2, DontUseMovt]>; 3805199989Srdivackydef : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>; 3806199989Srdivackydef : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>, 3807199989Srdivacky Requires<[IsThumb2, UseMovt]>; 3808199989Srdivacky 3809199989Srdivackydef : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id), 3810199989Srdivacky (t2LEApcrelJT tjumptable:$dst, imm:$id)>; 3811199989Srdivacky 3812199481Srdivacky// Pseudo instruction that combines ldr from constpool and add pc. This should 3813199481Srdivacky// be expanded into two instructions late to allow if-conversion and 3814199481Srdivacky// scheduling. 3815204642Srdivackylet canFoldAsLoad = 1, isReMaterializable = 1 in 3816218893Sdimdef t2LDRpci_pic : PseudoInst<(outs rGPR:$dst), (ins i32imm:$addr, pclabel:$cp), 3817218893Sdim IIC_iLoadiALU, 3818218893Sdim [(set rGPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)), 3819199481Srdivacky imm:$cp))]>, 3820199481Srdivacky Requires<[IsThumb2]>; 3821204642Srdivacky 3822234353Sdim// Pseudo isntruction that combines movs + predicated rsbmi 3823226633Sdim// to implement integer ABS 3824226633Sdimlet usesCustomInserter = 1, Defs = [CPSR] in { 3825226633Sdimdef t2ABS : PseudoInst<(outs rGPR:$dst), (ins rGPR:$src), 3826226633Sdim NoItinerary, []>, Requires<[IsThumb2]>; 3827226633Sdim} 3828226633Sdim 3829204642Srdivacky//===----------------------------------------------------------------------===// 3830226633Sdim// Coprocessor load/store -- for disassembly only 3831226633Sdim// 3832226633Sdimclass T2CI<bits<4> op31_28, dag oops, dag iops, string opc, string asm> 3833226633Sdim : T2I<oops, iops, NoItinerary, opc, asm, []> { 3834226633Sdim let Inst{31-28} = op31_28; 3835226633Sdim let Inst{27-25} = 0b110; 3836226633Sdim} 3837226633Sdim 3838226633Sdimmulticlass t2LdStCop<bits<4> op31_28, bit load, bit Dbit, string asm> { 3839226633Sdim def _OFFSET : T2CI<op31_28, 3840226633Sdim (outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5:$addr), 3841226633Sdim asm, "\t$cop, $CRd, $addr"> { 3842226633Sdim bits<13> addr; 3843226633Sdim bits<4> cop; 3844226633Sdim bits<4> CRd; 3845226633Sdim let Inst{24} = 1; // P = 1 3846226633Sdim let Inst{23} = addr{8}; 3847226633Sdim let Inst{22} = Dbit; 3848226633Sdim let Inst{21} = 0; // W = 0 3849226633Sdim let Inst{20} = load; 3850226633Sdim let Inst{19-16} = addr{12-9}; 3851226633Sdim let Inst{15-12} = CRd; 3852226633Sdim let Inst{11-8} = cop; 3853226633Sdim let Inst{7-0} = addr{7-0}; 3854226633Sdim let DecoderMethod = "DecodeCopMemInstruction"; 3855226633Sdim } 3856226633Sdim def _PRE : T2CI<op31_28, 3857263508Sdim (outs), (ins p_imm:$cop, c_imm:$CRd, addrmode5_pre:$addr), 3858226633Sdim asm, "\t$cop, $CRd, $addr!"> { 3859226633Sdim bits<13> addr; 3860226633Sdim bits<4> cop; 3861226633Sdim bits<4> CRd; 3862226633Sdim let Inst{24} = 1; // P = 1 3863226633Sdim let Inst{23} = addr{8}; 3864226633Sdim let Inst{22} = Dbit; 3865226633Sdim let Inst{21} = 1; // W = 1 3866226633Sdim let Inst{20} = load; 3867226633Sdim let Inst{19-16} = addr{12-9}; 3868226633Sdim let Inst{15-12} = CRd; 3869226633Sdim let Inst{11-8} = cop; 3870226633Sdim let Inst{7-0} = addr{7-0}; 3871226633Sdim let DecoderMethod = "DecodeCopMemInstruction"; 3872226633Sdim } 3873226633Sdim def _POST: T2CI<op31_28, 3874226633Sdim (outs), (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 3875226633Sdim postidx_imm8s4:$offset), 3876226633Sdim asm, "\t$cop, $CRd, $addr, $offset"> { 3877226633Sdim bits<9> offset; 3878226633Sdim bits<4> addr; 3879226633Sdim bits<4> cop; 3880226633Sdim bits<4> CRd; 3881226633Sdim let Inst{24} = 0; // P = 0 3882226633Sdim let Inst{23} = offset{8}; 3883226633Sdim let Inst{22} = Dbit; 3884226633Sdim let Inst{21} = 1; // W = 1 3885226633Sdim let Inst{20} = load; 3886226633Sdim let Inst{19-16} = addr; 3887226633Sdim let Inst{15-12} = CRd; 3888226633Sdim let Inst{11-8} = cop; 3889226633Sdim let Inst{7-0} = offset{7-0}; 3890226633Sdim let DecoderMethod = "DecodeCopMemInstruction"; 3891226633Sdim } 3892226633Sdim def _OPTION : T2CI<op31_28, (outs), 3893226633Sdim (ins p_imm:$cop, c_imm:$CRd, addr_offset_none:$addr, 3894226633Sdim coproc_option_imm:$option), 3895226633Sdim asm, "\t$cop, $CRd, $addr, $option"> { 3896226633Sdim bits<8> option; 3897226633Sdim bits<4> addr; 3898226633Sdim bits<4> cop; 3899226633Sdim bits<4> CRd; 3900226633Sdim let Inst{24} = 0; // P = 0 3901226633Sdim let Inst{23} = 1; // U = 1 3902226633Sdim let Inst{22} = Dbit; 3903226633Sdim let Inst{21} = 0; // W = 0 3904226633Sdim let Inst{20} = load; 3905226633Sdim let Inst{19-16} = addr; 3906226633Sdim let Inst{15-12} = CRd; 3907226633Sdim let Inst{11-8} = cop; 3908226633Sdim let Inst{7-0} = option; 3909226633Sdim let DecoderMethod = "DecodeCopMemInstruction"; 3910226633Sdim } 3911226633Sdim} 3912226633Sdim 3913226633Sdimdefm t2LDC : t2LdStCop<0b1110, 1, 0, "ldc">; 3914226633Sdimdefm t2LDCL : t2LdStCop<0b1110, 1, 1, "ldcl">; 3915226633Sdimdefm t2STC : t2LdStCop<0b1110, 0, 0, "stc">; 3916226633Sdimdefm t2STCL : t2LdStCop<0b1110, 0, 1, "stcl">; 3917263508Sdimdefm t2LDC2 : t2LdStCop<0b1111, 1, 0, "ldc2">, Requires<[PreV8]>; 3918263508Sdimdefm t2LDC2L : t2LdStCop<0b1111, 1, 1, "ldc2l">, Requires<[PreV8]>; 3919263508Sdimdefm t2STC2 : t2LdStCop<0b1111, 0, 0, "stc2">, Requires<[PreV8]>; 3920263508Sdimdefm t2STC2L : t2LdStCop<0b1111, 0, 1, "stc2l">, Requires<[PreV8]>; 3921226633Sdim 3922226633Sdim 3923226633Sdim//===----------------------------------------------------------------------===// 3924204642Srdivacky// Move between special register and ARM core register -- for disassembly only 3925204642Srdivacky// 3926226633Sdim// Move to ARM core register from Special Register 3927204642Srdivacky 3928226633Sdim// A/R class MRS. 3929226633Sdim// 3930226633Sdim// A/R class can only move from CPSR or SPSR. 3931239462Sdimdef t2MRS_AR : T2I<(outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, apsr", 3932263508Sdim []>, Requires<[IsThumb2,IsNotMClass]> { 3933226633Sdim bits<4> Rd; 3934226633Sdim let Inst{31-12} = 0b11110011111011111000; 3935226633Sdim let Inst{11-8} = Rd; 3936226633Sdim let Inst{7-0} = 0b0000; 3937204642Srdivacky} 3938204642Srdivacky 3939226633Sdimdef : t2InstAlias<"mrs${p} $Rd, cpsr", (t2MRS_AR GPR:$Rd, pred:$p)>; 3940226633Sdim 3941239462Sdimdef t2MRSsys_AR: T2I<(outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, spsr", 3942263508Sdim []>, Requires<[IsThumb2,IsNotMClass]> { 3943218893Sdim bits<4> Rd; 3944226633Sdim let Inst{31-12} = 0b11110011111111111000; 3945218893Sdim let Inst{11-8} = Rd; 3946226633Sdim let Inst{7-0} = 0b0000; 3947226633Sdim} 3948226633Sdim 3949226633Sdim// M class MRS. 3950226633Sdim// 3951226633Sdim// This MRS has a mask field in bits 7-0 and can take more values than 3952226633Sdim// the A/R class (a full msr_mask). 3953226633Sdimdef t2MRS_M : T2I<(outs rGPR:$Rd), (ins msr_mask:$mask), NoItinerary, 3954226633Sdim "mrs", "\t$Rd, $mask", []>, 3955239462Sdim Requires<[IsThumb,IsMClass]> { 3956226633Sdim bits<4> Rd; 3957226633Sdim bits<8> mask; 3958226633Sdim let Inst{31-12} = 0b11110011111011111000; 3959226633Sdim let Inst{11-8} = Rd; 3960218893Sdim let Inst{19-16} = 0b1111; 3961226633Sdim let Inst{7-0} = mask; 3962204642Srdivacky} 3963204642Srdivacky 3964218893Sdim 3965218893Sdim// Move from ARM core register to Special Register 3966218893Sdim// 3967226633Sdim// A/R class MSR. 3968226633Sdim// 3969218893Sdim// No need to have both system and application versions, the encodings are the 3970218893Sdim// same and the assembly parser has no way to distinguish between them. The mask 3971218893Sdim// operand contains the special register (R Bit) in bit 4 and bits 3-0 contains 3972218893Sdim// the mask with the fields to be accessed in the special register. 3973226633Sdimdef t2MSR_AR : T2I<(outs), (ins msr_mask:$mask, rGPR:$Rn), 3974226633Sdim NoItinerary, "msr", "\t$mask, $Rn", []>, 3975263508Sdim Requires<[IsThumb2,IsNotMClass]> { 3976218893Sdim bits<5> mask; 3977218893Sdim bits<4> Rn; 3978226633Sdim let Inst{31-21} = 0b11110011100; 3979226633Sdim let Inst{20} = mask{4}; // R Bit 3980218893Sdim let Inst{19-16} = Rn; 3981226633Sdim let Inst{15-12} = 0b1000; 3982218893Sdim let Inst{11-8} = mask{3-0}; 3983226633Sdim let Inst{7-0} = 0; 3984204642Srdivacky} 3985204642Srdivacky 3986226633Sdim// M class MSR. 3987226633Sdim// 3988226633Sdim// Move from ARM core register to Special Register 3989226633Sdimdef t2MSR_M : T2I<(outs), (ins msr_mask:$SYSm, rGPR:$Rn), 3990226633Sdim NoItinerary, "msr", "\t$SYSm, $Rn", []>, 3991239462Sdim Requires<[IsThumb,IsMClass]> { 3992239462Sdim bits<12> SYSm; 3993226633Sdim bits<4> Rn; 3994226633Sdim let Inst{31-21} = 0b11110011100; 3995226633Sdim let Inst{20} = 0b0; 3996226633Sdim let Inst{19-16} = Rn; 3997226633Sdim let Inst{15-12} = 0b1000; 3998239462Sdim let Inst{11-0} = SYSm; 3999226633Sdim} 4000226633Sdim 4001226633Sdim 4002218893Sdim//===----------------------------------------------------------------------===// 4003224145Sdim// Move between coprocessor and ARM core register 4004218893Sdim// 4005218893Sdim 4006224145Sdimclass t2MovRCopro<bits<4> Op, string opc, bit direction, dag oops, dag iops, 4007223017Sdim list<dag> pattern> 4008263508Sdim : T2Cop<Op, oops, iops, opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2", 4009223017Sdim pattern> { 4010218893Sdim let Inst{27-24} = 0b1110; 4011218893Sdim let Inst{20} = direction; 4012218893Sdim let Inst{4} = 1; 4013218893Sdim 4014218893Sdim bits<4> Rt; 4015218893Sdim bits<4> cop; 4016218893Sdim bits<3> opc1; 4017218893Sdim bits<3> opc2; 4018218893Sdim bits<4> CRm; 4019218893Sdim bits<4> CRn; 4020218893Sdim 4021218893Sdim let Inst{15-12} = Rt; 4022218893Sdim let Inst{11-8} = cop; 4023218893Sdim let Inst{23-21} = opc1; 4024218893Sdim let Inst{7-5} = opc2; 4025218893Sdim let Inst{3-0} = CRm; 4026218893Sdim let Inst{19-16} = CRn; 4027218893Sdim} 4028218893Sdim 4029224145Sdimclass t2MovRRCopro<bits<4> Op, string opc, bit direction, 4030224145Sdim list<dag> pattern = []> 4031224145Sdim : T2Cop<Op, (outs), 4032224145Sdim (ins p_imm:$cop, imm0_15:$opc1, GPR:$Rt, GPR:$Rt2, c_imm:$CRm), 4033263508Sdim opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", pattern> { 4034218893Sdim let Inst{27-24} = 0b1100; 4035218893Sdim let Inst{23-21} = 0b010; 4036218893Sdim let Inst{20} = direction; 4037218893Sdim 4038218893Sdim bits<4> Rt; 4039218893Sdim bits<4> Rt2; 4040218893Sdim bits<4> cop; 4041218893Sdim bits<4> opc1; 4042218893Sdim bits<4> CRm; 4043218893Sdim 4044218893Sdim let Inst{15-12} = Rt; 4045218893Sdim let Inst{19-16} = Rt2; 4046218893Sdim let Inst{11-8} = cop; 4047218893Sdim let Inst{7-4} = opc1; 4048218893Sdim let Inst{3-0} = CRm; 4049218893Sdim} 4050218893Sdim 4051224145Sdim/* from ARM core register to coprocessor */ 4052224145Sdimdef t2MCR : t2MovRCopro<0b1110, "mcr", 0, 4053224145Sdim (outs), 4054224145Sdim (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 4055224145Sdim c_imm:$CRm, imm0_7:$opc2), 4056224145Sdim [(int_arm_mcr imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn, 4057263508Sdim imm:$CRm, imm:$opc2)]>, 4058263508Sdim ComplexDeprecationPredicate<"MCR">; 4059263508Sdimdef : t2InstAlias<"mcr${p} $cop, $opc1, $Rt, $CRn, $CRm", 4060234353Sdim (t2MCR p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 4061263508Sdim c_imm:$CRm, 0, pred:$p)>; 4062224145Sdimdef t2MCR2 : t2MovRCopro<0b1111, "mcr2", 0, 4063224145Sdim (outs), (ins p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 4064224145Sdim c_imm:$CRm, imm0_7:$opc2), 4065224145Sdim [(int_arm_mcr2 imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn, 4066263508Sdim imm:$CRm, imm:$opc2)]> { 4067263508Sdim let Predicates = [IsThumb2, PreV8]; 4068263508Sdim} 4069263508Sdimdef : t2InstAlias<"mcr2${p} $cop, $opc1, $Rt, $CRn, $CRm", 4070234353Sdim (t2MCR2 p_imm:$cop, imm0_7:$opc1, GPR:$Rt, c_imm:$CRn, 4071263508Sdim c_imm:$CRm, 0, pred:$p)>; 4072224145Sdim 4073224145Sdim/* from coprocessor to ARM core register */ 4074224145Sdimdef t2MRC : t2MovRCopro<0b1110, "mrc", 1, 4075263508Sdim (outs GPRwithAPSR:$Rt), (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 4076226633Sdim c_imm:$CRm, imm0_7:$opc2), []>; 4077263508Sdimdef : t2InstAlias<"mrc${p} $cop, $opc1, $Rt, $CRn, $CRm", 4078263508Sdim (t2MRC GPRwithAPSR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 4079263508Sdim c_imm:$CRm, 0, pred:$p)>; 4080224145Sdim 4081224145Sdimdef t2MRC2 : t2MovRCopro<0b1111, "mrc2", 1, 4082263508Sdim (outs GPRwithAPSR:$Rt), (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 4083263508Sdim c_imm:$CRm, imm0_7:$opc2), []> { 4084263508Sdim let Predicates = [IsThumb2, PreV8]; 4085263508Sdim} 4086263508Sdimdef : t2InstAlias<"mrc2${p} $cop, $opc1, $Rt, $CRn, $CRm", 4087263508Sdim (t2MRC2 GPRwithAPSR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, 4088263508Sdim c_imm:$CRm, 0, pred:$p)>; 4089224145Sdim 4090224145Sdimdef : T2v6Pat<(int_arm_mrc imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2), 4091224145Sdim (t2MRC imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>; 4092224145Sdim 4093224145Sdimdef : T2v6Pat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2), 4094224145Sdim (t2MRC2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>; 4095224145Sdim 4096224145Sdim 4097224145Sdim/* from ARM core register to coprocessor */ 4098224145Sdimdef t2MCRR : t2MovRRCopro<0b1110, "mcrr", 0, 4099224145Sdim [(int_arm_mcrr imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, 4100224145Sdim imm:$CRm)]>; 4101224145Sdimdef t2MCRR2 : t2MovRRCopro<0b1111, "mcrr2", 0, 4102223017Sdim [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPR:$Rt, 4103263508Sdim GPR:$Rt2, imm:$CRm)]> { 4104263508Sdim let Predicates = [IsThumb2, PreV8]; 4105263508Sdim} 4106263508Sdim 4107224145Sdim/* from coprocessor to ARM core register */ 4108224145Sdimdef t2MRRC : t2MovRRCopro<0b1110, "mrrc", 1>; 4109218893Sdim 4110263508Sdimdef t2MRRC2 : t2MovRRCopro<0b1111, "mrrc2", 1> { 4111263508Sdim let Predicates = [IsThumb2, PreV8]; 4112263508Sdim} 4113224145Sdim 4114218893Sdim//===----------------------------------------------------------------------===// 4115224145Sdim// Other Coprocessor Instructions. 4116218893Sdim// 4117218893Sdim 4118263508Sdimdef t2CDP : T2Cop<0b1110, (outs), (ins p_imm:$cop, imm0_15:$opc1, 4119224145Sdim c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2), 4120263508Sdim "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", 4121224145Sdim [(int_arm_cdp imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn, 4122224145Sdim imm:$CRm, imm:$opc2)]> { 4123224145Sdim let Inst{27-24} = 0b1110; 4124224145Sdim 4125224145Sdim bits<4> opc1; 4126224145Sdim bits<4> CRn; 4127224145Sdim bits<4> CRd; 4128224145Sdim bits<4> cop; 4129224145Sdim bits<3> opc2; 4130224145Sdim bits<4> CRm; 4131224145Sdim 4132224145Sdim let Inst{3-0} = CRm; 4133224145Sdim let Inst{4} = 0; 4134224145Sdim let Inst{7-5} = opc2; 4135224145Sdim let Inst{11-8} = cop; 4136224145Sdim let Inst{15-12} = CRd; 4137224145Sdim let Inst{19-16} = CRn; 4138224145Sdim let Inst{23-20} = opc1; 4139263508Sdim 4140263508Sdim let Predicates = [IsThumb2, PreV8]; 4141224145Sdim} 4142224145Sdim 4143224145Sdimdef t2CDP2 : T2Cop<0b1111, (outs), (ins p_imm:$cop, imm0_15:$opc1, 4144224145Sdim c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, imm0_7:$opc2), 4145263508Sdim "cdp2", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", 4146223017Sdim [(int_arm_cdp2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn, 4147223017Sdim imm:$CRm, imm:$opc2)]> { 4148218893Sdim let Inst{27-24} = 0b1110; 4149218893Sdim 4150218893Sdim bits<4> opc1; 4151218893Sdim bits<4> CRn; 4152218893Sdim bits<4> CRd; 4153218893Sdim bits<4> cop; 4154218893Sdim bits<3> opc2; 4155218893Sdim bits<4> CRm; 4156218893Sdim 4157218893Sdim let Inst{3-0} = CRm; 4158218893Sdim let Inst{4} = 0; 4159218893Sdim let Inst{7-5} = opc2; 4160218893Sdim let Inst{11-8} = cop; 4161218893Sdim let Inst{15-12} = CRd; 4162218893Sdim let Inst{19-16} = CRn; 4163218893Sdim let Inst{23-20} = opc1; 4164263508Sdim 4165263508Sdim let Predicates = [IsThumb2, PreV8]; 4166204642Srdivacky} 4167226633Sdim 4168226633Sdim 4169226633Sdim 4170226633Sdim//===----------------------------------------------------------------------===// 4171226633Sdim// Non-Instruction Patterns 4172226633Sdim// 4173226633Sdim 4174226633Sdim// SXT/UXT with no rotate 4175226633Sdimlet AddedComplexity = 16 in { 4176226633Sdimdef : T2Pat<(and rGPR:$Rm, 0x000000FF), (t2UXTB rGPR:$Rm, 0)>, 4177226633Sdim Requires<[IsThumb2]>; 4178226633Sdimdef : T2Pat<(and rGPR:$Rm, 0x0000FFFF), (t2UXTH rGPR:$Rm, 0)>, 4179226633Sdim Requires<[IsThumb2]>; 4180226633Sdimdef : T2Pat<(and rGPR:$Rm, 0x00FF00FF), (t2UXTB16 rGPR:$Rm, 0)>, 4181226633Sdim Requires<[HasT2ExtractPack, IsThumb2]>; 4182226633Sdimdef : T2Pat<(add rGPR:$Rn, (and rGPR:$Rm, 0x00FF)), 4183226633Sdim (t2UXTAB rGPR:$Rn, rGPR:$Rm, 0)>, 4184226633Sdim Requires<[HasT2ExtractPack, IsThumb2]>; 4185226633Sdimdef : T2Pat<(add rGPR:$Rn, (and rGPR:$Rm, 0xFFFF)), 4186226633Sdim (t2UXTAH rGPR:$Rn, rGPR:$Rm, 0)>, 4187226633Sdim Requires<[HasT2ExtractPack, IsThumb2]>; 4188226633Sdim} 4189226633Sdim 4190226633Sdimdef : T2Pat<(sext_inreg rGPR:$Src, i8), (t2SXTB rGPR:$Src, 0)>, 4191226633Sdim Requires<[IsThumb2]>; 4192226633Sdimdef : T2Pat<(sext_inreg rGPR:$Src, i16), (t2SXTH rGPR:$Src, 0)>, 4193226633Sdim Requires<[IsThumb2]>; 4194226633Sdimdef : T2Pat<(add rGPR:$Rn, (sext_inreg rGPR:$Rm, i8)), 4195226633Sdim (t2SXTAB rGPR:$Rn, rGPR:$Rm, 0)>, 4196226633Sdim Requires<[HasT2ExtractPack, IsThumb2]>; 4197226633Sdimdef : T2Pat<(add rGPR:$Rn, (sext_inreg rGPR:$Rm, i16)), 4198226633Sdim (t2SXTAH rGPR:$Rn, rGPR:$Rm, 0)>, 4199226633Sdim Requires<[HasT2ExtractPack, IsThumb2]>; 4200226633Sdim 4201226633Sdim// Atomic load/store patterns 4202226633Sdimdef : T2Pat<(atomic_load_8 t2addrmode_imm12:$addr), 4203226633Sdim (t2LDRBi12 t2addrmode_imm12:$addr)>; 4204226633Sdimdef : T2Pat<(atomic_load_8 t2addrmode_negimm8:$addr), 4205226633Sdim (t2LDRBi8 t2addrmode_negimm8:$addr)>; 4206226633Sdimdef : T2Pat<(atomic_load_8 t2addrmode_so_reg:$addr), 4207226633Sdim (t2LDRBs t2addrmode_so_reg:$addr)>; 4208226633Sdimdef : T2Pat<(atomic_load_16 t2addrmode_imm12:$addr), 4209226633Sdim (t2LDRHi12 t2addrmode_imm12:$addr)>; 4210226633Sdimdef : T2Pat<(atomic_load_16 t2addrmode_negimm8:$addr), 4211226633Sdim (t2LDRHi8 t2addrmode_negimm8:$addr)>; 4212226633Sdimdef : T2Pat<(atomic_load_16 t2addrmode_so_reg:$addr), 4213226633Sdim (t2LDRHs t2addrmode_so_reg:$addr)>; 4214226633Sdimdef : T2Pat<(atomic_load_32 t2addrmode_imm12:$addr), 4215226633Sdim (t2LDRi12 t2addrmode_imm12:$addr)>; 4216226633Sdimdef : T2Pat<(atomic_load_32 t2addrmode_negimm8:$addr), 4217226633Sdim (t2LDRi8 t2addrmode_negimm8:$addr)>; 4218226633Sdimdef : T2Pat<(atomic_load_32 t2addrmode_so_reg:$addr), 4219226633Sdim (t2LDRs t2addrmode_so_reg:$addr)>; 4220226633Sdimdef : T2Pat<(atomic_store_8 t2addrmode_imm12:$addr, GPR:$val), 4221226633Sdim (t2STRBi12 GPR:$val, t2addrmode_imm12:$addr)>; 4222226633Sdimdef : T2Pat<(atomic_store_8 t2addrmode_negimm8:$addr, GPR:$val), 4223226633Sdim (t2STRBi8 GPR:$val, t2addrmode_negimm8:$addr)>; 4224226633Sdimdef : T2Pat<(atomic_store_8 t2addrmode_so_reg:$addr, GPR:$val), 4225226633Sdim (t2STRBs GPR:$val, t2addrmode_so_reg:$addr)>; 4226226633Sdimdef : T2Pat<(atomic_store_16 t2addrmode_imm12:$addr, GPR:$val), 4227226633Sdim (t2STRHi12 GPR:$val, t2addrmode_imm12:$addr)>; 4228226633Sdimdef : T2Pat<(atomic_store_16 t2addrmode_negimm8:$addr, GPR:$val), 4229226633Sdim (t2STRHi8 GPR:$val, t2addrmode_negimm8:$addr)>; 4230226633Sdimdef : T2Pat<(atomic_store_16 t2addrmode_so_reg:$addr, GPR:$val), 4231226633Sdim (t2STRHs GPR:$val, t2addrmode_so_reg:$addr)>; 4232226633Sdimdef : T2Pat<(atomic_store_32 t2addrmode_imm12:$addr, GPR:$val), 4233226633Sdim (t2STRi12 GPR:$val, t2addrmode_imm12:$addr)>; 4234226633Sdimdef : T2Pat<(atomic_store_32 t2addrmode_negimm8:$addr, GPR:$val), 4235226633Sdim (t2STRi8 GPR:$val, t2addrmode_negimm8:$addr)>; 4236226633Sdimdef : T2Pat<(atomic_store_32 t2addrmode_so_reg:$addr, GPR:$val), 4237226633Sdim (t2STRs GPR:$val, t2addrmode_so_reg:$addr)>; 4238226633Sdim 4239263508Sdimlet AddedComplexity = 8 in { 4240263508Sdim def : T2Pat<(atomic_load_acquire_8 addr_offset_none:$addr), (t2LDAB addr_offset_none:$addr)>; 4241263508Sdim def : T2Pat<(atomic_load_acquire_16 addr_offset_none:$addr), (t2LDAH addr_offset_none:$addr)>; 4242263508Sdim def : T2Pat<(atomic_load_acquire_32 addr_offset_none:$addr), (t2LDA addr_offset_none:$addr)>; 4243263508Sdim def : T2Pat<(atomic_store_release_8 addr_offset_none:$addr, GPR:$val), (t2STLB GPR:$val, addr_offset_none:$addr)>; 4244263508Sdim def : T2Pat<(atomic_store_release_16 addr_offset_none:$addr, GPR:$val), (t2STLH GPR:$val, addr_offset_none:$addr)>; 4245263508Sdim def : T2Pat<(atomic_store_release_32 addr_offset_none:$addr, GPR:$val), (t2STL GPR:$val, addr_offset_none:$addr)>; 4246263508Sdim} 4247226633Sdim 4248263508Sdim 4249226633Sdim//===----------------------------------------------------------------------===// 4250226633Sdim// Assembler aliases 4251226633Sdim// 4252226633Sdim 4253226633Sdim// Aliases for ADC without the ".w" optional width specifier. 4254226633Sdimdef : t2InstAlias<"adc${s}${p} $Rd, $Rn, $Rm", 4255226633Sdim (t2ADCrr rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>; 4256226633Sdimdef : t2InstAlias<"adc${s}${p} $Rd, $Rn, $ShiftedRm", 4257226633Sdim (t2ADCrs rGPR:$Rd, rGPR:$Rn, t2_so_reg:$ShiftedRm, 4258226633Sdim pred:$p, cc_out:$s)>; 4259226633Sdim 4260226633Sdim// Aliases for SBC without the ".w" optional width specifier. 4261226633Sdimdef : t2InstAlias<"sbc${s}${p} $Rd, $Rn, $Rm", 4262226633Sdim (t2SBCrr rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>; 4263226633Sdimdef : t2InstAlias<"sbc${s}${p} $Rd, $Rn, $ShiftedRm", 4264226633Sdim (t2SBCrs rGPR:$Rd, rGPR:$Rn, t2_so_reg:$ShiftedRm, 4265226633Sdim pred:$p, cc_out:$s)>; 4266226633Sdim 4267226633Sdim// Aliases for ADD without the ".w" optional width specifier. 4268226633Sdimdef : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm", 4269263508Sdim (t2ADDri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p, 4270263508Sdim cc_out:$s)>; 4271226633Sdimdef : t2InstAlias<"add${p} $Rd, $Rn, $imm", 4272226633Sdim (t2ADDri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>; 4273226633Sdimdef : t2InstAlias<"add${s}${p} $Rd, $Rn, $Rm", 4274226633Sdim (t2ADDrr GPRnopc:$Rd, GPRnopc:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>; 4275226633Sdimdef : t2InstAlias<"add${s}${p} $Rd, $Rn, $ShiftedRm", 4276226633Sdim (t2ADDrs GPRnopc:$Rd, GPRnopc:$Rn, t2_so_reg:$ShiftedRm, 4277226633Sdim pred:$p, cc_out:$s)>; 4278234353Sdim// ... and with the destination and source register combined. 4279234353Sdimdef : t2InstAlias<"add${s}${p} $Rdn, $imm", 4280234353Sdim (t2ADDri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>; 4281234353Sdimdef : t2InstAlias<"add${p} $Rdn, $imm", 4282234353Sdim (t2ADDri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095:$imm, pred:$p)>; 4283234353Sdimdef : t2InstAlias<"add${s}${p} $Rdn, $Rm", 4284234353Sdim (t2ADDrr GPRnopc:$Rdn, GPRnopc:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>; 4285234353Sdimdef : t2InstAlias<"add${s}${p} $Rdn, $ShiftedRm", 4286234353Sdim (t2ADDrs GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_reg:$ShiftedRm, 4287234353Sdim pred:$p, cc_out:$s)>; 4288226633Sdim 4289234353Sdim// add w/ negative immediates is just a sub. 4290234353Sdimdef : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm", 4291234353Sdim (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p, 4292234353Sdim cc_out:$s)>; 4293234353Sdimdef : t2InstAlias<"add${p} $Rd, $Rn, $imm", 4294234353Sdim (t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>; 4295234353Sdimdef : t2InstAlias<"add${s}${p} $Rdn, $imm", 4296234353Sdim (t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm_neg:$imm, pred:$p, 4297234353Sdim cc_out:$s)>; 4298234353Sdimdef : t2InstAlias<"add${p} $Rdn, $imm", 4299234353Sdim (t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095_neg:$imm, pred:$p)>; 4300234353Sdim 4301239462Sdimdef : t2InstAlias<"add${s}${p}.w $Rd, $Rn, $imm", 4302239462Sdim (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, pred:$p, 4303239462Sdim cc_out:$s)>; 4304239462Sdimdef : t2InstAlias<"addw${p} $Rd, $Rn, $imm", 4305239462Sdim (t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>; 4306239462Sdimdef : t2InstAlias<"add${s}${p}.w $Rdn, $imm", 4307239462Sdim (t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm_neg:$imm, pred:$p, 4308239462Sdim cc_out:$s)>; 4309239462Sdimdef : t2InstAlias<"addw${p} $Rdn, $imm", 4310239462Sdim (t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095_neg:$imm, pred:$p)>; 4311234353Sdim 4312239462Sdim 4313226633Sdim// Aliases for SUB without the ".w" optional width specifier. 4314226633Sdimdef : t2InstAlias<"sub${s}${p} $Rd, $Rn, $imm", 4315226633Sdim (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>; 4316226633Sdimdef : t2InstAlias<"sub${p} $Rd, $Rn, $imm", 4317226633Sdim (t2SUBri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095:$imm, pred:$p)>; 4318226633Sdimdef : t2InstAlias<"sub${s}${p} $Rd, $Rn, $Rm", 4319226633Sdim (t2SUBrr GPRnopc:$Rd, GPRnopc:$Rn, rGPR:$Rm, pred:$p, cc_out:$s)>; 4320226633Sdimdef : t2InstAlias<"sub${s}${p} $Rd, $Rn, $ShiftedRm", 4321226633Sdim (t2SUBrs GPRnopc:$Rd, GPRnopc:$Rn, t2_so_reg:$ShiftedRm, 4322226633Sdim pred:$p, cc_out:$s)>; 4323234353Sdim// ... and with the destination and source register combined. 4324234353Sdimdef : t2InstAlias<"sub${s}${p} $Rdn, $imm", 4325234353Sdim (t2SUBri GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>; 4326234353Sdimdef : t2InstAlias<"sub${p} $Rdn, $imm", 4327234353Sdim (t2SUBri12 GPRnopc:$Rdn, GPRnopc:$Rdn, imm0_4095:$imm, pred:$p)>; 4328234353Sdimdef : t2InstAlias<"sub${s}${p}.w $Rdn, $Rm", 4329234353Sdim (t2SUBrr GPRnopc:$Rdn, GPRnopc:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>; 4330234353Sdimdef : t2InstAlias<"sub${s}${p} $Rdn, $Rm", 4331234353Sdim (t2SUBrr GPRnopc:$Rdn, GPRnopc:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>; 4332234353Sdimdef : t2InstAlias<"sub${s}${p} $Rdn, $ShiftedRm", 4333234353Sdim (t2SUBrs GPRnopc:$Rdn, GPRnopc:$Rdn, t2_so_reg:$ShiftedRm, 4334234353Sdim pred:$p, cc_out:$s)>; 4335226633Sdim 4336226633Sdim// Alias for compares without the ".w" optional width specifier. 4337226633Sdimdef : t2InstAlias<"cmn${p} $Rn, $Rm", 4338226633Sdim (t2CMNzrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>; 4339226633Sdimdef : t2InstAlias<"teq${p} $Rn, $Rm", 4340226633Sdim (t2TEQrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>; 4341226633Sdimdef : t2InstAlias<"tst${p} $Rn, $Rm", 4342226633Sdim (t2TSTrr GPRnopc:$Rn, rGPR:$Rm, pred:$p)>; 4343226633Sdim 4344226633Sdim// Memory barriers 4345263508Sdimdef : InstAlias<"dmb${p}", (t2DMB 0xf, pred:$p)>, Requires<[HasDB]>; 4346263508Sdimdef : InstAlias<"dsb${p}", (t2DSB 0xf, pred:$p)>, Requires<[HasDB]>; 4347263508Sdimdef : InstAlias<"isb${p}", (t2ISB 0xf, pred:$p)>, Requires<[HasDB]>; 4348226633Sdim 4349226633Sdim// Alias for LDR, LDRB, LDRH, LDRSB, and LDRSH without the ".w" optional 4350226633Sdim// width specifier. 4351226633Sdimdef : t2InstAlias<"ldr${p} $Rt, $addr", 4352226633Sdim (t2LDRi12 GPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4353226633Sdimdef : t2InstAlias<"ldrb${p} $Rt, $addr", 4354226633Sdim (t2LDRBi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4355226633Sdimdef : t2InstAlias<"ldrh${p} $Rt, $addr", 4356226633Sdim (t2LDRHi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4357226633Sdimdef : t2InstAlias<"ldrsb${p} $Rt, $addr", 4358226633Sdim (t2LDRSBi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4359226633Sdimdef : t2InstAlias<"ldrsh${p} $Rt, $addr", 4360226633Sdim (t2LDRSHi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4361226633Sdim 4362226633Sdimdef : t2InstAlias<"ldr${p} $Rt, $addr", 4363226633Sdim (t2LDRs GPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4364226633Sdimdef : t2InstAlias<"ldrb${p} $Rt, $addr", 4365226633Sdim (t2LDRBs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4366226633Sdimdef : t2InstAlias<"ldrh${p} $Rt, $addr", 4367226633Sdim (t2LDRHs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4368226633Sdimdef : t2InstAlias<"ldrsb${p} $Rt, $addr", 4369226633Sdim (t2LDRSBs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4370226633Sdimdef : t2InstAlias<"ldrsh${p} $Rt, $addr", 4371226633Sdim (t2LDRSHs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4372226633Sdim 4373234353Sdimdef : t2InstAlias<"ldr${p} $Rt, $addr", 4374263508Sdim (t2LDRpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>; 4375234353Sdimdef : t2InstAlias<"ldrb${p} $Rt, $addr", 4376234353Sdim (t2LDRBpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>; 4377234353Sdimdef : t2InstAlias<"ldrh${p} $Rt, $addr", 4378234353Sdim (t2LDRHpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>; 4379234353Sdimdef : t2InstAlias<"ldrsb${p} $Rt, $addr", 4380234353Sdim (t2LDRSBpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>; 4381234353Sdimdef : t2InstAlias<"ldrsh${p} $Rt, $addr", 4382234353Sdim (t2LDRSHpci rGPR:$Rt, t2ldrlabel:$addr, pred:$p)>; 4383234353Sdim 4384234353Sdim// Alias for MVN with(out) the ".w" optional width specifier. 4385234353Sdimdef : t2InstAlias<"mvn${s}${p}.w $Rd, $imm", 4386234353Sdim (t2MVNi rGPR:$Rd, t2_so_imm:$imm, pred:$p, cc_out:$s)>; 4387226633Sdimdef : t2InstAlias<"mvn${s}${p} $Rd, $Rm", 4388226633Sdim (t2MVNr rGPR:$Rd, rGPR:$Rm, pred:$p, cc_out:$s)>; 4389226633Sdimdef : t2InstAlias<"mvn${s}${p} $Rd, $ShiftedRm", 4390226633Sdim (t2MVNs rGPR:$Rd, t2_so_reg:$ShiftedRm, pred:$p, cc_out:$s)>; 4391226633Sdim 4392226633Sdim// PKHBT/PKHTB with default shift amount. PKHTB is equivalent to PKHBT when the 4393226633Sdim// shift amount is zero (i.e., unspecified). 4394226633Sdimdef : InstAlias<"pkhbt${p} $Rd, $Rn, $Rm", 4395226633Sdim (t2PKHBT rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>, 4396226633Sdim Requires<[HasT2ExtractPack, IsThumb2]>; 4397226633Sdimdef : InstAlias<"pkhtb${p} $Rd, $Rn, $Rm", 4398226633Sdim (t2PKHBT rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>, 4399226633Sdim Requires<[HasT2ExtractPack, IsThumb2]>; 4400226633Sdim 4401226633Sdim// PUSH/POP aliases for STM/LDM 4402226633Sdimdef : t2InstAlias<"push${p}.w $regs", (t2STMDB_UPD SP, pred:$p, reglist:$regs)>; 4403226633Sdimdef : t2InstAlias<"push${p} $regs", (t2STMDB_UPD SP, pred:$p, reglist:$regs)>; 4404226633Sdimdef : t2InstAlias<"pop${p}.w $regs", (t2LDMIA_UPD SP, pred:$p, reglist:$regs)>; 4405226633Sdimdef : t2InstAlias<"pop${p} $regs", (t2LDMIA_UPD SP, pred:$p, reglist:$regs)>; 4406226633Sdim 4407234353Sdim// STMIA/STMIA_UPD aliases w/o the optional .w suffix 4408234353Sdimdef : t2InstAlias<"stm${p} $Rn, $regs", 4409234353Sdim (t2STMIA GPR:$Rn, pred:$p, reglist:$regs)>; 4410234353Sdimdef : t2InstAlias<"stm${p} $Rn!, $regs", 4411234353Sdim (t2STMIA_UPD GPR:$Rn, pred:$p, reglist:$regs)>; 4412234353Sdim 4413234353Sdim// LDMIA/LDMIA_UPD aliases w/o the optional .w suffix 4414234353Sdimdef : t2InstAlias<"ldm${p} $Rn, $regs", 4415234353Sdim (t2LDMIA GPR:$Rn, pred:$p, reglist:$regs)>; 4416234353Sdimdef : t2InstAlias<"ldm${p} $Rn!, $regs", 4417234353Sdim (t2LDMIA_UPD GPR:$Rn, pred:$p, reglist:$regs)>; 4418234353Sdim 4419234353Sdim// STMDB/STMDB_UPD aliases w/ the optional .w suffix 4420234353Sdimdef : t2InstAlias<"stmdb${p}.w $Rn, $regs", 4421234353Sdim (t2STMDB GPR:$Rn, pred:$p, reglist:$regs)>; 4422234353Sdimdef : t2InstAlias<"stmdb${p}.w $Rn!, $regs", 4423234353Sdim (t2STMDB_UPD GPR:$Rn, pred:$p, reglist:$regs)>; 4424234353Sdim 4425234353Sdim// LDMDB/LDMDB_UPD aliases w/ the optional .w suffix 4426234353Sdimdef : t2InstAlias<"ldmdb${p}.w $Rn, $regs", 4427234353Sdim (t2LDMDB GPR:$Rn, pred:$p, reglist:$regs)>; 4428234353Sdimdef : t2InstAlias<"ldmdb${p}.w $Rn!, $regs", 4429234353Sdim (t2LDMDB_UPD GPR:$Rn, pred:$p, reglist:$regs)>; 4430234353Sdim 4431226633Sdim// Alias for REV/REV16/REVSH without the ".w" optional width specifier. 4432226633Sdimdef : t2InstAlias<"rev${p} $Rd, $Rm", (t2REV rGPR:$Rd, rGPR:$Rm, pred:$p)>; 4433226633Sdimdef : t2InstAlias<"rev16${p} $Rd, $Rm", (t2REV16 rGPR:$Rd, rGPR:$Rm, pred:$p)>; 4434226633Sdimdef : t2InstAlias<"revsh${p} $Rd, $Rm", (t2REVSH rGPR:$Rd, rGPR:$Rm, pred:$p)>; 4435226633Sdim 4436226633Sdim 4437226633Sdim// Alias for RSB without the ".w" optional width specifier, and with optional 4438226633Sdim// implied destination register. 4439226633Sdimdef : t2InstAlias<"rsb${s}${p} $Rd, $Rn, $imm", 4440226633Sdim (t2RSBri rGPR:$Rd, rGPR:$Rn, t2_so_imm:$imm, pred:$p, cc_out:$s)>; 4441226633Sdimdef : t2InstAlias<"rsb${s}${p} $Rdn, $imm", 4442226633Sdim (t2RSBri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm:$imm, pred:$p, cc_out:$s)>; 4443226633Sdimdef : t2InstAlias<"rsb${s}${p} $Rdn, $Rm", 4444226633Sdim (t2RSBrr rGPR:$Rdn, rGPR:$Rdn, rGPR:$Rm, pred:$p, cc_out:$s)>; 4445226633Sdimdef : t2InstAlias<"rsb${s}${p} $Rdn, $ShiftedRm", 4446226633Sdim (t2RSBrs rGPR:$Rdn, rGPR:$Rdn, t2_so_reg:$ShiftedRm, pred:$p, 4447226633Sdim cc_out:$s)>; 4448226633Sdim 4449226633Sdim// SSAT/USAT optional shift operand. 4450226633Sdimdef : t2InstAlias<"ssat${p} $Rd, $sat_imm, $Rn", 4451226633Sdim (t2SSAT rGPR:$Rd, imm1_32:$sat_imm, rGPR:$Rn, 0, pred:$p)>; 4452226633Sdimdef : t2InstAlias<"usat${p} $Rd, $sat_imm, $Rn", 4453226633Sdim (t2USAT rGPR:$Rd, imm0_31:$sat_imm, rGPR:$Rn, 0, pred:$p)>; 4454226633Sdim 4455226633Sdim// STM w/o the .w suffix. 4456226633Sdimdef : t2InstAlias<"stm${p} $Rn, $regs", 4457226633Sdim (t2STMIA GPR:$Rn, pred:$p, reglist:$regs)>; 4458226633Sdim 4459226633Sdim// Alias for STR, STRB, and STRH without the ".w" optional 4460226633Sdim// width specifier. 4461226633Sdimdef : t2InstAlias<"str${p} $Rt, $addr", 4462226633Sdim (t2STRi12 GPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4463226633Sdimdef : t2InstAlias<"strb${p} $Rt, $addr", 4464226633Sdim (t2STRBi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4465226633Sdimdef : t2InstAlias<"strh${p} $Rt, $addr", 4466226633Sdim (t2STRHi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>; 4467226633Sdim 4468226633Sdimdef : t2InstAlias<"str${p} $Rt, $addr", 4469226633Sdim (t2STRs GPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4470226633Sdimdef : t2InstAlias<"strb${p} $Rt, $addr", 4471226633Sdim (t2STRBs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4472226633Sdimdef : t2InstAlias<"strh${p} $Rt, $addr", 4473226633Sdim (t2STRHs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>; 4474226633Sdim 4475226633Sdim// Extend instruction optional rotate operand. 4476226633Sdimdef : t2InstAlias<"sxtab${p} $Rd, $Rn, $Rm", 4477226633Sdim (t2SXTAB rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>; 4478226633Sdimdef : t2InstAlias<"sxtah${p} $Rd, $Rn, $Rm", 4479226633Sdim (t2SXTAH rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>; 4480226633Sdimdef : t2InstAlias<"sxtab16${p} $Rd, $Rn, $Rm", 4481226633Sdim (t2SXTAB16 rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>; 4482226633Sdim 4483226633Sdimdef : t2InstAlias<"sxtb${p} $Rd, $Rm", 4484226633Sdim (t2SXTB rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4485226633Sdimdef : t2InstAlias<"sxtb16${p} $Rd, $Rm", 4486226633Sdim (t2SXTB16 rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4487226633Sdimdef : t2InstAlias<"sxth${p} $Rd, $Rm", 4488226633Sdim (t2SXTH rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4489226633Sdimdef : t2InstAlias<"sxtb${p}.w $Rd, $Rm", 4490226633Sdim (t2SXTB rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4491226633Sdimdef : t2InstAlias<"sxth${p}.w $Rd, $Rm", 4492226633Sdim (t2SXTH rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4493226633Sdim 4494226633Sdimdef : t2InstAlias<"uxtab${p} $Rd, $Rn, $Rm", 4495226633Sdim (t2UXTAB rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>; 4496226633Sdimdef : t2InstAlias<"uxtah${p} $Rd, $Rn, $Rm", 4497226633Sdim (t2UXTAH rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>; 4498226633Sdimdef : t2InstAlias<"uxtab16${p} $Rd, $Rn, $Rm", 4499226633Sdim (t2UXTAB16 rGPR:$Rd, rGPR:$Rn, rGPR:$Rm, 0, pred:$p)>; 4500226633Sdimdef : t2InstAlias<"uxtb${p} $Rd, $Rm", 4501226633Sdim (t2UXTB rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4502226633Sdimdef : t2InstAlias<"uxtb16${p} $Rd, $Rm", 4503226633Sdim (t2UXTB16 rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4504226633Sdimdef : t2InstAlias<"uxth${p} $Rd, $Rm", 4505226633Sdim (t2UXTH rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4506226633Sdim 4507226633Sdimdef : t2InstAlias<"uxtb${p}.w $Rd, $Rm", 4508226633Sdim (t2UXTB rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4509226633Sdimdef : t2InstAlias<"uxth${p}.w $Rd, $Rm", 4510226633Sdim (t2UXTH rGPR:$Rd, rGPR:$Rm, 0, pred:$p)>; 4511226633Sdim 4512226633Sdim// Extend instruction w/o the ".w" optional width specifier. 4513226633Sdimdef : t2InstAlias<"uxtb${p} $Rd, $Rm$rot", 4514226633Sdim (t2UXTB rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>; 4515226633Sdimdef : t2InstAlias<"uxtb16${p} $Rd, $Rm$rot", 4516226633Sdim (t2UXTB16 rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>; 4517226633Sdimdef : t2InstAlias<"uxth${p} $Rd, $Rm$rot", 4518226633Sdim (t2UXTH rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>; 4519226633Sdim 4520226633Sdimdef : t2InstAlias<"sxtb${p} $Rd, $Rm$rot", 4521226633Sdim (t2SXTB rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>; 4522226633Sdimdef : t2InstAlias<"sxtb16${p} $Rd, $Rm$rot", 4523226633Sdim (t2SXTB16 rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>; 4524226633Sdimdef : t2InstAlias<"sxth${p} $Rd, $Rm$rot", 4525226633Sdim (t2SXTH rGPR:$Rd, rGPR:$Rm, rot_imm:$rot, pred:$p)>; 4526234353Sdim 4527234353Sdim 4528234353Sdim// "mov Rd, t2_so_imm_not" can be handled via "mvn" in assembly, just like 4529234353Sdim// for isel. 4530234353Sdimdef : t2InstAlias<"mov${p} $Rd, $imm", 4531234353Sdim (t2MVNi rGPR:$Rd, t2_so_imm_not:$imm, pred:$p, zero_reg)>; 4532234353Sdimdef : t2InstAlias<"mvn${p} $Rd, $imm", 4533234353Sdim (t2MOVi rGPR:$Rd, t2_so_imm_not:$imm, pred:$p, zero_reg)>; 4534234353Sdim// Same for AND <--> BIC 4535234353Sdimdef : t2InstAlias<"bic${s}${p} $Rd, $Rn, $imm", 4536263508Sdim (t2ANDri rGPR:$Rd, rGPR:$Rn, t2_so_imm_not:$imm, 4537234353Sdim pred:$p, cc_out:$s)>; 4538234353Sdimdef : t2InstAlias<"bic${s}${p} $Rdn, $imm", 4539263508Sdim (t2ANDri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm_not:$imm, 4540234353Sdim pred:$p, cc_out:$s)>; 4541234353Sdimdef : t2InstAlias<"and${s}${p} $Rd, $Rn, $imm", 4542263508Sdim (t2BICri rGPR:$Rd, rGPR:$Rn, t2_so_imm_not:$imm, 4543234353Sdim pred:$p, cc_out:$s)>; 4544234353Sdimdef : t2InstAlias<"and${s}${p} $Rdn, $imm", 4545263508Sdim (t2BICri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm_not:$imm, 4546234353Sdim pred:$p, cc_out:$s)>; 4547234353Sdim// Likewise, "add Rd, t2_so_imm_neg" -> sub 4548234353Sdimdef : t2InstAlias<"add${s}${p} $Rd, $Rn, $imm", 4549234353Sdim (t2SUBri GPRnopc:$Rd, GPRnopc:$Rn, t2_so_imm_neg:$imm, 4550234353Sdim pred:$p, cc_out:$s)>; 4551234353Sdimdef : t2InstAlias<"add${s}${p} $Rd, $imm", 4552234353Sdim (t2SUBri GPRnopc:$Rd, GPRnopc:$Rd, t2_so_imm_neg:$imm, 4553234353Sdim pred:$p, cc_out:$s)>; 4554234353Sdim// Same for CMP <--> CMN via t2_so_imm_neg 4555234353Sdimdef : t2InstAlias<"cmp${p} $Rd, $imm", 4556239462Sdim (t2CMNri rGPR:$Rd, t2_so_imm_neg:$imm, pred:$p)>; 4557234353Sdimdef : t2InstAlias<"cmn${p} $Rd, $imm", 4558234353Sdim (t2CMPri rGPR:$Rd, t2_so_imm_neg:$imm, pred:$p)>; 4559234353Sdim 4560234353Sdim 4561234353Sdim// Wide 'mul' encoding can be specified with only two operands. 4562234353Sdimdef : t2InstAlias<"mul${p} $Rn, $Rm", 4563234353Sdim (t2MUL rGPR:$Rn, rGPR:$Rm, rGPR:$Rn, pred:$p)>; 4564234353Sdim 4565234353Sdim// "neg" is and alias for "rsb rd, rn, #0" 4566234353Sdimdef : t2InstAlias<"neg${s}${p} $Rd, $Rm", 4567234353Sdim (t2RSBri rGPR:$Rd, rGPR:$Rm, 0, pred:$p, cc_out:$s)>; 4568234353Sdim 4569234353Sdim// MOV so_reg assembler pseudos. InstAlias isn't expressive enough for 4570234353Sdim// these, unfortunately. 4571234353Sdimdef t2MOVsi: t2AsmPseudo<"mov${p} $Rd, $shift", 4572234353Sdim (ins rGPR:$Rd, t2_so_reg:$shift, pred:$p)>; 4573234353Sdimdef t2MOVSsi: t2AsmPseudo<"movs${p} $Rd, $shift", 4574234353Sdim (ins rGPR:$Rd, t2_so_reg:$shift, pred:$p)>; 4575234353Sdim 4576234353Sdimdef t2MOVsr: t2AsmPseudo<"mov${p} $Rd, $shift", 4577234353Sdim (ins rGPR:$Rd, so_reg_reg:$shift, pred:$p)>; 4578234353Sdimdef t2MOVSsr: t2AsmPseudo<"movs${p} $Rd, $shift", 4579234353Sdim (ins rGPR:$Rd, so_reg_reg:$shift, pred:$p)>; 4580234353Sdim 4581234353Sdim// ADR w/o the .w suffix 4582234353Sdimdef : t2InstAlias<"adr${p} $Rd, $addr", 4583234353Sdim (t2ADR rGPR:$Rd, t2adrlabel:$addr, pred:$p)>; 4584234353Sdim 4585234353Sdim// LDR(literal) w/ alternate [pc, #imm] syntax. 4586234353Sdimdef t2LDRpcrel : t2AsmPseudo<"ldr${p} $Rt, $addr", 4587263508Sdim (ins GPR:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4588234353Sdimdef t2LDRBpcrel : t2AsmPseudo<"ldrb${p} $Rt, $addr", 4589234353Sdim (ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4590234353Sdimdef t2LDRHpcrel : t2AsmPseudo<"ldrh${p} $Rt, $addr", 4591234353Sdim (ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4592234353Sdimdef t2LDRSBpcrel : t2AsmPseudo<"ldrsb${p} $Rt, $addr", 4593234353Sdim (ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4594234353Sdimdef t2LDRSHpcrel : t2AsmPseudo<"ldrsh${p} $Rt, $addr", 4595234353Sdim (ins GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4596234353Sdim // Version w/ the .w suffix. 4597234353Sdimdef : t2InstAlias<"ldr${p}.w $Rt, $addr", 4598263508Sdim (t2LDRpcrel GPR:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p), 0>; 4599234353Sdimdef : t2InstAlias<"ldrb${p}.w $Rt, $addr", 4600234353Sdim (t2LDRBpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4601234353Sdimdef : t2InstAlias<"ldrh${p}.w $Rt, $addr", 4602234353Sdim (t2LDRHpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4603234353Sdimdef : t2InstAlias<"ldrsb${p}.w $Rt, $addr", 4604234353Sdim (t2LDRSBpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4605234353Sdimdef : t2InstAlias<"ldrsh${p}.w $Rt, $addr", 4606234353Sdim (t2LDRSHpcrel GPRnopc:$Rt, t2ldr_pcrel_imm12:$addr, pred:$p)>; 4607234353Sdim 4608234353Sdimdef : t2InstAlias<"add${p} $Rd, pc, $imm", 4609234353Sdim (t2ADR rGPR:$Rd, imm0_4095:$imm, pred:$p)>; 4610263508Sdim 4611263508Sdim// PLD/PLDW/PLI with alternate literal form. 4612263508Sdimdef : t2InstAlias<"pld${p} $addr", 4613263508Sdim (t2PLDpci t2ldr_pcrel_imm12:$addr, pred:$p)>; 4614263508Sdimdef : InstAlias<"pli${p} $addr", 4615263508Sdim (t2PLIpci t2ldr_pcrel_imm12:$addr, pred:$p)>, 4616263508Sdim Requires<[IsThumb2,HasV7]>; 4617