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