ARMInstrInfo.td revision 223017
1//===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file describes the ARM instructions in TableGen format. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// ARM specific DAG Nodes. 16// 17 18// Type profiles. 19def SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 20def SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>; 21 22def SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>; 23 24def SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; 25 26def SDT_ARMCMov : SDTypeProfile<1, 3, 27 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 28 SDTCisVT<3, i32>]>; 29 30def SDT_ARMBrcond : SDTypeProfile<0, 2, 31 [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>; 32 33def SDT_ARMBrJT : SDTypeProfile<0, 3, 34 [SDTCisPtrTy<0>, SDTCisVT<1, i32>, 35 SDTCisVT<2, i32>]>; 36 37def SDT_ARMBr2JT : SDTypeProfile<0, 4, 38 [SDTCisPtrTy<0>, SDTCisVT<1, i32>, 39 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 40 41def SDT_ARMBCC_i64 : SDTypeProfile<0, 6, 42 [SDTCisVT<0, i32>, 43 SDTCisVT<1, i32>, SDTCisVT<2, i32>, 44 SDTCisVT<3, i32>, SDTCisVT<4, i32>, 45 SDTCisVT<5, OtherVT>]>; 46 47def SDT_ARMAnd : SDTypeProfile<1, 2, 48 [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 49 SDTCisVT<2, i32>]>; 50 51def SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; 52 53def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, 54 SDTCisPtrTy<1>, SDTCisVT<2, i32>]>; 55 56def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; 57def SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisPtrTy<1>, 58 SDTCisInt<2>]>; 59def SDT_ARMEH_SJLJ_Longjmp: SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisInt<1>]>; 60 61def SDT_ARMEH_SJLJ_DispatchSetup: SDTypeProfile<0, 1, [SDTCisInt<0>]>; 62 63def SDT_ARMMEMBARRIER : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 64 65def SDT_ARMTCRET : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 66 67def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 68 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 69 70// Node definitions. 71def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>; 72def ARMWrapperDYN : SDNode<"ARMISD::WrapperDYN", SDTIntUnaryOp>; 73def ARMWrapperPIC : SDNode<"ARMISD::WrapperPIC", SDTIntUnaryOp>; 74def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>; 75 76def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart, 77 [SDNPHasChain, SDNPOutGlue]>; 78def ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd, 79 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 80 81def ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall, 82 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 83 SDNPVariadic]>; 84def ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall, 85 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 86 SDNPVariadic]>; 87def ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall, 88 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, 89 SDNPVariadic]>; 90 91def ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone, 92 [SDNPHasChain, SDNPOptInGlue]>; 93 94def ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov, 95 [SDNPInGlue]>; 96 97def ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond, 98 [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>; 99 100def ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT, 101 [SDNPHasChain]>; 102def ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT, 103 [SDNPHasChain]>; 104 105def ARMBcci64 : SDNode<"ARMISD::BCC_i64", SDT_ARMBCC_i64, 106 [SDNPHasChain]>; 107 108def ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp, 109 [SDNPOutGlue]>; 110 111def ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp, 112 [SDNPOutGlue, SDNPCommutative]>; 113 114def ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>; 115 116def ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>; 117def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutGlue]>; 118def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInGlue ]>; 119 120def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; 121def ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", 122 SDT_ARMEH_SJLJ_Setjmp, [SDNPHasChain]>; 123def ARMeh_sjlj_longjmp: SDNode<"ARMISD::EH_SJLJ_LONGJMP", 124 SDT_ARMEH_SJLJ_Longjmp, [SDNPHasChain]>; 125def ARMeh_sjlj_dispatchsetup: SDNode<"ARMISD::EH_SJLJ_DISPATCHSETUP", 126 SDT_ARMEH_SJLJ_DispatchSetup, [SDNPHasChain]>; 127 128 129def ARMMemBarrier : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIER, 130 [SDNPHasChain]>; 131def ARMMemBarrierMCR : SDNode<"ARMISD::MEMBARRIER_MCR", SDT_ARMMEMBARRIER, 132 [SDNPHasChain]>; 133def ARMPreload : SDNode<"ARMISD::PRELOAD", SDTPrefetch, 134 [SDNPHasChain, SDNPMayLoad, SDNPMayStore]>; 135 136def ARMrbit : SDNode<"ARMISD::RBIT", SDTIntUnaryOp>; 137 138def ARMtcret : SDNode<"ARMISD::TC_RETURN", SDT_ARMTCRET, 139 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 140 141 142def ARMbfi : SDNode<"ARMISD::BFI", SDT_ARMBFI>; 143 144//===----------------------------------------------------------------------===// 145// ARM Instruction Predicate Definitions. 146// 147def HasV4T : Predicate<"Subtarget->hasV4TOps()">, AssemblerPredicate; 148def NoV4T : Predicate<"!Subtarget->hasV4TOps()">; 149def HasV5T : Predicate<"Subtarget->hasV5TOps()">; 150def HasV5TE : Predicate<"Subtarget->hasV5TEOps()">, AssemblerPredicate; 151def HasV6 : Predicate<"Subtarget->hasV6Ops()">, AssemblerPredicate; 152def NoV6 : Predicate<"!Subtarget->hasV6Ops()">; 153def HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">, AssemblerPredicate; 154def NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">; 155def HasV7 : Predicate<"Subtarget->hasV7Ops()">, AssemblerPredicate; 156def NoVFP : Predicate<"!Subtarget->hasVFP2()">; 157def HasVFP2 : Predicate<"Subtarget->hasVFP2()">, AssemblerPredicate; 158def HasVFP3 : Predicate<"Subtarget->hasVFP3()">, AssemblerPredicate; 159def HasNEON : Predicate<"Subtarget->hasNEON()">, AssemblerPredicate; 160def HasFP16 : Predicate<"Subtarget->hasFP16()">, AssemblerPredicate; 161def HasDivide : Predicate<"Subtarget->hasDivide()">, AssemblerPredicate; 162def HasT2ExtractPack : Predicate<"Subtarget->hasT2ExtractPack()">, 163 AssemblerPredicate; 164def HasDB : Predicate<"Subtarget->hasDataBarrier()">, 165 AssemblerPredicate; 166def HasMP : Predicate<"Subtarget->hasMPExtension()">, 167 AssemblerPredicate; 168def UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">; 169def DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">; 170def IsThumb : Predicate<"Subtarget->isThumb()">, AssemblerPredicate; 171def IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">; 172def IsThumb2 : Predicate<"Subtarget->isThumb2()">, AssemblerPredicate; 173def IsARM : Predicate<"!Subtarget->isThumb()">, AssemblerPredicate; 174def IsDarwin : Predicate<"Subtarget->isTargetDarwin()">; 175def IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">; 176 177// FIXME: Eventually this will be just "hasV6T2Ops". 178def UseMovt : Predicate<"Subtarget->useMovt()">; 179def DontUseMovt : Predicate<"!Subtarget->useMovt()">; 180def UseFPVMLx : Predicate<"Subtarget->useFPVMLx()">; 181 182//===----------------------------------------------------------------------===// 183// ARM Flag Definitions. 184 185class RegConstraint<string C> { 186 string Constraints = C; 187} 188 189//===----------------------------------------------------------------------===// 190// ARM specific transformation functions and pattern fragments. 191// 192 193// so_imm_neg_XFORM - Return a so_imm value packed into the format described for 194// so_imm_neg def below. 195def so_imm_neg_XFORM : SDNodeXForm<imm, [{ 196 return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32); 197}]>; 198 199// so_imm_not_XFORM - Return a so_imm value packed into the format described for 200// so_imm_not def below. 201def so_imm_not_XFORM : SDNodeXForm<imm, [{ 202 return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32); 203}]>; 204 205/// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15]. 206def imm1_15 : ImmLeaf<i32, [{ 207 return (int32_t)Imm >= 1 && (int32_t)Imm < 16; 208}]>; 209 210/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31]. 211def imm16_31 : ImmLeaf<i32, [{ 212 return (int32_t)Imm >= 16 && (int32_t)Imm < 32; 213}]>; 214 215def so_imm_neg : 216 PatLeaf<(imm), [{ 217 return ARM_AM::getSOImmVal(-(uint32_t)N->getZExtValue()) != -1; 218 }], so_imm_neg_XFORM>; 219 220def so_imm_not : 221 PatLeaf<(imm), [{ 222 return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1; 223 }], so_imm_not_XFORM>; 224 225// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits. 226def sext_16_node : PatLeaf<(i32 GPR:$a), [{ 227 return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17; 228}]>; 229 230/// Split a 32-bit immediate into two 16 bit parts. 231def hi16 : SDNodeXForm<imm, [{ 232 return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32); 233}]>; 234 235def lo16AllZero : PatLeaf<(i32 imm), [{ 236 // Returns true if all low 16-bits are 0. 237 return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0; 238}], hi16>; 239 240/// imm0_65535 predicate - True if the 32-bit immediate is in the range 241/// [0.65535]. 242def imm0_65535 : ImmLeaf<i32, [{ 243 return Imm >= 0 && Imm < 65536; 244}]>; 245 246class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 247class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>; 248 249/// adde and sube predicates - True based on whether the carry flag output 250/// will be needed or not. 251def adde_dead_carry : 252 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS), 253 [{return !N->hasAnyUseOfValue(1);}]>; 254def sube_dead_carry : 255 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS), 256 [{return !N->hasAnyUseOfValue(1);}]>; 257def adde_live_carry : 258 PatFrag<(ops node:$LHS, node:$RHS), (adde node:$LHS, node:$RHS), 259 [{return N->hasAnyUseOfValue(1);}]>; 260def sube_live_carry : 261 PatFrag<(ops node:$LHS, node:$RHS), (sube node:$LHS, node:$RHS), 262 [{return N->hasAnyUseOfValue(1);}]>; 263 264// An 'and' node with a single use. 265def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{ 266 return N->hasOneUse(); 267}]>; 268 269// An 'xor' node with a single use. 270def xor_su : PatFrag<(ops node:$lhs, node:$rhs), (xor node:$lhs, node:$rhs), [{ 271 return N->hasOneUse(); 272}]>; 273 274// An 'fmul' node with a single use. 275def fmul_su : PatFrag<(ops node:$lhs, node:$rhs), (fmul node:$lhs, node:$rhs),[{ 276 return N->hasOneUse(); 277}]>; 278 279// An 'fadd' node which checks for single non-hazardous use. 280def fadd_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fadd node:$lhs, node:$rhs),[{ 281 return hasNoVMLxHazardUse(N); 282}]>; 283 284// An 'fsub' node which checks for single non-hazardous use. 285def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{ 286 return hasNoVMLxHazardUse(N); 287}]>; 288 289//===----------------------------------------------------------------------===// 290// Operand Definitions. 291// 292 293// Branch target. 294// FIXME: rename brtarget to t2_brtarget 295def brtarget : Operand<OtherVT> { 296 let EncoderMethod = "getBranchTargetOpValue"; 297} 298 299// FIXME: get rid of this one? 300def uncondbrtarget : Operand<OtherVT> { 301 let EncoderMethod = "getUnconditionalBranchTargetOpValue"; 302} 303 304// Branch target for ARM. Handles conditional/unconditional 305def br_target : Operand<OtherVT> { 306 let EncoderMethod = "getARMBranchTargetOpValue"; 307} 308 309// Call target. 310// FIXME: rename bltarget to t2_bl_target? 311def bltarget : Operand<i32> { 312 // Encoded the same as branch targets. 313 let EncoderMethod = "getBranchTargetOpValue"; 314} 315 316// Call target for ARM. Handles conditional/unconditional 317// FIXME: rename bl_target to t2_bltarget? 318def bl_target : Operand<i32> { 319 // Encoded the same as branch targets. 320 let EncoderMethod = "getARMBranchTargetOpValue"; 321} 322 323 324// A list of registers separated by comma. Used by load/store multiple. 325def RegListAsmOperand : AsmOperandClass { 326 let Name = "RegList"; 327 let SuperClasses = []; 328} 329 330def DPRRegListAsmOperand : AsmOperandClass { 331 let Name = "DPRRegList"; 332 let SuperClasses = []; 333} 334 335def SPRRegListAsmOperand : AsmOperandClass { 336 let Name = "SPRRegList"; 337 let SuperClasses = []; 338} 339 340def reglist : Operand<i32> { 341 let EncoderMethod = "getRegisterListOpValue"; 342 let ParserMatchClass = RegListAsmOperand; 343 let PrintMethod = "printRegisterList"; 344} 345 346def dpr_reglist : Operand<i32> { 347 let EncoderMethod = "getRegisterListOpValue"; 348 let ParserMatchClass = DPRRegListAsmOperand; 349 let PrintMethod = "printRegisterList"; 350} 351 352def spr_reglist : Operand<i32> { 353 let EncoderMethod = "getRegisterListOpValue"; 354 let ParserMatchClass = SPRRegListAsmOperand; 355 let PrintMethod = "printRegisterList"; 356} 357 358// An operand for the CONSTPOOL_ENTRY pseudo-instruction. 359def cpinst_operand : Operand<i32> { 360 let PrintMethod = "printCPInstOperand"; 361} 362 363// Local PC labels. 364def pclabel : Operand<i32> { 365 let PrintMethod = "printPCLabel"; 366} 367 368// ADR instruction labels. 369def adrlabel : Operand<i32> { 370 let EncoderMethod = "getAdrLabelOpValue"; 371} 372 373def neon_vcvt_imm32 : Operand<i32> { 374 let EncoderMethod = "getNEONVcvtImm32OpValue"; 375} 376 377// rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24. 378def rot_imm : Operand<i32>, ImmLeaf<i32, [{ 379 int32_t v = (int32_t)Imm; 380 return v == 8 || v == 16 || v == 24; }]> { 381 let EncoderMethod = "getRotImmOpValue"; 382} 383 384def ShifterAsmOperand : AsmOperandClass { 385 let Name = "Shifter"; 386 let SuperClasses = []; 387} 388 389// shift_imm: An integer that encodes a shift amount and the type of shift 390// (currently either asr or lsl) using the same encoding used for the 391// immediates in so_reg operands. 392def shift_imm : Operand<i32> { 393 let PrintMethod = "printShiftImmOperand"; 394 let ParserMatchClass = ShifterAsmOperand; 395} 396 397// shifter_operand operands: so_reg and so_imm. 398def so_reg : Operand<i32>, // reg reg imm 399 ComplexPattern<i32, 3, "SelectShifterOperandReg", 400 [shl,srl,sra,rotr]> { 401 let EncoderMethod = "getSORegOpValue"; 402 let PrintMethod = "printSORegOperand"; 403 let MIOperandInfo = (ops GPR, GPR, shift_imm); 404} 405def shift_so_reg : Operand<i32>, // reg reg imm 406 ComplexPattern<i32, 3, "SelectShiftShifterOperandReg", 407 [shl,srl,sra,rotr]> { 408 let EncoderMethod = "getSORegOpValue"; 409 let PrintMethod = "printSORegOperand"; 410 let MIOperandInfo = (ops GPR, GPR, shift_imm); 411} 412 413// so_imm - Match a 32-bit shifter_operand immediate operand, which is an 414// 8-bit immediate rotated by an arbitrary number of bits. 415def so_imm : Operand<i32>, ImmLeaf<i32, [{ 416 return ARM_AM::getSOImmVal(Imm) != -1; 417 }]> { 418 let EncoderMethod = "getSOImmOpValue"; 419 let PrintMethod = "printSOImmOperand"; 420} 421 422// Break so_imm's up into two pieces. This handles immediates with up to 16 423// bits set in them. This uses so_imm2part to match and so_imm2part_[12] to 424// get the first/second pieces. 425def so_imm2part : PatLeaf<(imm), [{ 426 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue()); 427}]>; 428 429/// arm_i32imm - True for +V6T2, or true only if so_imm2part is true. 430/// 431def arm_i32imm : PatLeaf<(imm), [{ 432 if (Subtarget->hasV6T2Ops()) 433 return true; 434 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue()); 435}]>; 436 437/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31]. 438def imm0_31 : Operand<i32>, ImmLeaf<i32, [{ 439 return Imm >= 0 && Imm < 32; 440}]>; 441 442/// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'. 443def imm0_31_m1 : Operand<i32>, ImmLeaf<i32, [{ 444 return Imm >= 0 && Imm < 32; 445}]> { 446 let EncoderMethod = "getImmMinusOneOpValue"; 447} 448 449// i32imm_hilo16 - For movt/movw - sets the MC Encoder method. 450// The imm is split into imm{15-12}, imm{11-0} 451// 452def i32imm_hilo16 : Operand<i32> { 453 let EncoderMethod = "getHiLo16ImmOpValue"; 454} 455 456/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield 457/// e.g., 0xf000ffff 458def bf_inv_mask_imm : Operand<i32>, 459 PatLeaf<(imm), [{ 460 return ARM::isBitFieldInvertedMask(N->getZExtValue()); 461}] > { 462 let EncoderMethod = "getBitfieldInvertedMaskOpValue"; 463 let PrintMethod = "printBitfieldInvMaskImmOperand"; 464} 465 466/// lsb_pos_imm - position of the lsb bit, used by BFI4p and t2BFI4p 467def lsb_pos_imm : Operand<i32>, ImmLeaf<i32, [{ 468 return isInt<5>(Imm); 469}]>; 470 471/// width_imm - number of bits to be copied, used by BFI4p and t2BFI4p 472def width_imm : Operand<i32>, ImmLeaf<i32, [{ 473 return Imm > 0 && Imm <= 32; 474}] > { 475 let EncoderMethod = "getMsbOpValue"; 476} 477 478def ssat_imm : Operand<i32>, ImmLeaf<i32, [{ 479 return Imm > 0 && Imm <= 32; 480}]> { 481 let EncoderMethod = "getSsatBitPosValue"; 482} 483 484// Define ARM specific addressing modes. 485 486def MemMode2AsmOperand : AsmOperandClass { 487 let Name = "MemMode2"; 488 let SuperClasses = []; 489 let ParserMethod = "tryParseMemMode2Operand"; 490} 491 492def MemMode3AsmOperand : AsmOperandClass { 493 let Name = "MemMode3"; 494 let SuperClasses = []; 495 let ParserMethod = "tryParseMemMode3Operand"; 496} 497 498// addrmode_imm12 := reg +/- imm12 499// 500def addrmode_imm12 : Operand<i32>, 501 ComplexPattern<i32, 2, "SelectAddrModeImm12", []> { 502 // 12-bit immediate operand. Note that instructions using this encode 503 // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other 504 // immediate values are as normal. 505 506 let EncoderMethod = "getAddrModeImm12OpValue"; 507 let PrintMethod = "printAddrModeImm12Operand"; 508 let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); 509} 510// ldst_so_reg := reg +/- reg shop imm 511// 512def ldst_so_reg : Operand<i32>, 513 ComplexPattern<i32, 3, "SelectLdStSOReg", []> { 514 let EncoderMethod = "getLdStSORegOpValue"; 515 // FIXME: Simplify the printer 516 let PrintMethod = "printAddrMode2Operand"; 517 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 518} 519 520// addrmode2 := reg +/- imm12 521// := reg +/- reg shop imm 522// 523def addrmode2 : Operand<i32>, 524 ComplexPattern<i32, 3, "SelectAddrMode2", []> { 525 let EncoderMethod = "getAddrMode2OpValue"; 526 let PrintMethod = "printAddrMode2Operand"; 527 let ParserMatchClass = MemMode2AsmOperand; 528 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 529} 530 531def am2offset : Operand<i32>, 532 ComplexPattern<i32, 2, "SelectAddrMode2Offset", 533 [], [SDNPWantRoot]> { 534 let EncoderMethod = "getAddrMode2OffsetOpValue"; 535 let PrintMethod = "printAddrMode2OffsetOperand"; 536 let MIOperandInfo = (ops GPR, i32imm); 537} 538 539// addrmode3 := reg +/- reg 540// addrmode3 := reg +/- imm8 541// 542def addrmode3 : Operand<i32>, 543 ComplexPattern<i32, 3, "SelectAddrMode3", []> { 544 let EncoderMethod = "getAddrMode3OpValue"; 545 let PrintMethod = "printAddrMode3Operand"; 546 let ParserMatchClass = MemMode3AsmOperand; 547 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 548} 549 550def am3offset : Operand<i32>, 551 ComplexPattern<i32, 2, "SelectAddrMode3Offset", 552 [], [SDNPWantRoot]> { 553 let EncoderMethod = "getAddrMode3OffsetOpValue"; 554 let PrintMethod = "printAddrMode3OffsetOperand"; 555 let MIOperandInfo = (ops GPR, i32imm); 556} 557 558// ldstm_mode := {ia, ib, da, db} 559// 560def ldstm_mode : OptionalDefOperand<OtherVT, (ops i32), (ops (i32 1))> { 561 let EncoderMethod = "getLdStmModeOpValue"; 562 let PrintMethod = "printLdStmModeOperand"; 563} 564 565def MemMode5AsmOperand : AsmOperandClass { 566 let Name = "MemMode5"; 567 let SuperClasses = []; 568} 569 570// addrmode5 := reg +/- imm8*4 571// 572def addrmode5 : Operand<i32>, 573 ComplexPattern<i32, 2, "SelectAddrMode5", []> { 574 let PrintMethod = "printAddrMode5Operand"; 575 let MIOperandInfo = (ops GPR:$base, i32imm); 576 let ParserMatchClass = MemMode5AsmOperand; 577 let EncoderMethod = "getAddrMode5OpValue"; 578} 579 580// addrmode6 := reg with optional alignment 581// 582def addrmode6 : Operand<i32>, 583 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ 584 let PrintMethod = "printAddrMode6Operand"; 585 let MIOperandInfo = (ops GPR:$addr, i32imm); 586 let EncoderMethod = "getAddrMode6AddressOpValue"; 587} 588 589def am6offset : Operand<i32>, 590 ComplexPattern<i32, 1, "SelectAddrMode6Offset", 591 [], [SDNPWantRoot]> { 592 let PrintMethod = "printAddrMode6OffsetOperand"; 593 let MIOperandInfo = (ops GPR); 594 let EncoderMethod = "getAddrMode6OffsetOpValue"; 595} 596 597// Special version of addrmode6 to handle alignment encoding for VST1/VLD1 598// (single element from one lane) for size 32. 599def addrmode6oneL32 : Operand<i32>, 600 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ 601 let PrintMethod = "printAddrMode6Operand"; 602 let MIOperandInfo = (ops GPR:$addr, i32imm); 603 let EncoderMethod = "getAddrMode6OneLane32AddressOpValue"; 604} 605 606// Special version of addrmode6 to handle alignment encoding for VLD-dup 607// instructions, specifically VLD4-dup. 608def addrmode6dup : Operand<i32>, 609 ComplexPattern<i32, 2, "SelectAddrMode6", [], [SDNPWantParent]>{ 610 let PrintMethod = "printAddrMode6Operand"; 611 let MIOperandInfo = (ops GPR:$addr, i32imm); 612 let EncoderMethod = "getAddrMode6DupAddressOpValue"; 613} 614 615// addrmodepc := pc + reg 616// 617def addrmodepc : Operand<i32>, 618 ComplexPattern<i32, 2, "SelectAddrModePC", []> { 619 let PrintMethod = "printAddrModePCOperand"; 620 let MIOperandInfo = (ops GPR, i32imm); 621} 622 623def MemMode7AsmOperand : AsmOperandClass { 624 let Name = "MemMode7"; 625 let SuperClasses = []; 626} 627 628// addrmode7 := reg 629// Used by load/store exclusive instructions. Useful to enable right assembly 630// parsing and printing. Not used for any codegen matching. 631// 632def addrmode7 : Operand<i32> { 633 let PrintMethod = "printAddrMode7Operand"; 634 let MIOperandInfo = (ops GPR); 635 let ParserMatchClass = MemMode7AsmOperand; 636} 637 638def nohash_imm : Operand<i32> { 639 let PrintMethod = "printNoHashImmediate"; 640} 641 642def CoprocNumAsmOperand : AsmOperandClass { 643 let Name = "CoprocNum"; 644 let SuperClasses = []; 645 let ParserMethod = "tryParseCoprocNumOperand"; 646} 647 648def CoprocRegAsmOperand : AsmOperandClass { 649 let Name = "CoprocReg"; 650 let SuperClasses = []; 651 let ParserMethod = "tryParseCoprocRegOperand"; 652} 653 654def p_imm : Operand<i32> { 655 let PrintMethod = "printPImmediate"; 656 let ParserMatchClass = CoprocNumAsmOperand; 657} 658 659def c_imm : Operand<i32> { 660 let PrintMethod = "printCImmediate"; 661 let ParserMatchClass = CoprocRegAsmOperand; 662} 663 664//===----------------------------------------------------------------------===// 665 666include "ARMInstrFormats.td" 667 668//===----------------------------------------------------------------------===// 669// Multiclass helpers... 670// 671 672/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a 673/// binop that produces a value. 674multiclass AsI1_bin_irs<bits<4> opcod, string opc, 675 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 676 PatFrag opnode, bit Commutable = 0> { 677 // The register-immediate version is re-materializable. This is useful 678 // in particular for taking the address of a local. 679 let isReMaterializable = 1 in { 680 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm, 681 iii, opc, "\t$Rd, $Rn, $imm", 682 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> { 683 bits<4> Rd; 684 bits<4> Rn; 685 bits<12> imm; 686 let Inst{25} = 1; 687 let Inst{19-16} = Rn; 688 let Inst{15-12} = Rd; 689 let Inst{11-0} = imm; 690 } 691 } 692 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, 693 iir, opc, "\t$Rd, $Rn, $Rm", 694 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> { 695 bits<4> Rd; 696 bits<4> Rn; 697 bits<4> Rm; 698 let Inst{25} = 0; 699 let isCommutable = Commutable; 700 let Inst{19-16} = Rn; 701 let Inst{15-12} = Rd; 702 let Inst{11-4} = 0b00000000; 703 let Inst{3-0} = Rm; 704 } 705 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, 706 iis, opc, "\t$Rd, $Rn, $shift", 707 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> { 708 bits<4> Rd; 709 bits<4> Rn; 710 bits<12> shift; 711 let Inst{25} = 0; 712 let Inst{19-16} = Rn; 713 let Inst{15-12} = Rd; 714 let Inst{11-0} = shift; 715 } 716} 717 718/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the 719/// instruction modifies the CPSR register. 720let isCodeGenOnly = 1, Defs = [CPSR] in { 721multiclass AI1_bin_s_irs<bits<4> opcod, string opc, 722 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 723 PatFrag opnode, bit Commutable = 0> { 724 def ri : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm, 725 iii, opc, "\t$Rd, $Rn, $imm", 726 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]> { 727 bits<4> Rd; 728 bits<4> Rn; 729 bits<12> imm; 730 let Inst{25} = 1; 731 let Inst{20} = 1; 732 let Inst{19-16} = Rn; 733 let Inst{15-12} = Rd; 734 let Inst{11-0} = imm; 735 } 736 def rr : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, 737 iir, opc, "\t$Rd, $Rn, $Rm", 738 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> { 739 bits<4> Rd; 740 bits<4> Rn; 741 bits<4> Rm; 742 let isCommutable = Commutable; 743 let Inst{25} = 0; 744 let Inst{20} = 1; 745 let Inst{19-16} = Rn; 746 let Inst{15-12} = Rd; 747 let Inst{11-4} = 0b00000000; 748 let Inst{3-0} = Rm; 749 } 750 def rs : AI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, 751 iis, opc, "\t$Rd, $Rn, $shift", 752 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> { 753 bits<4> Rd; 754 bits<4> Rn; 755 bits<12> shift; 756 let Inst{25} = 0; 757 let Inst{20} = 1; 758 let Inst{19-16} = Rn; 759 let Inst{15-12} = Rd; 760 let Inst{11-0} = shift; 761 } 762} 763} 764 765/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test 766/// patterns. Similar to AsI1_bin_irs except the instruction does not produce 767/// a explicit result, only implicitly set CPSR. 768let isCompare = 1, Defs = [CPSR] in { 769multiclass AI1_cmp_irs<bits<4> opcod, string opc, 770 InstrItinClass iii, InstrItinClass iir, InstrItinClass iis, 771 PatFrag opnode, bit Commutable = 0> { 772 def ri : AI1<opcod, (outs), (ins GPR:$Rn, so_imm:$imm), DPFrm, iii, 773 opc, "\t$Rn, $imm", 774 [(opnode GPR:$Rn, so_imm:$imm)]> { 775 bits<4> Rn; 776 bits<12> imm; 777 let Inst{25} = 1; 778 let Inst{20} = 1; 779 let Inst{19-16} = Rn; 780 let Inst{15-12} = 0b0000; 781 let Inst{11-0} = imm; 782 } 783 def rr : AI1<opcod, (outs), (ins GPR:$Rn, GPR:$Rm), DPFrm, iir, 784 opc, "\t$Rn, $Rm", 785 [(opnode GPR:$Rn, GPR:$Rm)]> { 786 bits<4> Rn; 787 bits<4> Rm; 788 let isCommutable = Commutable; 789 let Inst{25} = 0; 790 let Inst{20} = 1; 791 let Inst{19-16} = Rn; 792 let Inst{15-12} = 0b0000; 793 let Inst{11-4} = 0b00000000; 794 let Inst{3-0} = Rm; 795 } 796 def rs : AI1<opcod, (outs), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm, iis, 797 opc, "\t$Rn, $shift", 798 [(opnode GPR:$Rn, so_reg:$shift)]> { 799 bits<4> Rn; 800 bits<12> shift; 801 let Inst{25} = 0; 802 let Inst{20} = 1; 803 let Inst{19-16} = Rn; 804 let Inst{15-12} = 0b0000; 805 let Inst{11-0} = shift; 806 } 807} 808} 809 810/// AI_ext_rrot - A unary operation with two forms: one whose operand is a 811/// register and one whose operand is a register rotated by 8/16/24. 812/// FIXME: Remove the 'r' variant. Its rot_imm is zero. 813multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> { 814 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm), 815 IIC_iEXTr, opc, "\t$Rd, $Rm", 816 [(set GPR:$Rd, (opnode GPR:$Rm))]>, 817 Requires<[IsARM, HasV6]> { 818 bits<4> Rd; 819 bits<4> Rm; 820 let Inst{19-16} = 0b1111; 821 let Inst{15-12} = Rd; 822 let Inst{11-10} = 0b00; 823 let Inst{3-0} = Rm; 824 } 825 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot), 826 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot", 827 [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>, 828 Requires<[IsARM, HasV6]> { 829 bits<4> Rd; 830 bits<4> Rm; 831 bits<2> rot; 832 let Inst{19-16} = 0b1111; 833 let Inst{15-12} = Rd; 834 let Inst{11-10} = rot; 835 let Inst{3-0} = Rm; 836 } 837} 838 839multiclass AI_ext_rrot_np<bits<8> opcod, string opc> { 840 def r : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm), 841 IIC_iEXTr, opc, "\t$Rd, $Rm", 842 [/* For disassembly only; pattern left blank */]>, 843 Requires<[IsARM, HasV6]> { 844 let Inst{19-16} = 0b1111; 845 let Inst{11-10} = 0b00; 846 } 847 def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot), 848 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot", 849 [/* For disassembly only; pattern left blank */]>, 850 Requires<[IsARM, HasV6]> { 851 bits<2> rot; 852 let Inst{19-16} = 0b1111; 853 let Inst{11-10} = rot; 854 } 855} 856 857/// AI_exta_rrot - A binary operation with two forms: one whose operand is a 858/// register and one whose operand is a register rotated by 8/16/24. 859multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> { 860 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 861 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm", 862 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>, 863 Requires<[IsARM, HasV6]> { 864 bits<4> Rd; 865 bits<4> Rm; 866 bits<4> Rn; 867 let Inst{19-16} = Rn; 868 let Inst{15-12} = Rd; 869 let Inst{11-10} = 0b00; 870 let Inst{9-4} = 0b000111; 871 let Inst{3-0} = Rm; 872 } 873 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, 874 rot_imm:$rot), 875 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot", 876 [(set GPR:$Rd, (opnode GPR:$Rn, 877 (rotr GPR:$Rm, rot_imm:$rot)))]>, 878 Requires<[IsARM, HasV6]> { 879 bits<4> Rd; 880 bits<4> Rm; 881 bits<4> Rn; 882 bits<2> rot; 883 let Inst{19-16} = Rn; 884 let Inst{15-12} = Rd; 885 let Inst{11-10} = rot; 886 let Inst{9-4} = 0b000111; 887 let Inst{3-0} = Rm; 888 } 889} 890 891// For disassembly only. 892multiclass AI_exta_rrot_np<bits<8> opcod, string opc> { 893 def rr : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 894 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm", 895 [/* For disassembly only; pattern left blank */]>, 896 Requires<[IsARM, HasV6]> { 897 let Inst{11-10} = 0b00; 898 } 899 def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, 900 rot_imm:$rot), 901 IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot", 902 [/* For disassembly only; pattern left blank */]>, 903 Requires<[IsARM, HasV6]> { 904 bits<4> Rn; 905 bits<2> rot; 906 let Inst{19-16} = Rn; 907 let Inst{11-10} = rot; 908 } 909} 910 911/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube. 912let Uses = [CPSR] in { 913multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, 914 bit Commutable = 0> { 915 def ri : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), 916 DPFrm, IIC_iALUi, opc, "\t$Rd, $Rn, $imm", 917 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>, 918 Requires<[IsARM]> { 919 bits<4> Rd; 920 bits<4> Rn; 921 bits<12> imm; 922 let Inst{25} = 1; 923 let Inst{15-12} = Rd; 924 let Inst{19-16} = Rn; 925 let Inst{11-0} = imm; 926 } 927 def rr : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 928 DPFrm, IIC_iALUr, opc, "\t$Rd, $Rn, $Rm", 929 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]>, 930 Requires<[IsARM]> { 931 bits<4> Rd; 932 bits<4> Rn; 933 bits<4> Rm; 934 let Inst{11-4} = 0b00000000; 935 let Inst{25} = 0; 936 let isCommutable = Commutable; 937 let Inst{3-0} = Rm; 938 let Inst{15-12} = Rd; 939 let Inst{19-16} = Rn; 940 } 941 def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), 942 DPSoRegFrm, IIC_iALUsr, opc, "\t$Rd, $Rn, $shift", 943 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>, 944 Requires<[IsARM]> { 945 bits<4> Rd; 946 bits<4> Rn; 947 bits<12> shift; 948 let Inst{25} = 0; 949 let Inst{11-0} = shift; 950 let Inst{15-12} = Rd; 951 let Inst{19-16} = Rn; 952 } 953} 954} 955 956// Carry setting variants 957// NOTE: CPSR def omitted because it will be handled by the custom inserter. 958let usesCustomInserter = 1 in { 959multiclass AI1_adde_sube_s_irs<PatFrag opnode, bit Commutable = 0> { 960 def ri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), 961 Size4Bytes, IIC_iALUi, 962 [(set GPR:$Rd, (opnode GPR:$Rn, so_imm:$imm))]>; 963 def rr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 964 Size4Bytes, IIC_iALUr, 965 [(set GPR:$Rd, (opnode GPR:$Rn, GPR:$Rm))]> { 966 let isCommutable = Commutable; 967 } 968 def rs : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), 969 Size4Bytes, IIC_iALUsr, 970 [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]>; 971} 972} 973 974let canFoldAsLoad = 1, isReMaterializable = 1 in { 975multiclass AI_ldr1<bit isByte, string opc, InstrItinClass iii, 976 InstrItinClass iir, PatFrag opnode> { 977 // Note: We use the complex addrmode_imm12 rather than just an input 978 // GPR and a constrained immediate so that we can use this to match 979 // frame index references and avoid matching constant pool references. 980 def i12: AI2ldst<0b010, 1, isByte, (outs GPR:$Rt), (ins addrmode_imm12:$addr), 981 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr", 982 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> { 983 bits<4> Rt; 984 bits<17> addr; 985 let Inst{23} = addr{12}; // U (add = ('U' == 1)) 986 let Inst{19-16} = addr{16-13}; // Rn 987 let Inst{15-12} = Rt; 988 let Inst{11-0} = addr{11-0}; // imm12 989 } 990 def rs : AI2ldst<0b011, 1, isByte, (outs GPR:$Rt), (ins ldst_so_reg:$shift), 991 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift", 992 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> { 993 bits<4> Rt; 994 bits<17> shift; 995 let shift{4} = 0; // Inst{4} = 0 996 let Inst{23} = shift{12}; // U (add = ('U' == 1)) 997 let Inst{19-16} = shift{16-13}; // Rn 998 let Inst{15-12} = Rt; 999 let Inst{11-0} = shift{11-0}; 1000 } 1001} 1002} 1003 1004multiclass AI_str1<bit isByte, string opc, InstrItinClass iii, 1005 InstrItinClass iir, PatFrag opnode> { 1006 // Note: We use the complex addrmode_imm12 rather than just an input 1007 // GPR and a constrained immediate so that we can use this to match 1008 // frame index references and avoid matching constant pool references. 1009 def i12 : AI2ldst<0b010, 0, isByte, (outs), 1010 (ins GPR:$Rt, addrmode_imm12:$addr), 1011 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr", 1012 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> { 1013 bits<4> Rt; 1014 bits<17> addr; 1015 let Inst{23} = addr{12}; // U (add = ('U' == 1)) 1016 let Inst{19-16} = addr{16-13}; // Rn 1017 let Inst{15-12} = Rt; 1018 let Inst{11-0} = addr{11-0}; // imm12 1019 } 1020 def rs : AI2ldst<0b011, 0, isByte, (outs), (ins GPR:$Rt, ldst_so_reg:$shift), 1021 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift", 1022 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> { 1023 bits<4> Rt; 1024 bits<17> shift; 1025 let shift{4} = 0; // Inst{4} = 0 1026 let Inst{23} = shift{12}; // U (add = ('U' == 1)) 1027 let Inst{19-16} = shift{16-13}; // Rn 1028 let Inst{15-12} = Rt; 1029 let Inst{11-0} = shift{11-0}; 1030 } 1031} 1032//===----------------------------------------------------------------------===// 1033// Instructions 1034//===----------------------------------------------------------------------===// 1035 1036//===----------------------------------------------------------------------===// 1037// Miscellaneous Instructions. 1038// 1039 1040/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in 1041/// the function. The first operand is the ID# for this instruction, the second 1042/// is the index into the MachineConstantPool that this is, the third is the 1043/// size in bytes of this constant pool entry. 1044let neverHasSideEffects = 1, isNotDuplicable = 1 in 1045def CONSTPOOL_ENTRY : 1046PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx, 1047 i32imm:$size), NoItinerary, []>; 1048 1049// FIXME: Marking these as hasSideEffects is necessary to prevent machine DCE 1050// from removing one half of the matched pairs. That breaks PEI, which assumes 1051// these will always be in pairs, and asserts if it finds otherwise. Better way? 1052let Defs = [SP], Uses = [SP], hasSideEffects = 1 in { 1053def ADJCALLSTACKUP : 1054PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, 1055 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>; 1056 1057def ADJCALLSTACKDOWN : 1058PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, 1059 [(ARMcallseq_start timm:$amt)]>; 1060} 1061 1062def NOP : AI<(outs), (ins), MiscFrm, NoItinerary, "nop", "", 1063 [/* For disassembly only; pattern left blank */]>, 1064 Requires<[IsARM, HasV6T2]> { 1065 let Inst{27-16} = 0b001100100000; 1066 let Inst{15-8} = 0b11110000; 1067 let Inst{7-0} = 0b00000000; 1068} 1069 1070def YIELD : AI<(outs), (ins), MiscFrm, NoItinerary, "yield", "", 1071 [/* For disassembly only; pattern left blank */]>, 1072 Requires<[IsARM, HasV6T2]> { 1073 let Inst{27-16} = 0b001100100000; 1074 let Inst{15-8} = 0b11110000; 1075 let Inst{7-0} = 0b00000001; 1076} 1077 1078def WFE : AI<(outs), (ins), MiscFrm, NoItinerary, "wfe", "", 1079 [/* For disassembly only; pattern left blank */]>, 1080 Requires<[IsARM, HasV6T2]> { 1081 let Inst{27-16} = 0b001100100000; 1082 let Inst{15-8} = 0b11110000; 1083 let Inst{7-0} = 0b00000010; 1084} 1085 1086def WFI : AI<(outs), (ins), MiscFrm, NoItinerary, "wfi", "", 1087 [/* For disassembly only; pattern left blank */]>, 1088 Requires<[IsARM, HasV6T2]> { 1089 let Inst{27-16} = 0b001100100000; 1090 let Inst{15-8} = 0b11110000; 1091 let Inst{7-0} = 0b00000011; 1092} 1093 1094def SEL : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, NoItinerary, "sel", 1095 "\t$dst, $a, $b", 1096 [/* For disassembly only; pattern left blank */]>, 1097 Requires<[IsARM, HasV6]> { 1098 bits<4> Rd; 1099 bits<4> Rn; 1100 bits<4> Rm; 1101 let Inst{3-0} = Rm; 1102 let Inst{15-12} = Rd; 1103 let Inst{19-16} = Rn; 1104 let Inst{27-20} = 0b01101000; 1105 let Inst{7-4} = 0b1011; 1106 let Inst{11-8} = 0b1111; 1107} 1108 1109def SEV : AI<(outs), (ins), MiscFrm, NoItinerary, "sev", "", 1110 [/* For disassembly only; pattern left blank */]>, 1111 Requires<[IsARM, HasV6T2]> { 1112 let Inst{27-16} = 0b001100100000; 1113 let Inst{15-8} = 0b11110000; 1114 let Inst{7-0} = 0b00000100; 1115} 1116 1117// The i32imm operand $val can be used by a debugger to store more information 1118// about the breakpoint. 1119def BKPT : AI<(outs), (ins i32imm:$val), MiscFrm, NoItinerary, "bkpt", "\t$val", 1120 [/* For disassembly only; pattern left blank */]>, 1121 Requires<[IsARM]> { 1122 bits<16> val; 1123 let Inst{3-0} = val{3-0}; 1124 let Inst{19-8} = val{15-4}; 1125 let Inst{27-20} = 0b00010010; 1126 let Inst{7-4} = 0b0111; 1127} 1128 1129// Change Processor State is a system instruction -- for disassembly and 1130// parsing only. 1131// FIXME: Since the asm parser has currently no clean way to handle optional 1132// operands, create 3 versions of the same instruction. Once there's a clean 1133// framework to represent optional operands, change this behavior. 1134class CPS<dag iops, string asm_ops> 1135 : AXI<(outs), iops, MiscFrm, NoItinerary, !strconcat("cps", asm_ops), 1136 [/* For disassembly only; pattern left blank */]>, Requires<[IsARM]> { 1137 bits<2> imod; 1138 bits<3> iflags; 1139 bits<5> mode; 1140 bit M; 1141 1142 let Inst{31-28} = 0b1111; 1143 let Inst{27-20} = 0b00010000; 1144 let Inst{19-18} = imod; 1145 let Inst{17} = M; // Enabled if mode is set; 1146 let Inst{16} = 0; 1147 let Inst{8-6} = iflags; 1148 let Inst{5} = 0; 1149 let Inst{4-0} = mode; 1150} 1151 1152let M = 1 in 1153 def CPS3p : CPS<(ins imod_op:$imod, iflags_op:$iflags, i32imm:$mode), 1154 "$imod\t$iflags, $mode">; 1155let mode = 0, M = 0 in 1156 def CPS2p : CPS<(ins imod_op:$imod, iflags_op:$iflags), "$imod\t$iflags">; 1157 1158let imod = 0, iflags = 0, M = 1 in 1159 def CPS1p : CPS<(ins i32imm:$mode), "\t$mode">; 1160 1161// Preload signals the memory system of possible future data/instruction access. 1162// These are for disassembly only. 1163multiclass APreLoad<bits<1> read, bits<1> data, string opc> { 1164 1165 def i12 : AXI<(outs), (ins addrmode_imm12:$addr), MiscFrm, IIC_Preload, 1166 !strconcat(opc, "\t$addr"), 1167 [(ARMPreload addrmode_imm12:$addr, (i32 read), (i32 data))]> { 1168 bits<4> Rt; 1169 bits<17> addr; 1170 let Inst{31-26} = 0b111101; 1171 let Inst{25} = 0; // 0 for immediate form 1172 let Inst{24} = data; 1173 let Inst{23} = addr{12}; // U (add = ('U' == 1)) 1174 let Inst{22} = read; 1175 let Inst{21-20} = 0b01; 1176 let Inst{19-16} = addr{16-13}; // Rn 1177 let Inst{15-12} = 0b1111; 1178 let Inst{11-0} = addr{11-0}; // imm12 1179 } 1180 1181 def rs : AXI<(outs), (ins ldst_so_reg:$shift), MiscFrm, IIC_Preload, 1182 !strconcat(opc, "\t$shift"), 1183 [(ARMPreload ldst_so_reg:$shift, (i32 read), (i32 data))]> { 1184 bits<17> shift; 1185 let Inst{31-26} = 0b111101; 1186 let Inst{25} = 1; // 1 for register form 1187 let Inst{24} = data; 1188 let Inst{23} = shift{12}; // U (add = ('U' == 1)) 1189 let Inst{22} = read; 1190 let Inst{21-20} = 0b01; 1191 let Inst{19-16} = shift{16-13}; // Rn 1192 let Inst{15-12} = 0b1111; 1193 let Inst{11-0} = shift{11-0}; 1194 } 1195} 1196 1197defm PLD : APreLoad<1, 1, "pld">, Requires<[IsARM]>; 1198defm PLDW : APreLoad<0, 1, "pldw">, Requires<[IsARM,HasV7,HasMP]>; 1199defm PLI : APreLoad<1, 0, "pli">, Requires<[IsARM,HasV7]>; 1200 1201def SETEND : AXI<(outs),(ins setend_op:$end), MiscFrm, NoItinerary, 1202 "setend\t$end", 1203 [/* For disassembly only; pattern left blank */]>, 1204 Requires<[IsARM]> { 1205 bits<1> end; 1206 let Inst{31-10} = 0b1111000100000001000000; 1207 let Inst{9} = end; 1208 let Inst{8-0} = 0; 1209} 1210 1211def DBG : AI<(outs), (ins i32imm:$opt), MiscFrm, NoItinerary, "dbg", "\t$opt", 1212 [/* For disassembly only; pattern left blank */]>, 1213 Requires<[IsARM, HasV7]> { 1214 bits<4> opt; 1215 let Inst{27-4} = 0b001100100000111100001111; 1216 let Inst{3-0} = opt; 1217} 1218 1219// A5.4 Permanently UNDEFINED instructions. 1220let isBarrier = 1, isTerminator = 1 in 1221def TRAP : AXI<(outs), (ins), MiscFrm, NoItinerary, 1222 "trap", [(trap)]>, 1223 Requires<[IsARM]> { 1224 let Inst = 0xe7ffdefe; 1225} 1226 1227// Address computation and loads and stores in PIC mode. 1228let isNotDuplicable = 1 in { 1229def PICADD : ARMPseudoInst<(outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p), 1230 Size4Bytes, IIC_iALUr, 1231 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>; 1232 1233let AddedComplexity = 10 in { 1234def PICLDR : ARMPseudoInst<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 1235 Size4Bytes, IIC_iLoad_r, 1236 [(set GPR:$dst, (load addrmodepc:$addr))]>; 1237 1238def PICLDRH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 1239 Size4Bytes, IIC_iLoad_bh_r, 1240 [(set GPR:$Rt, (zextloadi16 addrmodepc:$addr))]>; 1241 1242def PICLDRB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 1243 Size4Bytes, IIC_iLoad_bh_r, 1244 [(set GPR:$Rt, (zextloadi8 addrmodepc:$addr))]>; 1245 1246def PICLDRSH : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 1247 Size4Bytes, IIC_iLoad_bh_r, 1248 [(set GPR:$Rt, (sextloadi16 addrmodepc:$addr))]>; 1249 1250def PICLDRSB : ARMPseudoInst<(outs GPR:$Rt), (ins addrmodepc:$addr, pred:$p), 1251 Size4Bytes, IIC_iLoad_bh_r, 1252 [(set GPR:$Rt, (sextloadi8 addrmodepc:$addr))]>; 1253} 1254let AddedComplexity = 10 in { 1255def PICSTR : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 1256 Size4Bytes, IIC_iStore_r, [(store GPR:$src, addrmodepc:$addr)]>; 1257 1258def PICSTRH : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 1259 Size4Bytes, IIC_iStore_bh_r, [(truncstorei16 GPR:$src, 1260 addrmodepc:$addr)]>; 1261 1262def PICSTRB : ARMPseudoInst<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 1263 Size4Bytes, IIC_iStore_bh_r, [(truncstorei8 GPR:$src, addrmodepc:$addr)]>; 1264} 1265} // isNotDuplicable = 1 1266 1267 1268// LEApcrel - Load a pc-relative address into a register without offending the 1269// assembler. 1270let neverHasSideEffects = 1, isReMaterializable = 1 in 1271// The 'adr' mnemonic encodes differently if the label is before or after 1272// the instruction. The {24-21} opcode bits are set by the fixup, as we don't 1273// know until then which form of the instruction will be used. 1274def ADR : AI1<{0,?,?,0}, (outs GPR:$Rd), (ins adrlabel:$label), 1275 MiscFrm, IIC_iALUi, "adr", "\t$Rd, #$label", []> { 1276 bits<4> Rd; 1277 bits<12> label; 1278 let Inst{27-25} = 0b001; 1279 let Inst{20} = 0; 1280 let Inst{19-16} = 0b1111; 1281 let Inst{15-12} = Rd; 1282 let Inst{11-0} = label; 1283} 1284def LEApcrel : ARMPseudoInst<(outs GPR:$Rd), (ins i32imm:$label, pred:$p), 1285 Size4Bytes, IIC_iALUi, []>; 1286 1287def LEApcrelJT : ARMPseudoInst<(outs GPR:$Rd), 1288 (ins i32imm:$label, nohash_imm:$id, pred:$p), 1289 Size4Bytes, IIC_iALUi, []>; 1290 1291//===----------------------------------------------------------------------===// 1292// Control Flow Instructions. 1293// 1294 1295let isReturn = 1, isTerminator = 1, isBarrier = 1 in { 1296 // ARMV4T and above 1297 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 1298 "bx", "\tlr", [(ARMretflag)]>, 1299 Requires<[IsARM, HasV4T]> { 1300 let Inst{27-0} = 0b0001001011111111111100011110; 1301 } 1302 1303 // ARMV4 only 1304 def MOVPCLR : AI<(outs), (ins), BrMiscFrm, IIC_Br, 1305 "mov", "\tpc, lr", [(ARMretflag)]>, 1306 Requires<[IsARM, NoV4T]> { 1307 let Inst{27-0} = 0b0001101000001111000000001110; 1308 } 1309} 1310 1311// Indirect branches 1312let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 1313 // ARMV4T and above 1314 def BX : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst", 1315 [(brind GPR:$dst)]>, 1316 Requires<[IsARM, HasV4T]> { 1317 bits<4> dst; 1318 let Inst{31-4} = 0b1110000100101111111111110001; 1319 let Inst{3-0} = dst; 1320 } 1321 1322 // For disassembly only. 1323 def BX_pred : AXI<(outs), (ins GPR:$dst, pred:$p), BrMiscFrm, IIC_Br, 1324 "bx$p\t$dst", [/* pattern left blank */]>, 1325 Requires<[IsARM, HasV4T]> { 1326 bits<4> dst; 1327 let Inst{27-4} = 0b000100101111111111110001; 1328 let Inst{3-0} = dst; 1329 } 1330 1331 // ARMV4 only 1332 // FIXME: We would really like to define this as a vanilla ARMPat like: 1333 // ARMPat<(brind GPR:$dst), (MOVr PC, GPR:$dst)> 1334 // With that, however, we can't set isBranch, isTerminator, etc.. 1335 def MOVPCRX : ARMPseudoInst<(outs), (ins GPR:$dst), 1336 Size4Bytes, IIC_Br, [(brind GPR:$dst)]>, 1337 Requires<[IsARM, NoV4T]>; 1338} 1339 1340// All calls clobber the non-callee saved registers. SP is marked as 1341// a use to prevent stack-pointer assignments that appear immediately 1342// before calls from potentially appearing dead. 1343let isCall = 1, 1344 // On non-Darwin platforms R9 is callee-saved. 1345 // FIXME: Do we really need a non-predicated version? If so, it should 1346 // at least be a pseudo instruction expanding to the predicated version 1347 // at MC lowering time. 1348 Defs = [R0, R1, R2, R3, R12, LR, QQQQ0, QQQQ2, QQQQ3, CPSR, FPSCR], 1349 Uses = [SP] in { 1350 def BL : ABXI<0b1011, (outs), (ins bl_target:$func, variable_ops), 1351 IIC_Br, "bl\t$func", 1352 [(ARMcall tglobaladdr:$func)]>, 1353 Requires<[IsARM, IsNotDarwin]> { 1354 let Inst{31-28} = 0b1110; 1355 bits<24> func; 1356 let Inst{23-0} = func; 1357 } 1358 1359 def BL_pred : ABI<0b1011, (outs), (ins bl_target:$func, variable_ops), 1360 IIC_Br, "bl", "\t$func", 1361 [(ARMcall_pred tglobaladdr:$func)]>, 1362 Requires<[IsARM, IsNotDarwin]> { 1363 bits<24> func; 1364 let Inst{23-0} = func; 1365 } 1366 1367 // ARMv5T and above 1368 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm, 1369 IIC_Br, "blx\t$func", 1370 [(ARMcall GPR:$func)]>, 1371 Requires<[IsARM, HasV5T, IsNotDarwin]> { 1372 bits<4> func; 1373 let Inst{31-4} = 0b1110000100101111111111110011; 1374 let Inst{3-0} = func; 1375 } 1376 1377 def BLX_pred : AI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm, 1378 IIC_Br, "blx", "\t$func", 1379 [(ARMcall_pred GPR:$func)]>, 1380 Requires<[IsARM, HasV5T, IsNotDarwin]> { 1381 bits<4> func; 1382 let Inst{27-4} = 0b000100101111111111110011; 1383 let Inst{3-0} = func; 1384 } 1385 1386 // ARMv4T 1387 // Note: Restrict $func to the tGPR regclass to prevent it being in LR. 1388 def BX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops), 1389 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, 1390 Requires<[IsARM, HasV4T, IsNotDarwin]>; 1391 1392 // ARMv4 1393 def BMOVPCRX_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops), 1394 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, 1395 Requires<[IsARM, NoV4T, IsNotDarwin]>; 1396} 1397 1398let isCall = 1, 1399 // On Darwin R9 is call-clobbered. 1400 // R7 is marked as a use to prevent frame-pointer assignments from being 1401 // moved above / below calls. 1402 Defs = [R0, R1, R2, R3, R9, R12, LR, QQQQ0, QQQQ2, QQQQ3, CPSR, FPSCR], 1403 Uses = [R7, SP] in { 1404 def BLr9 : ARMPseudoInst<(outs), (ins bltarget:$func, variable_ops), 1405 Size4Bytes, IIC_Br, 1406 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]>; 1407 1408 def BLr9_pred : ARMPseudoInst<(outs), 1409 (ins bltarget:$func, pred:$p, variable_ops), 1410 Size4Bytes, IIC_Br, 1411 [(ARMcall_pred tglobaladdr:$func)]>, 1412 Requires<[IsARM, IsDarwin]>; 1413 1414 // ARMv5T and above 1415 def BLXr9 : ARMPseudoInst<(outs), (ins GPR:$func, variable_ops), 1416 Size4Bytes, IIC_Br, 1417 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]>; 1418 1419 def BLXr9_pred: ARMPseudoInst<(outs), (ins GPR:$func, pred:$p, variable_ops), 1420 Size4Bytes, IIC_Br, 1421 [(ARMcall_pred GPR:$func)]>, 1422 Requires<[IsARM, HasV5T, IsDarwin]>; 1423 1424 // ARMv4T 1425 // Note: Restrict $func to the tGPR regclass to prevent it being in LR. 1426 def BXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops), 1427 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, 1428 Requires<[IsARM, HasV4T, IsDarwin]>; 1429 1430 // ARMv4 1431 def BMOVPCRXr9_CALL : ARMPseudoInst<(outs), (ins tGPR:$func, variable_ops), 1432 Size8Bytes, IIC_Br, [(ARMcall_nolink tGPR:$func)]>, 1433 Requires<[IsARM, NoV4T, IsDarwin]>; 1434} 1435 1436// Tail calls. 1437 1438// FIXME: The Thumb versions of these should live in ARMInstrThumb.td 1439let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in { 1440 // Darwin versions. 1441 let Defs = [R0, R1, R2, R3, R9, R12, QQQQ0, QQQQ2, QQQQ3, PC], 1442 Uses = [SP] in { 1443 def TCRETURNdi : PseudoInst<(outs), (ins i32imm:$dst, variable_ops), 1444 IIC_Br, []>, Requires<[IsDarwin]>; 1445 1446 def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops), 1447 IIC_Br, []>, Requires<[IsDarwin]>; 1448 1449 def TAILJMPd : ARMPseudoInst<(outs), (ins brtarget:$dst, variable_ops), 1450 Size4Bytes, IIC_Br, 1451 []>, Requires<[IsARM, IsDarwin]>; 1452 1453 def tTAILJMPd: tPseudoInst<(outs), (ins brtarget:$dst, variable_ops), 1454 Size4Bytes, IIC_Br, 1455 []>, Requires<[IsThumb, IsDarwin]>; 1456 1457 def TAILJMPr : ARMPseudoInst<(outs), (ins tcGPR:$dst, variable_ops), 1458 Size4Bytes, IIC_Br, 1459 []>, Requires<[IsARM, IsDarwin]>; 1460 1461 def tTAILJMPr : tPseudoInst<(outs), (ins tcGPR:$dst, variable_ops), 1462 Size4Bytes, IIC_Br, 1463 []>, Requires<[IsThumb, IsDarwin]>; 1464 } 1465 1466 // Non-Darwin versions (the difference is R9). 1467 let Defs = [R0, R1, R2, R3, R12, QQQQ0, QQQQ2, QQQQ3, PC], 1468 Uses = [SP] in { 1469 def TCRETURNdiND : PseudoInst<(outs), (ins i32imm:$dst, variable_ops), 1470 IIC_Br, []>, Requires<[IsNotDarwin]>; 1471 1472 def TCRETURNriND : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops), 1473 IIC_Br, []>, Requires<[IsNotDarwin]>; 1474 1475 def TAILJMPdND : ARMPseudoInst<(outs), (ins brtarget:$dst, variable_ops), 1476 Size4Bytes, IIC_Br, 1477 []>, Requires<[IsARM, IsNotDarwin]>; 1478 1479 def tTAILJMPdND : tPseudoInst<(outs), (ins brtarget:$dst, variable_ops), 1480 Size4Bytes, IIC_Br, 1481 []>, Requires<[IsThumb, IsNotDarwin]>; 1482 1483 def TAILJMPrND : ARMPseudoInst<(outs), (ins tcGPR:$dst, variable_ops), 1484 Size4Bytes, IIC_Br, 1485 []>, Requires<[IsARM, IsNotDarwin]>; 1486 def tTAILJMPrND : tPseudoInst<(outs), (ins tcGPR:$dst, variable_ops), 1487 Size4Bytes, IIC_Br, 1488 []>, Requires<[IsThumb, IsNotDarwin]>; 1489 } 1490} 1491 1492let isBranch = 1, isTerminator = 1 in { 1493 // B is "predicable" since it's just a Bcc with an 'always' condition. 1494 let isBarrier = 1 in { 1495 let isPredicable = 1 in 1496 // FIXME: We shouldn't need this pseudo at all. Just using Bcc directly 1497 // should be sufficient. 1498 def B : ARMPseudoInst<(outs), (ins brtarget:$target), Size4Bytes, IIC_Br, 1499 [(br bb:$target)]>; 1500 1501 let isNotDuplicable = 1, isIndirectBranch = 1 in { 1502 def BR_JTr : ARMPseudoInst<(outs), 1503 (ins GPR:$target, i32imm:$jt, i32imm:$id), 1504 SizeSpecial, IIC_Br, 1505 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>; 1506 // FIXME: This shouldn't use the generic "addrmode2," but rather be split 1507 // into i12 and rs suffixed versions. 1508 def BR_JTm : ARMPseudoInst<(outs), 1509 (ins addrmode2:$target, i32imm:$jt, i32imm:$id), 1510 SizeSpecial, IIC_Br, 1511 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt, 1512 imm:$id)]>; 1513 def BR_JTadd : ARMPseudoInst<(outs), 1514 (ins GPR:$target, GPR:$idx, i32imm:$jt, i32imm:$id), 1515 SizeSpecial, IIC_Br, 1516 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, 1517 imm:$id)]>; 1518 } // isNotDuplicable = 1, isIndirectBranch = 1 1519 } // isBarrier = 1 1520 1521 // FIXME: should be able to write a pattern for ARMBrcond, but can't use 1522 // a two-value operand where a dag node expects two operands. :( 1523 def Bcc : ABI<0b1010, (outs), (ins br_target:$target), 1524 IIC_Br, "b", "\t$target", 1525 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]> { 1526 bits<24> target; 1527 let Inst{23-0} = target; 1528 } 1529} 1530 1531// BLX (immediate) -- for disassembly only 1532def BLXi : AXI<(outs), (ins br_target:$target), BrMiscFrm, NoItinerary, 1533 "blx\t$target", [/* pattern left blank */]>, 1534 Requires<[IsARM, HasV5T]> { 1535 let Inst{31-25} = 0b1111101; 1536 bits<25> target; 1537 let Inst{23-0} = target{24-1}; 1538 let Inst{24} = target{0}; 1539} 1540 1541// Branch and Exchange Jazelle -- for disassembly only 1542def BXJ : ABI<0b0001, (outs), (ins GPR:$func), NoItinerary, "bxj", "\t$func", 1543 [/* For disassembly only; pattern left blank */]> { 1544 let Inst{23-20} = 0b0010; 1545 //let Inst{19-8} = 0xfff; 1546 let Inst{7-4} = 0b0010; 1547} 1548 1549// Secure Monitor Call is a system instruction -- for disassembly only 1550def SMC : ABI<0b0001, (outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt", 1551 [/* For disassembly only; pattern left blank */]> { 1552 bits<4> opt; 1553 let Inst{23-4} = 0b01100000000000000111; 1554 let Inst{3-0} = opt; 1555} 1556 1557// Supervisor Call (Software Interrupt) -- for disassembly only 1558let isCall = 1, Uses = [SP] in { 1559def SVC : ABI<0b1111, (outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc", 1560 [/* For disassembly only; pattern left blank */]> { 1561 bits<24> svc; 1562 let Inst{23-0} = svc; 1563} 1564} 1565def : MnemonicAlias<"swi", "svc">; 1566 1567// Store Return State is a system instruction -- for disassembly only 1568let isCodeGenOnly = 1 in { // FIXME: This should not use submode! 1569def SRSW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode), 1570 NoItinerary, "srs${amode}\tsp!, $mode", 1571 [/* For disassembly only; pattern left blank */]> { 1572 let Inst{31-28} = 0b1111; 1573 let Inst{22-20} = 0b110; // W = 1 1574 let Inst{19-8} = 0xd05; 1575 let Inst{7-5} = 0b000; 1576} 1577 1578def SRS : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, i32imm:$mode), 1579 NoItinerary, "srs${amode}\tsp, $mode", 1580 [/* For disassembly only; pattern left blank */]> { 1581 let Inst{31-28} = 0b1111; 1582 let Inst{22-20} = 0b100; // W = 0 1583 let Inst{19-8} = 0xd05; 1584 let Inst{7-5} = 0b000; 1585} 1586 1587// Return From Exception is a system instruction -- for disassembly only 1588def RFEW : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base), 1589 NoItinerary, "rfe${amode}\t$base!", 1590 [/* For disassembly only; pattern left blank */]> { 1591 let Inst{31-28} = 0b1111; 1592 let Inst{22-20} = 0b011; // W = 1 1593 let Inst{15-0} = 0x0a00; 1594} 1595 1596def RFE : ABXI<{1,0,0,?}, (outs), (ins ldstm_mode:$amode, GPR:$base), 1597 NoItinerary, "rfe${amode}\t$base", 1598 [/* For disassembly only; pattern left blank */]> { 1599 let Inst{31-28} = 0b1111; 1600 let Inst{22-20} = 0b001; // W = 0 1601 let Inst{15-0} = 0x0a00; 1602} 1603} // isCodeGenOnly = 1 1604 1605//===----------------------------------------------------------------------===// 1606// Load / store Instructions. 1607// 1608 1609// Load 1610 1611 1612defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_r, IIC_iLoad_si, 1613 UnOpFrag<(load node:$Src)>>; 1614defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_r, IIC_iLoad_bh_si, 1615 UnOpFrag<(zextloadi8 node:$Src)>>; 1616defm STR : AI_str1<0, "str", IIC_iStore_r, IIC_iStore_si, 1617 BinOpFrag<(store node:$LHS, node:$RHS)>>; 1618defm STRB : AI_str1<1, "strb", IIC_iStore_bh_r, IIC_iStore_bh_si, 1619 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>; 1620 1621// Special LDR for loads from non-pc-relative constpools. 1622let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1, 1623 isReMaterializable = 1 in 1624def LDRcp : AI2ldst<0b010, 1, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr), 1625 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr", 1626 []> { 1627 bits<4> Rt; 1628 bits<17> addr; 1629 let Inst{23} = addr{12}; // U (add = ('U' == 1)) 1630 let Inst{19-16} = 0b1111; 1631 let Inst{15-12} = Rt; 1632 let Inst{11-0} = addr{11-0}; // imm12 1633} 1634 1635// Loads with zero extension 1636def LDRH : AI3ld<0b1011, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm, 1637 IIC_iLoad_bh_r, "ldrh", "\t$Rt, $addr", 1638 [(set GPR:$Rt, (zextloadi16 addrmode3:$addr))]>; 1639 1640// Loads with sign extension 1641def LDRSH : AI3ld<0b1111, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm, 1642 IIC_iLoad_bh_r, "ldrsh", "\t$Rt, $addr", 1643 [(set GPR:$Rt, (sextloadi16 addrmode3:$addr))]>; 1644 1645def LDRSB : AI3ld<0b1101, 1, (outs GPR:$Rt), (ins addrmode3:$addr), LdMiscFrm, 1646 IIC_iLoad_bh_r, "ldrsb", "\t$Rt, $addr", 1647 [(set GPR:$Rt, (sextloadi8 addrmode3:$addr))]>; 1648 1649let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in { 1650// Load doubleword 1651def LDRD : AI3ld<0b1101, 0, (outs GPR:$Rd, GPR:$dst2), 1652 (ins addrmode3:$addr), LdMiscFrm, 1653 IIC_iLoad_d_r, "ldrd", "\t$Rd, $dst2, $addr", 1654 []>, Requires<[IsARM, HasV5TE]>; 1655} 1656 1657// Indexed loads 1658multiclass AI2_ldridx<bit isByte, string opc, InstrItinClass itin> { 1659 def _PRE : AI2ldstidx<1, isByte, 1, (outs GPR:$Rt, GPR:$Rn_wb), 1660 (ins addrmode2:$addr), IndexModePre, LdFrm, itin, 1661 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 1662 // {17-14} Rn 1663 // {13} 1 == Rm, 0 == imm12 1664 // {12} isAdd 1665 // {11-0} imm12/Rm 1666 bits<18> addr; 1667 let Inst{25} = addr{13}; 1668 let Inst{23} = addr{12}; 1669 let Inst{19-16} = addr{17-14}; 1670 let Inst{11-0} = addr{11-0}; 1671 let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; 1672 } 1673 def _POST : AI2ldstidx<1, isByte, 0, (outs GPR:$Rt, GPR:$Rn_wb), 1674 (ins GPR:$Rn, am2offset:$offset), 1675 IndexModePost, LdFrm, itin, 1676 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> { 1677 // {13} 1 == Rm, 0 == imm12 1678 // {12} isAdd 1679 // {11-0} imm12/Rm 1680 bits<14> offset; 1681 bits<4> Rn; 1682 let Inst{25} = offset{13}; 1683 let Inst{23} = offset{12}; 1684 let Inst{19-16} = Rn; 1685 let Inst{11-0} = offset{11-0}; 1686 } 1687} 1688 1689let mayLoad = 1, neverHasSideEffects = 1 in { 1690defm LDR : AI2_ldridx<0, "ldr", IIC_iLoad_ru>; 1691defm LDRB : AI2_ldridx<1, "ldrb", IIC_iLoad_bh_ru>; 1692} 1693 1694multiclass AI3_ldridx<bits<4> op, bit op20, string opc, InstrItinClass itin> { 1695 def _PRE : AI3ldstidx<op, op20, 1, 1, (outs GPR:$Rt, GPR:$Rn_wb), 1696 (ins addrmode3:$addr), IndexModePre, 1697 LdMiscFrm, itin, 1698 opc, "\t$Rt, $addr!", "$addr.base = $Rn_wb", []> { 1699 bits<14> addr; 1700 let Inst{23} = addr{8}; // U bit 1701 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 1702 let Inst{19-16} = addr{12-9}; // Rn 1703 let Inst{11-8} = addr{7-4}; // imm7_4/zero 1704 let Inst{3-0} = addr{3-0}; // imm3_0/Rm 1705 } 1706 def _POST : AI3ldstidx<op, op20, 1, 0, (outs GPR:$Rt, GPR:$Rn_wb), 1707 (ins GPR:$Rn, am3offset:$offset), IndexModePost, 1708 LdMiscFrm, itin, 1709 opc, "\t$Rt, [$Rn], $offset", "$Rn = $Rn_wb", []> { 1710 bits<10> offset; 1711 bits<4> Rn; 1712 let Inst{23} = offset{8}; // U bit 1713 let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm 1714 let Inst{19-16} = Rn; 1715 let Inst{11-8} = offset{7-4}; // imm7_4/zero 1716 let Inst{3-0} = offset{3-0}; // imm3_0/Rm 1717 } 1718} 1719 1720let mayLoad = 1, neverHasSideEffects = 1 in { 1721defm LDRH : AI3_ldridx<0b1011, 1, "ldrh", IIC_iLoad_bh_ru>; 1722defm LDRSH : AI3_ldridx<0b1111, 1, "ldrsh", IIC_iLoad_bh_ru>; 1723defm LDRSB : AI3_ldridx<0b1101, 1, "ldrsb", IIC_iLoad_bh_ru>; 1724let hasExtraDefRegAllocReq = 1 in { 1725def LDRD_PRE : AI3ldstidx<0b1101, 0, 1, 1, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), 1726 (ins addrmode3:$addr), IndexModePre, 1727 LdMiscFrm, IIC_iLoad_d_ru, 1728 "ldrd", "\t$Rt, $Rt2, $addr!", 1729 "$addr.base = $Rn_wb", []> { 1730 bits<14> addr; 1731 let Inst{23} = addr{8}; // U bit 1732 let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm 1733 let Inst{19-16} = addr{12-9}; // Rn 1734 let Inst{11-8} = addr{7-4}; // imm7_4/zero 1735 let Inst{3-0} = addr{3-0}; // imm3_0/Rm 1736} 1737def LDRD_POST: AI3ldstidx<0b1101, 0, 1, 0, (outs GPR:$Rt, GPR:$Rt2, GPR:$Rn_wb), 1738 (ins GPR:$Rn, am3offset:$offset), IndexModePost, 1739 LdMiscFrm, IIC_iLoad_d_ru, 1740 "ldrd", "\t$Rt, $Rt2, [$Rn], $offset", 1741 "$Rn = $Rn_wb", []> { 1742 bits<10> offset; 1743 bits<4> Rn; 1744 let Inst{23} = offset{8}; // U bit 1745 let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm 1746 let Inst{19-16} = Rn; 1747 let Inst{11-8} = offset{7-4}; // imm7_4/zero 1748 let Inst{3-0} = offset{3-0}; // imm3_0/Rm 1749} 1750} // hasExtraDefRegAllocReq = 1 1751} // mayLoad = 1, neverHasSideEffects = 1 1752 1753// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only. 1754let mayLoad = 1, neverHasSideEffects = 1 in { 1755def LDRT : AI2ldstidx<1, 0, 0, (outs GPR:$Rt, GPR:$base_wb), 1756 (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_ru, 1757 "ldrt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { 1758 // {17-14} Rn 1759 // {13} 1 == Rm, 0 == imm12 1760 // {12} isAdd 1761 // {11-0} imm12/Rm 1762 bits<18> addr; 1763 let Inst{25} = addr{13}; 1764 let Inst{23} = addr{12}; 1765 let Inst{21} = 1; // overwrite 1766 let Inst{19-16} = addr{17-14}; 1767 let Inst{11-0} = addr{11-0}; 1768 let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; 1769} 1770def LDRBT : AI2ldstidx<1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), 1771 (ins addrmode2:$addr), IndexModePost, LdFrm, IIC_iLoad_bh_ru, 1772 "ldrbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { 1773 // {17-14} Rn 1774 // {13} 1 == Rm, 0 == imm12 1775 // {12} isAdd 1776 // {11-0} imm12/Rm 1777 bits<18> addr; 1778 let Inst{25} = addr{13}; 1779 let Inst{23} = addr{12}; 1780 let Inst{21} = 1; // overwrite 1781 let Inst{19-16} = addr{17-14}; 1782 let Inst{11-0} = addr{11-0}; 1783 let AsmMatchConverter = "CvtLdWriteBackRegAddrMode2"; 1784} 1785def LDRSBT : AI3ldstidxT<0b1101, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), 1786 (ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, 1787 "ldrsbt", "\t$Rt, $addr", "$addr.base = $base_wb", []> { 1788 let Inst{21} = 1; // overwrite 1789} 1790def LDRHT : AI3ldstidxT<0b1011, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), 1791 (ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, 1792 "ldrht", "\t$Rt, $addr", "$addr.base = $base_wb", []> { 1793 let Inst{21} = 1; // overwrite 1794} 1795def LDRSHT : AI3ldstidxT<0b1111, 1, 1, 0, (outs GPR:$Rt, GPR:$base_wb), 1796 (ins addrmode3:$addr), IndexModePost, LdMiscFrm, IIC_iLoad_bh_ru, 1797 "ldrsht", "\t$Rt, $addr", "$addr.base = $base_wb", []> { 1798 let Inst{21} = 1; // overwrite 1799} 1800} 1801 1802// Store 1803 1804// Stores with truncate 1805def STRH : AI3str<0b1011, (outs), (ins GPR:$Rt, addrmode3:$addr), StMiscFrm, 1806 IIC_iStore_bh_r, "strh", "\t$Rt, $addr", 1807 [(truncstorei16 GPR:$Rt, addrmode3:$addr)]>; 1808 1809// Store doubleword 1810let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in 1811def STRD : AI3str<0b1111, (outs), (ins GPR:$Rt, GPR:$src2, addrmode3:$addr), 1812 StMiscFrm, IIC_iStore_d_r, 1813 "strd", "\t$Rt, $src2, $addr", []>, Requires<[IsARM, HasV5TE]>; 1814 1815// Indexed stores 1816def STR_PRE : AI2stridx<0, 1, (outs GPR:$Rn_wb), 1817 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), 1818 IndexModePre, StFrm, IIC_iStore_ru, 1819 "str", "\t$Rt, [$Rn, $offset]!", 1820 "$Rn = $Rn_wb,@earlyclobber $Rn_wb", 1821 [(set GPR:$Rn_wb, 1822 (pre_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>; 1823 1824def STR_POST : AI2stridx<0, 0, (outs GPR:$Rn_wb), 1825 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), 1826 IndexModePost, StFrm, IIC_iStore_ru, 1827 "str", "\t$Rt, [$Rn], $offset", 1828 "$Rn = $Rn_wb,@earlyclobber $Rn_wb", 1829 [(set GPR:$Rn_wb, 1830 (post_store GPR:$Rt, GPR:$Rn, am2offset:$offset))]>; 1831 1832def STRB_PRE : AI2stridx<1, 1, (outs GPR:$Rn_wb), 1833 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), 1834 IndexModePre, StFrm, IIC_iStore_bh_ru, 1835 "strb", "\t$Rt, [$Rn, $offset]!", 1836 "$Rn = $Rn_wb,@earlyclobber $Rn_wb", 1837 [(set GPR:$Rn_wb, (pre_truncsti8 GPR:$Rt, 1838 GPR:$Rn, am2offset:$offset))]>; 1839def STRB_POST: AI2stridx<1, 0, (outs GPR:$Rn_wb), 1840 (ins GPR:$Rt, GPR:$Rn, am2offset:$offset), 1841 IndexModePost, StFrm, IIC_iStore_bh_ru, 1842 "strb", "\t$Rt, [$Rn], $offset", 1843 "$Rn = $Rn_wb,@earlyclobber $Rn_wb", 1844 [(set GPR:$Rn_wb, (post_truncsti8 GPR:$Rt, 1845 GPR:$Rn, am2offset:$offset))]>; 1846 1847def STRH_PRE : AI3stridx<0b1011, 0, 1, (outs GPR:$Rn_wb), 1848 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset), 1849 IndexModePre, StMiscFrm, IIC_iStore_ru, 1850 "strh", "\t$Rt, [$Rn, $offset]!", 1851 "$Rn = $Rn_wb,@earlyclobber $Rn_wb", 1852 [(set GPR:$Rn_wb, 1853 (pre_truncsti16 GPR:$Rt, GPR:$Rn, am3offset:$offset))]>; 1854 1855def STRH_POST: AI3stridx<0b1011, 0, 0, (outs GPR:$Rn_wb), 1856 (ins GPR:$Rt, GPR:$Rn, am3offset:$offset), 1857 IndexModePost, StMiscFrm, IIC_iStore_bh_ru, 1858 "strh", "\t$Rt, [$Rn], $offset", 1859 "$Rn = $Rn_wb,@earlyclobber $Rn_wb", 1860 [(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt, 1861 GPR:$Rn, am3offset:$offset))]>; 1862 1863// For disassembly only 1864let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in { 1865def STRD_PRE : AI3stdpr<(outs GPR:$base_wb), 1866 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset), 1867 StMiscFrm, IIC_iStore_d_ru, 1868 "strd", "\t$src1, $src2, [$base, $offset]!", 1869 "$base = $base_wb", []>; 1870 1871// For disassembly only 1872def STRD_POST: AI3stdpo<(outs GPR:$base_wb), 1873 (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset), 1874 StMiscFrm, IIC_iStore_d_ru, 1875 "strd", "\t$src1, $src2, [$base], $offset", 1876 "$base = $base_wb", []>; 1877} // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 1878 1879// STRT, STRBT, and STRHT are for disassembly only. 1880 1881def STRT : AI2stridxT<0, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), 1882 IndexModePost, StFrm, IIC_iStore_ru, 1883 "strt", "\t$Rt, $addr", "$addr.base = $Rn_wb", 1884 [/* For disassembly only; pattern left blank */]> { 1885 let Inst{21} = 1; // overwrite 1886 let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; 1887} 1888 1889def STRBT : AI2stridxT<1, 0, (outs GPR:$Rn_wb), (ins GPR:$Rt, addrmode2:$addr), 1890 IndexModePost, StFrm, IIC_iStore_bh_ru, 1891 "strbt", "\t$Rt, $addr", "$addr.base = $Rn_wb", 1892 [/* For disassembly only; pattern left blank */]> { 1893 let Inst{21} = 1; // overwrite 1894 let AsmMatchConverter = "CvtStWriteBackRegAddrMode2"; 1895} 1896 1897def STRHT: AI3sthpo<(outs GPR:$base_wb), (ins GPR:$Rt, addrmode3:$addr), 1898 StMiscFrm, IIC_iStore_bh_ru, 1899 "strht", "\t$Rt, $addr", "$addr.base = $base_wb", 1900 [/* For disassembly only; pattern left blank */]> { 1901 let Inst{21} = 1; // overwrite 1902 let AsmMatchConverter = "CvtStWriteBackRegAddrMode3"; 1903} 1904 1905//===----------------------------------------------------------------------===// 1906// Load / store multiple Instructions. 1907// 1908 1909multiclass arm_ldst_mult<string asm, bit L_bit, Format f, 1910 InstrItinClass itin, InstrItinClass itin_upd> { 1911 def IA : 1912 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1913 IndexModeNone, f, itin, 1914 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> { 1915 let Inst{24-23} = 0b01; // Increment After 1916 let Inst{21} = 0; // No writeback 1917 let Inst{20} = L_bit; 1918 } 1919 def IA_UPD : 1920 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1921 IndexModeUpd, f, itin_upd, 1922 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 1923 let Inst{24-23} = 0b01; // Increment After 1924 let Inst{21} = 1; // Writeback 1925 let Inst{20} = L_bit; 1926 } 1927 def DA : 1928 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1929 IndexModeNone, f, itin, 1930 !strconcat(asm, "da${p}\t$Rn, $regs"), "", []> { 1931 let Inst{24-23} = 0b00; // Decrement After 1932 let Inst{21} = 0; // No writeback 1933 let Inst{20} = L_bit; 1934 } 1935 def DA_UPD : 1936 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1937 IndexModeUpd, f, itin_upd, 1938 !strconcat(asm, "da${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 1939 let Inst{24-23} = 0b00; // Decrement After 1940 let Inst{21} = 1; // Writeback 1941 let Inst{20} = L_bit; 1942 } 1943 def DB : 1944 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1945 IndexModeNone, f, itin, 1946 !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> { 1947 let Inst{24-23} = 0b10; // Decrement Before 1948 let Inst{21} = 0; // No writeback 1949 let Inst{20} = L_bit; 1950 } 1951 def DB_UPD : 1952 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1953 IndexModeUpd, f, itin_upd, 1954 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 1955 let Inst{24-23} = 0b10; // Decrement Before 1956 let Inst{21} = 1; // Writeback 1957 let Inst{20} = L_bit; 1958 } 1959 def IB : 1960 AXI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1961 IndexModeNone, f, itin, 1962 !strconcat(asm, "ib${p}\t$Rn, $regs"), "", []> { 1963 let Inst{24-23} = 0b11; // Increment Before 1964 let Inst{21} = 0; // No writeback 1965 let Inst{20} = L_bit; 1966 } 1967 def IB_UPD : 1968 AXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops), 1969 IndexModeUpd, f, itin_upd, 1970 !strconcat(asm, "ib${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 1971 let Inst{24-23} = 0b11; // Increment Before 1972 let Inst{21} = 1; // Writeback 1973 let Inst{20} = L_bit; 1974 } 1975} 1976 1977let neverHasSideEffects = 1 in { 1978 1979let mayLoad = 1, hasExtraDefRegAllocReq = 1 in 1980defm LDM : arm_ldst_mult<"ldm", 1, LdStMulFrm, IIC_iLoad_m, IIC_iLoad_mu>; 1981 1982let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 1983defm STM : arm_ldst_mult<"stm", 0, LdStMulFrm, IIC_iStore_m, IIC_iStore_mu>; 1984 1985} // neverHasSideEffects 1986 1987// Load / Store Multiple Mnemonic Aliases 1988def : MnemonicAlias<"ldm", "ldmia">; 1989def : MnemonicAlias<"stm", "stmia">; 1990 1991// FIXME: remove when we have a way to marking a MI with these properties. 1992// FIXME: Should pc be an implicit operand like PICADD, etc? 1993let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 1994 hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in 1995def LDMIA_RET : ARMPseudoInst<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, 1996 reglist:$regs, variable_ops), 1997 Size4Bytes, IIC_iLoad_mBr, []>, 1998 RegConstraint<"$Rn = $wb">; 1999 2000//===----------------------------------------------------------------------===// 2001// Move Instructions. 2002// 2003 2004let neverHasSideEffects = 1 in 2005def MOVr : AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMOVr, 2006 "mov", "\t$Rd, $Rm", []>, UnaryDP { 2007 bits<4> Rd; 2008 bits<4> Rm; 2009 2010 let Inst{19-16} = 0b0000; 2011 let Inst{11-4} = 0b00000000; 2012 let Inst{25} = 0; 2013 let Inst{3-0} = Rm; 2014 let Inst{15-12} = Rd; 2015} 2016 2017// A version for the smaller set of tail call registers. 2018let neverHasSideEffects = 1 in 2019def MOVr_TC : AsI1<0b1101, (outs tcGPR:$Rd), (ins tcGPR:$Rm), DPFrm, 2020 IIC_iMOVr, "mov", "\t$Rd, $Rm", []>, UnaryDP { 2021 bits<4> Rd; 2022 bits<4> Rm; 2023 2024 let Inst{11-4} = 0b00000000; 2025 let Inst{25} = 0; 2026 let Inst{3-0} = Rm; 2027 let Inst{15-12} = Rd; 2028} 2029 2030def MOVs : AsI1<0b1101, (outs GPR:$Rd), (ins shift_so_reg:$src), 2031 DPSoRegFrm, IIC_iMOVsr, 2032 "mov", "\t$Rd, $src", [(set GPR:$Rd, shift_so_reg:$src)]>, 2033 UnaryDP { 2034 bits<4> Rd; 2035 bits<12> src; 2036 let Inst{15-12} = Rd; 2037 let Inst{19-16} = 0b0000; 2038 let Inst{11-0} = src; 2039 let Inst{25} = 0; 2040} 2041 2042let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 2043def MOVi : AsI1<0b1101, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, IIC_iMOVi, 2044 "mov", "\t$Rd, $imm", [(set GPR:$Rd, so_imm:$imm)]>, UnaryDP { 2045 bits<4> Rd; 2046 bits<12> imm; 2047 let Inst{25} = 1; 2048 let Inst{15-12} = Rd; 2049 let Inst{19-16} = 0b0000; 2050 let Inst{11-0} = imm; 2051} 2052 2053let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 2054def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm_hilo16:$imm), 2055 DPFrm, IIC_iMOVi, 2056 "movw", "\t$Rd, $imm", 2057 [(set GPR:$Rd, imm0_65535:$imm)]>, 2058 Requires<[IsARM, HasV6T2]>, UnaryDP { 2059 bits<4> Rd; 2060 bits<16> imm; 2061 let Inst{15-12} = Rd; 2062 let Inst{11-0} = imm{11-0}; 2063 let Inst{19-16} = imm{15-12}; 2064 let Inst{20} = 0; 2065 let Inst{25} = 1; 2066} 2067 2068def MOVi16_ga_pcrel : PseudoInst<(outs GPR:$Rd), 2069 (ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>; 2070 2071let Constraints = "$src = $Rd" in { 2072def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm_hilo16:$imm), 2073 DPFrm, IIC_iMOVi, 2074 "movt", "\t$Rd, $imm", 2075 [(set GPR:$Rd, 2076 (or (and GPR:$src, 0xffff), 2077 lo16AllZero:$imm))]>, UnaryDP, 2078 Requires<[IsARM, HasV6T2]> { 2079 bits<4> Rd; 2080 bits<16> imm; 2081 let Inst{15-12} = Rd; 2082 let Inst{11-0} = imm{11-0}; 2083 let Inst{19-16} = imm{15-12}; 2084 let Inst{20} = 0; 2085 let Inst{25} = 1; 2086} 2087 2088def MOVTi16_ga_pcrel : PseudoInst<(outs GPR:$Rd), 2089 (ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>; 2090 2091} // Constraints 2092 2093def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>, 2094 Requires<[IsARM, HasV6T2]>; 2095 2096let Uses = [CPSR] in 2097def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi, 2098 [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP, 2099 Requires<[IsARM]>; 2100 2101// These aren't really mov instructions, but we have to define them this way 2102// due to flag operands. 2103 2104let Defs = [CPSR] in { 2105def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, 2106 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP, 2107 Requires<[IsARM]>; 2108def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, 2109 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP, 2110 Requires<[IsARM]>; 2111} 2112 2113//===----------------------------------------------------------------------===// 2114// Extend Instructions. 2115// 2116 2117// Sign extenders 2118 2119defm SXTB : AI_ext_rrot<0b01101010, 2120 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>; 2121defm SXTH : AI_ext_rrot<0b01101011, 2122 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>; 2123 2124defm SXTAB : AI_exta_rrot<0b01101010, 2125 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>; 2126defm SXTAH : AI_exta_rrot<0b01101011, 2127 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>; 2128 2129// For disassembly only 2130defm SXTB16 : AI_ext_rrot_np<0b01101000, "sxtb16">; 2131 2132// For disassembly only 2133defm SXTAB16 : AI_exta_rrot_np<0b01101000, "sxtab16">; 2134 2135// Zero extenders 2136 2137let AddedComplexity = 16 in { 2138defm UXTB : AI_ext_rrot<0b01101110, 2139 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>; 2140defm UXTH : AI_ext_rrot<0b01101111, 2141 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>; 2142defm UXTB16 : AI_ext_rrot<0b01101100, 2143 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>; 2144 2145// FIXME: This pattern incorrectly assumes the shl operator is a rotate. 2146// The transformation should probably be done as a combiner action 2147// instead so we can include a check for masking back in the upper 2148// eight bits of the source into the lower eight bits of the result. 2149//def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF), 2150// (UXTB16r_rot GPR:$Src, 24)>; 2151def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF), 2152 (UXTB16r_rot GPR:$Src, 8)>; 2153 2154defm UXTAB : AI_exta_rrot<0b01101110, "uxtab", 2155 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; 2156defm UXTAH : AI_exta_rrot<0b01101111, "uxtah", 2157 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; 2158} 2159 2160// This isn't safe in general, the add is two 16-bit units, not a 32-bit add. 2161// For disassembly only 2162defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">; 2163 2164 2165def SBFX : I<(outs GPR:$Rd), 2166 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width), 2167 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, 2168 "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>, 2169 Requires<[IsARM, HasV6T2]> { 2170 bits<4> Rd; 2171 bits<4> Rn; 2172 bits<5> lsb; 2173 bits<5> width; 2174 let Inst{27-21} = 0b0111101; 2175 let Inst{6-4} = 0b101; 2176 let Inst{20-16} = width; 2177 let Inst{15-12} = Rd; 2178 let Inst{11-7} = lsb; 2179 let Inst{3-0} = Rn; 2180} 2181 2182def UBFX : I<(outs GPR:$Rd), 2183 (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width), 2184 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, 2185 "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>, 2186 Requires<[IsARM, HasV6T2]> { 2187 bits<4> Rd; 2188 bits<4> Rn; 2189 bits<5> lsb; 2190 bits<5> width; 2191 let Inst{27-21} = 0b0111111; 2192 let Inst{6-4} = 0b101; 2193 let Inst{20-16} = width; 2194 let Inst{15-12} = Rd; 2195 let Inst{11-7} = lsb; 2196 let Inst{3-0} = Rn; 2197} 2198 2199//===----------------------------------------------------------------------===// 2200// Arithmetic Instructions. 2201// 2202 2203defm ADD : AsI1_bin_irs<0b0100, "add", 2204 IIC_iALUi, IIC_iALUr, IIC_iALUsr, 2205 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>; 2206defm SUB : AsI1_bin_irs<0b0010, "sub", 2207 IIC_iALUi, IIC_iALUr, IIC_iALUsr, 2208 BinOpFrag<(sub node:$LHS, node:$RHS)>>; 2209 2210// ADD and SUB with 's' bit set. 2211defm ADDS : AI1_bin_s_irs<0b0100, "adds", 2212 IIC_iALUi, IIC_iALUr, IIC_iALUsr, 2213 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>; 2214defm SUBS : AI1_bin_s_irs<0b0010, "subs", 2215 IIC_iALUi, IIC_iALUr, IIC_iALUsr, 2216 BinOpFrag<(subc node:$LHS, node:$RHS)>>; 2217 2218defm ADC : AI1_adde_sube_irs<0b0101, "adc", 2219 BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>; 2220defm SBC : AI1_adde_sube_irs<0b0110, "sbc", 2221 BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>; 2222 2223// ADC and SUBC with 's' bit set. 2224let usesCustomInserter = 1 in { 2225defm ADCS : AI1_adde_sube_s_irs< 2226 BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>; 2227defm SBCS : AI1_adde_sube_s_irs< 2228 BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>; 2229} 2230 2231def RSBri : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), DPFrm, 2232 IIC_iALUi, "rsb", "\t$Rd, $Rn, $imm", 2233 [(set GPR:$Rd, (sub so_imm:$imm, GPR:$Rn))]> { 2234 bits<4> Rd; 2235 bits<4> Rn; 2236 bits<12> imm; 2237 let Inst{25} = 1; 2238 let Inst{15-12} = Rd; 2239 let Inst{19-16} = Rn; 2240 let Inst{11-0} = imm; 2241} 2242 2243// The reg/reg form is only defined for the disassembler; for codegen it is 2244// equivalent to SUBrr. 2245def RSBrr : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), DPFrm, 2246 IIC_iALUr, "rsb", "\t$Rd, $Rn, $Rm", 2247 [/* For disassembly only; pattern left blank */]> { 2248 bits<4> Rd; 2249 bits<4> Rn; 2250 bits<4> Rm; 2251 let Inst{11-4} = 0b00000000; 2252 let Inst{25} = 0; 2253 let Inst{3-0} = Rm; 2254 let Inst{15-12} = Rd; 2255 let Inst{19-16} = Rn; 2256} 2257 2258def RSBrs : AsI1<0b0011, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), 2259 DPSoRegFrm, IIC_iALUsr, "rsb", "\t$Rd, $Rn, $shift", 2260 [(set GPR:$Rd, (sub so_reg:$shift, GPR:$Rn))]> { 2261 bits<4> Rd; 2262 bits<4> Rn; 2263 bits<12> shift; 2264 let Inst{25} = 0; 2265 let Inst{11-0} = shift; 2266 let Inst{15-12} = Rd; 2267 let Inst{19-16} = Rn; 2268} 2269 2270// RSB with 's' bit set. 2271// NOTE: CPSR def omitted because it will be handled by the custom inserter. 2272let usesCustomInserter = 1 in { 2273def RSBSri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), 2274 Size4Bytes, IIC_iALUi, 2275 [(set GPR:$Rd, (subc so_imm:$imm, GPR:$Rn))]>; 2276def RSBSrr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2277 Size4Bytes, IIC_iALUr, 2278 [/* For disassembly only; pattern left blank */]>; 2279def RSBSrs : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), 2280 Size4Bytes, IIC_iALUsr, 2281 [(set GPR:$Rd, (subc so_reg:$shift, GPR:$Rn))]>; 2282} 2283 2284let Uses = [CPSR] in { 2285def RSCri : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), 2286 DPFrm, IIC_iALUi, "rsc", "\t$Rd, $Rn, $imm", 2287 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>, 2288 Requires<[IsARM]> { 2289 bits<4> Rd; 2290 bits<4> Rn; 2291 bits<12> imm; 2292 let Inst{25} = 1; 2293 let Inst{15-12} = Rd; 2294 let Inst{19-16} = Rn; 2295 let Inst{11-0} = imm; 2296} 2297// The reg/reg form is only defined for the disassembler; for codegen it is 2298// equivalent to SUBrr. 2299def RSCrr : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2300 DPFrm, IIC_iALUr, "rsc", "\t$Rd, $Rn, $Rm", 2301 [/* For disassembly only; pattern left blank */]> { 2302 bits<4> Rd; 2303 bits<4> Rn; 2304 bits<4> Rm; 2305 let Inst{11-4} = 0b00000000; 2306 let Inst{25} = 0; 2307 let Inst{3-0} = Rm; 2308 let Inst{15-12} = Rd; 2309 let Inst{19-16} = Rn; 2310} 2311def RSCrs : AsI1<0b0111, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), 2312 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$Rd, $Rn, $shift", 2313 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>, 2314 Requires<[IsARM]> { 2315 bits<4> Rd; 2316 bits<4> Rn; 2317 bits<12> shift; 2318 let Inst{25} = 0; 2319 let Inst{11-0} = shift; 2320 let Inst{15-12} = Rd; 2321 let Inst{19-16} = Rn; 2322} 2323} 2324 2325// NOTE: CPSR def omitted because it will be handled by the custom inserter. 2326let usesCustomInserter = 1, Uses = [CPSR] in { 2327def RSCSri : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_imm:$imm), 2328 Size4Bytes, IIC_iALUi, 2329 [(set GPR:$Rd, (sube_dead_carry so_imm:$imm, GPR:$Rn))]>; 2330def RSCSrs : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), 2331 Size4Bytes, IIC_iALUsr, 2332 [(set GPR:$Rd, (sube_dead_carry so_reg:$shift, GPR:$Rn))]>; 2333} 2334 2335// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 2336// The assume-no-carry-in form uses the negation of the input since add/sub 2337// assume opposite meanings of the carry flag (i.e., carry == !borrow). 2338// See the definition of AddWithCarry() in the ARM ARM A2.2.1 for the gory 2339// details. 2340def : ARMPat<(add GPR:$src, so_imm_neg:$imm), 2341 (SUBri GPR:$src, so_imm_neg:$imm)>; 2342def : ARMPat<(addc GPR:$src, so_imm_neg:$imm), 2343 (SUBSri GPR:$src, so_imm_neg:$imm)>; 2344// The with-carry-in form matches bitwise not instead of the negation. 2345// Effectively, the inverse interpretation of the carry flag already accounts 2346// for part of the negation. 2347def : ARMPat<(adde_dead_carry GPR:$src, so_imm_not:$imm), 2348 (SBCri GPR:$src, so_imm_not:$imm)>; 2349def : ARMPat<(adde_live_carry GPR:$src, so_imm_not:$imm), 2350 (SBCSri GPR:$src, so_imm_not:$imm)>; 2351 2352// Note: These are implemented in C++ code, because they have to generate 2353// ADD/SUBrs instructions, which use a complex pattern that a xform function 2354// cannot produce. 2355// (mul X, 2^n+1) -> (add (X << n), X) 2356// (mul X, 2^n-1) -> (rsb X, (X << n)) 2357 2358// ARM Arithmetic Instruction -- for disassembly only 2359// GPR:$dst = GPR:$a op GPR:$b 2360class AAI<bits<8> op27_20, bits<8> op11_4, string opc, 2361 list<dag> pattern = [/* For disassembly only; pattern left blank */], 2362 dag iops = (ins GPR:$Rn, GPR:$Rm), string asm = "\t$Rd, $Rn, $Rm"> 2363 : AI<(outs GPR:$Rd), iops, DPFrm, IIC_iALUr, opc, asm, pattern> { 2364 bits<4> Rn; 2365 bits<4> Rd; 2366 bits<4> Rm; 2367 let Inst{27-20} = op27_20; 2368 let Inst{11-4} = op11_4; 2369 let Inst{19-16} = Rn; 2370 let Inst{15-12} = Rd; 2371 let Inst{3-0} = Rm; 2372} 2373 2374// Saturating add/subtract -- for disassembly only 2375 2376def QADD : AAI<0b00010000, 0b00000101, "qadd", 2377 [(set GPR:$Rd, (int_arm_qadd GPR:$Rm, GPR:$Rn))], 2378 (ins GPR:$Rm, GPR:$Rn), "\t$Rd, $Rm, $Rn">; 2379def QSUB : AAI<0b00010010, 0b00000101, "qsub", 2380 [(set GPR:$Rd, (int_arm_qsub GPR:$Rm, GPR:$Rn))], 2381 (ins GPR:$Rm, GPR:$Rn), "\t$Rd, $Rm, $Rn">; 2382def QDADD : AAI<0b00010100, 0b00000101, "qdadd", [], (ins GPR:$Rm, GPR:$Rn), 2383 "\t$Rd, $Rm, $Rn">; 2384def QDSUB : AAI<0b00010110, 0b00000101, "qdsub", [], (ins GPR:$Rm, GPR:$Rn), 2385 "\t$Rd, $Rm, $Rn">; 2386 2387def QADD16 : AAI<0b01100010, 0b11110001, "qadd16">; 2388def QADD8 : AAI<0b01100010, 0b11111001, "qadd8">; 2389def QASX : AAI<0b01100010, 0b11110011, "qasx">; 2390def QSAX : AAI<0b01100010, 0b11110101, "qsax">; 2391def QSUB16 : AAI<0b01100010, 0b11110111, "qsub16">; 2392def QSUB8 : AAI<0b01100010, 0b11111111, "qsub8">; 2393def UQADD16 : AAI<0b01100110, 0b11110001, "uqadd16">; 2394def UQADD8 : AAI<0b01100110, 0b11111001, "uqadd8">; 2395def UQASX : AAI<0b01100110, 0b11110011, "uqasx">; 2396def UQSAX : AAI<0b01100110, 0b11110101, "uqsax">; 2397def UQSUB16 : AAI<0b01100110, 0b11110111, "uqsub16">; 2398def UQSUB8 : AAI<0b01100110, 0b11111111, "uqsub8">; 2399 2400// Signed/Unsigned add/subtract -- for disassembly only 2401 2402def SASX : AAI<0b01100001, 0b11110011, "sasx">; 2403def SADD16 : AAI<0b01100001, 0b11110001, "sadd16">; 2404def SADD8 : AAI<0b01100001, 0b11111001, "sadd8">; 2405def SSAX : AAI<0b01100001, 0b11110101, "ssax">; 2406def SSUB16 : AAI<0b01100001, 0b11110111, "ssub16">; 2407def SSUB8 : AAI<0b01100001, 0b11111111, "ssub8">; 2408def UASX : AAI<0b01100101, 0b11110011, "uasx">; 2409def UADD16 : AAI<0b01100101, 0b11110001, "uadd16">; 2410def UADD8 : AAI<0b01100101, 0b11111001, "uadd8">; 2411def USAX : AAI<0b01100101, 0b11110101, "usax">; 2412def USUB16 : AAI<0b01100101, 0b11110111, "usub16">; 2413def USUB8 : AAI<0b01100101, 0b11111111, "usub8">; 2414 2415// Signed/Unsigned halving add/subtract -- for disassembly only 2416 2417def SHASX : AAI<0b01100011, 0b11110011, "shasx">; 2418def SHADD16 : AAI<0b01100011, 0b11110001, "shadd16">; 2419def SHADD8 : AAI<0b01100011, 0b11111001, "shadd8">; 2420def SHSAX : AAI<0b01100011, 0b11110101, "shsax">; 2421def SHSUB16 : AAI<0b01100011, 0b11110111, "shsub16">; 2422def SHSUB8 : AAI<0b01100011, 0b11111111, "shsub8">; 2423def UHASX : AAI<0b01100111, 0b11110011, "uhasx">; 2424def UHADD16 : AAI<0b01100111, 0b11110001, "uhadd16">; 2425def UHADD8 : AAI<0b01100111, 0b11111001, "uhadd8">; 2426def UHSAX : AAI<0b01100111, 0b11110101, "uhsax">; 2427def UHSUB16 : AAI<0b01100111, 0b11110111, "uhsub16">; 2428def UHSUB8 : AAI<0b01100111, 0b11111111, "uhsub8">; 2429 2430// Unsigned Sum of Absolute Differences [and Accumulate] -- for disassembly only 2431 2432def USAD8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2433 MulFrm /* for convenience */, NoItinerary, "usad8", 2434 "\t$Rd, $Rn, $Rm", []>, 2435 Requires<[IsARM, HasV6]> { 2436 bits<4> Rd; 2437 bits<4> Rn; 2438 bits<4> Rm; 2439 let Inst{27-20} = 0b01111000; 2440 let Inst{15-12} = 0b1111; 2441 let Inst{7-4} = 0b0001; 2442 let Inst{19-16} = Rd; 2443 let Inst{11-8} = Rm; 2444 let Inst{3-0} = Rn; 2445} 2446def USADA8 : AI<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2447 MulFrm /* for convenience */, NoItinerary, "usada8", 2448 "\t$Rd, $Rn, $Rm, $Ra", []>, 2449 Requires<[IsARM, HasV6]> { 2450 bits<4> Rd; 2451 bits<4> Rn; 2452 bits<4> Rm; 2453 bits<4> Ra; 2454 let Inst{27-20} = 0b01111000; 2455 let Inst{7-4} = 0b0001; 2456 let Inst{19-16} = Rd; 2457 let Inst{15-12} = Ra; 2458 let Inst{11-8} = Rm; 2459 let Inst{3-0} = Rn; 2460} 2461 2462// Signed/Unsigned saturate -- for disassembly only 2463 2464def SSAT : AI<(outs GPR:$Rd), (ins ssat_imm:$sat_imm, GPR:$a, shift_imm:$sh), 2465 SatFrm, NoItinerary, "ssat", "\t$Rd, $sat_imm, $a$sh", 2466 [/* For disassembly only; pattern left blank */]> { 2467 bits<4> Rd; 2468 bits<5> sat_imm; 2469 bits<4> Rn; 2470 bits<8> sh; 2471 let Inst{27-21} = 0b0110101; 2472 let Inst{5-4} = 0b01; 2473 let Inst{20-16} = sat_imm; 2474 let Inst{15-12} = Rd; 2475 let Inst{11-7} = sh{7-3}; 2476 let Inst{6} = sh{0}; 2477 let Inst{3-0} = Rn; 2478} 2479 2480def SSAT16 : AI<(outs GPR:$Rd), (ins ssat_imm:$sat_imm, GPR:$Rn), SatFrm, 2481 NoItinerary, "ssat16", "\t$Rd, $sat_imm, $Rn", 2482 [/* For disassembly only; pattern left blank */]> { 2483 bits<4> Rd; 2484 bits<4> sat_imm; 2485 bits<4> Rn; 2486 let Inst{27-20} = 0b01101010; 2487 let Inst{11-4} = 0b11110011; 2488 let Inst{15-12} = Rd; 2489 let Inst{19-16} = sat_imm; 2490 let Inst{3-0} = Rn; 2491} 2492 2493def USAT : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a, shift_imm:$sh), 2494 SatFrm, NoItinerary, "usat", "\t$Rd, $sat_imm, $a$sh", 2495 [/* For disassembly only; pattern left blank */]> { 2496 bits<4> Rd; 2497 bits<5> sat_imm; 2498 bits<4> Rn; 2499 bits<8> sh; 2500 let Inst{27-21} = 0b0110111; 2501 let Inst{5-4} = 0b01; 2502 let Inst{15-12} = Rd; 2503 let Inst{11-7} = sh{7-3}; 2504 let Inst{6} = sh{0}; 2505 let Inst{20-16} = sat_imm; 2506 let Inst{3-0} = Rn; 2507} 2508 2509def USAT16 : AI<(outs GPR:$Rd), (ins i32imm:$sat_imm, GPR:$a), SatFrm, 2510 NoItinerary, "usat16", "\t$Rd, $sat_imm, $a", 2511 [/* For disassembly only; pattern left blank */]> { 2512 bits<4> Rd; 2513 bits<4> sat_imm; 2514 bits<4> Rn; 2515 let Inst{27-20} = 0b01101110; 2516 let Inst{11-4} = 0b11110011; 2517 let Inst{15-12} = Rd; 2518 let Inst{19-16} = sat_imm; 2519 let Inst{3-0} = Rn; 2520} 2521 2522def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>; 2523def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>; 2524 2525//===----------------------------------------------------------------------===// 2526// Bitwise Instructions. 2527// 2528 2529defm AND : AsI1_bin_irs<0b0000, "and", 2530 IIC_iBITi, IIC_iBITr, IIC_iBITsr, 2531 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>; 2532defm ORR : AsI1_bin_irs<0b1100, "orr", 2533 IIC_iBITi, IIC_iBITr, IIC_iBITsr, 2534 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>; 2535defm EOR : AsI1_bin_irs<0b0001, "eor", 2536 IIC_iBITi, IIC_iBITr, IIC_iBITsr, 2537 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>; 2538defm BIC : AsI1_bin_irs<0b1110, "bic", 2539 IIC_iBITi, IIC_iBITr, IIC_iBITsr, 2540 BinOpFrag<(and node:$LHS, (not node:$RHS))>>; 2541 2542def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm), 2543 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, 2544 "bfc", "\t$Rd, $imm", "$src = $Rd", 2545 [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>, 2546 Requires<[IsARM, HasV6T2]> { 2547 bits<4> Rd; 2548 bits<10> imm; 2549 let Inst{27-21} = 0b0111110; 2550 let Inst{6-0} = 0b0011111; 2551 let Inst{15-12} = Rd; 2552 let Inst{11-7} = imm{4-0}; // lsb 2553 let Inst{20-16} = imm{9-5}; // width 2554} 2555 2556// A8.6.18 BFI - Bitfield insert (Encoding A1) 2557def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm), 2558 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, 2559 "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd", 2560 [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn, 2561 bf_inv_mask_imm:$imm))]>, 2562 Requires<[IsARM, HasV6T2]> { 2563 bits<4> Rd; 2564 bits<4> Rn; 2565 bits<10> imm; 2566 let Inst{27-21} = 0b0111110; 2567 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15 2568 let Inst{15-12} = Rd; 2569 let Inst{11-7} = imm{4-0}; // lsb 2570 let Inst{20-16} = imm{9-5}; // width 2571 let Inst{3-0} = Rn; 2572} 2573 2574// GNU as only supports this form of bfi (w/ 4 arguments) 2575let isAsmParserOnly = 1 in 2576def BFI4p : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, 2577 lsb_pos_imm:$lsb, width_imm:$width), 2578 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, 2579 "bfi", "\t$Rd, $Rn, $lsb, $width", "$src = $Rd", 2580 []>, Requires<[IsARM, HasV6T2]> { 2581 bits<4> Rd; 2582 bits<4> Rn; 2583 bits<5> lsb; 2584 bits<5> width; 2585 let Inst{27-21} = 0b0111110; 2586 let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15 2587 let Inst{15-12} = Rd; 2588 let Inst{11-7} = lsb; 2589 let Inst{20-16} = width; // Custom encoder => lsb+width-1 2590 let Inst{3-0} = Rn; 2591} 2592 2593def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr, 2594 "mvn", "\t$Rd, $Rm", 2595 [(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP { 2596 bits<4> Rd; 2597 bits<4> Rm; 2598 let Inst{25} = 0; 2599 let Inst{19-16} = 0b0000; 2600 let Inst{11-4} = 0b00000000; 2601 let Inst{15-12} = Rd; 2602 let Inst{3-0} = Rm; 2603} 2604def MVNs : AsI1<0b1111, (outs GPR:$Rd), (ins so_reg:$shift), DPSoRegFrm, 2605 IIC_iMVNsr, "mvn", "\t$Rd, $shift", 2606 [(set GPR:$Rd, (not so_reg:$shift))]>, UnaryDP { 2607 bits<4> Rd; 2608 bits<12> shift; 2609 let Inst{25} = 0; 2610 let Inst{19-16} = 0b0000; 2611 let Inst{15-12} = Rd; 2612 let Inst{11-0} = shift; 2613} 2614let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in 2615def MVNi : AsI1<0b1111, (outs GPR:$Rd), (ins so_imm:$imm), DPFrm, 2616 IIC_iMVNi, "mvn", "\t$Rd, $imm", 2617 [(set GPR:$Rd, so_imm_not:$imm)]>,UnaryDP { 2618 bits<4> Rd; 2619 bits<12> imm; 2620 let Inst{25} = 1; 2621 let Inst{19-16} = 0b0000; 2622 let Inst{15-12} = Rd; 2623 let Inst{11-0} = imm; 2624} 2625 2626def : ARMPat<(and GPR:$src, so_imm_not:$imm), 2627 (BICri GPR:$src, so_imm_not:$imm)>; 2628 2629//===----------------------------------------------------------------------===// 2630// Multiply Instructions. 2631// 2632class AsMul1I32<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 2633 string opc, string asm, list<dag> pattern> 2634 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> { 2635 bits<4> Rd; 2636 bits<4> Rm; 2637 bits<4> Rn; 2638 let Inst{19-16} = Rd; 2639 let Inst{11-8} = Rm; 2640 let Inst{3-0} = Rn; 2641} 2642class AsMul1I64<bits<7> opcod, dag oops, dag iops, InstrItinClass itin, 2643 string opc, string asm, list<dag> pattern> 2644 : AsMul1I<opcod, oops, iops, itin, opc, asm, pattern> { 2645 bits<4> RdLo; 2646 bits<4> RdHi; 2647 bits<4> Rm; 2648 bits<4> Rn; 2649 let Inst{19-16} = RdHi; 2650 let Inst{15-12} = RdLo; 2651 let Inst{11-8} = Rm; 2652 let Inst{3-0} = Rn; 2653} 2654 2655let isCommutable = 1 in { 2656let Constraints = "@earlyclobber $Rd" in 2657def MULv5: ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, 2658 pred:$p, cc_out:$s), 2659 Size4Bytes, IIC_iMUL32, 2660 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>, 2661 Requires<[IsARM, NoV6]>; 2662 2663def MUL : AsMul1I32<0b0000000, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2664 IIC_iMUL32, "mul", "\t$Rd, $Rn, $Rm", 2665 [(set GPR:$Rd, (mul GPR:$Rn, GPR:$Rm))]>, 2666 Requires<[IsARM, HasV6]> { 2667 let Inst{15-12} = 0b0000; 2668} 2669} 2670 2671let Constraints = "@earlyclobber $Rd" in 2672def MLAv5: ARMPseudoInst<(outs GPR:$Rd), 2673 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra, pred:$p, cc_out:$s), 2674 Size4Bytes, IIC_iMAC32, 2675 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>, 2676 Requires<[IsARM, NoV6]> { 2677 bits<4> Ra; 2678 let Inst{15-12} = Ra; 2679} 2680def MLA : AsMul1I32<0b0000001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2681 IIC_iMAC32, "mla", "\t$Rd, $Rn, $Rm, $Ra", 2682 [(set GPR:$Rd, (add (mul GPR:$Rn, GPR:$Rm), GPR:$Ra))]>, 2683 Requires<[IsARM, HasV6]> { 2684 bits<4> Ra; 2685 let Inst{15-12} = Ra; 2686} 2687 2688def MLS : AMul1I<0b0000011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2689 IIC_iMAC32, "mls", "\t$Rd, $Rn, $Rm, $Ra", 2690 [(set GPR:$Rd, (sub GPR:$Ra, (mul GPR:$Rn, GPR:$Rm)))]>, 2691 Requires<[IsARM, HasV6T2]> { 2692 bits<4> Rd; 2693 bits<4> Rm; 2694 bits<4> Rn; 2695 bits<4> Ra; 2696 let Inst{19-16} = Rd; 2697 let Inst{15-12} = Ra; 2698 let Inst{11-8} = Rm; 2699 let Inst{3-0} = Rn; 2700} 2701 2702// Extra precision multiplies with low / high results 2703 2704let neverHasSideEffects = 1 in { 2705let isCommutable = 1 in { 2706let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in { 2707def SMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi), 2708 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 2709 Size4Bytes, IIC_iMUL64, []>, 2710 Requires<[IsARM, NoV6]>; 2711 2712def UMULLv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi), 2713 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 2714 Size4Bytes, IIC_iMUL64, []>, 2715 Requires<[IsARM, NoV6]>; 2716} 2717 2718def SMULL : AsMul1I64<0b0000110, (outs GPR:$RdLo, GPR:$RdHi), 2719 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64, 2720 "smull", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 2721 Requires<[IsARM, HasV6]>; 2722 2723def UMULL : AsMul1I64<0b0000100, (outs GPR:$RdLo, GPR:$RdHi), 2724 (ins GPR:$Rn, GPR:$Rm), IIC_iMUL64, 2725 "umull", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 2726 Requires<[IsARM, HasV6]>; 2727} 2728 2729// Multiply + accumulate 2730let Constraints = "@earlyclobber $RdLo,@earlyclobber $RdHi" in { 2731def SMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi), 2732 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 2733 Size4Bytes, IIC_iMAC64, []>, 2734 Requires<[IsARM, NoV6]>; 2735def UMLALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi), 2736 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 2737 Size4Bytes, IIC_iMAC64, []>, 2738 Requires<[IsARM, NoV6]>; 2739def UMAALv5 : ARMPseudoInst<(outs GPR:$RdLo, GPR:$RdHi), 2740 (ins GPR:$Rn, GPR:$Rm, pred:$p, cc_out:$s), 2741 Size4Bytes, IIC_iMAC64, []>, 2742 Requires<[IsARM, NoV6]>; 2743 2744} 2745 2746def SMLAL : AsMul1I64<0b0000111, (outs GPR:$RdLo, GPR:$RdHi), 2747 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64, 2748 "smlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 2749 Requires<[IsARM, HasV6]>; 2750def UMLAL : AsMul1I64<0b0000101, (outs GPR:$RdLo, GPR:$RdHi), 2751 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64, 2752 "umlal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 2753 Requires<[IsARM, HasV6]>; 2754 2755def UMAAL : AMul1I <0b0000010, (outs GPR:$RdLo, GPR:$RdHi), 2756 (ins GPR:$Rn, GPR:$Rm), IIC_iMAC64, 2757 "umaal", "\t$RdLo, $RdHi, $Rn, $Rm", []>, 2758 Requires<[IsARM, HasV6]> { 2759 bits<4> RdLo; 2760 bits<4> RdHi; 2761 bits<4> Rm; 2762 bits<4> Rn; 2763 let Inst{19-16} = RdLo; 2764 let Inst{15-12} = RdHi; 2765 let Inst{11-8} = Rm; 2766 let Inst{3-0} = Rn; 2767} 2768} // neverHasSideEffects 2769 2770// Most significant word multiply 2771def SMMUL : AMul2I <0b0111010, 0b0001, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2772 IIC_iMUL32, "smmul", "\t$Rd, $Rn, $Rm", 2773 [(set GPR:$Rd, (mulhs GPR:$Rn, GPR:$Rm))]>, 2774 Requires<[IsARM, HasV6]> { 2775 let Inst{15-12} = 0b1111; 2776} 2777 2778def SMMULR : AMul2I <0b0111010, 0b0011, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2779 IIC_iMUL32, "smmulr", "\t$Rd, $Rn, $Rm", 2780 [/* For disassembly only; pattern left blank */]>, 2781 Requires<[IsARM, HasV6]> { 2782 let Inst{15-12} = 0b1111; 2783} 2784 2785def SMMLA : AMul2Ia <0b0111010, 0b0001, (outs GPR:$Rd), 2786 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2787 IIC_iMAC32, "smmla", "\t$Rd, $Rn, $Rm, $Ra", 2788 [(set GPR:$Rd, (add (mulhs GPR:$Rn, GPR:$Rm), GPR:$Ra))]>, 2789 Requires<[IsARM, HasV6]>; 2790 2791def SMMLAR : AMul2Ia <0b0111010, 0b0011, (outs GPR:$Rd), 2792 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2793 IIC_iMAC32, "smmlar", "\t$Rd, $Rn, $Rm, $Ra", 2794 [/* For disassembly only; pattern left blank */]>, 2795 Requires<[IsARM, HasV6]>; 2796 2797def SMMLS : AMul2Ia <0b0111010, 0b1101, (outs GPR:$Rd), 2798 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2799 IIC_iMAC32, "smmls", "\t$Rd, $Rn, $Rm, $Ra", 2800 [(set GPR:$Rd, (sub GPR:$Ra, (mulhs GPR:$Rn, GPR:$Rm)))]>, 2801 Requires<[IsARM, HasV6]>; 2802 2803def SMMLSR : AMul2Ia <0b0111010, 0b1111, (outs GPR:$Rd), 2804 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2805 IIC_iMAC32, "smmlsr", "\t$Rd, $Rn, $Rm, $Ra", 2806 [/* For disassembly only; pattern left blank */]>, 2807 Requires<[IsARM, HasV6]>; 2808 2809multiclass AI_smul<string opc, PatFrag opnode> { 2810 def BB : AMulxyI<0b0001011, 0b00, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2811 IIC_iMUL16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm", 2812 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16), 2813 (sext_inreg GPR:$Rm, i16)))]>, 2814 Requires<[IsARM, HasV5TE]>; 2815 2816 def BT : AMulxyI<0b0001011, 0b10, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2817 IIC_iMUL16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm", 2818 [(set GPR:$Rd, (opnode (sext_inreg GPR:$Rn, i16), 2819 (sra GPR:$Rm, (i32 16))))]>, 2820 Requires<[IsARM, HasV5TE]>; 2821 2822 def TB : AMulxyI<0b0001011, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2823 IIC_iMUL16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm", 2824 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)), 2825 (sext_inreg GPR:$Rm, i16)))]>, 2826 Requires<[IsARM, HasV5TE]>; 2827 2828 def TT : AMulxyI<0b0001011, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2829 IIC_iMUL16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm", 2830 [(set GPR:$Rd, (opnode (sra GPR:$Rn, (i32 16)), 2831 (sra GPR:$Rm, (i32 16))))]>, 2832 Requires<[IsARM, HasV5TE]>; 2833 2834 def WB : AMulxyI<0b0001001, 0b01, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2835 IIC_iMUL16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm", 2836 [(set GPR:$Rd, (sra (opnode GPR:$Rn, 2837 (sext_inreg GPR:$Rm, i16)), (i32 16)))]>, 2838 Requires<[IsARM, HasV5TE]>; 2839 2840 def WT : AMulxyI<0b0001001, 0b11, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2841 IIC_iMUL16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm", 2842 [(set GPR:$Rd, (sra (opnode GPR:$Rn, 2843 (sra GPR:$Rm, (i32 16))), (i32 16)))]>, 2844 Requires<[IsARM, HasV5TE]>; 2845} 2846 2847 2848multiclass AI_smla<string opc, PatFrag opnode> { 2849 def BB : AMulxyIa<0b0001000, 0b00, (outs GPR:$Rd), 2850 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2851 IIC_iMAC16, !strconcat(opc, "bb"), "\t$Rd, $Rn, $Rm, $Ra", 2852 [(set GPR:$Rd, (add GPR:$Ra, 2853 (opnode (sext_inreg GPR:$Rn, i16), 2854 (sext_inreg GPR:$Rm, i16))))]>, 2855 Requires<[IsARM, HasV5TE]>; 2856 2857 def BT : AMulxyIa<0b0001000, 0b10, (outs GPR:$Rd), 2858 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2859 IIC_iMAC16, !strconcat(opc, "bt"), "\t$Rd, $Rn, $Rm, $Ra", 2860 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sext_inreg GPR:$Rn, i16), 2861 (sra GPR:$Rm, (i32 16)))))]>, 2862 Requires<[IsARM, HasV5TE]>; 2863 2864 def TB : AMulxyIa<0b0001000, 0b01, (outs GPR:$Rd), 2865 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2866 IIC_iMAC16, !strconcat(opc, "tb"), "\t$Rd, $Rn, $Rm, $Ra", 2867 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)), 2868 (sext_inreg GPR:$Rm, i16))))]>, 2869 Requires<[IsARM, HasV5TE]>; 2870 2871 def TT : AMulxyIa<0b0001000, 0b11, (outs GPR:$Rd), 2872 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2873 IIC_iMAC16, !strconcat(opc, "tt"), "\t$Rd, $Rn, $Rm, $Ra", 2874 [(set GPR:$Rd, (add GPR:$Ra, (opnode (sra GPR:$Rn, (i32 16)), 2875 (sra GPR:$Rm, (i32 16)))))]>, 2876 Requires<[IsARM, HasV5TE]>; 2877 2878 def WB : AMulxyIa<0b0001001, 0b00, (outs GPR:$Rd), 2879 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2880 IIC_iMAC16, !strconcat(opc, "wb"), "\t$Rd, $Rn, $Rm, $Ra", 2881 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn, 2882 (sext_inreg GPR:$Rm, i16)), (i32 16))))]>, 2883 Requires<[IsARM, HasV5TE]>; 2884 2885 def WT : AMulxyIa<0b0001001, 0b10, (outs GPR:$Rd), 2886 (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2887 IIC_iMAC16, !strconcat(opc, "wt"), "\t$Rd, $Rn, $Rm, $Ra", 2888 [(set GPR:$Rd, (add GPR:$Ra, (sra (opnode GPR:$Rn, 2889 (sra GPR:$Rm, (i32 16))), (i32 16))))]>, 2890 Requires<[IsARM, HasV5TE]>; 2891} 2892 2893defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 2894defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 2895 2896// Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only 2897def SMLALBB : AMulxyI64<0b0001010, 0b00, (outs GPR:$RdLo, GPR:$RdHi), 2898 (ins GPR:$Rn, GPR:$Rm), 2899 IIC_iMAC64, "smlalbb", "\t$RdLo, $RdHi, $Rn, $Rm", 2900 [/* For disassembly only; pattern left blank */]>, 2901 Requires<[IsARM, HasV5TE]>; 2902 2903def SMLALBT : AMulxyI64<0b0001010, 0b10, (outs GPR:$RdLo, GPR:$RdHi), 2904 (ins GPR:$Rn, GPR:$Rm), 2905 IIC_iMAC64, "smlalbt", "\t$RdLo, $RdHi, $Rn, $Rm", 2906 [/* For disassembly only; pattern left blank */]>, 2907 Requires<[IsARM, HasV5TE]>; 2908 2909def SMLALTB : AMulxyI64<0b0001010, 0b01, (outs GPR:$RdLo, GPR:$RdHi), 2910 (ins GPR:$Rn, GPR:$Rm), 2911 IIC_iMAC64, "smlaltb", "\t$RdLo, $RdHi, $Rn, $Rm", 2912 [/* For disassembly only; pattern left blank */]>, 2913 Requires<[IsARM, HasV5TE]>; 2914 2915def SMLALTT : AMulxyI64<0b0001010, 0b11, (outs GPR:$RdLo, GPR:$RdHi), 2916 (ins GPR:$Rn, GPR:$Rm), 2917 IIC_iMAC64, "smlaltt", "\t$RdLo, $RdHi, $Rn, $Rm", 2918 [/* For disassembly only; pattern left blank */]>, 2919 Requires<[IsARM, HasV5TE]>; 2920 2921// Helper class for AI_smld -- for disassembly only 2922class AMulDualIbase<bit long, bit sub, bit swap, dag oops, dag iops, 2923 InstrItinClass itin, string opc, string asm> 2924 : AI<oops, iops, MulFrm, itin, opc, asm, []>, Requires<[IsARM, HasV6]> { 2925 bits<4> Rn; 2926 bits<4> Rm; 2927 let Inst{4} = 1; 2928 let Inst{5} = swap; 2929 let Inst{6} = sub; 2930 let Inst{7} = 0; 2931 let Inst{21-20} = 0b00; 2932 let Inst{22} = long; 2933 let Inst{27-23} = 0b01110; 2934 let Inst{11-8} = Rm; 2935 let Inst{3-0} = Rn; 2936} 2937class AMulDualI<bit long, bit sub, bit swap, dag oops, dag iops, 2938 InstrItinClass itin, string opc, string asm> 2939 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 2940 bits<4> Rd; 2941 let Inst{15-12} = 0b1111; 2942 let Inst{19-16} = Rd; 2943} 2944class AMulDualIa<bit long, bit sub, bit swap, dag oops, dag iops, 2945 InstrItinClass itin, string opc, string asm> 2946 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 2947 bits<4> Ra; 2948 let Inst{15-12} = Ra; 2949} 2950class AMulDualI64<bit long, bit sub, bit swap, dag oops, dag iops, 2951 InstrItinClass itin, string opc, string asm> 2952 : AMulDualIbase<long, sub, swap, oops, iops, itin, opc, asm> { 2953 bits<4> RdLo; 2954 bits<4> RdHi; 2955 let Inst{19-16} = RdHi; 2956 let Inst{15-12} = RdLo; 2957} 2958 2959multiclass AI_smld<bit sub, string opc> { 2960 2961 def D : AMulDualIa<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2962 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm, $Ra">; 2963 2964 def DX: AMulDualIa<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, GPR:$Ra), 2965 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm, $Ra">; 2966 2967 def LD: AMulDualI64<1, sub, 0, (outs GPR:$RdLo,GPR:$RdHi), 2968 (ins GPR:$Rn, GPR:$Rm), NoItinerary, 2969 !strconcat(opc, "ld"), "\t$RdLo, $RdHi, $Rn, $Rm">; 2970 2971 def LDX : AMulDualI64<1, sub, 1, (outs GPR:$RdLo,GPR:$RdHi), 2972 (ins GPR:$Rn, GPR:$Rm), NoItinerary, 2973 !strconcat(opc, "ldx"),"\t$RdLo, $RdHi, $Rn, $Rm">; 2974 2975} 2976 2977defm SMLA : AI_smld<0, "smla">; 2978defm SMLS : AI_smld<1, "smls">; 2979 2980multiclass AI_sdml<bit sub, string opc> { 2981 2982 def D : AMulDualI<0, sub, 0, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2983 NoItinerary, !strconcat(opc, "d"), "\t$Rd, $Rn, $Rm">; 2984 def DX : AMulDualI<0, sub, 1, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm), 2985 NoItinerary, !strconcat(opc, "dx"), "\t$Rd, $Rn, $Rm">; 2986} 2987 2988defm SMUA : AI_sdml<0, "smua">; 2989defm SMUS : AI_sdml<1, "smus">; 2990 2991//===----------------------------------------------------------------------===// 2992// Misc. Arithmetic Instructions. 2993// 2994 2995def CLZ : AMiscA1I<0b000010110, 0b0001, (outs GPR:$Rd), (ins GPR:$Rm), 2996 IIC_iUNAr, "clz", "\t$Rd, $Rm", 2997 [(set GPR:$Rd, (ctlz GPR:$Rm))]>, Requires<[IsARM, HasV5T]>; 2998 2999def RBIT : AMiscA1I<0b01101111, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm), 3000 IIC_iUNAr, "rbit", "\t$Rd, $Rm", 3001 [(set GPR:$Rd, (ARMrbit GPR:$Rm))]>, 3002 Requires<[IsARM, HasV6T2]>; 3003 3004def REV : AMiscA1I<0b01101011, 0b0011, (outs GPR:$Rd), (ins GPR:$Rm), 3005 IIC_iUNAr, "rev", "\t$Rd, $Rm", 3006 [(set GPR:$Rd, (bswap GPR:$Rm))]>, Requires<[IsARM, HasV6]>; 3007 3008def REV16 : AMiscA1I<0b01101011, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm), 3009 IIC_iUNAr, "rev16", "\t$Rd, $Rm", 3010 [(set GPR:$Rd, 3011 (or (and (srl GPR:$Rm, (i32 8)), 0xFF), 3012 (or (and (shl GPR:$Rm, (i32 8)), 0xFF00), 3013 (or (and (srl GPR:$Rm, (i32 8)), 0xFF0000), 3014 (and (shl GPR:$Rm, (i32 8)), 0xFF000000)))))]>, 3015 Requires<[IsARM, HasV6]>; 3016 3017def REVSH : AMiscA1I<0b01101111, 0b1011, (outs GPR:$Rd), (ins GPR:$Rm), 3018 IIC_iUNAr, "revsh", "\t$Rd, $Rm", 3019 [(set GPR:$Rd, 3020 (sext_inreg 3021 (or (srl GPR:$Rm, (i32 8)), 3022 (shl GPR:$Rm, (i32 8))), i16))]>, 3023 Requires<[IsARM, HasV6]>; 3024 3025def : ARMV6Pat<(sext_inreg (or (srl (and GPR:$Rm, 0xFF00), (i32 8)), 3026 (shl GPR:$Rm, (i32 8))), i16), 3027 (REVSH GPR:$Rm)>; 3028 3029// Need the AddedComplexity or else MOVs + REV would be chosen. 3030let AddedComplexity = 5 in 3031def : ARMV6Pat<(sra (bswap GPR:$Rm), (i32 16)), (REVSH GPR:$Rm)>; 3032 3033def lsl_shift_imm : SDNodeXForm<imm, [{ 3034 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue()); 3035 return CurDAG->getTargetConstant(Sh, MVT::i32); 3036}]>; 3037 3038def lsl_amt : ImmLeaf<i32, [{ 3039 return Imm > 0 && Imm < 32; 3040}], lsl_shift_imm>; 3041 3042def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd), 3043 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh), 3044 IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh", 3045 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF), 3046 (and (shl GPR:$Rm, lsl_amt:$sh), 3047 0xFFFF0000)))]>, 3048 Requires<[IsARM, HasV6]>; 3049 3050// Alternate cases for PKHBT where identities eliminate some nodes. 3051def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)), 3052 (PKHBT GPR:$Rn, GPR:$Rm, 0)>; 3053def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)), 3054 (PKHBT GPR:$Rn, GPR:$Rm, (lsl_shift_imm imm16_31:$sh))>; 3055 3056def asr_shift_imm : SDNodeXForm<imm, [{ 3057 unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue()); 3058 return CurDAG->getTargetConstant(Sh, MVT::i32); 3059}]>; 3060 3061def asr_amt : ImmLeaf<i32, [{ 3062 return Imm > 0 && Imm <= 32; 3063}], asr_shift_imm>; 3064 3065// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and 3066// will match the pattern below. 3067def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd), 3068 (ins GPR:$Rn, GPR:$Rm, shift_imm:$sh), 3069 IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh", 3070 [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000), 3071 (and (sra GPR:$Rm, asr_amt:$sh), 3072 0xFFFF)))]>, 3073 Requires<[IsARM, HasV6]>; 3074 3075// Alternate cases for PKHTB where identities eliminate some nodes. Note that 3076// a shift amount of 0 is *not legal* here, it is PKHBT instead. 3077def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)), 3078 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>; 3079def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), 3080 (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)), 3081 (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>; 3082 3083//===----------------------------------------------------------------------===// 3084// Comparison Instructions... 3085// 3086 3087defm CMP : AI1_cmp_irs<0b1010, "cmp", 3088 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr, 3089 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>; 3090 3091// ARMcmpZ can re-use the above instruction definitions. 3092def : ARMPat<(ARMcmpZ GPR:$src, so_imm:$imm), 3093 (CMPri GPR:$src, so_imm:$imm)>; 3094def : ARMPat<(ARMcmpZ GPR:$src, GPR:$rhs), 3095 (CMPrr GPR:$src, GPR:$rhs)>; 3096def : ARMPat<(ARMcmpZ GPR:$src, so_reg:$rhs), 3097 (CMPrs GPR:$src, so_reg:$rhs)>; 3098 3099// FIXME: We have to be careful when using the CMN instruction and comparison 3100// with 0. One would expect these two pieces of code should give identical 3101// results: 3102// 3103// rsbs r1, r1, 0 3104// cmp r0, r1 3105// mov r0, #0 3106// it ls 3107// mov r0, #1 3108// 3109// and: 3110// 3111// cmn r0, r1 3112// mov r0, #0 3113// it ls 3114// mov r0, #1 3115// 3116// However, the CMN gives the *opposite* result when r1 is 0. This is because 3117// the carry flag is set in the CMP case but not in the CMN case. In short, the 3118// CMP instruction doesn't perform a truncate of the (logical) NOT of 0 plus the 3119// value of r0 and the carry bit (because the "carry bit" parameter to 3120// AddWithCarry is defined as 1 in this case, the carry flag will always be set 3121// when r0 >= 0). The CMN instruction doesn't perform a NOT of 0 so there is 3122// never a "carry" when this AddWithCarry is performed (because the "carry bit" 3123// parameter to AddWithCarry is defined as 0). 3124// 3125// When x is 0 and unsigned: 3126// 3127// x = 0 3128// ~x = 0xFFFF FFFF 3129// ~x + 1 = 0x1 0000 0000 3130// (-x = 0) != (0x1 0000 0000 = ~x + 1) 3131// 3132// Therefore, we should disable CMN when comparing against zero, until we can 3133// limit when the CMN instruction is used (when we know that the RHS is not 0 or 3134// when it's a comparison which doesn't look at the 'carry' flag). 3135// 3136// (See the ARM docs for the "AddWithCarry" pseudo-code.) 3137// 3138// This is related to <rdar://problem/7569620>. 3139// 3140//defm CMN : AI1_cmp_irs<0b1011, "cmn", 3141// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>; 3142 3143// Note that TST/TEQ don't set all the same flags that CMP does! 3144defm TST : AI1_cmp_irs<0b1000, "tst", 3145 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr, 3146 BinOpFrag<(ARMcmpZ (and_su node:$LHS, node:$RHS), 0)>, 1>; 3147defm TEQ : AI1_cmp_irs<0b1001, "teq", 3148 IIC_iTSTi, IIC_iTSTr, IIC_iTSTsr, 3149 BinOpFrag<(ARMcmpZ (xor_su node:$LHS, node:$RHS), 0)>, 1>; 3150 3151defm CMNz : AI1_cmp_irs<0b1011, "cmn", 3152 IIC_iCMPi, IIC_iCMPr, IIC_iCMPsr, 3153 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>; 3154 3155//def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm), 3156// (CMNri GPR:$src, so_imm_neg:$imm)>; 3157 3158def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm), 3159 (CMNzri GPR:$src, so_imm_neg:$imm)>; 3160 3161// Pseudo i64 compares for some floating point compares. 3162let usesCustomInserter = 1, isBranch = 1, isTerminator = 1, 3163 Defs = [CPSR] in { 3164def BCCi64 : PseudoInst<(outs), 3165 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, brtarget:$dst), 3166 IIC_Br, 3167 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, GPR:$rhs1, GPR:$rhs2, bb:$dst)]>; 3168 3169def BCCZi64 : PseudoInst<(outs), 3170 (ins i32imm:$cc, GPR:$lhs1, GPR:$lhs2, brtarget:$dst), IIC_Br, 3171 [(ARMBcci64 imm:$cc, GPR:$lhs1, GPR:$lhs2, 0, 0, bb:$dst)]>; 3172} // usesCustomInserter 3173 3174 3175// Conditional moves 3176// FIXME: should be able to write a pattern for ARMcmov, but can't use 3177// a two-value operand where a dag node expects two operands. :( 3178let neverHasSideEffects = 1 in { 3179def MOVCCr : ARMPseudoInst<(outs GPR:$Rd), (ins GPR:$false, GPR:$Rm, pred:$p), 3180 Size4Bytes, IIC_iCMOVr, 3181 [/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>, 3182 RegConstraint<"$false = $Rd">; 3183def MOVCCs : ARMPseudoInst<(outs GPR:$Rd), 3184 (ins GPR:$false, so_reg:$shift, pred:$p), 3185 Size4Bytes, IIC_iCMOVsr, 3186 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_reg:$shift, imm:$cc, CCR:$ccr))*/]>, 3187 RegConstraint<"$false = $Rd">; 3188 3189let isMoveImm = 1 in 3190def MOVCCi16 : ARMPseudoInst<(outs GPR:$Rd), 3191 (ins GPR:$false, i32imm_hilo16:$imm, pred:$p), 3192 Size4Bytes, IIC_iMOVi, 3193 []>, 3194 RegConstraint<"$false = $Rd">, Requires<[IsARM, HasV6T2]>; 3195 3196let isMoveImm = 1 in 3197def MOVCCi : ARMPseudoInst<(outs GPR:$Rd), 3198 (ins GPR:$false, so_imm:$imm, pred:$p), 3199 Size4Bytes, IIC_iCMOVi, 3200 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm:$imm, imm:$cc, CCR:$ccr))*/]>, 3201 RegConstraint<"$false = $Rd">; 3202 3203// Two instruction predicate mov immediate. 3204let isMoveImm = 1 in 3205def MOVCCi32imm : ARMPseudoInst<(outs GPR:$Rd), 3206 (ins GPR:$false, i32imm:$src, pred:$p), 3207 Size8Bytes, IIC_iCMOVix2, []>, RegConstraint<"$false = $Rd">; 3208 3209let isMoveImm = 1 in 3210def MVNCCi : ARMPseudoInst<(outs GPR:$Rd), 3211 (ins GPR:$false, so_imm:$imm, pred:$p), 3212 Size4Bytes, IIC_iCMOVi, 3213 [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>, 3214 RegConstraint<"$false = $Rd">; 3215} // neverHasSideEffects 3216 3217//===----------------------------------------------------------------------===// 3218// Atomic operations intrinsics 3219// 3220 3221def memb_opt : Operand<i32> { 3222 let PrintMethod = "printMemBOption"; 3223 let ParserMatchClass = MemBarrierOptOperand; 3224} 3225 3226// memory barriers protect the atomic sequences 3227let hasSideEffects = 1 in { 3228def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, 3229 "dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>, 3230 Requires<[IsARM, HasDB]> { 3231 bits<4> opt; 3232 let Inst{31-4} = 0xf57ff05; 3233 let Inst{3-0} = opt; 3234} 3235} 3236 3237def DSB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary, 3238 "dsb", "\t$opt", 3239 [/* For disassembly only; pattern left blank */]>, 3240 Requires<[IsARM, HasDB]> { 3241 bits<4> opt; 3242 let Inst{31-4} = 0xf57ff04; 3243 let Inst{3-0} = opt; 3244} 3245 3246// ISB has only full system option -- for disassembly only 3247def ISB : AInoP<(outs), (ins), MiscFrm, NoItinerary, "isb", "", []>, 3248 Requires<[IsARM, HasDB]> { 3249 let Inst{31-4} = 0xf57ff06; 3250 let Inst{3-0} = 0b1111; 3251} 3252 3253let usesCustomInserter = 1 in { 3254 let Uses = [CPSR] in { 3255 def ATOMIC_LOAD_ADD_I8 : PseudoInst< 3256 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3257 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>; 3258 def ATOMIC_LOAD_SUB_I8 : PseudoInst< 3259 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3260 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>; 3261 def ATOMIC_LOAD_AND_I8 : PseudoInst< 3262 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3263 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>; 3264 def ATOMIC_LOAD_OR_I8 : PseudoInst< 3265 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3266 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>; 3267 def ATOMIC_LOAD_XOR_I8 : PseudoInst< 3268 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3269 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>; 3270 def ATOMIC_LOAD_NAND_I8 : PseudoInst< 3271 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3272 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>; 3273 def ATOMIC_LOAD_MIN_I8 : PseudoInst< 3274 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 3275 [(set GPR:$dst, (atomic_load_min_8 GPR:$ptr, GPR:$val))]>; 3276 def ATOMIC_LOAD_MAX_I8 : PseudoInst< 3277 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 3278 [(set GPR:$dst, (atomic_load_max_8 GPR:$ptr, GPR:$val))]>; 3279 def ATOMIC_LOAD_UMIN_I8 : PseudoInst< 3280 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 3281 [(set GPR:$dst, (atomic_load_min_8 GPR:$ptr, GPR:$val))]>; 3282 def ATOMIC_LOAD_UMAX_I8 : PseudoInst< 3283 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 3284 [(set GPR:$dst, (atomic_load_max_8 GPR:$ptr, GPR:$val))]>; 3285 def ATOMIC_LOAD_ADD_I16 : PseudoInst< 3286 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3287 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>; 3288 def ATOMIC_LOAD_SUB_I16 : PseudoInst< 3289 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3290 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>; 3291 def ATOMIC_LOAD_AND_I16 : PseudoInst< 3292 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3293 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>; 3294 def ATOMIC_LOAD_OR_I16 : PseudoInst< 3295 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3296 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>; 3297 def ATOMIC_LOAD_XOR_I16 : PseudoInst< 3298 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3299 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>; 3300 def ATOMIC_LOAD_NAND_I16 : PseudoInst< 3301 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3302 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>; 3303 def ATOMIC_LOAD_MIN_I16 : PseudoInst< 3304 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 3305 [(set GPR:$dst, (atomic_load_min_16 GPR:$ptr, GPR:$val))]>; 3306 def ATOMIC_LOAD_MAX_I16 : PseudoInst< 3307 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 3308 [(set GPR:$dst, (atomic_load_max_16 GPR:$ptr, GPR:$val))]>; 3309 def ATOMIC_LOAD_UMIN_I16 : PseudoInst< 3310 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 3311 [(set GPR:$dst, (atomic_load_min_16 GPR:$ptr, GPR:$val))]>; 3312 def ATOMIC_LOAD_UMAX_I16 : PseudoInst< 3313 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 3314 [(set GPR:$dst, (atomic_load_max_16 GPR:$ptr, GPR:$val))]>; 3315 def ATOMIC_LOAD_ADD_I32 : PseudoInst< 3316 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3317 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>; 3318 def ATOMIC_LOAD_SUB_I32 : PseudoInst< 3319 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3320 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>; 3321 def ATOMIC_LOAD_AND_I32 : PseudoInst< 3322 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3323 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>; 3324 def ATOMIC_LOAD_OR_I32 : PseudoInst< 3325 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3326 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>; 3327 def ATOMIC_LOAD_XOR_I32 : PseudoInst< 3328 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3329 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>; 3330 def ATOMIC_LOAD_NAND_I32 : PseudoInst< 3331 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 3332 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>; 3333 def ATOMIC_LOAD_MIN_I32 : PseudoInst< 3334 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 3335 [(set GPR:$dst, (atomic_load_min_32 GPR:$ptr, GPR:$val))]>; 3336 def ATOMIC_LOAD_MAX_I32 : PseudoInst< 3337 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 3338 [(set GPR:$dst, (atomic_load_max_32 GPR:$ptr, GPR:$val))]>; 3339 def ATOMIC_LOAD_UMIN_I32 : PseudoInst< 3340 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 3341 [(set GPR:$dst, (atomic_load_min_32 GPR:$ptr, GPR:$val))]>; 3342 def ATOMIC_LOAD_UMAX_I32 : PseudoInst< 3343 (outs GPR:$dst), (ins GPR:$ptr, GPR:$val), NoItinerary, 3344 [(set GPR:$dst, (atomic_load_max_32 GPR:$ptr, GPR:$val))]>; 3345 3346 def ATOMIC_SWAP_I8 : PseudoInst< 3347 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, 3348 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>; 3349 def ATOMIC_SWAP_I16 : PseudoInst< 3350 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, 3351 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>; 3352 def ATOMIC_SWAP_I32 : PseudoInst< 3353 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, 3354 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>; 3355 3356 def ATOMIC_CMP_SWAP_I8 : PseudoInst< 3357 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, 3358 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>; 3359 def ATOMIC_CMP_SWAP_I16 : PseudoInst< 3360 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, 3361 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>; 3362 def ATOMIC_CMP_SWAP_I32 : PseudoInst< 3363 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, 3364 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>; 3365} 3366} 3367 3368let mayLoad = 1 in { 3369def LDREXB : AIldrex<0b10, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary, 3370 "ldrexb", "\t$Rt, $addr", []>; 3371def LDREXH : AIldrex<0b11, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary, 3372 "ldrexh", "\t$Rt, $addr", []>; 3373def LDREX : AIldrex<0b00, (outs GPR:$Rt), (ins addrmode7:$addr), NoItinerary, 3374 "ldrex", "\t$Rt, $addr", []>; 3375let hasExtraDefRegAllocReq = 1 in 3376 def LDREXD : AIldrex<0b01, (outs GPR:$Rt, GPR:$Rt2), (ins addrmode7:$addr), 3377 NoItinerary, "ldrexd", "\t$Rt, $Rt2, $addr", []>; 3378} 3379 3380let mayStore = 1, Constraints = "@earlyclobber $Rd" in { 3381def STREXB : AIstrex<0b10, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr), 3382 NoItinerary, "strexb", "\t$Rd, $Rt, $addr", []>; 3383def STREXH : AIstrex<0b11, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr), 3384 NoItinerary, "strexh", "\t$Rd, $Rt, $addr", []>; 3385def STREX : AIstrex<0b00, (outs GPR:$Rd), (ins GPR:$Rt, addrmode7:$addr), 3386 NoItinerary, "strex", "\t$Rd, $Rt, $addr", []>; 3387} 3388 3389let hasExtraSrcRegAllocReq = 1, Constraints = "@earlyclobber $Rd" in 3390def STREXD : AIstrex<0b01, (outs GPR:$Rd), 3391 (ins GPR:$Rt, GPR:$Rt2, addrmode7:$addr), 3392 NoItinerary, "strexd", "\t$Rd, $Rt, $Rt2, $addr", []>; 3393 3394// Clear-Exclusive is for disassembly only. 3395def CLREX : AXI<(outs), (ins), MiscFrm, NoItinerary, "clrex", 3396 [/* For disassembly only; pattern left blank */]>, 3397 Requires<[IsARM, HasV7]> { 3398 let Inst{31-0} = 0b11110101011111111111000000011111; 3399} 3400 3401// SWP/SWPB are deprecated in V6/V7 and for disassembly only. 3402let mayLoad = 1 in { 3403def SWP : AIswp<0, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swp", 3404 [/* For disassembly only; pattern left blank */]>; 3405def SWPB : AIswp<1, (outs GPR:$Rt), (ins GPR:$Rt2, GPR:$Rn), "swpb", 3406 [/* For disassembly only; pattern left blank */]>; 3407} 3408 3409//===----------------------------------------------------------------------===// 3410// Coprocessor Instructions. 3411// 3412 3413def CDP : ABI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1, 3414 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2), 3415 NoItinerary, "cdp", "\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", 3416 [(int_arm_cdp imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn, 3417 imm:$CRm, imm:$opc2)]> { 3418 bits<4> opc1; 3419 bits<4> CRn; 3420 bits<4> CRd; 3421 bits<4> cop; 3422 bits<3> opc2; 3423 bits<4> CRm; 3424 3425 let Inst{3-0} = CRm; 3426 let Inst{4} = 0; 3427 let Inst{7-5} = opc2; 3428 let Inst{11-8} = cop; 3429 let Inst{15-12} = CRd; 3430 let Inst{19-16} = CRn; 3431 let Inst{23-20} = opc1; 3432} 3433 3434def CDP2 : ABXI<0b1110, (outs), (ins p_imm:$cop, i32imm:$opc1, 3435 c_imm:$CRd, c_imm:$CRn, c_imm:$CRm, i32imm:$opc2), 3436 NoItinerary, "cdp2\t$cop, $opc1, $CRd, $CRn, $CRm, $opc2", 3437 [(int_arm_cdp2 imm:$cop, imm:$opc1, imm:$CRd, imm:$CRn, 3438 imm:$CRm, imm:$opc2)]> { 3439 let Inst{31-28} = 0b1111; 3440 bits<4> opc1; 3441 bits<4> CRn; 3442 bits<4> CRd; 3443 bits<4> cop; 3444 bits<3> opc2; 3445 bits<4> CRm; 3446 3447 let Inst{3-0} = CRm; 3448 let Inst{4} = 0; 3449 let Inst{7-5} = opc2; 3450 let Inst{11-8} = cop; 3451 let Inst{15-12} = CRd; 3452 let Inst{19-16} = CRn; 3453 let Inst{23-20} = opc1; 3454} 3455 3456class ACI<dag oops, dag iops, string opc, string asm, 3457 IndexMode im = IndexModeNone> 3458 : InoP<oops, iops, AddrModeNone, Size4Bytes, im, BrFrm, NoItinerary, 3459 opc, asm, "", [/* For disassembly only; pattern left blank */]> { 3460 let Inst{27-25} = 0b110; 3461} 3462 3463multiclass LdStCop<bits<4> op31_28, bit load, dag ops, string opc, string cond>{ 3464 3465 def _OFFSET : ACI<(outs), 3466 !con((ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), ops), 3467 !strconcat(opc, cond), "\tp$cop, cr$CRd, $addr"> { 3468 let Inst{31-28} = op31_28; 3469 let Inst{24} = 1; // P = 1 3470 let Inst{21} = 0; // W = 0 3471 let Inst{22} = 0; // D = 0 3472 let Inst{20} = load; 3473 } 3474 3475 def _PRE : ACI<(outs), 3476 !con((ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), ops), 3477 !strconcat(opc, cond), "\tp$cop, cr$CRd, $addr!", IndexModePre> { 3478 let Inst{31-28} = op31_28; 3479 let Inst{24} = 1; // P = 1 3480 let Inst{21} = 1; // W = 1 3481 let Inst{22} = 0; // D = 0 3482 let Inst{20} = load; 3483 } 3484 3485 def _POST : ACI<(outs), 3486 !con((ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), ops), 3487 !strconcat(opc, cond), "\tp$cop, cr$CRd, $addr", IndexModePost> { 3488 let Inst{31-28} = op31_28; 3489 let Inst{24} = 0; // P = 0 3490 let Inst{21} = 1; // W = 1 3491 let Inst{22} = 0; // D = 0 3492 let Inst{20} = load; 3493 } 3494 3495 def _OPTION : ACI<(outs), 3496 !con((ins nohash_imm:$cop,nohash_imm:$CRd,GPR:$base, nohash_imm:$option), 3497 ops), 3498 !strconcat(opc, cond), "\tp$cop, cr$CRd, [$base], \\{$option\\}"> { 3499 let Inst{31-28} = op31_28; 3500 let Inst{24} = 0; // P = 0 3501 let Inst{23} = 1; // U = 1 3502 let Inst{21} = 0; // W = 0 3503 let Inst{22} = 0; // D = 0 3504 let Inst{20} = load; 3505 } 3506 3507 def L_OFFSET : ACI<(outs), 3508 !con((ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), ops), 3509 !strconcat(!strconcat(opc, "l"), cond), "\tp$cop, cr$CRd, $addr"> { 3510 let Inst{31-28} = op31_28; 3511 let Inst{24} = 1; // P = 1 3512 let Inst{21} = 0; // W = 0 3513 let Inst{22} = 1; // D = 1 3514 let Inst{20} = load; 3515 } 3516 3517 def L_PRE : ACI<(outs), 3518 !con((ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), ops), 3519 !strconcat(!strconcat(opc, "l"), cond), "\tp$cop, cr$CRd, $addr!", 3520 IndexModePre> { 3521 let Inst{31-28} = op31_28; 3522 let Inst{24} = 1; // P = 1 3523 let Inst{21} = 1; // W = 1 3524 let Inst{22} = 1; // D = 1 3525 let Inst{20} = load; 3526 } 3527 3528 def L_POST : ACI<(outs), 3529 !con((ins nohash_imm:$cop, nohash_imm:$CRd, addrmode2:$addr), ops), 3530 !strconcat(!strconcat(opc, "l"), cond), "\tp$cop, cr$CRd, $addr", 3531 IndexModePost> { 3532 let Inst{31-28} = op31_28; 3533 let Inst{24} = 0; // P = 0 3534 let Inst{21} = 1; // W = 1 3535 let Inst{22} = 1; // D = 1 3536 let Inst{20} = load; 3537 } 3538 3539 def L_OPTION : ACI<(outs), 3540 !con((ins nohash_imm:$cop, nohash_imm:$CRd,GPR:$base,nohash_imm:$option), 3541 ops), 3542 !strconcat(!strconcat(opc, "l"), cond), 3543 "\tp$cop, cr$CRd, [$base], \\{$option\\}"> { 3544 let Inst{31-28} = op31_28; 3545 let Inst{24} = 0; // P = 0 3546 let Inst{23} = 1; // U = 1 3547 let Inst{21} = 0; // W = 0 3548 let Inst{22} = 1; // D = 1 3549 let Inst{20} = load; 3550 } 3551} 3552 3553defm LDC : LdStCop<{?,?,?,?}, 1, (ins pred:$p), "ldc", "${p}">; 3554defm LDC2 : LdStCop<0b1111, 1, (ins), "ldc2", "">; 3555defm STC : LdStCop<{?,?,?,?}, 0, (ins pred:$p), "stc", "${p}">; 3556defm STC2 : LdStCop<0b1111, 0, (ins), "stc2", "">; 3557 3558//===----------------------------------------------------------------------===// 3559// Move between coprocessor and ARM core register -- for disassembly only 3560// 3561 3562class MovRCopro<string opc, bit direction, dag oops, dag iops, 3563 list<dag> pattern> 3564 : ABI<0b1110, oops, iops, NoItinerary, opc, 3565 "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2", pattern> { 3566 let Inst{20} = direction; 3567 let Inst{4} = 1; 3568 3569 bits<4> Rt; 3570 bits<4> cop; 3571 bits<3> opc1; 3572 bits<3> opc2; 3573 bits<4> CRm; 3574 bits<4> CRn; 3575 3576 let Inst{15-12} = Rt; 3577 let Inst{11-8} = cop; 3578 let Inst{23-21} = opc1; 3579 let Inst{7-5} = opc2; 3580 let Inst{3-0} = CRm; 3581 let Inst{19-16} = CRn; 3582} 3583 3584def MCR : MovRCopro<"mcr", 0 /* from ARM core register to coprocessor */, 3585 (outs), 3586 (ins p_imm:$cop, i32imm:$opc1, GPR:$Rt, c_imm:$CRn, 3587 c_imm:$CRm, i32imm:$opc2), 3588 [(int_arm_mcr imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn, 3589 imm:$CRm, imm:$opc2)]>; 3590def MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */, 3591 (outs GPR:$Rt), 3592 (ins p_imm:$cop, i32imm:$opc1, c_imm:$CRn, c_imm:$CRm, 3593 i32imm:$opc2), []>; 3594 3595def : ARMPat<(int_arm_mrc imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2), 3596 (MRC imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>; 3597 3598class MovRCopro2<string opc, bit direction, dag oops, dag iops, 3599 list<dag> pattern> 3600 : ABXI<0b1110, oops, iops, NoItinerary, 3601 !strconcat(opc, "\t$cop, $opc1, $Rt, $CRn, $CRm, $opc2"), pattern> { 3602 let Inst{31-28} = 0b1111; 3603 let Inst{20} = direction; 3604 let Inst{4} = 1; 3605 3606 bits<4> Rt; 3607 bits<4> cop; 3608 bits<3> opc1; 3609 bits<3> opc2; 3610 bits<4> CRm; 3611 bits<4> CRn; 3612 3613 let Inst{15-12} = Rt; 3614 let Inst{11-8} = cop; 3615 let Inst{23-21} = opc1; 3616 let Inst{7-5} = opc2; 3617 let Inst{3-0} = CRm; 3618 let Inst{19-16} = CRn; 3619} 3620 3621def MCR2 : MovRCopro2<"mcr2", 0 /* from ARM core register to coprocessor */, 3622 (outs), 3623 (ins p_imm:$cop, i32imm:$opc1, GPR:$Rt, c_imm:$CRn, 3624 c_imm:$CRm, i32imm:$opc2), 3625 [(int_arm_mcr2 imm:$cop, imm:$opc1, GPR:$Rt, imm:$CRn, 3626 imm:$CRm, imm:$opc2)]>; 3627def MRC2 : MovRCopro2<"mrc2", 1 /* from coprocessor to ARM core register */, 3628 (outs GPR:$Rt), 3629 (ins p_imm:$cop, i32imm:$opc1, c_imm:$CRn, c_imm:$CRm, 3630 i32imm:$opc2), []>; 3631 3632def : ARMV5TPat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn, 3633 imm:$CRm, imm:$opc2), 3634 (MRC2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>; 3635 3636class MovRRCopro<string opc, bit direction, 3637 list<dag> pattern = [/* For disassembly only */]> 3638 : ABI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc1, 3639 GPR:$Rt, GPR:$Rt2, c_imm:$CRm), 3640 NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", pattern> { 3641 let Inst{23-21} = 0b010; 3642 let Inst{20} = direction; 3643 3644 bits<4> Rt; 3645 bits<4> Rt2; 3646 bits<4> cop; 3647 bits<4> opc1; 3648 bits<4> CRm; 3649 3650 let Inst{15-12} = Rt; 3651 let Inst{19-16} = Rt2; 3652 let Inst{11-8} = cop; 3653 let Inst{7-4} = opc1; 3654 let Inst{3-0} = CRm; 3655} 3656 3657def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */, 3658 [(int_arm_mcrr imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, 3659 imm:$CRm)]>; 3660def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>; 3661 3662class MovRRCopro2<string opc, bit direction, 3663 list<dag> pattern = [/* For disassembly only */]> 3664 : ABXI<0b1100, (outs), (ins p_imm:$cop, i32imm:$opc1, 3665 GPR:$Rt, GPR:$Rt2, c_imm:$CRm), NoItinerary, 3666 !strconcat(opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm"), pattern> { 3667 let Inst{31-28} = 0b1111; 3668 let Inst{23-21} = 0b010; 3669 let Inst{20} = direction; 3670 3671 bits<4> Rt; 3672 bits<4> Rt2; 3673 bits<4> cop; 3674 bits<4> opc1; 3675 bits<4> CRm; 3676 3677 let Inst{15-12} = Rt; 3678 let Inst{19-16} = Rt2; 3679 let Inst{11-8} = cop; 3680 let Inst{7-4} = opc1; 3681 let Inst{3-0} = CRm; 3682} 3683 3684def MCRR2 : MovRRCopro2<"mcrr2", 0 /* from ARM core register to coprocessor */, 3685 [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, 3686 imm:$CRm)]>; 3687def MRRC2 : MovRRCopro2<"mrrc2", 1 /* from coprocessor to ARM core register */>; 3688 3689//===----------------------------------------------------------------------===// 3690// Move between special register and ARM core register -- for disassembly only 3691// 3692 3693// Move to ARM core register from Special Register 3694def MRS : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, cpsr", 3695 [/* For disassembly only; pattern left blank */]> { 3696 bits<4> Rd; 3697 let Inst{23-16} = 0b00001111; 3698 let Inst{15-12} = Rd; 3699 let Inst{7-4} = 0b0000; 3700} 3701 3702def MRSsys : ABI<0b0001, (outs GPR:$Rd), (ins), NoItinerary,"mrs","\t$Rd, spsr", 3703 [/* For disassembly only; pattern left blank */]> { 3704 bits<4> Rd; 3705 let Inst{23-16} = 0b01001111; 3706 let Inst{15-12} = Rd; 3707 let Inst{7-4} = 0b0000; 3708} 3709 3710// Move from ARM core register to Special Register 3711// 3712// No need to have both system and application versions, the encodings are the 3713// same and the assembly parser has no way to distinguish between them. The mask 3714// operand contains the special register (R Bit) in bit 4 and bits 3-0 contains 3715// the mask with the fields to be accessed in the special register. 3716def MSR : ABI<0b0001, (outs), (ins msr_mask:$mask, GPR:$Rn), NoItinerary, 3717 "msr", "\t$mask, $Rn", 3718 [/* For disassembly only; pattern left blank */]> { 3719 bits<5> mask; 3720 bits<4> Rn; 3721 3722 let Inst{23} = 0; 3723 let Inst{22} = mask{4}; // R bit 3724 let Inst{21-20} = 0b10; 3725 let Inst{19-16} = mask{3-0}; 3726 let Inst{15-12} = 0b1111; 3727 let Inst{11-4} = 0b00000000; 3728 let Inst{3-0} = Rn; 3729} 3730 3731def MSRi : ABI<0b0011, (outs), (ins msr_mask:$mask, so_imm:$a), NoItinerary, 3732 "msr", "\t$mask, $a", 3733 [/* For disassembly only; pattern left blank */]> { 3734 bits<5> mask; 3735 bits<12> a; 3736 3737 let Inst{23} = 0; 3738 let Inst{22} = mask{4}; // R bit 3739 let Inst{21-20} = 0b10; 3740 let Inst{19-16} = mask{3-0}; 3741 let Inst{15-12} = 0b1111; 3742 let Inst{11-0} = a; 3743} 3744 3745//===----------------------------------------------------------------------===// 3746// TLS Instructions 3747// 3748 3749// __aeabi_read_tp preserves the registers r1-r3. 3750// This is a pseudo inst so that we can get the encoding right, 3751// complete with fixup for the aeabi_read_tp function. 3752let isCall = 1, 3753 Defs = [R0, R12, LR, CPSR], Uses = [SP] in { 3754 def TPsoft : PseudoInst<(outs), (ins), IIC_Br, 3755 [(set R0, ARMthread_pointer)]>; 3756} 3757 3758//===----------------------------------------------------------------------===// 3759// SJLJ Exception handling intrinsics 3760// eh_sjlj_setjmp() is an instruction sequence to store the return 3761// address and save #0 in R0 for the non-longjmp case. 3762// Since by its nature we may be coming from some other function to get 3763// here, and we're using the stack frame for the containing function to 3764// save/restore registers, we can't keep anything live in regs across 3765// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 3766// when we get here from a longjmp(). We force everything out of registers 3767// except for our own input by listing the relevant registers in Defs. By 3768// doing so, we also cause the prologue/epilogue code to actively preserve 3769// all of the callee-saved resgisters, which is exactly what we want. 3770// A constant value is passed in $val, and we use the location as a scratch. 3771// 3772// These are pseudo-instructions and are lowered to individual MC-insts, so 3773// no encoding information is necessary. 3774let Defs = 3775 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR, 3776 QQQQ0, QQQQ1, QQQQ2, QQQQ3 ], hasSideEffects = 1, isBarrier = 1 in { 3777 def Int_eh_sjlj_setjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$val), 3778 NoItinerary, 3779 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>, 3780 Requires<[IsARM, HasVFP2]>; 3781} 3782 3783let Defs = 3784 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, CPSR ], 3785 hasSideEffects = 1, isBarrier = 1 in { 3786 def Int_eh_sjlj_setjmp_nofp : PseudoInst<(outs), (ins GPR:$src, GPR:$val), 3787 NoItinerary, 3788 [(set R0, (ARMeh_sjlj_setjmp GPR:$src, GPR:$val))]>, 3789 Requires<[IsARM, NoVFP]>; 3790} 3791 3792// FIXME: Non-Darwin version(s) 3793let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, 3794 Defs = [ R7, LR, SP ] in { 3795def Int_eh_sjlj_longjmp : PseudoInst<(outs), (ins GPR:$src, GPR:$scratch), 3796 NoItinerary, 3797 [(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>, 3798 Requires<[IsARM, IsDarwin]>; 3799} 3800 3801// eh.sjlj.dispatchsetup pseudo-instruction. 3802// This pseudo is used for ARM, Thumb1 and Thumb2. Any differences are 3803// handled when the pseudo is expanded (which happens before any passes 3804// that need the instruction size). 3805let isBarrier = 1, hasSideEffects = 1 in 3806def Int_eh_sjlj_dispatchsetup : 3807 PseudoInst<(outs), (ins GPR:$src), NoItinerary, 3808 [(ARMeh_sjlj_dispatchsetup GPR:$src)]>, 3809 Requires<[IsDarwin]>; 3810 3811//===----------------------------------------------------------------------===// 3812// Non-Instruction Patterns 3813// 3814 3815// Large immediate handling. 3816 3817// 32-bit immediate using two piece so_imms or movw + movt. 3818// This is a single pseudo instruction, the benefit is that it can be remat'd 3819// as a single unit instead of having to handle reg inputs. 3820// FIXME: Remove this when we can do generalized remat. 3821let isReMaterializable = 1, isMoveImm = 1 in 3822def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2, 3823 [(set GPR:$dst, (arm_i32imm:$src))]>, 3824 Requires<[IsARM]>; 3825 3826// Pseudo instruction that combines movw + movt + add pc (if PIC). 3827// It also makes it possible to rematerialize the instructions. 3828// FIXME: Remove this when we can do generalized remat and when machine licm 3829// can properly the instructions. 3830let isReMaterializable = 1 in { 3831def MOV_ga_pcrel : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 3832 IIC_iMOVix2addpc, 3833 [(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr))]>, 3834 Requires<[IsARM, UseMovt]>; 3835 3836def MOV_ga_dyn : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 3837 IIC_iMOVix2, 3838 [(set GPR:$dst, (ARMWrapperDYN tglobaladdr:$addr))]>, 3839 Requires<[IsARM, UseMovt]>; 3840 3841let AddedComplexity = 10 in 3842def MOV_ga_pcrel_ldr : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr), 3843 IIC_iMOVix2ld, 3844 [(set GPR:$dst, (load (ARMWrapperPIC tglobaladdr:$addr)))]>, 3845 Requires<[IsARM, UseMovt]>; 3846} // isReMaterializable 3847 3848// ConstantPool, GlobalAddress, and JumpTable 3849def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>, 3850 Requires<[IsARM, DontUseMovt]>; 3851def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>; 3852def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>, 3853 Requires<[IsARM, UseMovt]>; 3854def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id), 3855 (LEApcrelJT tjumptable:$dst, imm:$id)>; 3856 3857// TODO: add,sub,and, 3-instr forms? 3858 3859// Tail calls 3860def : ARMPat<(ARMtcret tcGPR:$dst), 3861 (TCRETURNri tcGPR:$dst)>, Requires<[IsDarwin]>; 3862 3863def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)), 3864 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>; 3865 3866def : ARMPat<(ARMtcret (i32 texternalsym:$dst)), 3867 (TCRETURNdi texternalsym:$dst)>, Requires<[IsDarwin]>; 3868 3869def : ARMPat<(ARMtcret tcGPR:$dst), 3870 (TCRETURNriND tcGPR:$dst)>, Requires<[IsNotDarwin]>; 3871 3872def : ARMPat<(ARMtcret (i32 tglobaladdr:$dst)), 3873 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>; 3874 3875def : ARMPat<(ARMtcret (i32 texternalsym:$dst)), 3876 (TCRETURNdiND texternalsym:$dst)>, Requires<[IsNotDarwin]>; 3877 3878// Direct calls 3879def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>, 3880 Requires<[IsARM, IsNotDarwin]>; 3881def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>, 3882 Requires<[IsARM, IsDarwin]>; 3883 3884// zextload i1 -> zextload i8 3885def : ARMPat<(zextloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 3886def : ARMPat<(zextloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 3887 3888// extload -> zextload 3889def : ARMPat<(extloadi1 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 3890def : ARMPat<(extloadi1 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 3891def : ARMPat<(extloadi8 addrmode_imm12:$addr), (LDRBi12 addrmode_imm12:$addr)>; 3892def : ARMPat<(extloadi8 ldst_so_reg:$addr), (LDRBrs ldst_so_reg:$addr)>; 3893 3894def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>; 3895 3896def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>; 3897def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>; 3898 3899// smul* and smla* 3900def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 3901 (sra (shl GPR:$b, (i32 16)), (i32 16))), 3902 (SMULBB GPR:$a, GPR:$b)>; 3903def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b), 3904 (SMULBB GPR:$a, GPR:$b)>; 3905def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 3906 (sra GPR:$b, (i32 16))), 3907 (SMULBT GPR:$a, GPR:$b)>; 3908def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))), 3909 (SMULBT GPR:$a, GPR:$b)>; 3910def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), 3911 (sra (shl GPR:$b, (i32 16)), (i32 16))), 3912 (SMULTB GPR:$a, GPR:$b)>; 3913def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b), 3914 (SMULTB GPR:$a, GPR:$b)>; 3915def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))), 3916 (i32 16)), 3917 (SMULWB GPR:$a, GPR:$b)>; 3918def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)), 3919 (SMULWB GPR:$a, GPR:$b)>; 3920 3921def : ARMV5TEPat<(add GPR:$acc, 3922 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 3923 (sra (shl GPR:$b, (i32 16)), (i32 16)))), 3924 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 3925def : ARMV5TEPat<(add GPR:$acc, 3926 (mul sext_16_node:$a, sext_16_node:$b)), 3927 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 3928def : ARMV5TEPat<(add GPR:$acc, 3929 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 3930 (sra GPR:$b, (i32 16)))), 3931 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 3932def : ARMV5TEPat<(add GPR:$acc, 3933 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))), 3934 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 3935def : ARMV5TEPat<(add GPR:$acc, 3936 (mul (sra GPR:$a, (i32 16)), 3937 (sra (shl GPR:$b, (i32 16)), (i32 16)))), 3938 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 3939def : ARMV5TEPat<(add GPR:$acc, 3940 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)), 3941 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 3942def : ARMV5TEPat<(add GPR:$acc, 3943 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))), 3944 (i32 16))), 3945 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>; 3946def : ARMV5TEPat<(add GPR:$acc, 3947 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))), 3948 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>; 3949 3950 3951// Pre-v7 uses MCR for synchronization barriers. 3952def : ARMPat<(ARMMemBarrierMCR GPR:$zero), (MCR 15, 0, GPR:$zero, 7, 10, 5)>, 3953 Requires<[IsARM, HasV6]>; 3954 3955 3956//===----------------------------------------------------------------------===// 3957// Thumb Support 3958// 3959 3960include "ARMInstrThumb.td" 3961 3962//===----------------------------------------------------------------------===// 3963// Thumb2 Support 3964// 3965 3966include "ARMInstrThumb2.td" 3967 3968//===----------------------------------------------------------------------===// 3969// Floating Point Support 3970// 3971 3972include "ARMInstrVFP.td" 3973 3974//===----------------------------------------------------------------------===// 3975// Advanced SIMD (NEON) Support 3976// 3977 3978include "ARMInstrNEON.td" 3979 3980