ARMInstrInfo.td revision 200581
154359Sroberto//===- ARMInstrInfo.td - Target Description for ARM Target -*- tablegen -*-===// 254359Sroberto// 354359Sroberto// The LLVM Compiler Infrastructure 454359Sroberto// 554359Sroberto// This file is distributed under the University of Illinois Open Source 682498Sroberto// License. See LICENSE.TXT for details. 754359Sroberto// 854359Sroberto//===----------------------------------------------------------------------===// 954359Sroberto// 1054359Sroberto// This file describes the ARM instructions in TableGen format. 1154359Sroberto// 1254359Sroberto//===----------------------------------------------------------------------===// 1354359Sroberto 1454359Sroberto//===----------------------------------------------------------------------===// 1554359Sroberto// ARM specific DAG Nodes. 1654359Sroberto// 1754359Sroberto 1854359Sroberto// Type profiles. 1954359Srobertodef SDT_ARMCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 2054359Srobertodef SDT_ARMCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>; 2154359Sroberto 2254359Srobertodef SDT_ARMSaveCallPC : SDTypeProfile<0, 1, []>; 2354359Sroberto 2454359Srobertodef SDT_ARMcall : SDTypeProfile<0, -1, [SDTCisInt<0>]>; 2554359Sroberto 2654359Srobertodef SDT_ARMCMov : SDTypeProfile<1, 3, 2754359Sroberto [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 2854359Sroberto SDTCisVT<3, i32>]>; 2954359Sroberto 3054359Srobertodef SDT_ARMBrcond : SDTypeProfile<0, 2, 3154359Sroberto [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>; 3254359Sroberto 3354359Srobertodef SDT_ARMBrJT : SDTypeProfile<0, 3, 3454359Sroberto [SDTCisPtrTy<0>, SDTCisVT<1, i32>, 3554359Sroberto SDTCisVT<2, i32>]>; 3654359Sroberto 3754359Srobertodef SDT_ARMBr2JT : SDTypeProfile<0, 4, 3854359Sroberto [SDTCisPtrTy<0>, SDTCisVT<1, i32>, 3954359Sroberto SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 4054359Sroberto 4154359Srobertodef SDT_ARMCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; 4254359Sroberto 4354359Srobertodef SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, 4454359Sroberto SDTCisPtrTy<1>, SDTCisVT<2, i32>]>; 4554359Sroberto 4654359Srobertodef SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; 4754359Srobertodef SDT_ARMEH_SJLJ_Setjmp : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisPtrTy<1>]>; 4854359Sroberto 4954359Srobertodef SDT_ARMMEMBARRIERV7 : SDTypeProfile<0, 0, []>; 5054359Srobertodef SDT_ARMSYNCBARRIERV7 : SDTypeProfile<0, 0, []>; 5154359Srobertodef SDT_ARMMEMBARRIERV6 : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 5254359Srobertodef SDT_ARMSYNCBARRIERV6 : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 5354359Sroberto 5454359Sroberto// Node definitions. 5554359Srobertodef ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>; 5654359Srobertodef ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>; 5754359Sroberto 5854359Srobertodef ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart, 5954359Sroberto [SDNPHasChain, SDNPOutFlag]>; 6054359Srobertodef ARMcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_ARMCallSeqEnd, 6154359Sroberto [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; 6254359Sroberto 6354359Srobertodef ARMcall : SDNode<"ARMISD::CALL", SDT_ARMcall, 6454359Sroberto [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; 6554359Srobertodef ARMcall_pred : SDNode<"ARMISD::CALL_PRED", SDT_ARMcall, 6654359Sroberto [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; 6754359Srobertodef ARMcall_nolink : SDNode<"ARMISD::CALL_NOLINK", SDT_ARMcall, 6854359Sroberto [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; 6954359Sroberto 7054359Srobertodef ARMretflag : SDNode<"ARMISD::RET_FLAG", SDTNone, 7154359Sroberto [SDNPHasChain, SDNPOptInFlag]>; 7254359Sroberto 7354359Srobertodef ARMcmov : SDNode<"ARMISD::CMOV", SDT_ARMCMov, 7454359Sroberto [SDNPInFlag]>; 7554359Srobertodef ARMcneg : SDNode<"ARMISD::CNEG", SDT_ARMCMov, 7654359Sroberto [SDNPInFlag]>; 7754359Sroberto 7854359Srobertodef ARMbrcond : SDNode<"ARMISD::BRCOND", SDT_ARMBrcond, 7954359Sroberto [SDNPHasChain, SDNPInFlag, SDNPOutFlag]>; 8054359Sroberto 8154359Srobertodef ARMbrjt : SDNode<"ARMISD::BR_JT", SDT_ARMBrJT, 8254359Sroberto [SDNPHasChain]>; 8354359Srobertodef ARMbr2jt : SDNode<"ARMISD::BR2_JT", SDT_ARMBr2JT, 8454359Sroberto [SDNPHasChain]>; 8554359Sroberto 8654359Srobertodef ARMcmp : SDNode<"ARMISD::CMP", SDT_ARMCmp, 8754359Sroberto [SDNPOutFlag]>; 8854359Sroberto 8954359Srobertodef ARMcmpZ : SDNode<"ARMISD::CMPZ", SDT_ARMCmp, 9054359Sroberto [SDNPOutFlag,SDNPCommutative]>; 9154359Sroberto 9254359Srobertodef ARMpic_add : SDNode<"ARMISD::PIC_ADD", SDT_ARMPICAdd>; 9354359Sroberto 9454359Srobertodef ARMsrl_flag : SDNode<"ARMISD::SRL_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>; 9554359Srobertodef ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>; 9654359Srobertodef ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>; 9754359Sroberto 9854359Srobertodef ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>; 9954359Srobertodef ARMeh_sjlj_setjmp: SDNode<"ARMISD::EH_SJLJ_SETJMP", SDT_ARMEH_SJLJ_Setjmp>; 10054359Sroberto 10154359Srobertodef ARMMemBarrierV7 : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV7, 10254359Sroberto [SDNPHasChain]>; 10354359Srobertodef ARMSyncBarrierV7 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV7, 10454359Sroberto [SDNPHasChain]>; 10554359Srobertodef ARMMemBarrierV6 : SDNode<"ARMISD::MEMBARRIER", SDT_ARMMEMBARRIERV6, 10654359Sroberto [SDNPHasChain]>; 10754359Srobertodef ARMSyncBarrierV6 : SDNode<"ARMISD::SYNCBARRIER", SDT_ARMMEMBARRIERV6, 10854359Sroberto [SDNPHasChain]>; 10954359Sroberto 11054359Sroberto//===----------------------------------------------------------------------===// 11154359Sroberto// ARM Instruction Predicate Definitions. 11254359Sroberto// 11354359Srobertodef HasV5T : Predicate<"Subtarget->hasV5TOps()">; 11454359Srobertodef HasV5TE : Predicate<"Subtarget->hasV5TEOps()">; 11554359Srobertodef HasV6 : Predicate<"Subtarget->hasV6Ops()">; 11654359Srobertodef HasV6T2 : Predicate<"Subtarget->hasV6T2Ops()">; 11754359Srobertodef NoV6T2 : Predicate<"!Subtarget->hasV6T2Ops()">; 11854359Srobertodef HasV7 : Predicate<"Subtarget->hasV7Ops()">; 11954359Srobertodef HasVFP2 : Predicate<"Subtarget->hasVFP2()">; 12054359Srobertodef HasVFP3 : Predicate<"Subtarget->hasVFP3()">; 12154359Srobertodef HasNEON : Predicate<"Subtarget->hasNEON()">; 12254359Srobertodef UseNEONForFP : Predicate<"Subtarget->useNEONForSinglePrecisionFP()">; 12354359Srobertodef DontUseNEONForFP : Predicate<"!Subtarget->useNEONForSinglePrecisionFP()">; 12454359Srobertodef IsThumb : Predicate<"Subtarget->isThumb()">; 12554359Srobertodef IsThumb1Only : Predicate<"Subtarget->isThumb1Only()">; 12654359Srobertodef IsThumb2 : Predicate<"Subtarget->isThumb2()">; 12754359Srobertodef IsARM : Predicate<"!Subtarget->isThumb()">; 12854359Srobertodef IsDarwin : Predicate<"Subtarget->isTargetDarwin()">; 12954359Srobertodef IsNotDarwin : Predicate<"!Subtarget->isTargetDarwin()">; 13054359Srobertodef CarryDefIsUnused : Predicate<"!N.getNode()->hasAnyUseOfValue(1)">; 13154359Srobertodef CarryDefIsUsed : Predicate<"N.getNode()->hasAnyUseOfValue(1)">; 13254359Sroberto 13354359Sroberto// FIXME: Eventually this will be just "hasV6T2Ops". 13454359Srobertodef UseMovt : Predicate<"Subtarget->useMovt()">; 13554359Srobertodef DontUseMovt : Predicate<"!Subtarget->useMovt()">; 13654359Sroberto 13754359Sroberto//===----------------------------------------------------------------------===// 13854359Sroberto// ARM Flag Definitions. 13954359Sroberto 14054359Srobertoclass RegConstraint<string C> { 14154359Sroberto string Constraints = C; 14254359Sroberto} 14354359Sroberto 14454359Sroberto//===----------------------------------------------------------------------===// 14554359Sroberto// ARM specific transformation functions and pattern fragments. 14654359Sroberto// 14754359Sroberto 14854359Sroberto// so_imm_neg_XFORM - Return a so_imm value packed into the format described for 14954359Sroberto// so_imm_neg def below. 15054359Srobertodef so_imm_neg_XFORM : SDNodeXForm<imm, [{ 15154359Sroberto return CurDAG->getTargetConstant(-(int)N->getZExtValue(), MVT::i32); 15254359Sroberto}]>; 15354359Sroberto 15454359Sroberto// so_imm_not_XFORM - Return a so_imm value packed into the format described for 15554359Sroberto// so_imm_not def below. 15654359Srobertodef so_imm_not_XFORM : SDNodeXForm<imm, [{ 15754359Sroberto return CurDAG->getTargetConstant(~(int)N->getZExtValue(), MVT::i32); 15854359Sroberto}]>; 15954359Sroberto 16054359Sroberto// rot_imm predicate - True if the 32-bit immediate is equal to 8, 16, or 24. 16154359Srobertodef rot_imm : PatLeaf<(i32 imm), [{ 16254359Sroberto int32_t v = (int32_t)N->getZExtValue(); 16354359Sroberto return v == 8 || v == 16 || v == 24; 16454359Sroberto}]>; 16554359Sroberto 16654359Sroberto/// imm1_15 predicate - True if the 32-bit immediate is in the range [1,15]. 16754359Srobertodef imm1_15 : PatLeaf<(i32 imm), [{ 16854359Sroberto return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 16; 16954359Sroberto}]>; 17054359Sroberto 17154359Sroberto/// imm16_31 predicate - True if the 32-bit immediate is in the range [16,31]. 17254359Srobertodef imm16_31 : PatLeaf<(i32 imm), [{ 17354359Sroberto return (int32_t)N->getZExtValue() >= 16 && (int32_t)N->getZExtValue() < 32; 17454359Sroberto}]>; 17554359Sroberto 17654359Srobertodef so_imm_neg : 17754359Sroberto PatLeaf<(imm), [{ 17854359Sroberto return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1; 17954359Sroberto }], so_imm_neg_XFORM>; 18054359Sroberto 18154359Srobertodef so_imm_not : 18254359Sroberto PatLeaf<(imm), [{ 18354359Sroberto return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1; 18454359Sroberto }], so_imm_not_XFORM>; 18554359Sroberto 18654359Sroberto// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits. 18754359Srobertodef sext_16_node : PatLeaf<(i32 GPR:$a), [{ 18854359Sroberto return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17; 18954359Sroberto}]>; 19054359Sroberto 19154359Sroberto/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield 19254359Sroberto/// e.g., 0xf000ffff 19354359Srobertodef bf_inv_mask_imm : Operand<i32>, 19454359Sroberto PatLeaf<(imm), [{ 19554359Sroberto uint32_t v = (uint32_t)N->getZExtValue(); 19654359Sroberto if (v == 0xffffffff) 19754359Sroberto return 0; 19854359Sroberto // there can be 1's on either or both "outsides", all the "inside" 19954359Sroberto // bits must be 0's 20054359Sroberto unsigned int lsb = 0, msb = 31; 20154359Sroberto while (v & (1 << msb)) --msb; 20254359Sroberto while (v & (1 << lsb)) ++lsb; 20354359Sroberto for (unsigned int i = lsb; i <= msb; ++i) { 20454359Sroberto if (v & (1 << i)) 20554359Sroberto return 0; 20654359Sroberto } 20754359Sroberto return 1; 20854359Sroberto}] > { 20954359Sroberto let PrintMethod = "printBitfieldInvMaskImmOperand"; 21054359Sroberto} 21154359Sroberto 21254359Sroberto/// Split a 32-bit immediate into two 16 bit parts. 21354359Srobertodef lo16 : SDNodeXForm<imm, [{ 21454359Sroberto return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff, 21554359Sroberto MVT::i32); 21654359Sroberto}]>; 21754359Sroberto 21854359Srobertodef hi16 : SDNodeXForm<imm, [{ 21954359Sroberto return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, MVT::i32); 22054359Sroberto}]>; 22154359Sroberto 22254359Srobertodef lo16AllZero : PatLeaf<(i32 imm), [{ 22354359Sroberto // Returns true if all low 16-bits are 0. 22454359Sroberto return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0; 22554359Sroberto}], hi16>; 226 227/// imm0_65535 predicate - True if the 32-bit immediate is in the range 228/// [0.65535]. 229def imm0_65535 : PatLeaf<(i32 imm), [{ 230 return (uint32_t)N->getZExtValue() < 65536; 231}]>; 232 233class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>; 234class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>; 235 236//===----------------------------------------------------------------------===// 237// Operand Definitions. 238// 239 240// Branch target. 241def brtarget : Operand<OtherVT>; 242 243// A list of registers separated by comma. Used by load/store multiple. 244def reglist : Operand<i32> { 245 let PrintMethod = "printRegisterList"; 246} 247 248// An operand for the CONSTPOOL_ENTRY pseudo-instruction. 249def cpinst_operand : Operand<i32> { 250 let PrintMethod = "printCPInstOperand"; 251} 252 253def jtblock_operand : Operand<i32> { 254 let PrintMethod = "printJTBlockOperand"; 255} 256def jt2block_operand : Operand<i32> { 257 let PrintMethod = "printJT2BlockOperand"; 258} 259 260// Local PC labels. 261def pclabel : Operand<i32> { 262 let PrintMethod = "printPCLabel"; 263} 264 265// shifter_operand operands: so_reg and so_imm. 266def so_reg : Operand<i32>, // reg reg imm 267 ComplexPattern<i32, 3, "SelectShifterOperandReg", 268 [shl,srl,sra,rotr]> { 269 let PrintMethod = "printSORegOperand"; 270 let MIOperandInfo = (ops GPR, GPR, i32imm); 271} 272 273// so_imm - Match a 32-bit shifter_operand immediate operand, which is an 274// 8-bit immediate rotated by an arbitrary number of bits. so_imm values are 275// represented in the imm field in the same 12-bit form that they are encoded 276// into so_imm instructions: the 8-bit immediate is the least significant bits 277// [bits 0-7], the 4-bit shift amount is the next 4 bits [bits 8-11]. 278def so_imm : Operand<i32>, 279 PatLeaf<(imm), [{ 280 return ARM_AM::getSOImmVal(N->getZExtValue()) != -1; 281 }]> { 282 let PrintMethod = "printSOImmOperand"; 283} 284 285// Break so_imm's up into two pieces. This handles immediates with up to 16 286// bits set in them. This uses so_imm2part to match and so_imm2part_[12] to 287// get the first/second pieces. 288def so_imm2part : Operand<i32>, 289 PatLeaf<(imm), [{ 290 return ARM_AM::isSOImmTwoPartVal((unsigned)N->getZExtValue()); 291 }]> { 292 let PrintMethod = "printSOImm2PartOperand"; 293} 294 295def so_imm2part_1 : SDNodeXForm<imm, [{ 296 unsigned V = ARM_AM::getSOImmTwoPartFirst((unsigned)N->getZExtValue()); 297 return CurDAG->getTargetConstant(V, MVT::i32); 298}]>; 299 300def so_imm2part_2 : SDNodeXForm<imm, [{ 301 unsigned V = ARM_AM::getSOImmTwoPartSecond((unsigned)N->getZExtValue()); 302 return CurDAG->getTargetConstant(V, MVT::i32); 303}]>; 304 305def so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{ 306 return ARM_AM::isSOImmTwoPartVal(-(int)N->getZExtValue()); 307 }]> { 308 let PrintMethod = "printSOImm2PartOperand"; 309} 310 311def so_neg_imm2part_1 : SDNodeXForm<imm, [{ 312 unsigned V = ARM_AM::getSOImmTwoPartFirst(-(int)N->getZExtValue()); 313 return CurDAG->getTargetConstant(V, MVT::i32); 314}]>; 315 316def so_neg_imm2part_2 : SDNodeXForm<imm, [{ 317 unsigned V = ARM_AM::getSOImmTwoPartSecond(-(int)N->getZExtValue()); 318 return CurDAG->getTargetConstant(V, MVT::i32); 319}]>; 320 321/// imm0_31 predicate - True if the 32-bit immediate is in the range [0,31]. 322def imm0_31 : Operand<i32>, PatLeaf<(imm), [{ 323 return (int32_t)N->getZExtValue() < 32; 324}]>; 325 326// Define ARM specific addressing modes. 327 328// addrmode2 := reg +/- reg shop imm 329// addrmode2 := reg +/- imm12 330// 331def addrmode2 : Operand<i32>, 332 ComplexPattern<i32, 3, "SelectAddrMode2", []> { 333 let PrintMethod = "printAddrMode2Operand"; 334 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 335} 336 337def am2offset : Operand<i32>, 338 ComplexPattern<i32, 2, "SelectAddrMode2Offset", []> { 339 let PrintMethod = "printAddrMode2OffsetOperand"; 340 let MIOperandInfo = (ops GPR, i32imm); 341} 342 343// addrmode3 := reg +/- reg 344// addrmode3 := reg +/- imm8 345// 346def addrmode3 : Operand<i32>, 347 ComplexPattern<i32, 3, "SelectAddrMode3", []> { 348 let PrintMethod = "printAddrMode3Operand"; 349 let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm); 350} 351 352def am3offset : Operand<i32>, 353 ComplexPattern<i32, 2, "SelectAddrMode3Offset", []> { 354 let PrintMethod = "printAddrMode3OffsetOperand"; 355 let MIOperandInfo = (ops GPR, i32imm); 356} 357 358// addrmode4 := reg, <mode|W> 359// 360def addrmode4 : Operand<i32>, 361 ComplexPattern<i32, 2, "SelectAddrMode4", []> { 362 let PrintMethod = "printAddrMode4Operand"; 363 let MIOperandInfo = (ops GPR, i32imm); 364} 365 366// addrmode5 := reg +/- imm8*4 367// 368def addrmode5 : Operand<i32>, 369 ComplexPattern<i32, 2, "SelectAddrMode5", []> { 370 let PrintMethod = "printAddrMode5Operand"; 371 let MIOperandInfo = (ops GPR, i32imm); 372} 373 374// addrmode6 := reg with optional writeback 375// 376def addrmode6 : Operand<i32>, 377 ComplexPattern<i32, 4, "SelectAddrMode6", []> { 378 let PrintMethod = "printAddrMode6Operand"; 379 let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm, i32imm); 380} 381 382// addrmodepc := pc + reg 383// 384def addrmodepc : Operand<i32>, 385 ComplexPattern<i32, 2, "SelectAddrModePC", []> { 386 let PrintMethod = "printAddrModePCOperand"; 387 let MIOperandInfo = (ops GPR, i32imm); 388} 389 390def nohash_imm : Operand<i32> { 391 let PrintMethod = "printNoHashImmediate"; 392} 393 394//===----------------------------------------------------------------------===// 395 396include "ARMInstrFormats.td" 397 398//===----------------------------------------------------------------------===// 399// Multiclass helpers... 400// 401 402/// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a 403/// binop that produces a value. 404multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode, 405 bit Commutable = 0> { 406 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, 407 IIC_iALUi, opc, "\t$dst, $a, $b", 408 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> { 409 let Inst{25} = 1; 410 } 411 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, 412 IIC_iALUr, opc, "\t$dst, $a, $b", 413 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> { 414 let Inst{11-4} = 0b00000000; 415 let Inst{25} = 0; 416 let isCommutable = Commutable; 417 } 418 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, 419 IIC_iALUsr, opc, "\t$dst, $a, $b", 420 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> { 421 let Inst{25} = 0; 422 } 423} 424 425/// AI1_bin_s_irs - Similar to AsI1_bin_irs except it sets the 's' bit so the 426/// instruction modifies the CPSR register. 427let Defs = [CPSR] in { 428multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode, 429 bit Commutable = 0> { 430 def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, 431 IIC_iALUi, opc, "\t$dst, $a, $b", 432 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> { 433 let Inst{20} = 1; 434 let Inst{25} = 1; 435 } 436 def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, 437 IIC_iALUr, opc, "\t$dst, $a, $b", 438 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> { 439 let isCommutable = Commutable; 440 let Inst{11-4} = 0b00000000; 441 let Inst{20} = 1; 442 let Inst{25} = 0; 443 } 444 def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, 445 IIC_iALUsr, opc, "\t$dst, $a, $b", 446 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> { 447 let Inst{20} = 1; 448 let Inst{25} = 0; 449 } 450} 451} 452 453/// AI1_cmp_irs - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test 454/// patterns. Similar to AsI1_bin_irs except the instruction does not produce 455/// a explicit result, only implicitly set CPSR. 456let Defs = [CPSR] in { 457multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode, 458 bit Commutable = 0> { 459 def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iCMPi, 460 opc, "\t$a, $b", 461 [(opnode GPR:$a, so_imm:$b)]> { 462 let Inst{20} = 1; 463 let Inst{25} = 1; 464 } 465 def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, IIC_iCMPr, 466 opc, "\t$a, $b", 467 [(opnode GPR:$a, GPR:$b)]> { 468 let Inst{11-4} = 0b00000000; 469 let Inst{20} = 1; 470 let Inst{25} = 0; 471 let isCommutable = Commutable; 472 } 473 def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iCMPsr, 474 opc, "\t$a, $b", 475 [(opnode GPR:$a, so_reg:$b)]> { 476 let Inst{20} = 1; 477 let Inst{25} = 0; 478 } 479} 480} 481 482/// AI_unary_rrot - A unary operation with two forms: one whose operand is a 483/// register and one whose operand is a register rotated by 8/16/24. 484/// FIXME: Remove the 'r' variant. Its rot_imm is zero. 485multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> { 486 def r : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src), 487 IIC_iUNAr, opc, "\t$dst, $src", 488 [(set GPR:$dst, (opnode GPR:$src))]>, 489 Requires<[IsARM, HasV6]> { 490 let Inst{11-10} = 0b00; 491 let Inst{19-16} = 0b1111; 492 } 493 def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$src, i32imm:$rot), 494 IIC_iUNAsi, opc, "\t$dst, $src, ror $rot", 495 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>, 496 Requires<[IsARM, HasV6]> { 497 let Inst{19-16} = 0b1111; 498 } 499} 500 501/// AI_bin_rrot - A binary operation with two forms: one whose operand is a 502/// register and one whose operand is a register rotated by 8/16/24. 503multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> { 504 def rr : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), 505 IIC_iALUr, opc, "\t$dst, $LHS, $RHS", 506 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>, 507 Requires<[IsARM, HasV6]> { 508 let Inst{11-10} = 0b00; 509 } 510 def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot), 511 IIC_iALUsi, opc, "\t$dst, $LHS, $RHS, ror $rot", 512 [(set GPR:$dst, (opnode GPR:$LHS, 513 (rotr GPR:$RHS, rot_imm:$rot)))]>, 514 Requires<[IsARM, HasV6]>; 515} 516 517/// AI1_adde_sube_irs - Define instructions and patterns for adde and sube. 518let Uses = [CPSR] in { 519multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode, 520 bit Commutable = 0> { 521 def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), 522 DPFrm, IIC_iALUi, opc, "\t$dst, $a, $b", 523 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>, 524 Requires<[IsARM, CarryDefIsUnused]> { 525 let Inst{25} = 1; 526 } 527 def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 528 DPFrm, IIC_iALUr, opc, "\t$dst, $a, $b", 529 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>, 530 Requires<[IsARM, CarryDefIsUnused]> { 531 let isCommutable = Commutable; 532 let Inst{11-4} = 0b00000000; 533 let Inst{25} = 0; 534 } 535 def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), 536 DPSoRegFrm, IIC_iALUsr, opc, "\t$dst, $a, $b", 537 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>, 538 Requires<[IsARM, CarryDefIsUnused]> { 539 let Inst{25} = 0; 540 } 541} 542// Carry setting variants 543let Defs = [CPSR] in { 544multiclass AI1_adde_sube_s_irs<bits<4> opcod, string opc, PatFrag opnode, 545 bit Commutable = 0> { 546 def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), 547 DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"), 548 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>, 549 Requires<[IsARM, CarryDefIsUsed]> { 550 let Defs = [CPSR]; 551 let Inst{20} = 1; 552 let Inst{25} = 1; 553 } 554 def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 555 DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"), 556 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>, 557 Requires<[IsARM, CarryDefIsUsed]> { 558 let Defs = [CPSR]; 559 let Inst{11-4} = 0b00000000; 560 let Inst{20} = 1; 561 let Inst{25} = 0; 562 } 563 def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), 564 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"), 565 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>, 566 Requires<[IsARM, CarryDefIsUsed]> { 567 let Defs = [CPSR]; 568 let Inst{20} = 1; 569 let Inst{25} = 0; 570 } 571} 572} 573} 574 575//===----------------------------------------------------------------------===// 576// Instructions 577//===----------------------------------------------------------------------===// 578 579//===----------------------------------------------------------------------===// 580// Miscellaneous Instructions. 581// 582 583/// CONSTPOOL_ENTRY - This instruction represents a floating constant pool in 584/// the function. The first operand is the ID# for this instruction, the second 585/// is the index into the MachineConstantPool that this is, the third is the 586/// size in bytes of this constant pool entry. 587let neverHasSideEffects = 1, isNotDuplicable = 1 in 588def CONSTPOOL_ENTRY : 589PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx, 590 i32imm:$size), NoItinerary, 591 "${instid:label} ${cpidx:cpentry}", []>; 592 593let Defs = [SP], Uses = [SP] in { 594def ADJCALLSTACKUP : 595PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary, 596 "@ ADJCALLSTACKUP $amt1", 597 [(ARMcallseq_end timm:$amt1, timm:$amt2)]>; 598 599def ADJCALLSTACKDOWN : 600PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary, 601 "@ ADJCALLSTACKDOWN $amt", 602 [(ARMcallseq_start timm:$amt)]>; 603} 604 605// Address computation and loads and stores in PIC mode. 606let isNotDuplicable = 1 in { 607def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p), 608 Pseudo, IIC_iALUr, "\n$cp:\n\tadd$p\t$dst, pc, $a", 609 [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>; 610 611let AddedComplexity = 10 in { 612def PICLDR : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 613 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldr$p\t$dst, $addr", 614 [(set GPR:$dst, (load addrmodepc:$addr))]>; 615 616def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 617 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrh${p}\t$dst, $addr", 618 [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>; 619 620def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 621 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrb${p}\t$dst, $addr", 622 [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>; 623 624def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 625 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsh${p}\t$dst, $addr", 626 [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>; 627 628def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p), 629 Pseudo, IIC_iLoadr, "\n${addr:label}:\n\tldrsb${p}\t$dst, $addr", 630 [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>; 631} 632let AddedComplexity = 10 in { 633def PICSTR : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 634 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstr$p\t$src, $addr", 635 [(store GPR:$src, addrmodepc:$addr)]>; 636 637def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 638 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrh${p}\t$src, $addr", 639 [(truncstorei16 GPR:$src, addrmodepc:$addr)]>; 640 641def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p), 642 Pseudo, IIC_iStorer, "\n${addr:label}:\n\tstrb${p}\t$src, $addr", 643 [(truncstorei8 GPR:$src, addrmodepc:$addr)]>; 644} 645} // isNotDuplicable = 1 646 647 648// LEApcrel - Load a pc-relative address into a register without offending the 649// assembler. 650def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p), 651 Pseudo, IIC_iALUi, 652 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(", 653 "${:private}PCRELL${:uid}+8))\n"), 654 !strconcat("${:private}PCRELL${:uid}:\n\t", 655 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")), 656 []>; 657 658def LEApcrelJT : AXI1<0x0, (outs GPR:$dst), 659 (ins i32imm:$label, nohash_imm:$id, pred:$p), 660 Pseudo, IIC_iALUi, 661 !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, " 662 "(${label}_${id}-(", 663 "${:private}PCRELL${:uid}+8))\n"), 664 !strconcat("${:private}PCRELL${:uid}:\n\t", 665 "add$p\t$dst, pc, #${:private}PCRELV${:uid}")), 666 []> { 667 let Inst{25} = 1; 668} 669 670//===----------------------------------------------------------------------===// 671// Control Flow Instructions. 672// 673 674let isReturn = 1, isTerminator = 1, isBarrier = 1 in 675 def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 676 "bx", "\tlr", [(ARMretflag)]> { 677 let Inst{3-0} = 0b1110; 678 let Inst{7-4} = 0b0001; 679 let Inst{19-8} = 0b111111111111; 680 let Inst{27-20} = 0b00010010; 681} 682 683// Indirect branches 684let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in { 685 def BRIND : AXI<(outs), (ins GPR:$dst), BrMiscFrm, IIC_Br, "bx\t$dst", 686 [(brind GPR:$dst)]> { 687 let Inst{7-4} = 0b0001; 688 let Inst{19-8} = 0b111111111111; 689 let Inst{27-20} = 0b00010010; 690 let Inst{31-28} = 0b1110; 691 } 692} 693 694// FIXME: remove when we have a way to marking a MI with these properties. 695// FIXME: Should pc be an implicit operand like PICADD, etc? 696let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1, 697 hasExtraDefRegAllocReq = 1 in 698 def LDM_RET : AXI4ld<(outs), 699 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 700 LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb", 701 []>; 702 703// On non-Darwin platforms R9 is callee-saved. 704let isCall = 1, 705 Defs = [R0, R1, R2, R3, R12, LR, 706 D0, D1, D2, D3, D4, D5, D6, D7, 707 D16, D17, D18, D19, D20, D21, D22, D23, 708 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 709 def BL : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops), 710 IIC_Br, "bl\t${func:call}", 711 [(ARMcall tglobaladdr:$func)]>, 712 Requires<[IsARM, IsNotDarwin]> { 713 let Inst{31-28} = 0b1110; 714 } 715 716 def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops), 717 IIC_Br, "bl", "\t${func:call}", 718 [(ARMcall_pred tglobaladdr:$func)]>, 719 Requires<[IsARM, IsNotDarwin]>; 720 721 // ARMv5T and above 722 def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm, 723 IIC_Br, "blx\t$func", 724 [(ARMcall GPR:$func)]>, 725 Requires<[IsARM, HasV5T, IsNotDarwin]> { 726 let Inst{7-4} = 0b0011; 727 let Inst{19-8} = 0b111111111111; 728 let Inst{27-20} = 0b00010010; 729 } 730 731 // ARMv4T 732 def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops), 733 IIC_Br, "mov\tlr, pc\n\tbx\t$func", 734 [(ARMcall_nolink GPR:$func)]>, 735 Requires<[IsARM, IsNotDarwin]> { 736 let Inst{7-4} = 0b0001; 737 let Inst{19-8} = 0b111111111111; 738 let Inst{27-20} = 0b00010010; 739 } 740} 741 742// On Darwin R9 is call-clobbered. 743let isCall = 1, 744 Defs = [R0, R1, R2, R3, R9, R12, LR, 745 D0, D1, D2, D3, D4, D5, D6, D7, 746 D16, D17, D18, D19, D20, D21, D22, D23, 747 D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in { 748 def BLr9 : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops), 749 IIC_Br, "bl\t${func:call}", 750 [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]> { 751 let Inst{31-28} = 0b1110; 752 } 753 754 def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops), 755 IIC_Br, "bl", "\t${func:call}", 756 [(ARMcall_pred tglobaladdr:$func)]>, 757 Requires<[IsARM, IsDarwin]>; 758 759 // ARMv5T and above 760 def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm, 761 IIC_Br, "blx\t$func", 762 [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> { 763 let Inst{7-4} = 0b0011; 764 let Inst{19-8} = 0b111111111111; 765 let Inst{27-20} = 0b00010010; 766 } 767 768 // ARMv4T 769 def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops), 770 IIC_Br, "mov\tlr, pc\n\tbx\t$func", 771 [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> { 772 let Inst{7-4} = 0b0001; 773 let Inst{19-8} = 0b111111111111; 774 let Inst{27-20} = 0b00010010; 775 } 776} 777 778let isBranch = 1, isTerminator = 1 in { 779 // B is "predicable" since it can be xformed into a Bcc. 780 let isBarrier = 1 in { 781 let isPredicable = 1 in 782 def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br, 783 "b\t$target", [(br bb:$target)]>; 784 785 let isNotDuplicable = 1, isIndirectBranch = 1 in { 786 def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id), 787 IIC_Br, "mov\tpc, $target \n$jt", 788 [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> { 789 let Inst{11-4} = 0b00000000; 790 let Inst{15-12} = 0b1111; 791 let Inst{20} = 0; // S Bit 792 let Inst{24-21} = 0b1101; 793 let Inst{27-25} = 0b000; 794 } 795 def BR_JTm : JTI<(outs), 796 (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id), 797 IIC_Br, "ldr\tpc, $target \n$jt", 798 [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt, 799 imm:$id)]> { 800 let Inst{15-12} = 0b1111; 801 let Inst{20} = 1; // L bit 802 let Inst{21} = 0; // W bit 803 let Inst{22} = 0; // B bit 804 let Inst{24} = 1; // P bit 805 let Inst{27-25} = 0b011; 806 } 807 def BR_JTadd : JTI<(outs), 808 (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id), 809 IIC_Br, "add\tpc, $target, $idx \n$jt", 810 [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, 811 imm:$id)]> { 812 let Inst{15-12} = 0b1111; 813 let Inst{20} = 0; // S bit 814 let Inst{24-21} = 0b0100; 815 let Inst{27-25} = 0b000; 816 } 817 } // isNotDuplicable = 1, isIndirectBranch = 1 818 } // isBarrier = 1 819 820 // FIXME: should be able to write a pattern for ARMBrcond, but can't use 821 // a two-value operand where a dag node expects two operands. :( 822 def Bcc : ABI<0b1010, (outs), (ins brtarget:$target), 823 IIC_Br, "b", "\t$target", 824 [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>; 825} 826 827//===----------------------------------------------------------------------===// 828// Load / store Instructions. 829// 830 831// Load 832let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in 833def LDR : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr, 834 "ldr", "\t$dst, $addr", 835 [(set GPR:$dst, (load addrmode2:$addr))]>; 836 837// Special LDR for loads from non-pc-relative constpools. 838let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1, 839 mayHaveSideEffects = 1 in 840def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr, 841 "ldr", "\t$dst, $addr", []>; 842 843// Loads with zero extension 844def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, 845 IIC_iLoadr, "ldrh", "\t$dst, $addr", 846 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>; 847 848def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, 849 IIC_iLoadr, "ldrb", "\t$dst, $addr", 850 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>; 851 852// Loads with sign extension 853def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, 854 IIC_iLoadr, "ldrsh", "\t$dst, $addr", 855 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>; 856 857def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, 858 IIC_iLoadr, "ldrsb", "\t$dst, $addr", 859 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>; 860 861let mayLoad = 1, hasExtraDefRegAllocReq = 1 in { 862// Load doubleword 863def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm, 864 IIC_iLoadr, "ldrd", "\t$dst1, $addr", 865 []>, Requires<[IsARM, HasV5TE]>; 866 867// Indexed loads 868def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb), 869 (ins addrmode2:$addr), LdFrm, IIC_iLoadru, 870 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 871 872def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb), 873 (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru, 874 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 875 876def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb), 877 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru, 878 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 879 880def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb), 881 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru, 882 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 883 884def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb), 885 (ins addrmode2:$addr), LdFrm, IIC_iLoadru, 886 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 887 888def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb), 889 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru, 890 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 891 892def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb), 893 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru, 894 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 895 896def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb), 897 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru, 898 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 899 900def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb), 901 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru, 902 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>; 903 904def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb), 905 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru, 906 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>; 907} 908 909// Store 910def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer, 911 "str", "\t$src, $addr", 912 [(store GPR:$src, addrmode2:$addr)]>; 913 914// Stores with truncate 915def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStorer, 916 "strh", "\t$src, $addr", 917 [(truncstorei16 GPR:$src, addrmode3:$addr)]>; 918 919def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer, 920 "strb", "\t$src, $addr", 921 [(truncstorei8 GPR:$src, addrmode2:$addr)]>; 922 923// Store doubleword 924let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 925def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr), 926 StMiscFrm, IIC_iStorer, 927 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>; 928 929// Indexed stores 930def STR_PRE : AI2stwpr<(outs GPR:$base_wb), 931 (ins GPR:$src, GPR:$base, am2offset:$offset), 932 StFrm, IIC_iStoreru, 933 "str", "\t$src, [$base, $offset]!", "$base = $base_wb", 934 [(set GPR:$base_wb, 935 (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>; 936 937def STR_POST : AI2stwpo<(outs GPR:$base_wb), 938 (ins GPR:$src, GPR:$base,am2offset:$offset), 939 StFrm, IIC_iStoreru, 940 "str", "\t$src, [$base], $offset", "$base = $base_wb", 941 [(set GPR:$base_wb, 942 (post_store GPR:$src, GPR:$base, am2offset:$offset))]>; 943 944def STRH_PRE : AI3sthpr<(outs GPR:$base_wb), 945 (ins GPR:$src, GPR:$base,am3offset:$offset), 946 StMiscFrm, IIC_iStoreru, 947 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb", 948 [(set GPR:$base_wb, 949 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>; 950 951def STRH_POST: AI3sthpo<(outs GPR:$base_wb), 952 (ins GPR:$src, GPR:$base,am3offset:$offset), 953 StMiscFrm, IIC_iStoreru, 954 "strh", "\t$src, [$base], $offset", "$base = $base_wb", 955 [(set GPR:$base_wb, (post_truncsti16 GPR:$src, 956 GPR:$base, am3offset:$offset))]>; 957 958def STRB_PRE : AI2stbpr<(outs GPR:$base_wb), 959 (ins GPR:$src, GPR:$base,am2offset:$offset), 960 StFrm, IIC_iStoreru, 961 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb", 962 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src, 963 GPR:$base, am2offset:$offset))]>; 964 965def STRB_POST: AI2stbpo<(outs GPR:$base_wb), 966 (ins GPR:$src, GPR:$base,am2offset:$offset), 967 StFrm, IIC_iStoreru, 968 "strb", "\t$src, [$base], $offset", "$base = $base_wb", 969 [(set GPR:$base_wb, (post_truncsti8 GPR:$src, 970 GPR:$base, am2offset:$offset))]>; 971 972//===----------------------------------------------------------------------===// 973// Load / store multiple Instructions. 974// 975 976let mayLoad = 1, hasExtraDefRegAllocReq = 1 in 977def LDM : AXI4ld<(outs), 978 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 979 LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb", 980 []>; 981 982let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 983def STM : AXI4st<(outs), 984 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops), 985 LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb", 986 []>; 987 988//===----------------------------------------------------------------------===// 989// Move Instructions. 990// 991 992let neverHasSideEffects = 1 in 993def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr, 994 "mov", "\t$dst, $src", []>, UnaryDP { 995 let Inst{11-4} = 0b00000000; 996 let Inst{25} = 0; 997} 998 999def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), 1000 DPSoRegFrm, IIC_iMOVsr, 1001 "mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP { 1002 let Inst{25} = 0; 1003} 1004 1005let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1006def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi, 1007 "mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP { 1008 let Inst{25} = 1; 1009} 1010 1011let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1012def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src), 1013 DPFrm, IIC_iMOVi, 1014 "movw", "\t$dst, $src", 1015 [(set GPR:$dst, imm0_65535:$src)]>, 1016 Requires<[IsARM, HasV6T2]> { 1017 let Inst{20} = 0; 1018 let Inst{25} = 1; 1019} 1020 1021let Constraints = "$src = $dst" in 1022def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm), 1023 DPFrm, IIC_iMOVi, 1024 "movt", "\t$dst, $imm", 1025 [(set GPR:$dst, 1026 (or (and GPR:$src, 0xffff), 1027 lo16AllZero:$imm))]>, UnaryDP, 1028 Requires<[IsARM, HasV6T2]> { 1029 let Inst{20} = 0; 1030 let Inst{25} = 1; 1031} 1032 1033def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>, 1034 Requires<[IsARM, HasV6T2]>; 1035 1036let Uses = [CPSR] in 1037def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi, 1038 "mov", "\t$dst, $src, rrx", 1039 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP; 1040 1041// These aren't really mov instructions, but we have to define them this way 1042// due to flag operands. 1043 1044let Defs = [CPSR] in { 1045def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, 1046 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1", 1047 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP; 1048def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, 1049 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1", 1050 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP; 1051} 1052 1053//===----------------------------------------------------------------------===// 1054// Extend Instructions. 1055// 1056 1057// Sign extenders 1058 1059defm SXTB : AI_unary_rrot<0b01101010, 1060 "sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>; 1061defm SXTH : AI_unary_rrot<0b01101011, 1062 "sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>; 1063 1064defm SXTAB : AI_bin_rrot<0b01101010, 1065 "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>; 1066defm SXTAH : AI_bin_rrot<0b01101011, 1067 "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>; 1068 1069// TODO: SXT(A){B|H}16 1070 1071// Zero extenders 1072 1073let AddedComplexity = 16 in { 1074defm UXTB : AI_unary_rrot<0b01101110, 1075 "uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>; 1076defm UXTH : AI_unary_rrot<0b01101111, 1077 "uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>; 1078defm UXTB16 : AI_unary_rrot<0b01101100, 1079 "uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>; 1080 1081def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF), 1082 (UXTB16r_rot GPR:$Src, 24)>; 1083def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF), 1084 (UXTB16r_rot GPR:$Src, 8)>; 1085 1086defm UXTAB : AI_bin_rrot<0b01101110, "uxtab", 1087 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; 1088defm UXTAH : AI_bin_rrot<0b01101111, "uxtah", 1089 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; 1090} 1091 1092// This isn't safe in general, the add is two 16-bit units, not a 32-bit add. 1093//defm UXTAB16 : xxx<"uxtab16", 0xff00ff>; 1094 1095// TODO: UXT(A){B|H}16 1096 1097def SBFX : I<(outs GPR:$dst), 1098 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width), 1099 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi, 1100 "sbfx", "\t$dst, $src, $lsb, $width", "", []>, 1101 Requires<[IsARM, HasV6T2]> { 1102 let Inst{27-21} = 0b0111101; 1103 let Inst{6-4} = 0b101; 1104} 1105 1106def UBFX : I<(outs GPR:$dst), 1107 (ins GPR:$src, imm0_31:$lsb, imm0_31:$width), 1108 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi, 1109 "ubfx", "\t$dst, $src, $lsb, $width", "", []>, 1110 Requires<[IsARM, HasV6T2]> { 1111 let Inst{27-21} = 0b0111111; 1112 let Inst{6-4} = 0b101; 1113} 1114 1115//===----------------------------------------------------------------------===// 1116// Arithmetic Instructions. 1117// 1118 1119defm ADD : AsI1_bin_irs<0b0100, "add", 1120 BinOpFrag<(add node:$LHS, node:$RHS)>, 1>; 1121defm SUB : AsI1_bin_irs<0b0010, "sub", 1122 BinOpFrag<(sub node:$LHS, node:$RHS)>>; 1123 1124// ADD and SUB with 's' bit set. 1125defm ADDS : AI1_bin_s_irs<0b0100, "adds", 1126 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>; 1127defm SUBS : AI1_bin_s_irs<0b0010, "subs", 1128 BinOpFrag<(subc node:$LHS, node:$RHS)>>; 1129 1130defm ADC : AI1_adde_sube_irs<0b0101, "adc", 1131 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>; 1132defm SBC : AI1_adde_sube_irs<0b0110, "sbc", 1133 BinOpFrag<(sube node:$LHS, node:$RHS)>>; 1134defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs", 1135 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>; 1136defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs", 1137 BinOpFrag<(sube node:$LHS, node:$RHS)>>; 1138 1139// These don't define reg/reg forms, because they are handled above. 1140def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, 1141 IIC_iALUi, "rsb", "\t$dst, $a, $b", 1142 [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> { 1143 let Inst{25} = 1; 1144} 1145 1146def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, 1147 IIC_iALUsr, "rsb", "\t$dst, $a, $b", 1148 [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> { 1149 let Inst{25} = 0; 1150} 1151 1152// RSB with 's' bit set. 1153let Defs = [CPSR] in { 1154def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm, 1155 IIC_iALUi, "rsbs", "\t$dst, $a, $b", 1156 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> { 1157 let Inst{20} = 1; 1158 let Inst{25} = 1; 1159} 1160def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm, 1161 IIC_iALUsr, "rsbs", "\t$dst, $a, $b", 1162 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> { 1163 let Inst{20} = 1; 1164 let Inst{25} = 0; 1165} 1166} 1167 1168let Uses = [CPSR] in { 1169def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), 1170 DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b", 1171 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>, 1172 Requires<[IsARM, CarryDefIsUnused]> { 1173 let Inst{25} = 1; 1174} 1175def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), 1176 DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b", 1177 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>, 1178 Requires<[IsARM, CarryDefIsUnused]> { 1179 let Inst{25} = 0; 1180} 1181} 1182 1183// FIXME: Allow these to be predicated. 1184let Defs = [CPSR], Uses = [CPSR] in { 1185def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), 1186 DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b", 1187 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>, 1188 Requires<[IsARM, CarryDefIsUnused]> { 1189 let Inst{20} = 1; 1190 let Inst{25} = 1; 1191} 1192def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), 1193 DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b", 1194 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>, 1195 Requires<[IsARM, CarryDefIsUnused]> { 1196 let Inst{20} = 1; 1197 let Inst{25} = 0; 1198} 1199} 1200 1201// (sub X, imm) gets canonicalized to (add X, -imm). Match this form. 1202def : ARMPat<(add GPR:$src, so_imm_neg:$imm), 1203 (SUBri GPR:$src, so_imm_neg:$imm)>; 1204 1205//def : ARMPat<(addc GPR:$src, so_imm_neg:$imm), 1206// (SUBSri GPR:$src, so_imm_neg:$imm)>; 1207//def : ARMPat<(adde GPR:$src, so_imm_neg:$imm), 1208// (SBCri GPR:$src, so_imm_neg:$imm)>; 1209 1210// Note: These are implemented in C++ code, because they have to generate 1211// ADD/SUBrs instructions, which use a complex pattern that a xform function 1212// cannot produce. 1213// (mul X, 2^n+1) -> (add (X << n), X) 1214// (mul X, 2^n-1) -> (rsb X, (X << n)) 1215 1216 1217//===----------------------------------------------------------------------===// 1218// Bitwise Instructions. 1219// 1220 1221defm AND : AsI1_bin_irs<0b0000, "and", 1222 BinOpFrag<(and node:$LHS, node:$RHS)>, 1>; 1223defm ORR : AsI1_bin_irs<0b1100, "orr", 1224 BinOpFrag<(or node:$LHS, node:$RHS)>, 1>; 1225defm EOR : AsI1_bin_irs<0b0001, "eor", 1226 BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>; 1227defm BIC : AsI1_bin_irs<0b1110, "bic", 1228 BinOpFrag<(and node:$LHS, (not node:$RHS))>>; 1229 1230def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm), 1231 AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, 1232 "bfc", "\t$dst, $imm", "$src = $dst", 1233 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>, 1234 Requires<[IsARM, HasV6T2]> { 1235 let Inst{27-21} = 0b0111110; 1236 let Inst{6-0} = 0b0011111; 1237} 1238 1239def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr, 1240 "mvn", "\t$dst, $src", 1241 [(set GPR:$dst, (not GPR:$src))]>, UnaryDP { 1242 let Inst{11-4} = 0b00000000; 1243} 1244def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm, 1245 IIC_iMOVsr, "mvn", "\t$dst, $src", 1246 [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP; 1247let isReMaterializable = 1, isAsCheapAsAMove = 1 in 1248def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm, 1249 IIC_iMOVi, "mvn", "\t$dst, $imm", 1250 [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP { 1251 let Inst{25} = 1; 1252} 1253 1254def : ARMPat<(and GPR:$src, so_imm_not:$imm), 1255 (BICri GPR:$src, so_imm_not:$imm)>; 1256 1257//===----------------------------------------------------------------------===// 1258// Multiply Instructions. 1259// 1260 1261let isCommutable = 1 in 1262def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1263 IIC_iMUL32, "mul", "\t$dst, $a, $b", 1264 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>; 1265 1266def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 1267 IIC_iMAC32, "mla", "\t$dst, $a, $b, $c", 1268 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>; 1269 1270def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 1271 IIC_iMAC32, "mls", "\t$dst, $a, $b, $c", 1272 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>, 1273 Requires<[IsARM, HasV6T2]>; 1274 1275// Extra precision multiplies with low / high results 1276let neverHasSideEffects = 1 in { 1277let isCommutable = 1 in { 1278def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst), 1279 (ins GPR:$a, GPR:$b), IIC_iMUL64, 1280 "smull", "\t$ldst, $hdst, $a, $b", []>; 1281 1282def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst), 1283 (ins GPR:$a, GPR:$b), IIC_iMUL64, 1284 "umull", "\t$ldst, $hdst, $a, $b", []>; 1285} 1286 1287// Multiply + accumulate 1288def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst), 1289 (ins GPR:$a, GPR:$b), IIC_iMAC64, 1290 "smlal", "\t$ldst, $hdst, $a, $b", []>; 1291 1292def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst), 1293 (ins GPR:$a, GPR:$b), IIC_iMAC64, 1294 "umlal", "\t$ldst, $hdst, $a, $b", []>; 1295 1296def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst), 1297 (ins GPR:$a, GPR:$b), IIC_iMAC64, 1298 "umaal", "\t$ldst, $hdst, $a, $b", []>, 1299 Requires<[IsARM, HasV6]>; 1300} // neverHasSideEffects 1301 1302// Most significant word multiply 1303def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1304 IIC_iMUL32, "smmul", "\t$dst, $a, $b", 1305 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>, 1306 Requires<[IsARM, HasV6]> { 1307 let Inst{7-4} = 0b0001; 1308 let Inst{15-12} = 0b1111; 1309} 1310 1311def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 1312 IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c", 1313 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>, 1314 Requires<[IsARM, HasV6]> { 1315 let Inst{7-4} = 0b0001; 1316} 1317 1318 1319def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), 1320 IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c", 1321 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>, 1322 Requires<[IsARM, HasV6]> { 1323 let Inst{7-4} = 0b1101; 1324} 1325 1326multiclass AI_smul<string opc, PatFrag opnode> { 1327 def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1328 IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b", 1329 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16), 1330 (sext_inreg GPR:$b, i16)))]>, 1331 Requires<[IsARM, HasV5TE]> { 1332 let Inst{5} = 0; 1333 let Inst{6} = 0; 1334 } 1335 1336 def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1337 IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b", 1338 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16), 1339 (sra GPR:$b, (i32 16))))]>, 1340 Requires<[IsARM, HasV5TE]> { 1341 let Inst{5} = 0; 1342 let Inst{6} = 1; 1343 } 1344 1345 def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1346 IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b", 1347 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)), 1348 (sext_inreg GPR:$b, i16)))]>, 1349 Requires<[IsARM, HasV5TE]> { 1350 let Inst{5} = 1; 1351 let Inst{6} = 0; 1352 } 1353 1354 def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1355 IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b", 1356 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)), 1357 (sra GPR:$b, (i32 16))))]>, 1358 Requires<[IsARM, HasV5TE]> { 1359 let Inst{5} = 1; 1360 let Inst{6} = 1; 1361 } 1362 1363 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1364 IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b", 1365 [(set GPR:$dst, (sra (opnode GPR:$a, 1366 (sext_inreg GPR:$b, i16)), (i32 16)))]>, 1367 Requires<[IsARM, HasV5TE]> { 1368 let Inst{5} = 1; 1369 let Inst{6} = 0; 1370 } 1371 1372 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b), 1373 IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b", 1374 [(set GPR:$dst, (sra (opnode GPR:$a, 1375 (sra GPR:$b, (i32 16))), (i32 16)))]>, 1376 Requires<[IsARM, HasV5TE]> { 1377 let Inst{5} = 1; 1378 let Inst{6} = 1; 1379 } 1380} 1381 1382 1383multiclass AI_smla<string opc, PatFrag opnode> { 1384 def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 1385 IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc", 1386 [(set GPR:$dst, (add GPR:$acc, 1387 (opnode (sext_inreg GPR:$a, i16), 1388 (sext_inreg GPR:$b, i16))))]>, 1389 Requires<[IsARM, HasV5TE]> { 1390 let Inst{5} = 0; 1391 let Inst{6} = 0; 1392 } 1393 1394 def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 1395 IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc", 1396 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16), 1397 (sra GPR:$b, (i32 16)))))]>, 1398 Requires<[IsARM, HasV5TE]> { 1399 let Inst{5} = 0; 1400 let Inst{6} = 1; 1401 } 1402 1403 def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 1404 IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc", 1405 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)), 1406 (sext_inreg GPR:$b, i16))))]>, 1407 Requires<[IsARM, HasV5TE]> { 1408 let Inst{5} = 1; 1409 let Inst{6} = 0; 1410 } 1411 1412 def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 1413 IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc", 1414 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)), 1415 (sra GPR:$b, (i32 16)))))]>, 1416 Requires<[IsARM, HasV5TE]> { 1417 let Inst{5} = 1; 1418 let Inst{6} = 1; 1419 } 1420 1421 def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 1422 IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc", 1423 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a, 1424 (sext_inreg GPR:$b, i16)), (i32 16))))]>, 1425 Requires<[IsARM, HasV5TE]> { 1426 let Inst{5} = 0; 1427 let Inst{6} = 0; 1428 } 1429 1430 def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), 1431 IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc", 1432 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a, 1433 (sra GPR:$b, (i32 16))), (i32 16))))]>, 1434 Requires<[IsARM, HasV5TE]> { 1435 let Inst{5} = 0; 1436 let Inst{6} = 1; 1437 } 1438} 1439 1440defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 1441defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>; 1442 1443// TODO: Halfword multiple accumulate long: SMLAL<x><y> 1444// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD 1445 1446//===----------------------------------------------------------------------===// 1447// Misc. Arithmetic Instructions. 1448// 1449 1450def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, 1451 "clz", "\t$dst, $src", 1452 [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> { 1453 let Inst{7-4} = 0b0001; 1454 let Inst{11-8} = 0b1111; 1455 let Inst{19-16} = 0b1111; 1456} 1457 1458def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, 1459 "rev", "\t$dst, $src", 1460 [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> { 1461 let Inst{7-4} = 0b0011; 1462 let Inst{11-8} = 0b1111; 1463 let Inst{19-16} = 0b1111; 1464} 1465 1466def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, 1467 "rev16", "\t$dst, $src", 1468 [(set GPR:$dst, 1469 (or (and (srl GPR:$src, (i32 8)), 0xFF), 1470 (or (and (shl GPR:$src, (i32 8)), 0xFF00), 1471 (or (and (srl GPR:$src, (i32 8)), 0xFF0000), 1472 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>, 1473 Requires<[IsARM, HasV6]> { 1474 let Inst{7-4} = 0b1011; 1475 let Inst{11-8} = 0b1111; 1476 let Inst{19-16} = 0b1111; 1477} 1478 1479def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr, 1480 "revsh", "\t$dst, $src", 1481 [(set GPR:$dst, 1482 (sext_inreg 1483 (or (srl (and GPR:$src, 0xFF00), (i32 8)), 1484 (shl GPR:$src, (i32 8))), i16))]>, 1485 Requires<[IsARM, HasV6]> { 1486 let Inst{7-4} = 0b1011; 1487 let Inst{11-8} = 0b1111; 1488 let Inst{19-16} = 0b1111; 1489} 1490 1491def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst), 1492 (ins GPR:$src1, GPR:$src2, i32imm:$shamt), 1493 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt", 1494 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF), 1495 (and (shl GPR:$src2, (i32 imm:$shamt)), 1496 0xFFFF0000)))]>, 1497 Requires<[IsARM, HasV6]> { 1498 let Inst{6-4} = 0b001; 1499} 1500 1501// Alternate cases for PKHBT where identities eliminate some nodes. 1502def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)), 1503 (PKHBT GPR:$src1, GPR:$src2, 0)>; 1504def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)), 1505 (PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>; 1506 1507 1508def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst), 1509 (ins GPR:$src1, GPR:$src2, i32imm:$shamt), 1510 IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt", 1511 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000), 1512 (and (sra GPR:$src2, imm16_31:$shamt), 1513 0xFFFF)))]>, Requires<[IsARM, HasV6]> { 1514 let Inst{6-4} = 0b101; 1515} 1516 1517// Alternate cases for PKHTB where identities eliminate some nodes. Note that 1518// a shift amount of 0 is *not legal* here, it is PKHBT instead. 1519def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))), 1520 (PKHTB GPR:$src1, GPR:$src2, 16)>; 1521def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), 1522 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)), 1523 (PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>; 1524 1525//===----------------------------------------------------------------------===// 1526// Comparison Instructions... 1527// 1528 1529defm CMP : AI1_cmp_irs<0b1010, "cmp", 1530 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>; 1531defm CMN : AI1_cmp_irs<0b1011, "cmn", 1532 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>; 1533 1534// Note that TST/TEQ don't set all the same flags that CMP does! 1535defm TST : AI1_cmp_irs<0b1000, "tst", 1536 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>; 1537defm TEQ : AI1_cmp_irs<0b1001, "teq", 1538 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>; 1539 1540defm CMPz : AI1_cmp_irs<0b1010, "cmp", 1541 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>; 1542defm CMNz : AI1_cmp_irs<0b1011, "cmn", 1543 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>; 1544 1545def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm), 1546 (CMNri GPR:$src, so_imm_neg:$imm)>; 1547 1548def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm), 1549 (CMNri GPR:$src, so_imm_neg:$imm)>; 1550 1551 1552// Conditional moves 1553// FIXME: should be able to write a pattern for ARMcmov, but can't use 1554// a two-value operand where a dag node expects two operands. :( 1555def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm, 1556 IIC_iCMOVr, "mov", "\t$dst, $true", 1557 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>, 1558 RegConstraint<"$false = $dst">, UnaryDP { 1559 let Inst{11-4} = 0b00000000; 1560 let Inst{25} = 0; 1561} 1562 1563def MOVCCs : AI1<0b1101, (outs GPR:$dst), 1564 (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr, 1565 "mov", "\t$dst, $true", 1566 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>, 1567 RegConstraint<"$false = $dst">, UnaryDP { 1568 let Inst{25} = 0; 1569} 1570 1571def MOVCCi : AI1<0b1101, (outs GPR:$dst), 1572 (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi, 1573 "mov", "\t$dst, $true", 1574 [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>, 1575 RegConstraint<"$false = $dst">, UnaryDP { 1576 let Inst{25} = 1; 1577} 1578 1579//===----------------------------------------------------------------------===// 1580// Atomic operations intrinsics 1581// 1582 1583// memory barriers protect the atomic sequences 1584let hasSideEffects = 1 in { 1585def Int_MemBarrierV7 : AInoP<(outs), (ins), 1586 Pseudo, NoItinerary, 1587 "dmb", "", 1588 [(ARMMemBarrierV7)]>, 1589 Requires<[IsARM, HasV7]> { 1590 let Inst{31-4} = 0xf57ff05; 1591 // FIXME: add support for options other than a full system DMB 1592 let Inst{3-0} = 0b1111; 1593} 1594 1595def Int_SyncBarrierV7 : AInoP<(outs), (ins), 1596 Pseudo, NoItinerary, 1597 "dsb", "", 1598 [(ARMSyncBarrierV7)]>, 1599 Requires<[IsARM, HasV7]> { 1600 let Inst{31-4} = 0xf57ff04; 1601 // FIXME: add support for options other than a full system DSB 1602 let Inst{3-0} = 0b1111; 1603} 1604 1605def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero), 1606 Pseudo, NoItinerary, 1607 "mcr", "\tp15, 0, $zero, c7, c10, 5", 1608 [(ARMMemBarrierV6 GPR:$zero)]>, 1609 Requires<[IsARM, HasV6]> { 1610 // FIXME: add support for options other than a full system DMB 1611 // FIXME: add encoding 1612} 1613 1614def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero), 1615 Pseudo, NoItinerary, 1616 "mcr", "\tp15, 0, $zero, c7, c10, 4", 1617 [(ARMSyncBarrierV6 GPR:$zero)]>, 1618 Requires<[IsARM, HasV6]> { 1619 // FIXME: add support for options other than a full system DSB 1620 // FIXME: add encoding 1621} 1622} 1623 1624let usesCustomInserter = 1 in { 1625 let Uses = [CPSR] in { 1626 def ATOMIC_LOAD_ADD_I8 : PseudoInst< 1627 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1628 "${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!", 1629 [(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>; 1630 def ATOMIC_LOAD_SUB_I8 : PseudoInst< 1631 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1632 "${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!", 1633 [(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>; 1634 def ATOMIC_LOAD_AND_I8 : PseudoInst< 1635 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1636 "${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!", 1637 [(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>; 1638 def ATOMIC_LOAD_OR_I8 : PseudoInst< 1639 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1640 "${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!", 1641 [(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>; 1642 def ATOMIC_LOAD_XOR_I8 : PseudoInst< 1643 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1644 "${:comment} ATOMIC_LOAD_XOR_I8 PSEUDO!", 1645 [(set GPR:$dst, (atomic_load_xor_8 GPR:$ptr, GPR:$incr))]>; 1646 def ATOMIC_LOAD_NAND_I8 : PseudoInst< 1647 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1648 "${:comment} ATOMIC_LOAD_NAND_I8 PSEUDO!", 1649 [(set GPR:$dst, (atomic_load_nand_8 GPR:$ptr, GPR:$incr))]>; 1650 def ATOMIC_LOAD_ADD_I16 : PseudoInst< 1651 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1652 "${:comment} ATOMIC_LOAD_ADD_I16 PSEUDO!", 1653 [(set GPR:$dst, (atomic_load_add_16 GPR:$ptr, GPR:$incr))]>; 1654 def ATOMIC_LOAD_SUB_I16 : PseudoInst< 1655 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1656 "${:comment} ATOMIC_LOAD_SUB_I16 PSEUDO!", 1657 [(set GPR:$dst, (atomic_load_sub_16 GPR:$ptr, GPR:$incr))]>; 1658 def ATOMIC_LOAD_AND_I16 : PseudoInst< 1659 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1660 "${:comment} ATOMIC_LOAD_AND_I16 PSEUDO!", 1661 [(set GPR:$dst, (atomic_load_and_16 GPR:$ptr, GPR:$incr))]>; 1662 def ATOMIC_LOAD_OR_I16 : PseudoInst< 1663 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1664 "${:comment} ATOMIC_LOAD_OR_I16 PSEUDO!", 1665 [(set GPR:$dst, (atomic_load_or_16 GPR:$ptr, GPR:$incr))]>; 1666 def ATOMIC_LOAD_XOR_I16 : PseudoInst< 1667 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1668 "${:comment} ATOMIC_LOAD_XOR_I16 PSEUDO!", 1669 [(set GPR:$dst, (atomic_load_xor_16 GPR:$ptr, GPR:$incr))]>; 1670 def ATOMIC_LOAD_NAND_I16 : PseudoInst< 1671 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1672 "${:comment} ATOMIC_LOAD_NAND_I16 PSEUDO!", 1673 [(set GPR:$dst, (atomic_load_nand_16 GPR:$ptr, GPR:$incr))]>; 1674 def ATOMIC_LOAD_ADD_I32 : PseudoInst< 1675 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1676 "${:comment} ATOMIC_LOAD_ADD_I32 PSEUDO!", 1677 [(set GPR:$dst, (atomic_load_add_32 GPR:$ptr, GPR:$incr))]>; 1678 def ATOMIC_LOAD_SUB_I32 : PseudoInst< 1679 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1680 "${:comment} ATOMIC_LOAD_SUB_I32 PSEUDO!", 1681 [(set GPR:$dst, (atomic_load_sub_32 GPR:$ptr, GPR:$incr))]>; 1682 def ATOMIC_LOAD_AND_I32 : PseudoInst< 1683 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1684 "${:comment} ATOMIC_LOAD_AND_I32 PSEUDO!", 1685 [(set GPR:$dst, (atomic_load_and_32 GPR:$ptr, GPR:$incr))]>; 1686 def ATOMIC_LOAD_OR_I32 : PseudoInst< 1687 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1688 "${:comment} ATOMIC_LOAD_OR_I32 PSEUDO!", 1689 [(set GPR:$dst, (atomic_load_or_32 GPR:$ptr, GPR:$incr))]>; 1690 def ATOMIC_LOAD_XOR_I32 : PseudoInst< 1691 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1692 "${:comment} ATOMIC_LOAD_XOR_I32 PSEUDO!", 1693 [(set GPR:$dst, (atomic_load_xor_32 GPR:$ptr, GPR:$incr))]>; 1694 def ATOMIC_LOAD_NAND_I32 : PseudoInst< 1695 (outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary, 1696 "${:comment} ATOMIC_LOAD_NAND_I32 PSEUDO!", 1697 [(set GPR:$dst, (atomic_load_nand_32 GPR:$ptr, GPR:$incr))]>; 1698 1699 def ATOMIC_SWAP_I8 : PseudoInst< 1700 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, 1701 "${:comment} ATOMIC_SWAP_I8 PSEUDO!", 1702 [(set GPR:$dst, (atomic_swap_8 GPR:$ptr, GPR:$new))]>; 1703 def ATOMIC_SWAP_I16 : PseudoInst< 1704 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, 1705 "${:comment} ATOMIC_SWAP_I16 PSEUDO!", 1706 [(set GPR:$dst, (atomic_swap_16 GPR:$ptr, GPR:$new))]>; 1707 def ATOMIC_SWAP_I32 : PseudoInst< 1708 (outs GPR:$dst), (ins GPR:$ptr, GPR:$new), NoItinerary, 1709 "${:comment} ATOMIC_SWAP_I32 PSEUDO!", 1710 [(set GPR:$dst, (atomic_swap_32 GPR:$ptr, GPR:$new))]>; 1711 1712 def ATOMIC_CMP_SWAP_I8 : PseudoInst< 1713 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, 1714 "${:comment} ATOMIC_CMP_SWAP_I8 PSEUDO!", 1715 [(set GPR:$dst, (atomic_cmp_swap_8 GPR:$ptr, GPR:$old, GPR:$new))]>; 1716 def ATOMIC_CMP_SWAP_I16 : PseudoInst< 1717 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, 1718 "${:comment} ATOMIC_CMP_SWAP_I16 PSEUDO!", 1719 [(set GPR:$dst, (atomic_cmp_swap_16 GPR:$ptr, GPR:$old, GPR:$new))]>; 1720 def ATOMIC_CMP_SWAP_I32 : PseudoInst< 1721 (outs GPR:$dst), (ins GPR:$ptr, GPR:$old, GPR:$new), NoItinerary, 1722 "${:comment} ATOMIC_CMP_SWAP_I32 PSEUDO!", 1723 [(set GPR:$dst, (atomic_cmp_swap_32 GPR:$ptr, GPR:$old, GPR:$new))]>; 1724} 1725} 1726 1727let mayLoad = 1 in { 1728def LDREXB : AIldrex<0b10, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary, 1729 "ldrexb", "\t$dest, [$ptr]", 1730 []>; 1731def LDREXH : AIldrex<0b11, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary, 1732 "ldrexh", "\t$dest, [$ptr]", 1733 []>; 1734def LDREX : AIldrex<0b00, (outs GPR:$dest), (ins GPR:$ptr), NoItinerary, 1735 "ldrex", "\t$dest, [$ptr]", 1736 []>; 1737def LDREXD : AIldrex<0b01, (outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr), 1738 NoItinerary, 1739 "ldrexd", "\t$dest, $dest2, [$ptr]", 1740 []>; 1741} 1742 1743let mayStore = 1 in { 1744def STREXB : AIstrex<0b10, (outs GPR:$success), (ins GPR:$src, GPR:$ptr), 1745 NoItinerary, 1746 "strexb", "\t$success, $src, [$ptr]", 1747 []>; 1748def STREXH : AIstrex<0b11, (outs GPR:$success), (ins GPR:$src, GPR:$ptr), 1749 NoItinerary, 1750 "strexh", "\t$success, $src, [$ptr]", 1751 []>; 1752def STREX : AIstrex<0b00, (outs GPR:$success), (ins GPR:$src, GPR:$ptr), 1753 NoItinerary, 1754 "strex", "\t$success, $src, [$ptr]", 1755 []>; 1756def STREXD : AIstrex<0b01, (outs GPR:$success), 1757 (ins GPR:$src, GPR:$src2, GPR:$ptr), 1758 NoItinerary, 1759 "strexd", "\t$success, $src, $src2, [$ptr]", 1760 []>; 1761} 1762 1763//===----------------------------------------------------------------------===// 1764// TLS Instructions 1765// 1766 1767// __aeabi_read_tp preserves the registers r1-r3. 1768let isCall = 1, 1769 Defs = [R0, R12, LR, CPSR] in { 1770 def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br, 1771 "bl\t__aeabi_read_tp", 1772 [(set R0, ARMthread_pointer)]>; 1773} 1774 1775//===----------------------------------------------------------------------===// 1776// SJLJ Exception handling intrinsics 1777// eh_sjlj_setjmp() is an instruction sequence to store the return 1778// address and save #0 in R0 for the non-longjmp case. 1779// Since by its nature we may be coming from some other function to get 1780// here, and we're using the stack frame for the containing function to 1781// save/restore registers, we can't keep anything live in regs across 1782// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon 1783// when we get here from a longjmp(). We force everthing out of registers 1784// except for our own input by listing the relevant registers in Defs. By 1785// doing so, we also cause the prologue/epilogue code to actively preserve 1786// all of the callee-saved resgisters, which is exactly what we want. 1787let Defs = 1788 [ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0, 1789 D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, 1790 D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, 1791 D31 ] in { 1792 def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src), 1793 AddrModeNone, SizeSpecial, IndexModeNone, 1794 Pseudo, NoItinerary, 1795 "str\tsp, [$src, #+8] @ eh_setjmp begin\n\t" 1796 "add\tr12, pc, #8\n\t" 1797 "str\tr12, [$src, #+4]\n\t" 1798 "mov\tr0, #0\n\t" 1799 "add\tpc, pc, #0\n\t" 1800 "mov\tr0, #1 @ eh_setjmp end", "", 1801 [(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>; 1802} 1803 1804//===----------------------------------------------------------------------===// 1805// Non-Instruction Patterns 1806// 1807 1808// Large immediate handling. 1809 1810// Two piece so_imms. 1811let isReMaterializable = 1 in 1812def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), 1813 Pseudo, IIC_iMOVi, 1814 "mov", "\t$dst, $src", 1815 [(set GPR:$dst, so_imm2part:$src)]>, 1816 Requires<[IsARM, NoV6T2]>; 1817 1818def : ARMPat<(or GPR:$LHS, so_imm2part:$RHS), 1819 (ORRri (ORRri GPR:$LHS, (so_imm2part_1 imm:$RHS)), 1820 (so_imm2part_2 imm:$RHS))>; 1821def : ARMPat<(xor GPR:$LHS, so_imm2part:$RHS), 1822 (EORri (EORri GPR:$LHS, (so_imm2part_1 imm:$RHS)), 1823 (so_imm2part_2 imm:$RHS))>; 1824def : ARMPat<(add GPR:$LHS, so_imm2part:$RHS), 1825 (ADDri (ADDri GPR:$LHS, (so_imm2part_1 imm:$RHS)), 1826 (so_imm2part_2 imm:$RHS))>; 1827def : ARMPat<(add GPR:$LHS, so_neg_imm2part:$RHS), 1828 (SUBri (SUBri GPR:$LHS, (so_neg_imm2part_1 imm:$RHS)), 1829 (so_neg_imm2part_2 imm:$RHS))>; 1830 1831// 32-bit immediate using movw + movt. 1832// This is a single pseudo instruction, the benefit is that it can be remat'd 1833// as a single unit instead of having to handle reg inputs. 1834// FIXME: Remove this when we can do generalized remat. 1835let isReMaterializable = 1 in 1836def MOVi32imm : AI1x2<(outs GPR:$dst), (ins i32imm:$src), Pseudo, IIC_iMOVi, 1837 "movw", "\t$dst, ${src:lo16}\n\tmovt${p}\t$dst, ${src:hi16}", 1838 [(set GPR:$dst, (i32 imm:$src))]>, 1839 Requires<[IsARM, HasV6T2]>; 1840 1841// ConstantPool, GlobalAddress, and JumpTable 1842def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>, 1843 Requires<[IsARM, DontUseMovt]>; 1844def : ARMPat<(ARMWrapper tconstpool :$dst), (LEApcrel tconstpool :$dst)>; 1845def : ARMPat<(ARMWrapper tglobaladdr :$dst), (MOVi32imm tglobaladdr :$dst)>, 1846 Requires<[IsARM, UseMovt]>; 1847def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id), 1848 (LEApcrelJT tjumptable:$dst, imm:$id)>; 1849 1850// TODO: add,sub,and, 3-instr forms? 1851 1852 1853// Direct calls 1854def : ARMPat<(ARMcall texternalsym:$func), (BL texternalsym:$func)>, 1855 Requires<[IsARM, IsNotDarwin]>; 1856def : ARMPat<(ARMcall texternalsym:$func), (BLr9 texternalsym:$func)>, 1857 Requires<[IsARM, IsDarwin]>; 1858 1859// zextload i1 -> zextload i8 1860def : ARMPat<(zextloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>; 1861 1862// extload -> zextload 1863def : ARMPat<(extloadi1 addrmode2:$addr), (LDRB addrmode2:$addr)>; 1864def : ARMPat<(extloadi8 addrmode2:$addr), (LDRB addrmode2:$addr)>; 1865def : ARMPat<(extloadi16 addrmode3:$addr), (LDRH addrmode3:$addr)>; 1866 1867def : ARMPat<(extloadi8 addrmodepc:$addr), (PICLDRB addrmodepc:$addr)>; 1868def : ARMPat<(extloadi16 addrmodepc:$addr), (PICLDRH addrmodepc:$addr)>; 1869 1870// smul* and smla* 1871def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 1872 (sra (shl GPR:$b, (i32 16)), (i32 16))), 1873 (SMULBB GPR:$a, GPR:$b)>; 1874def : ARMV5TEPat<(mul sext_16_node:$a, sext_16_node:$b), 1875 (SMULBB GPR:$a, GPR:$b)>; 1876def : ARMV5TEPat<(mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 1877 (sra GPR:$b, (i32 16))), 1878 (SMULBT GPR:$a, GPR:$b)>; 1879def : ARMV5TEPat<(mul sext_16_node:$a, (sra GPR:$b, (i32 16))), 1880 (SMULBT GPR:$a, GPR:$b)>; 1881def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), 1882 (sra (shl GPR:$b, (i32 16)), (i32 16))), 1883 (SMULTB GPR:$a, GPR:$b)>; 1884def : ARMV5TEPat<(mul (sra GPR:$a, (i32 16)), sext_16_node:$b), 1885 (SMULTB GPR:$a, GPR:$b)>; 1886def : ARMV5TEPat<(sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))), 1887 (i32 16)), 1888 (SMULWB GPR:$a, GPR:$b)>; 1889def : ARMV5TEPat<(sra (mul GPR:$a, sext_16_node:$b), (i32 16)), 1890 (SMULWB GPR:$a, GPR:$b)>; 1891 1892def : ARMV5TEPat<(add GPR:$acc, 1893 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 1894 (sra (shl GPR:$b, (i32 16)), (i32 16)))), 1895 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 1896def : ARMV5TEPat<(add GPR:$acc, 1897 (mul sext_16_node:$a, sext_16_node:$b)), 1898 (SMLABB GPR:$a, GPR:$b, GPR:$acc)>; 1899def : ARMV5TEPat<(add GPR:$acc, 1900 (mul (sra (shl GPR:$a, (i32 16)), (i32 16)), 1901 (sra GPR:$b, (i32 16)))), 1902 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 1903def : ARMV5TEPat<(add GPR:$acc, 1904 (mul sext_16_node:$a, (sra GPR:$b, (i32 16)))), 1905 (SMLABT GPR:$a, GPR:$b, GPR:$acc)>; 1906def : ARMV5TEPat<(add GPR:$acc, 1907 (mul (sra GPR:$a, (i32 16)), 1908 (sra (shl GPR:$b, (i32 16)), (i32 16)))), 1909 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 1910def : ARMV5TEPat<(add GPR:$acc, 1911 (mul (sra GPR:$a, (i32 16)), sext_16_node:$b)), 1912 (SMLATB GPR:$a, GPR:$b, GPR:$acc)>; 1913def : ARMV5TEPat<(add GPR:$acc, 1914 (sra (mul GPR:$a, (sra (shl GPR:$b, (i32 16)), (i32 16))), 1915 (i32 16))), 1916 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>; 1917def : ARMV5TEPat<(add GPR:$acc, 1918 (sra (mul GPR:$a, sext_16_node:$b), (i32 16))), 1919 (SMLAWB GPR:$a, GPR:$b, GPR:$acc)>; 1920 1921//===----------------------------------------------------------------------===// 1922// Thumb Support 1923// 1924 1925include "ARMInstrThumb.td" 1926 1927//===----------------------------------------------------------------------===// 1928// Thumb2 Support 1929// 1930 1931include "ARMInstrThumb2.td" 1932 1933//===----------------------------------------------------------------------===// 1934// Floating Point Support 1935// 1936 1937include "ARMInstrVFP.td" 1938 1939//===----------------------------------------------------------------------===// 1940// Advanced SIMD (NEON) Support 1941// 1942 1943include "ARMInstrNEON.td" 1944