llvm.org GIT mirror llvm / e516549
Use Unified Assembly Syntax for the ARM backend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86494 91177308-0d34-0410-b5e6-96231b3b80d8 Jim Grosbach 10 years ago
53 changed file(s) with 423 addition(s) and 421 deletion(s). Raw diff Collapse all Expand all
519519 return ((AM5Opc >> 8) & 1) ? sub : add;
520520 }
521521
522 /// getAM5Opc - This function encodes the addrmode5 opc field for FLDM and
523 /// FSTM instructions.
522 /// getAM5Opc - This function encodes the addrmode5 opc field for VLDM and
523 /// VSTM instructions.
524524 static inline unsigned getAM5Opc(AMSubMode SubMode, bool WB,
525525 unsigned char Offset) {
526526 assert((SubMode == ia || SubMode == db) &&
508508
509509 switch (MI.getOpcode()) {
510510 default: break;
511 case ARM::FCPYS:
512 case ARM::FCPYD:
511 case ARM::VMOVS:
513512 case ARM::VMOVD:
513 case ARM::VMOVDneon:
514514 case ARM::VMOVQ: {
515515 SrcReg = MI.getOperand(1).getReg();
516516 DstReg = MI.getOperand(0).getReg();
560560 return MI->getOperand(0).getReg();
561561 }
562562 break;
563 case ARM::FLDD:
564 case ARM::FLDS:
563 case ARM::VLDRD:
564 case ARM::VLDRS:
565565 if (MI->getOperand(1).isFI() &&
566566 MI->getOperand(2).isImm() &&
567567 MI->getOperand(2).getImm() == 0) {
599599 return MI->getOperand(0).getReg();
600600 }
601601 break;
602 case ARM::FSTD:
603 case ARM::FSTS:
602 case ARM::VSTRD:
603 case ARM::VSTRS:
604604 if (MI->getOperand(1).isFI() &&
605605 MI->getOperand(2).isImm() &&
606606 MI->getOperand(2).getImm() == 0) {
636636 AddDefaultCC(AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::MOVr),
637637 DestReg).addReg(SrcReg)));
638638 } else if (DestRC == ARM::SPRRegisterClass) {
639 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYS), DestReg)
639 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVS), DestReg)
640640 .addReg(SrcReg));
641641 } else if (DestRC == ARM::DPRRegisterClass) {
642 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FCPYD), DestReg)
642 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVD), DestReg)
643643 .addReg(SrcReg));
644644 } else if (DestRC == ARM::DPR_VFP2RegisterClass ||
645645 DestRC == ARM::DPR_8RegisterClass ||
646646 SrcRC == ARM::DPR_VFP2RegisterClass ||
647647 SrcRC == ARM::DPR_8RegisterClass) {
648648 // Always use neon reg-reg move if source or dest is NEON-only regclass.
649 BuildMI(MBB, I, DL, get(ARM::VMOVD), DestReg).addReg(SrcReg);
649 BuildMI(MBB, I, DL, get(ARM::VMOVDneon), DestReg).addReg(SrcReg);
650650 } else if (DestRC == ARM::QPRRegisterClass ||
651651 DestRC == ARM::QPR_VFP2RegisterClass ||
652652 DestRC == ARM::QPR_8RegisterClass) {
681681 } else if (RC == ARM::DPRRegisterClass ||
682682 RC == ARM::DPR_VFP2RegisterClass ||
683683 RC == ARM::DPR_8RegisterClass) {
684 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTD))
684 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRD))
685685 .addReg(SrcReg, getKillRegState(isKill))
686686 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
687687 } else if (RC == ARM::SPRRegisterClass) {
688 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FSTS))
688 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRS))
689689 .addReg(SrcReg, getKillRegState(isKill))
690690 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
691691 } else {
727727 } else if (RC == ARM::DPRRegisterClass ||
728728 RC == ARM::DPR_VFP2RegisterClass ||
729729 RC == ARM::DPR_8RegisterClass) {
730 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDD), DestReg)
730 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRD), DestReg)
731731 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
732732 } else if (RC == ARM::SPRRegisterClass) {
733 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::FLDS), DestReg)
733 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRS), DestReg)
734734 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
735735 } else {
736736 assert((RC == ARM::QPRRegisterClass ||
826826 DstSubReg)
827827 .addFrameIndex(FI).addImm(0).addImm(ARMCC::AL).addReg(0);
828828 }
829 } else if (Opc == ARM::FCPYS) {
829 } else if (Opc == ARM::VMOVS) {
830830 unsigned Pred = MI->getOperand(2).getImm();
831831 unsigned PredReg = MI->getOperand(3).getReg();
832832 if (OpNum == 0) { // move -> store
834834 unsigned SrcSubReg = MI->getOperand(1).getSubReg();
835835 bool isKill = MI->getOperand(1).isKill();
836836 bool isUndef = MI->getOperand(1).isUndef();
837 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTS))
837 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VSTRS))
838838 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef),
839839 SrcSubReg)
840840 .addFrameIndex(FI)
844844 unsigned DstSubReg = MI->getOperand(0).getSubReg();
845845 bool isDead = MI->getOperand(0).isDead();
846846 bool isUndef = MI->getOperand(0).isUndef();
847 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDS))
847 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VLDRS))
848848 .addReg(DstReg,
849849 RegState::Define |
850850 getDeadRegState(isDead) |
853853 .addFrameIndex(FI).addImm(0).addImm(Pred).addReg(PredReg);
854854 }
855855 }
856 else if (Opc == ARM::FCPYD) {
856 else if (Opc == ARM::VMOVD) {
857857 unsigned Pred = MI->getOperand(2).getImm();
858858 unsigned PredReg = MI->getOperand(3).getReg();
859859 if (OpNum == 0) { // move -> store
861861 unsigned SrcSubReg = MI->getOperand(1).getSubReg();
862862 bool isKill = MI->getOperand(1).isKill();
863863 bool isUndef = MI->getOperand(1).isUndef();
864 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FSTD))
864 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VSTRD))
865865 .addReg(SrcReg,
866866 getKillRegState(isKill) | getUndefRegState(isUndef),
867867 SrcSubReg)
871871 unsigned DstSubReg = MI->getOperand(0).getSubReg();
872872 bool isDead = MI->getOperand(0).isDead();
873873 bool isUndef = MI->getOperand(0).isUndef();
874 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::FLDD))
874 NewMI = BuildMI(MF, MI->getDebugLoc(), get(ARM::VLDRD))
875875 .addReg(DstReg,
876876 RegState::Define |
877877 getDeadRegState(isDead) |
907907 Opc == ARM::tMOVtgpr2gpr ||
908908 Opc == ARM::tMOVgpr2tgpr) {
909909 return true;
910 } else if (Opc == ARM::FCPYS || Opc == ARM::FCPYD) {
910 } else if (Opc == ARM::VMOVS || Opc == ARM::VMOVD) {
911911 return true;
912 } else if (Opc == ARM::VMOVD || Opc == ARM::VMOVQ) {
912 } else if (Opc == ARM::VMOVDneon || Opc == ARM::VMOVQ) {
913913 return false; // FIXME
914914 }
915915
13451345 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
13461346 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
13471347
1348 movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 0, 3, STI);
1348 movePastCSLoadStoreOps(MBB, MBBI, ARM::VSTRD, 0, 3, STI);
13491349 NumBytes = DPRCSOffset;
13501350 if (NumBytes) {
13511351 // Adjust SP after all the callee-save spills.
13841384 static bool isCSRestore(MachineInstr *MI,
13851385 const ARMBaseInstrInfo &TII,
13861386 const unsigned *CSRegs) {
1387 return ((MI->getOpcode() == (int)ARM::FLDD ||
1387 return ((MI->getOpcode() == (int)ARM::VLDRD ||
13881388 MI->getOpcode() == (int)ARM::LDR ||
13891389 MI->getOpcode() == (int)ARM::t2LDRi12) &&
13901390 MI->getOperand(1).isFI() &&
14101410 if (NumBytes != 0)
14111411 emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
14121412 } else {
1413 // Unwind MBBI to point to first LDR / FLDD.
1413 // Unwind MBBI to point to first LDR / VLDRD.
14141414 const unsigned *CSRegs = getCalleeSavedRegs();
14151415 if (MBBI != MBB.begin()) {
14161416 do
14581458 emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
14591459
14601460 // Move SP to start of integer callee save spill area 2.
1461 movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 0, 3, STI);
1461 movePastCSLoadStoreOps(MBB, MBBI, ARM::VLDRD, 0, 3, STI);
14621462 emitSPUpdate(isARM, MBB, MBBI, dl, TII, AFI->getDPRCalleeSavedAreaSize());
14631463
14641464 // Move SP to start of integer callee save spill area 1.
540540 Scale = 4; // +(offset_8*4)
541541 break;
542542
543 case ARM::FLDD:
544 case ARM::FLDS:
543 case ARM::VLDRD:
544 case ARM::VLDRS:
545545 Bits = 8;
546546 Scale = 4; // +-(offset_8*4)
547547 NegOk = true;
14651465 }
14661466 break;
14671467 }
1468 case ARMISD::FMRRD:
1469 return CurDAG->getMachineNode(ARM::FMRRD, dl, MVT::i32, MVT::i32,
1468 case ARMISD::VMOVRRD:
1469 return CurDAG->getMachineNode(ARM::VMOVRRD, dl, MVT::i32, MVT::i32,
14701470 Op.getOperand(0), getAL(CurDAG),
14711471 CurDAG->getRegister(0, MVT::i32));
14721472 case ISD::UMUL_LOHI: {
16551655 : ARM::MOVCCr;
16561656 break;
16571657 case MVT::f32:
1658 Opc = ARM::FCPYScc;
1658 Opc = ARM::VMOVScc;
16591659 break;
16601660 case MVT::f64:
1661 Opc = ARM::FCPYDcc;
1661 Opc = ARM::VMOVDcc;
16621662 break;
16631663 }
16641664 return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5);
16821682 default: assert(false && "Illegal conditional move type!");
16831683 break;
16841684 case MVT::f32:
1685 Opc = ARM::FNEGScc;
1685 Opc = ARM::VNEGScc;
16861686 break;
16871687 case MVT::f64:
1688 Opc = ARM::FNEGDcc;
1688 Opc = ARM::VNEGDcc;
16891689 break;
16901690 }
16911691 return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5);
388388 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
389389
390390 if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb1Only())
391 // Turn f64->i64 into FMRRD, i64 -> f64 to FMDRR iff target supports vfp2.
391 // Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR iff target supports vfp2.
392392 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Custom);
393393
394394 // We want to custom lower some of our intrinsics.
433433 }
434434
435435 // We have target-specific dag combine patterns for the following nodes:
436 // ARMISD::FMRRD - No need to call setTargetDAGCombine
436 // ARMISD::VMOVRRD - No need to call setTargetDAGCombine
437437 setTargetDAGCombine(ISD::ADD);
438438 setTargetDAGCombine(ISD::SUB);
439439
492492 case ARMISD::SRA_FLAG: return "ARMISD::SRA_FLAG";
493493 case ARMISD::RRX: return "ARMISD::RRX";
494494
495 case ARMISD::FMRRD: return "ARMISD::FMRRD";
496 case ARMISD::FMDRR: return "ARMISD::FMDRR";
495 case ARMISD::VMOVRRD: return "ARMISD::VMOVRRD";
496 case ARMISD::VMOVDRR: return "ARMISD::VMOVDRR";
497497
498498 case ARMISD::EH_SJLJ_SETJMP: return "ARMISD::EH_SJLJ_SETJMP";
499499 case ARMISD::EH_SJLJ_LONGJMP:return "ARMISD::EH_SJLJ_LONGJMP";
789789 InFlag);
790790 Chain = Hi.getValue(1);
791791 InFlag = Hi.getValue(2);
792 Val = DAG.getNode(ARMISD::FMDRR, dl, MVT::f64, Lo, Hi);
792 Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
793793
794794 if (VA.getLocVT() == MVT::v2f64) {
795795 SDValue Vec = DAG.getNode(ISD::UNDEF, dl, MVT::v2f64);
804804 Hi = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), MVT::i32, InFlag);
805805 Chain = Hi.getValue(1);
806806 InFlag = Hi.getValue(2);
807 Val = DAG.getNode(ARMISD::FMDRR, dl, MVT::f64, Lo, Hi);
807 Val = DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
808808 Val = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, MVT::v2f64, Vec, Val,
809809 DAG.getConstant(1, MVT::i32));
810810 }
869869 SmallVector &MemOpChains,
870870 ISD::ArgFlagsTy Flags) {
871871
872 SDValue fmrrd = DAG.getNode(ARMISD::FMRRD, dl,
872 SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl,
873873 DAG.getVTList(MVT::i32, MVT::i32), Arg);
874874 RegsToPass.push_back(std::make_pair(VA.getLocReg(), fmrrd));
875875
11481148 // Extract the first half and return it in two registers.
11491149 SDValue Half = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
11501150 DAG.getConstant(0, MVT::i32));
1151 SDValue HalfGPRs = DAG.getNode(ARMISD::FMRRD, dl,
1151 SDValue HalfGPRs = DAG.getNode(ARMISD::VMOVRRD, dl,
11521152 DAG.getVTList(MVT::i32, MVT::i32), Half);
11531153
11541154 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), HalfGPRs, Flag);
11651165 }
11661166 // Legalize ret f64 -> ret 2 x i32. We always have fmrrd if f64 is
11671167 // available.
1168 SDValue fmrrd = DAG.getNode(ARMISD::FMRRD, dl,
1168 SDValue fmrrd = DAG.getNode(ARMISD::VMOVRRD, dl,
11691169 DAG.getVTList(MVT::i32, MVT::i32), &Arg, 1);
11701170 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), fmrrd, Flag);
11711171 Flag = Chain.getValue(1);
15551555 ArgValue2 = DAG.getCopyFromReg(Root, dl, Reg, MVT::i32);
15561556 }
15571557
1558 return DAG.getNode(ARMISD::FMDRR, dl, MVT::f64, ArgValue, ArgValue2);
1558 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, ArgValue, ArgValue2);
15591559 }
15601560
15611561 SDValue
20712071 SDValue Op = N->getOperand(0);
20722072 DebugLoc dl = N->getDebugLoc();
20732073 if (N->getValueType(0) == MVT::f64) {
2074 // Turn i64->f64 into FMDRR.
2074 // Turn i64->f64 into VMOVDRR.
20752075 SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Op,
20762076 DAG.getConstant(0, MVT::i32));
20772077 SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Op,
20782078 DAG.getConstant(1, MVT::i32));
2079 return DAG.getNode(ARMISD::FMDRR, dl, MVT::f64, Lo, Hi);
2080 }
2081
2082 // Turn f64->i64 into FMRRD.
2083 SDValue Cvt = DAG.getNode(ARMISD::FMRRD, dl,
2079 return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Lo, Hi);
2080 }
2081
2082 // Turn f64->i64 into VMOVRRD.
2083 SDValue Cvt = DAG.getNode(ARMISD::VMOVRRD, dl,
20842084 DAG.getVTList(MVT::i32, MVT::i32), &Op, 1);
20852085
20862086 // Merge the pieces into a single i64 value.
31773177 return SDValue();
31783178 }
31793179
3180 /// PerformFMRRDCombine - Target-specific dag combine xforms for ARMISD::FMRRD.
3181 static SDValue PerformFMRRDCombine(SDNode *N,
3180 /// PerformVMOVRRDCombine - Target-specific dag combine xforms for ARMISD::VMOVRRD.
3181 static SDValue PerformVMOVRRDCombine(SDNode *N,
31823182 TargetLowering::DAGCombinerInfo &DCI) {
31833183 // fmrrd(fmdrr x, y) -> x,y
31843184 SDValue InDouble = N->getOperand(0);
3185 if (InDouble.getOpcode() == ARMISD::FMDRR)
3185 if (InDouble.getOpcode() == ARMISD::VMOVDRR)
31863186 return DCI.CombineTo(N, InDouble.getOperand(0), InDouble.getOperand(1));
31873187 return SDValue();
31883188 }
34773477 default: break;
34783478 case ISD::ADD: return PerformADDCombine(N, DCI);
34793479 case ISD::SUB: return PerformSUBCombine(N, DCI);
3480 case ARMISD::FMRRD: return PerformFMRRDCombine(N, DCI);
3480 case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI);
34813481 case ISD::INTRINSIC_WO_CHAIN:
34823482 return PerformIntrinsicCombine(N, DCI.DAG);
34833483 case ISD::SHL:
37593759 return true;
37603760 }
37613761
3762 // FIXME: Use FLDM / FSTM to emulate indexed FP load / store.
3762 // FIXME: Use VLDM / VSTM to emulate indexed FP load / store.
37633763 return false;
37643764 }
37653765
6161 SRA_FLAG, // V,Flag = sra_flag X -> sra X, 1 + save carry out.
6262 RRX, // V = RRX X, Flag -> srl X, 1 + shift in carry flag.
6363
64 FMRRD, // double to two gprs.
65 FMDRR, // Two gprs to double.
64 VMOVRRD, // double to two gprs.
65 VMOVDRR, // Two gprs to double.
6666
6767 EH_SJLJ_SETJMP, // SjLj exception handling setjmp.
6868 EH_SJLJ_LONGJMP, // SjLj exception handling longjmp.
393393 multiclass AI1_bin_s_irs opcod, string opc, PatFrag opnode,
394394 bit Commutable = 0> {
395395 def ri : AI1
396 IIC_iALUi, opc, "s\t$dst, $a, $b",
396 IIC_iALUi, opc, "\t$dst, $a, $b",
397397 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
398398 let Inst{20} = 1;
399399 let Inst{25} = 1;
400400 }
401401 def rr : AI1
402 IIC_iALUr, opc, "s\t$dst, $a, $b",
402 IIC_iALUr, opc, "\t$dst, $a, $b",
403403 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
404404 let isCommutable = Commutable;
405405 let Inst{11-4} = 0b00000000;
407407 let Inst{25} = 0;
408408 }
409409 def rs : AI1
410 IIC_iALUsr, opc, "s\t$dst, $a, $b",
410 IIC_iALUsr, opc, "\t$dst, $a, $b",
411411 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
412412 let Inst{20} = 1;
413413 let Inst{25} = 0;
503503 Requires<[IsARM, CarryDefIsUnused]> {
504504 let Inst{25} = 0;
505505 }
506 // Carry setting variants
506 }
507 // Carry setting variants
508 let Defs = [CPSR] in {
509 multiclass AI1_adde_sube_s_irs opcod, string opc, PatFrag opnode,
510 bit Commutable = 0> {
507511 def Sri : AXI1
508 DPFrm, IIC_iALUi, !strconcat(opc, "s\t$dst, $a, $b"),
512 DPFrm, IIC_iALUi, !strconcat(opc, "\t$dst, $a, $b"),
509513 [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
510514 Requires<[IsARM, CarryDefIsUsed]> {
511515 let Defs = [CPSR];
513517 let Inst{25} = 1;
514518 }
515519 def Srr : AXI1
516 DPFrm, IIC_iALUr, !strconcat(opc, "s\t$dst, $a, $b"),
520 DPFrm, IIC_iALUr, !strconcat(opc, "\t$dst, $a, $b"),
517521 [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
518522 Requires<[IsARM, CarryDefIsUsed]> {
519523 let Defs = [CPSR];
522526 let Inst{25} = 0;
523527 }
524528 def Srs : AXI1
525 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "s\t$dst, $a, $b"),
529 DPSoRegFrm, IIC_iALUsr, !strconcat(opc, "\t$dst, $a, $b"),
526530 [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
527531 Requires<[IsARM, CarryDefIsUsed]> {
528532 let Defs = [CPSR];
529533 let Inst{20} = 1;
530534 let Inst{25} = 0;
531535 }
536 }
532537 }
533538 }
534539
662667 hasExtraDefRegAllocReq = 1 in
663668 def LDM_RET : AXI4ld<(outs),
664669 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
665 LdStMulFrm, IIC_Br, "ldm${p}${addr:submode}\t$addr, $wb",
670 LdStMulFrm, IIC_Br, "ldm${addr:submode}${p}\t$addr, $wb",
666671 []>;
667672
668673 // On non-Darwin platforms R9 is callee-saved.
802807
803808 // Loads with zero extension
804809 def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
805 IIC_iLoadr, "ldr", "h\t$dst, $addr",
810 IIC_iLoadr, "ldrh", "\t$dst, $addr",
806811 [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
807812
808813 def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
809 IIC_iLoadr, "ldr", "b\t$dst, $addr",
814 IIC_iLoadr, "ldrb", "\t$dst, $addr",
810815 [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
811816
812817 // Loads with sign extension
813818 def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
814 IIC_iLoadr, "ldr", "sh\t$dst, $addr",
819 IIC_iLoadr, "ldrsh", "\t$dst, $addr",
815820 [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
816821
817822 def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
818 IIC_iLoadr, "ldr", "sb\t$dst, $addr",
823 IIC_iLoadr, "ldrsb", "\t$dst, $addr",
819824 [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
820825
821826 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
822827 // Load doubleword
823828 def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
824 IIC_iLoadr, "ldr", "d\t$dst1, $addr",
829 IIC_iLoadr, "ldrd", "\t$dst1, $addr",
825830 []>, Requires<[IsARM, HasV5TE]>;
826831
827832 // Indexed loads
835840
836841 def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
837842 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
838 "ldr", "h\t$dst, $addr!", "$addr.base = $base_wb", []>;
843 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
839844
840845 def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
841846 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
842 "ldr", "h\t$dst, [$base], $offset", "$base = $base_wb", []>;
847 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
843848
844849 def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
845850 (ins addrmode2:$addr), LdFrm, IIC_iLoadru,
846 "ldr", "b\t$dst, $addr!", "$addr.base = $base_wb", []>;
851 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
847852
848853 def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
849854 (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
850 "ldr", "b\t$dst, [$base], $offset", "$base = $base_wb", []>;
855 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
851856
852857 def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
853858 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
854 "ldr", "sh\t$dst, $addr!", "$addr.base = $base_wb", []>;
859 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
855860
856861 def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
857862 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
858 "ldr", "sh\t$dst, [$base], $offset", "$base = $base_wb", []>;
863 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
859864
860865 def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
861866 (ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
862 "ldr", "sb\t$dst, $addr!", "$addr.base = $base_wb", []>;
867 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
863868
864869 def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
865870 (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
866 "ldr", "sb\t$dst, [$base], $offset", "$base = $base_wb", []>;
871 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
867872 }
868873
869874 // Store
873878
874879 // Stores with truncate
875880 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStorer,
876 "str", "h\t$src, $addr",
881 "strh", "\t$src, $addr",
877882 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
878883
879884 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
880 "str", "b\t$src, $addr",
885 "strb", "\t$src, $addr",
881886 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
882887
883888 // Store doubleword
884889 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
885890 def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
886891 StMiscFrm, IIC_iStorer,
887 "str", "d\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
892 "strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
888893
889894 // Indexed stores
890895 def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
904909 def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
905910 (ins GPR:$src, GPR:$base,am3offset:$offset),
906911 StMiscFrm, IIC_iStoreru,
907 "str", "h\t$src, [$base, $offset]!", "$base = $base_wb",
912 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
908913 [(set GPR:$base_wb,
909914 (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
910915
911916 def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
912917 (ins GPR:$src, GPR:$base,am3offset:$offset),
913918 StMiscFrm, IIC_iStoreru,
914 "str", "h\t$src, [$base], $offset", "$base = $base_wb",
919 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
915920 [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
916921 GPR:$base, am3offset:$offset))]>;
917922
918923 def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
919924 (ins GPR:$src, GPR:$base,am2offset:$offset),
920925 StFrm, IIC_iStoreru,
921 "str", "b\t$src, [$base, $offset]!", "$base = $base_wb",
926 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
922927 [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
923928 GPR:$base, am2offset:$offset))]>;
924929
925930 def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
926931 (ins GPR:$src, GPR:$base,am2offset:$offset),
927932 StFrm, IIC_iStoreru,
928 "str", "b\t$src, [$base], $offset", "$base = $base_wb",
933 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
929934 [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
930935 GPR:$base, am2offset:$offset))]>;
931936
936941 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
937942 def LDM : AXI4ld<(outs),
938943 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
939 LdStMulFrm, IIC_iLoadm, "ldm${p}${addr:submode}\t$addr, $wb",
944 LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
940945 []>;
941946
942947 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
943948 def STM : AXI4st<(outs),
944949 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
945 LdStMulFrm, IIC_iStorem, "stm${p}${addr:submode}\t$addr, $wb",
950 LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
946951 []>;
947952
948953 //===----------------------------------------------------------------------===//
10031008
10041009 let Defs = [CPSR] in {
10051010 def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1006 IIC_iMOVsi, "mov", "s\t$dst, $src, lsr #1",
1011 IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
10071012 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
10081013 def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
1009 IIC_iMOVsi, "mov", "s\t$dst, $src, asr #1",
1014 IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
10101015 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
10111016 }
10121017
10821087 BinOpFrag<(sub node:$LHS, node:$RHS)>>;
10831088
10841089 // ADD and SUB with 's' bit set.
1085 defm ADDS : AI1_bin_s_irs<0b0100, "add",
1086 BinOpFrag<(addc node:$LHS, node:$RHS)>>;
1087 defm SUBS : AI1_bin_s_irs<0b0010, "sub",
1090 defm ADDS : AI1_bin_s_irs<0b0100, "adds",
1091 BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
1092 defm SUBS : AI1_bin_s_irs<0b0010, "subs",
10881093 BinOpFrag<(subc node:$LHS, node:$RHS)>>;
10891094
10901095 defm ADC : AI1_adde_sube_irs<0b0101, "adc",
10911096 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
10921097 defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
1098 BinOpFrag<(sube node:$LHS, node:$RHS)>>;
1099 defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
1100 BinOpFrag<(adde node:$LHS, node:$RHS)>, 1>;
1101 defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
10931102 BinOpFrag<(sube node:$LHS, node:$RHS)>>;
10941103
10951104 // These don't define reg/reg forms, because they are handled above.
11081117 // RSB with 's' bit set.
11091118 let Defs = [CPSR] in {
11101119 def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
1111 IIC_iALUi, "rsb", "s\t$dst, $a, $b",
1120 IIC_iALUi, "rsbs", "\t$dst, $a, $b",
11121121 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
11131122 let Inst{20} = 1;
11141123 let Inst{25} = 1;
11151124 }
11161125 def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
1117 IIC_iALUsr, "rsb", "s\t$dst, $a, $b",
1126 IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
11181127 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
11191128 let Inst{20} = 1;
11201129 let Inst{25} = 0;
22942294
22952295 // VMOV : Vector Move (Register)
22962296
2297 def VMOVD : N3V<0, 0, 0b10, 0b0001, 0, 1, (outs DPR:$dst), (ins DPR:$src),
2297 def VMOVDneon: N3V<0, 0, 0b10, 0b0001, 0, 1, (outs DPR:$dst), (ins DPR:$src),
22982298 IIC_VMOVD, "vmov\t$dst, $src", "", []>;
22992299 def VMOVQ : N3V<0, 0, 0b10, 0b0001, 1, 1, (outs QPR:$dst), (ins QPR:$src),
23002300 IIC_VMOVD, "vmov\t$dst, $src", "", []>;
1616 SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>;
1717 def SDT_CMPFP0 :
1818 SDTypeProfile<0, 1, [SDTCisFP<0>]>;
19 def SDT_FMDRR :
19 def SDT_VMOVDRR :
2020 SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>,
2121 SDTCisSameAs<1, 2>]>;
2222
2727 def arm_fmstat : SDNode<"ARMISD::FMSTAT", SDTNone, [SDNPInFlag,SDNPOutFlag]>;
2828 def arm_cmpfp : SDNode<"ARMISD::CMPFP", SDT_ARMCmp, [SDNPOutFlag]>;
2929 def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0",SDT_CMPFP0, [SDNPOutFlag]>;
30 def arm_fmdrr : SDNode<"ARMISD::FMDRR", SDT_FMDRR>;
30 def arm_fmdrr : SDNode<"ARMISD::VMOVDRR", SDT_VMOVDRR>;
3131
3232 //===----------------------------------------------------------------------===//
3333 // Operand Definitions.
5454 //
5555
5656 let canFoldAsLoad = 1 in {
57 def FLDD : ADI5<0b1101, 0b01, (outs DPR:$dst), (ins addrmode5:$addr),
58 IIC_fpLoad64, "fldd", "\t$dst, $addr",
57 def VLDRD : ADI5<0b1101, 0b01, (outs DPR:$dst), (ins addrmode5:$addr),
58 IIC_fpLoad64, "vldr", ".64\t$dst, $addr",
5959 [(set DPR:$dst, (load addrmode5:$addr))]>;
6060
61 def FLDS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr),
62 IIC_fpLoad32, "flds", "\t$dst, $addr",
61 def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr),
62 IIC_fpLoad32, "vldr", ".32\t$dst, $addr",
6363 [(set SPR:$dst, (load addrmode5:$addr))]>;
6464 } // canFoldAsLoad
6565
66 def FSTD : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr),
67 IIC_fpStore64, "fstd", "\t$src, $addr",
66 def VSTRD : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr),
67 IIC_fpStore64, "vstr", ".64\t$src, $addr",
6868 [(store DPR:$src, addrmode5:$addr)]>;
6969
70 def FSTS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr),
71 IIC_fpStore32, "fsts", "\t$src, $addr",
70 def VSTRS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr),
71 IIC_fpStore32, "vstr", ".32\t$src, $addr",
7272 [(store SPR:$src, addrmode5:$addr)]>;
7373
7474 //===----------------------------------------------------------------------===//
7676 //
7777
7878 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
79 def FLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
79 def VLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
8080 variable_ops), IIC_fpLoadm,
81 "fldm${addr:submode}d${p}\t${addr:base}, $wb",
81 "vldm${addr:submode}${p}\t${addr:base}, $wb",
8282 []> {
8383 let Inst{20} = 1;
8484 }
8585
86 def FLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
86 def VLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
8787 variable_ops), IIC_fpLoadm,
88 "fldm${addr:submode}s${p}\t${addr:base}, $wb",
88 "vldm${addr:submode}${p}\t${addr:base}, $wb",
8989 []> {
9090 let Inst{20} = 1;
9191 }
9292 } // mayLoad, hasExtraDefRegAllocReq
9393
9494 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in {
95 def FSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
95 def VSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
9696 variable_ops), IIC_fpStorem,
97 "fstm${addr:submode}d${p}\t${addr:base}, $wb",
97 "vstm${addr:submode}${p}\t${addr:base}, $wb",
9898 []> {
9999 let Inst{20} = 0;
100100 }
101101
102 def FSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
102 def VSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$wb,
103103 variable_ops), IIC_fpStorem,
104 "fstm${addr:submode}s${p}\t${addr:base}, $wb",
104 "vstm${addr:submode}${p}\t${addr:base}, $wb",
105105 []> {
106106 let Inst{20} = 0;
107107 }
113113 // FP Binary Operations.
114114 //
115115
116 def FADDD : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
117 IIC_fpALU64, "faddd", "\t$dst, $a, $b",
116 def VADDD : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
117 IIC_fpALU64, "vadd", ".f64\t$dst, $a, $b",
118118 [(set DPR:$dst, (fadd DPR:$a, DPR:$b))]>;
119119
120 def FADDS : ASbIn<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
121 IIC_fpALU32, "fadds", "\t$dst, $a, $b",
120 def VADDS : ASbIn<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
121 IIC_fpALU32, "vadd", ".f32\t$dst, $a, $b",
122122 [(set SPR:$dst, (fadd SPR:$a, SPR:$b))]>;
123123
124124 // These are encoded as unary instructions.
125125 let Defs = [FPSCR] in {
126 def FCMPED : ADuI<0b11101011, 0b0100, 0b1100, (outs), (ins DPR:$a, DPR:$b),
127 IIC_fpCMP64, "fcmped", "\t$a, $b",
126 def VCMPED : ADuI<0b11101011, 0b0100, 0b1100, (outs), (ins DPR:$a, DPR:$b),
127 IIC_fpCMP64, "vcmpe", ".f64\t$a, $b",
128128 [(arm_cmpfp DPR:$a, DPR:$b)]>;
129129
130 def FCMPES : ASuI<0b11101011, 0b0100, 0b1100, (outs), (ins SPR:$a, SPR:$b),
131 IIC_fpCMP32, "fcmpes", "\t$a, $b",
130 def VCMPES : ASuI<0b11101011, 0b0100, 0b1100, (outs), (ins SPR:$a, SPR:$b),
131 IIC_fpCMP32, "vcmpe", ".f32\t$a, $b",
132132 [(arm_cmpfp SPR:$a, SPR:$b)]>;
133133 }
134134
135 def FDIVD : ADbI<0b11101000, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
136 IIC_fpDIV64, "fdivd", "\t$dst, $a, $b",
135 def VDIVD : ADbI<0b11101000, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
136 IIC_fpDIV64, "vdiv", ".f64\t$dst, $a, $b",
137137 [(set DPR:$dst, (fdiv DPR:$a, DPR:$b))]>;
138138
139 def FDIVS : ASbI<0b11101000, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
140 IIC_fpDIV32, "fdivs", "\t$dst, $a, $b",
139 def VDIVS : ASbI<0b11101000, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
140 IIC_fpDIV32, "vdiv", ".f32\t$dst, $a, $b",
141141 [(set SPR:$dst, (fdiv SPR:$a, SPR:$b))]>;
142142
143 def FMULD : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
144 IIC_fpMUL64, "fmuld", "\t$dst, $a, $b",
143 def VMULD : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
144 IIC_fpMUL64, "vmul", ".f64\t$dst, $a, $b",
145145 [(set DPR:$dst, (fmul DPR:$a, DPR:$b))]>;
146146
147 def FMULS : ASbIn<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
148 IIC_fpMUL32, "fmuls", "\t$dst, $a, $b",
147 def VMULS : ASbIn<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
148 IIC_fpMUL32, "vmul", ".f32\t$dst, $a, $b",
149149 [(set SPR:$dst, (fmul SPR:$a, SPR:$b))]>;
150
151 def FNMULD : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
152 IIC_fpMUL64, "fnmuld", "\t$dst, $a, $b",
150
151 def VNMULD : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
152 IIC_fpMUL64, "vnmul", ".f64\t$dst, $a, $b",
153153 [(set DPR:$dst, (fneg (fmul DPR:$a, DPR:$b)))]> {
154154 let Inst{6} = 1;
155155 }
156156
157 def FNMULS : ASbI<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
158 IIC_fpMUL32, "fnmuls", "\t$dst, $a, $b",
157 def VNMULS : ASbI<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
158 IIC_fpMUL32, "vnmul", ".f32\t$dst, $a, $b",
159159 [(set SPR:$dst, (fneg (fmul SPR:$a, SPR:$b)))]> {
160160 let Inst{6} = 1;
161161 }
162162
163163 // Match reassociated forms only if not sign dependent rounding.
164164 def : Pat<(fmul (fneg DPR:$a), DPR:$b),
165 (FNMULD DPR:$a, DPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
165 (VNMULD DPR:$a, DPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
166166 def : Pat<(fmul (fneg SPR:$a), SPR:$b),
167 (FNMULS SPR:$a, SPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
168
169
170 def FSUBD : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
171 IIC_fpALU64, "fsubd", "\t$dst, $a, $b",
167 (VNMULS SPR:$a, SPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
168
169
170 def VSUBD : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
171 IIC_fpALU64, "vsub", ".f64\t$dst, $a, $b",
172172 [(set DPR:$dst, (fsub DPR:$a, DPR:$b))]> {
173173 let Inst{6} = 1;
174174 }
175175
176 def FSUBS : ASbIn<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
177 IIC_fpALU32, "fsubs", "\t$dst, $a, $b",
176 def VSUBS : ASbIn<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
177 IIC_fpALU32, "vsub", ".f32\t$dst, $a, $b",
178178 [(set SPR:$dst, (fsub SPR:$a, SPR:$b))]> {
179179 let Inst{6} = 1;
180180 }
183183 // FP Unary Operations.
184184 //
185185
186 def FABSD : ADuI<0b11101011, 0b0000, 0b1100, (outs DPR:$dst), (ins DPR:$a),
187 IIC_fpUNA64, "fabsd", "\t$dst, $a",
186 def VABSD : ADuI<0b11101011, 0b0000, 0b1100, (outs DPR:$dst), (ins DPR:$a),
187 IIC_fpUNA64, "vabs", ".f64\t$dst, $a",
188188 [(set DPR:$dst, (fabs DPR:$a))]>;
189189
190 def FABSS : ASuIn<0b11101011, 0b0000, 0b1100, (outs SPR:$dst), (ins SPR:$a),
191 IIC_fpUNA32, "fabss", "\t$dst, $a",
190 def VABSS : ASuIn<0b11101011, 0b0000, 0b1100, (outs SPR:$dst), (ins SPR:$a),
191 IIC_fpUNA32, "vabs", ".f32\t$dst, $a",
192192 [(set SPR:$dst, (fabs SPR:$a))]>;
193193
194194 let Defs = [FPSCR] in {
195 def FCMPEZD : ADuI<0b11101011, 0b0101, 0b1100, (outs), (ins DPR:$a),
196 IIC_fpCMP64, "fcmpezd", "\t$a",
195 def VCMPEZD : ADuI<0b11101011, 0b0101, 0b1100, (outs), (ins DPR:$a),
196 IIC_fpCMP64, "vcmpe", ".f64\t$a, #0.0",
197197 [(arm_cmpfp0 DPR:$a)]>;
198198
199 def FCMPEZS : ASuI<0b11101011, 0b0101, 0b1100, (outs), (ins SPR:$a),
200 IIC_fpCMP32, "fcmpezs", "\t$a",
199 def VCMPEZS : ASuI<0b11101011, 0b0101, 0b1100, (outs), (ins SPR:$a),
200 IIC_fpCMP32, "vcmpe", ".f32\t$a, #0.0",
201201 [(arm_cmpfp0 SPR:$a)]>;
202202 }
203203
204 def FCVTDS : ASuI<0b11101011, 0b0111, 0b1100, (outs DPR:$dst), (ins SPR:$a),
205 IIC_fpCVTDS, "fcvtds", "\t$dst, $a",
204 def VCVTDS : ASuI<0b11101011, 0b0111, 0b1100, (outs DPR:$dst), (ins SPR:$a),
205 IIC_fpCVTDS, "vcvt", ".f64.f32\t$dst, $a",
206206 [(set DPR:$dst, (fextend SPR:$a))]>;
207207
208208 // Special case encoding: bits 11-8 is 0b1011.
209 def FCVTSD : VFPAI<(outs SPR:$dst), (ins DPR:$a), VFPUnaryFrm,
210 IIC_fpCVTSD, "fcvtsd", "\t$dst, $a",
209 def VCVTSD : VFPAI<(outs SPR:$dst), (ins DPR:$a), VFPUnaryFrm,
210 IIC_fpCVTSD, "vcvt", ".f32.f64\t$dst, $a",
211211 [(set SPR:$dst, (fround DPR:$a))]> {
212212 let Inst{27-23} = 0b11101;
213213 let Inst{21-16} = 0b110111;
216216 }
217217
218218 let neverHasSideEffects = 1 in {
219 def FCPYD : ADuI<0b11101011, 0b0000, 0b0100, (outs DPR:$dst), (ins DPR:$a),
220 IIC_fpUNA64, "fcpyd", "\t$dst, $a", []>;
221
222 def FCPYS : ASuI<0b11101011, 0b0000, 0b0100, (outs SPR:$dst), (ins SPR:$a),
223 IIC_fpUNA32, "fcpys", "\t$dst, $a", []>;
219 def VMOVD: ADuI<0b11101011, 0b0000, 0b0100, (outs DPR:$dst), (ins DPR:$a),
220 IIC_fpUNA64, "vmov", ".f64\t$dst, $a", []>;
221
222 def VMOVS: ASuI<0b11101011, 0b0000, 0b0100, (outs SPR:$dst), (ins SPR:$a),
223 IIC_fpUNA32, "vmov", ".f32\t$dst, $a", []>;
224224 } // neverHasSideEffects
225225
226 def FNEGD : ADuI<0b11101011, 0b0001, 0b0100, (outs DPR:$dst), (ins DPR:$a),
227 IIC_fpUNA64, "fnegd", "\t$dst, $a",
226 def VNEGD : ADuI<0b11101011, 0b0001, 0b0100, (outs DPR:$dst), (ins DPR:$a),
227 IIC_fpUNA64, "vneg", ".f64\t$dst, $a",
228228 [(set DPR:$dst, (fneg DPR:$a))]>;
229229
230 def FNEGS : ASuIn<0b11101011, 0b0001, 0b0100, (outs SPR:$dst), (ins SPR:$a),
231 IIC_fpUNA32, "fnegs", "\t$dst, $a",
230 def VNEGS : ASuIn<0b11101011, 0b0001, 0b0100, (outs SPR:$dst), (ins SPR:$a),
231 IIC_fpUNA32, "vneg", ".f32\t$dst, $a",
232232 [(set SPR:$dst, (fneg SPR:$a))]>;
233233
234 def FSQRTD : ADuI<0b11101011, 0b0001, 0b1100, (outs DPR:$dst), (ins DPR:$a),
235 IIC_fpSQRT64, "fsqrtd", "\t$dst, $a",
234 def VSQRTD : ADuI<0b11101011, 0b0001, 0b1100, (outs DPR:$dst), (ins DPR:$a),
235 IIC_fpSQRT64, "vsqrt", ".f64\t$dst, $a",
236236 [(set DPR:$dst, (fsqrt DPR:$a))]>;
237237
238 def FSQRTS : ASuI<0b11101011, 0b0001, 0b1100, (outs SPR:$dst), (ins SPR:$a),
239 IIC_fpSQRT32, "fsqrts", "\t$dst, $a",
238 def VSQRTS : ASuI<0b11101011, 0b0001, 0b1100, (outs SPR:$dst), (ins SPR:$a),
239 IIC_fpSQRT32, "vsqrt", ".f32\t$dst, $a",
240240 [(set SPR:$dst, (fsqrt SPR:$a))]>;
241241
242242 //===----------------------------------------------------------------------===//
243243 // FP <-> GPR Copies. Int <-> FP Conversions.
244244 //
245245
246 def FMRS : AVConv2I<0b11100001, 0b1010, (outs GPR:$dst), (ins SPR:$src),
247 IIC_VMOVSI, "fmrs", "\t$dst, $src",
246 def VMOVRS : AVConv2I<0b11100001, 0b1010, (outs GPR:$dst), (ins SPR:$src),
247 IIC_VMOVSI, "vmov", "\t$dst, $src",
248248 [(set GPR:$dst, (bitconvert SPR:$src))]>;
249249
250 def FMSR : AVConv4I<0b11100000, 0b1010, (outs SPR:$dst), (ins GPR:$src),
251 IIC_VMOVIS, "fmsr", "\t$dst, $src",
250 def VMOVSR : AVConv4I<0b11100000, 0b1010, (outs SPR:$dst), (ins GPR:$src),
251 IIC_VMOVIS, "vmov", "\t$dst, $src",
252252 [(set SPR:$dst, (bitconvert GPR:$src))]>;
253253
254 def FMRRD : AVConv3I<0b11000101, 0b1011,
254 def VMOVRRD : AVConv3I<0b11000101, 0b1011,
255255 (outs GPR:$wb, GPR:$dst2), (ins DPR:$src),
256 IIC_VMOVDI, "fmrrd", "\t$wb, $dst2, $src",
256 IIC_VMOVDI, "vmov", "\t$wb, $dst2, $src",
257257 [/* FIXME: Can't write pattern for multiple result instr*/]>;
258258
259259 // FMDHR: GPR -> SPR
260260 // FMDLR: GPR -> SPR
261261
262 def FMDRR : AVConv5I<0b11000100, 0b1011,
262 def VMOVDRR : AVConv5I<0b11000100, 0b1011,
263263 (outs DPR:$dst), (ins GPR:$src1, GPR:$src2),
264 IIC_VMOVID, "fmdrr", "\t$dst, $src1, $src2",
264 IIC_VMOVID, "vmov", "\t$dst, $src1, $src2",
265265 [(set DPR:$dst, (arm_fmdrr GPR:$src1, GPR:$src2))]>;
266266
267267 // FMRDH: SPR -> GPR
276276
277277 // Int to FP:
278278
279 def FSITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
280 IIC_fpCVTID, "fsitod", "\t$dst, $a",
279 def VSITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
280 IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a",
281281 [(set DPR:$dst, (arm_sitof SPR:$a))]> {
282282 let Inst{7} = 1;
283283 }
284284
285 def FSITOS : AVConv1In<0b11101011, 0b1000, 0b1010, (outs SPR:$dst),(ins SPR:$a),
286 IIC_fpCVTIS, "fsitos", "\t$dst, $a",
285 def VSITOS : AVConv1In<0b11101011, 0b1000, 0b1010, (outs SPR:$dst),(ins SPR:$a),
286 IIC_fpCVTIS, "vcvt", ".f32.s32\t$dst, $a",
287287 [(set SPR:$dst, (arm_sitof SPR:$a))]> {
288288 let Inst{7} = 1;
289289 }
290290
291 def FUITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
292 IIC_fpCVTID, "fuitod", "\t$dst, $a",
291 def VUITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
292 IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a",
293293 [(set DPR:$dst, (arm_uitof SPR:$a))]>;
294294
295 def FUITOS : AVConv1In<0b11101011, 0b1000, 0b1010, (outs SPR:$dst),(ins SPR:$a),
296 IIC_fpCVTIS, "fuitos", "\t$dst, $a",
295 def VUITOS : AVConv1In<0b11101011, 0b1000, 0b1010, (outs SPR:$dst),(ins SPR:$a),
296 IIC_fpCVTIS, "vcvt", ".f32.u32\t$dst, $a",
297297 [(set SPR:$dst, (arm_uitof SPR:$a))]>;
298298
299299 // FP to Int:
300300 // Always set Z bit in the instruction, i.e. "round towards zero" variants.
301301
302 def FTOSIZD : AVConv1I<0b11101011, 0b1101, 0b1011,
302 def VTOSIZD : AVConv1I<0b11101011, 0b1101, 0b1011,
303303 (outs SPR:$dst), (ins DPR:$a),
304 IIC_fpCVTDI, "ftosizd", "\t$dst, $a",
304 IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a",
305305 [(set SPR:$dst, (arm_ftosi DPR:$a))]> {
306306 let Inst{7} = 1; // Z bit
307307 }
308308
309 def FTOSIZS : AVConv1In<0b11101011, 0b1101, 0b1010,
309 def VTOSIZS : AVConv1In<0b11101011, 0b1101, 0b1010,
310310 (outs SPR:$dst), (ins SPR:$a),
311 IIC_fpCVTSI, "ftosizs", "\t$dst, $a",
311 IIC_fpCVTSI, "vcvt", ".s32.f32\t$dst, $a",
312312 [(set SPR:$dst, (arm_ftosi SPR:$a))]> {
313313 let Inst{7} = 1; // Z bit
314314 }
315315
316 def FTOUIZD : AVConv1I<0b11101011, 0b1100, 0b1011,
316 def VTOUIZD : AVConv1I<0b11101011, 0b1100, 0b1011,
317317 (outs SPR:$dst), (ins DPR:$a),
318 IIC_fpCVTDI, "ftouizd", "\t$dst, $a",
318 IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a",
319319 [(set SPR:$dst, (arm_ftoui DPR:$a))]> {
320320 let Inst{7} = 1; // Z bit
321321 }
322322
323 def FTOUIZS : AVConv1In<0b11101011, 0b1100, 0b1010,
323 def VTOUIZS : AVConv1In<0b11101011, 0b1100, 0b1010,
324324 (outs SPR:$dst), (ins SPR:$a),
325 IIC_fpCVTSI, "ftouizs", "\t$dst, $a",
325 IIC_fpCVTSI, "vcvt", ".u32.f32\t$dst, $a",
326326 [(set SPR:$dst, (arm_ftoui SPR:$a))]> {
327327 let Inst{7} = 1; // Z bit
328328 }
331331 // FP FMA Operations.
332332 //
333333
334 def FMACD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
335 IIC_fpMAC64, "fmacd", "\t$dst, $a, $b",
334 def VMLAD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
335 IIC_fpMAC64, "vmla", ".f64\t$dst, $a, $b",
336336 [(set DPR:$dst, (fadd (fmul DPR:$a, DPR:$b), DPR:$dstin))]>,
337337 RegConstraint<"$dstin = $dst">;
338338
339 def FMACS : ASbIn<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
340 IIC_fpMAC32, "fmacs", "\t$dst, $a, $b",
339 def VMLAS : ASbIn<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
340 IIC_fpMAC32, "vmla", ".f32\t$dst, $a, $b",
341341 [(set SPR:$dst, (fadd (fmul SPR:$a, SPR:$b), SPR:$dstin))]>,
342342 RegConstraint<"$dstin = $dst">;
343343
344 def FMSCD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
345 IIC_fpMAC64, "fmscd", "\t$dst, $a, $b",
344 def VNMLSD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
345 IIC_fpMAC64, "vnmls", ".f64\t$dst, $a, $b",
346346 [(set DPR:$dst, (fsub (fmul DPR:$a, DPR:$b), DPR:$dstin))]>,
347347 RegConstraint<"$dstin = $dst">;
348348
349 def FMSCS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
350 IIC_fpMAC32, "fmscs", "\t$dst, $a, $b",
349 def VNMLSS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
350 IIC_fpMAC32, "vnmls", ".f32\t$dst, $a, $b",
351351 [(set SPR:$dst, (fsub (fmul SPR:$a, SPR:$b), SPR:$dstin))]>,
352352 RegConstraint<"$dstin = $dst">;
353353
354 def FNMACD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
355 IIC_fpMAC64, "fnmacd", "\t$dst, $a, $b",
354 def VMLSD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
355 IIC_fpMAC64, "vmls", ".f64\t$dst, $a, $b",
356356 [(set DPR:$dst, (fadd (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>,
357357 RegConstraint<"$dstin = $dst"> {
358358 let Inst{6} = 1;
359359 }
360360
361 def FNMACS : ASbIn<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
362 IIC_fpMAC32, "fnmacs", "\t$dst, $a, $b",
361 def VMLSS : ASbIn<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
362 IIC_fpMAC32, "vmls", ".f32\t$dst, $a, $b",
363363 [(set SPR:$dst, (fadd (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>,
364364 RegConstraint<"$dstin = $dst"> {
365365 let Inst{6} = 1;
366366 }
367367
368368 def : Pat<(fsub DPR:$dstin, (fmul DPR:$a, DPR:$b)),
369 (FNMACD DPR:$dstin, DPR:$a, DPR:$b)>, Requires<[DontUseNEONForFP]>;
369 (VMLSD DPR:$dstin, DPR:$a, DPR:$b)>, Requires<[DontUseNEONForFP]>;
370370 def : Pat<(fsub SPR:$dstin, (fmul SPR:$a, SPR:$b)),
371 (FNMACS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>;
372
373 def FNMSCD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
374 IIC_fpMAC64, "fnmscd", "\t$dst, $a, $b",
371 (VMLSS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>;
372
373 def VNMLAD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
374 IIC_fpMAC64, "vnmla", ".f64\t$dst, $a, $b",
375375 [(set DPR:$dst, (fsub (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>,
376376 RegConstraint<"$dstin = $dst"> {
377377 let Inst{6} = 1;
378378 }
379379
380 def FNMSCS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
381 IIC_fpMAC32, "fnmscs", "\t$dst, $a, $b",
380 def VNMLAS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
381 IIC_fpMAC32, "vnmla", ".f32\t$dst, $a, $b",
382382 [(set SPR:$dst, (fsub (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>,
383383 RegConstraint<"$dstin = $dst"> {
384384 let Inst{6} = 1;
388388 // FP Conditional moves.
389389 //
390390
391 def FCPYDcc : ADuI<0b11101011, 0b0000, 0b0100,
391 def VMOVDcc : ADuI<0b11101011, 0b0000, 0b0100,
392392 (outs DPR:$dst), (ins DPR:$false, DPR:$true),
393 IIC_fpUNA64, "fcpyd", "\t$dst, $true",
393 IIC_fpUNA64, "vmov", ".f64\t$dst, $true",
394394 [/*(set DPR:$dst, (ARMcmov DPR:$false, DPR:$true, imm:$cc))*/]>,
395395 RegConstraint<"$false = $dst">;
396396
397 def FCPYScc : ASuI<0b11101011, 0b0000, 0b0100,
397 def VMOVScc : ASuI<0b11101011, 0b0000, 0b0100,
398398 (outs SPR:$dst), (ins SPR:$false, SPR:$true),
399 IIC_fpUNA32, "fcpys", "\t$dst, $true",
399 IIC_fpUNA32, "vmov", ".f32\t$dst, $true",
400400 [/*(set SPR:$dst, (ARMcmov SPR:$false, SPR:$true, imm:$cc))*/]>,
401401 RegConstraint<"$false = $dst">;
402402
403 def FNEGDcc : ADuI<0b11101011, 0b0001, 0b0100,
403 def VNEGDcc : ADuI<0b11101011, 0b0001, 0b0100,
404404 (outs DPR:$dst), (ins DPR:$false, DPR:$true),
405 IIC_fpUNA64, "fnegd", "\t$dst, $true",
405 IIC_fpUNA64, "vneg", ".f64\t$dst, $true",
406406 [/*(set DPR:$dst, (ARMcneg DPR:$false, DPR:$true, imm:$cc))*/]>,
407407 RegConstraint<"$false = $dst">;
408408
409 def FNEGScc : ASuI<0b11101011, 0b0001, 0b0100,
409 def VNEGScc : ASuI<0b11101011, 0b0001, 0b0100,
410410 (outs SPR:$dst), (ins SPR:$false, SPR:$true),
411 IIC_fpUNA32, "fnegs", "\t$dst, $true",
411 IIC_fpUNA32, "vneg", ".f32\t$dst, $true",
412412 [/*(set SPR:$dst, (ARMcneg SPR:$false, SPR:$true, imm:$cc))*/]>,
413413 RegConstraint<"$false = $dst">;
414414
418418 //
419419
420420 let Defs = [CPSR], Uses = [FPSCR] in
421 def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "fmstat", "",
421 def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "vmrs",
422 "\tAPSR_nzcv, FPSCR",
422423 [(arm_fmstat)]> {
423424 let Inst{27-20} = 0b11101111;
424425 let Inst{19-16} = 0b0001;
430431
431432
432433 // Materialize FP immediates. VFP3 only.
433 let isReMaterializable = 1 in
434 let isReMaterializable = 1 in {
435 def FCONSTD : VFPAI<(outs DPR:$dst), (ins vfp_f64imm:$imm),
436 VFPMiscFrm, IIC_VMOVImm,
437 "fconstd", "\t$dst, $imm",
438 [(set DPR:$dst, vfp_f64imm:$imm)]>, Requires<[HasVFP3]> {
439 let Inst{27-23} = 0b11101;
440 let Inst{21-20} = 0b11;
441 let Inst{11-9} = 0b101;
442 let Inst{8} = 1;
443 let Inst{7-4} = 0b0000;
444 }
445
434446 def FCONSTS : VFPAI<(outs SPR:$dst), (ins vfp_f32imm:$imm),
435447 VFPMiscFrm, IIC_VMOVImm,
436448 "fconsts", "\t$dst, $imm",
441453 let Inst{8} = 0;
442454 let Inst{7-4} = 0b0000;
443455 }
444
445 let isReMaterializable = 1 in
446 def FCONSTD : VFPAI<(outs DPR:$dst), (ins vfp_f64imm:$imm),
447 VFPMiscFrm, IIC_VMOVImm,
448 "fconstd", "\t$dst, $imm",
449 [(set DPR:$dst, vfp_f64imm:$imm)]>, Requires<[HasVFP3]> {
450 let Inst{27-23} = 0b11101;
451 let Inst{21-20} = 0b11;
452 let Inst{11-9} = 0b101;
453 let Inst{8} = 1;
454 let Inst{7-4} = 0b0000;
455 }
456 }
4040
4141 STATISTIC(NumLDMGened , "Number of ldm instructions generated");
4242 STATISTIC(NumSTMGened , "Number of stm instructions generated");
43 STATISTIC(NumFLDMGened, "Number of fldm instructions generated");
44 STATISTIC(NumFSTMGened, "Number of fstm instructions generated");
43 STATISTIC(NumVLDMGened, "Number of vldm instructions generated");
44 STATISTIC(NumVSTMGened, "Number of vstm instructions generated");
4545 STATISTIC(NumLdStMoved, "Number of load / store instructions moved");
4646 STATISTIC(NumLDRDFormed,"Number of ldrd created before allocation");
4747 STATISTIC(NumSTRDFormed,"Number of strd created before allocation");
126126 case ARM::t2STRi12:
127127 NumSTMGened++;
128128 return ARM::t2STM;
129 case ARM::FLDS:
130 NumFLDMGened++;
131 return ARM::FLDMS;
132 case ARM::FSTS:
133 NumFSTMGened++;
134 return ARM::FSTMS;
135 case ARM::FLDD:
136 NumFLDMGened++;
137 return ARM::FLDMD;
138 case ARM::FSTD:
139 NumFSTMGened++;
140 return ARM::FSTMD;
129 case ARM::VLDRS:
130 NumVLDMGened++;
131 return ARM::VLDMS;
132 case ARM::VSTRS:
133 NumVSTMGened++;
134 return ARM::VSTMS;
135 case ARM::VLDRD:
136 NumVLDMGened++;
137 return ARM::VLDMD;
138 case ARM::VSTRD:
139 NumVSTMGened++;
140 return ARM::VSTMD;
141141 default: llvm_unreachable("Unhandled opcode!");
142142 }
143143 return 0;
228228 BaseKill = true; // New base is always killed right its use.
229229 }
230230
231 bool isDPR = Opcode == ARM::FLDD || Opcode == ARM::FSTD;
232 bool isDef = isi32Load(Opcode) || Opcode == ARM::FLDS || Opcode == ARM::FLDD;
231 bool isDPR = Opcode == ARM::VLDRD || Opcode == ARM::VSTRD;
232 bool isDef = isi32Load(Opcode) || Opcode == ARM::VLDRS || Opcode == ARM::VLDRD;
233233 Opcode = getLoadStoreMultipleOpcode(Opcode);
234234 MachineInstrBuilder MIB = (isAM4)
235235 ? BuildMI(MBB, MBBI, dl, TII->get(Opcode))
372372 case ARM::t2LDRi12:
373373 case ARM::t2STRi8:
374374 case ARM::t2STRi12:
375 case ARM::FLDS:
376 case ARM::FSTS:
375 case ARM::VLDRS:
376 case ARM::VSTRS:
377377 return 4;
378 case ARM::FLDD:
379 case ARM::FSTD:
378 case ARM::VLDRD:
379 case ARM::VSTRD:
380380 return 8;
381381 case ARM::LDM:
382382 case ARM::STM:
383383 case ARM::t2LDM:
384384 case ARM::t2STM:
385385 return (MI->getNumOperands() - 5) * 4;
386 case ARM::FLDMS:
387 case ARM::FSTMS:
388 case ARM::FLDMD:
389 case ARM::FSTMD:
386 case ARM::VLDMS:
387 case ARM::VSTMS:
388 case ARM::VLDMD:
389 case ARM::VSTMD:
390390 return ARM_AM::getAM5Offset(MI->getOperand(1).getImm()) * 4;
391391 }
392392 }
393393
394394 /// MergeBaseUpdateLSMultiple - Fold proceeding/trailing inc/dec of base
395 /// register into the LDM/STM/FLDM{D|S}/FSTM{D|S} op when possible:
395 /// register into the LDM/STM/VLDM{D|S}/VSTM{D|S} op when possible:
396396 ///
397397 /// stmia rn,
398398 /// rn := rn + 4 * 3;
474474 }
475475 }
476476 } else {
477 // FLDM{D|S}, FSTM{D|S} addressing mode 5 ops.
477 // VLDM{D|S}, VSTM{D|S} addressing mode 5 ops.
478478 if (ARM_AM::getAM5WBFlag(MI->getOperand(1).getImm()))
479479 return false;
480480
516516 switch (Opc) {
517517 case ARM::LDR: return ARM::LDR_PRE;
518518 case ARM::STR: return ARM::STR_PRE;
519 case ARM::FLDS: return ARM::FLDMS;
520 case ARM::FLDD: return ARM::FLDMD;
521 case ARM::FSTS: return ARM::FSTMS;
522 case ARM::FSTD: return ARM::FSTMD;
519 case ARM::VLDRS: return ARM::VLDMS;
520 case ARM::VLDRD: return ARM::VLDMD;
521 case ARM::VSTRS: return ARM::VSTMS;
522 case ARM::VSTRD: return ARM::VSTMD;
523523 case ARM::t2LDRi8:
524524 case ARM::t2LDRi12:
525525 return ARM::t2LDR_PRE;
535535 switch (Opc) {
536536 case ARM::LDR: return ARM::LDR_POST;
537537 case ARM::STR: return ARM::STR_POST;
538 case ARM::FLDS: return ARM::FLDMS;
539 case ARM::FLDD: return ARM::FLDMD;
540 case ARM::FSTS: return ARM::FSTMS;
541 case ARM::FSTD: return ARM::FSTMD;
538 case ARM::VLDRS: return ARM::VLDMS;
539 case ARM::VLDRD: return ARM::VLDMD;
540 case ARM::VSTRS: return ARM::VSTMS;
541 case ARM::VSTRD: return ARM::VSTMD;
542542 case ARM::t2LDRi8:
543543 case ARM::t2LDRi12:
544544 return ARM::t2LDR_POST;
563563 unsigned Bytes = getLSMultipleTransferSize(MI);
564564 int Opcode = MI->getOpcode();
565565 DebugLoc dl = MI->getDebugLoc();
566 bool isAM5 = Opcode == ARM::FLDD || Opcode == ARM::FLDS ||
567 Opcode == ARM::FSTD || Opcode == ARM::FSTS;
566 bool isAM5 = Opcode == ARM::VLDRD || Opcode == ARM::VLDRS ||
567 Opcode == ARM::VSTRD || Opcode == ARM::VSTRS;
568568 bool isAM2 = Opcode == ARM::LDR || Opcode == ARM::STR;
569569 if (isAM2 && ARM_AM::getAM2Offset(MI->getOperand(3).getImm()) != 0)
570570 return false;
574574 if (MI->getOperand(2).getImm() != 0)
575575 return false;
576576
577 bool isLd = isi32Load(Opcode) || Opcode == ARM::FLDS || Opcode == ARM::FLDD;
577 bool isLd = isi32Load(Opcode) || Opcode == ARM::VLDRS || Opcode == ARM::VLDRD;
578578 // Can't do the merge if the destination register is the same as the would-be
579579 // writeback register.
580580 if (isLd && MI->getOperand(0).getReg() == Base)
625625 if (!DoMerge)
626626 return false;
627627
628 bool isDPR = NewOpc == ARM::FLDMD || NewOpc == ARM::FSTMD;
628 bool isDPR = NewOpc == ARM::VLDMD || NewOpc == ARM::VSTMD;
629629 unsigned Offset = 0;
630630 if (isAM5)
631631 Offset = ARM_AM::getAM5Opc((AddSub == ARM_AM::sub)
637637 Offset = AddSub == ARM_AM::sub ? -Bytes : Bytes;
638638 if (isLd) {
639639 if (isAM5)
640 // FLDMS, FLDMD
640 // VLDMS, VLDMD
641641 BuildMI(MBB, MBBI, dl, TII->get(NewOpc))
642642 .addReg(Base, getKillRegState(BaseKill))
643643 .addImm(Offset).addImm(Pred).addReg(PredReg)
656656 } else {
657657 MachineOperand &MO = MI->getOperand(0);
658658 if (isAM5)
659 // FSTMS, FSTMD
659 // VSTMS, VSTMD
660660 BuildMI(MBB, MBBI, dl, TII->get(NewOpc)).addReg(Base).addImm(Offset)
661661 .addImm(Pred).addReg(PredReg)
662662 .addReg(Base, getDefRegState(true)) // WB base register
686686 case ARM::LDR:
687687 case ARM::STR:
688688 return MI->getOperand(1).isReg() && MI->getOperand(2).getReg() == 0;
689 case ARM::FLDS:
690 case ARM::FSTS:
689 case ARM::VLDRS:
690 case ARM::VSTRS:
691691 return MI->getOperand(1).isReg();
692 case ARM::FLDD:
693 case ARM::FSTD:
692 case ARM::VLDRD:
693 case ARM::VSTRD:
694694 return MI->getOperand(1).isReg();
695695 case ARM::t2LDRi8:
696696 case ARM::t2LDRi12:
12131213 if (!STI->hasV5TEOps())
12141214 return false;
12151215
1216 // FIXME: FLDS / FSTS -> FLDD / FSTD
1216 // FIXME: VLDRS / VSTRS -> VLDRD / VSTRD
12171217 unsigned Scale = 1;
12181218 unsigned Opcode = Op0->getOpcode();
12191219 if (Opcode == ARM::LDR)
14551455 continue;
14561456
14571457 int Opc = MI->getOpcode();
1458 bool isLd = isi32Load(Opc) || Opc == ARM::FLDS || Opc == ARM::FLDD;
1458 bool isLd = isi32Load(Opc) || Opc == ARM::VLDRS || Opc == ARM::VLDRD;
14591459 unsigned Base = MI->getOperand(1).getReg();
14601460 int Offset = getMemoryOpOffset(MI);
14611461
608608
609609 if (Modifier && strcmp(Modifier, "submode") == 0) {
610610 ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
611 if (MO1.getReg() == ARM::SP) {
612 bool isFLDM = (MI->getOpcode() == ARM::FLDMD ||
613 MI->getOpcode() == ARM::FLDMS);
614 O << ARM_AM::getAMSubModeAltStr(Mode, isFLDM);
615 } else
616 O << ARM_AM::getAMSubModeStr(Mode);
611 O << ARM_AM::getAMSubModeStr(Mode);
617612 return;
618613 } else if (Modifier && strcmp(Modifier, "base") == 0) {
619614 // Used for FSTM{D|S} and LSTM{D|S} operations.
11301125 }
11311126 }
11321127
1133 // Use unified assembler syntax mode for Thumb.
1134 if (Subtarget->isThumb())
1135 O << "\t.syntax unified\n";
1128 // Use unified assembler syntax.
1129 O << "\t.syntax unified\n";
11361130
11371131 // Emit ARM Build Attributes
11381132 if (Subtarget->isTargetELF()) {
258258
259259 if (Modifier && strcmp(Modifier, "submode") == 0) {
260260 ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
261 if (MO1.getReg() == ARM::SP) {
262 bool isFLDM = (MI->getOpcode() == ARM::FLDMD ||
263 MI->getOpcode() == ARM::FLDMS);
264 O << ARM_AM::getAMSubModeAltStr(Mode, isFLDM);
265 } else
266 O << ARM_AM::getAMSubModeStr(Mode);
261 O << ARM_AM::getAMSubModeStr(Mode);
267262 return;
268263 } else if (Modifier && strcmp(Modifier, "base") == 0) {
269264 // Used for FSTM{D|S} and LSTM{D|S} operations.
5353 NextMII = next(MII);
5454 MachineInstr *MI = &*MII;
5555
56 if (MI->getOpcode() == ARM::FCPYD &&
56 if (MI->getOpcode() == ARM::VMOVD &&
5757 !TII->isPredicated(MI)) {
5858 unsigned SrcReg = MI->getOperand(1).getReg();
59 // If we do not found an instruction defining the reg, this means the
59 // If we do not find an instruction defining the reg, this means the
6060 // register should be live-in for this BB. It's always to better to use
6161 // NEON reg-reg moves.
6262 unsigned Domain = ARMII::DomainNEON;
7070 }
7171
7272 if (Domain & ARMII::DomainNEON) {
73 // Convert FCPYD to VMOVD.
73 // Convert VMOVD to VMOVDneon
7474 unsigned DestReg = MI->getOperand(0).getReg();
7575
7676 DEBUG({errs() << "vmov convert: "; MI->dump();});
8181 // - The imp-defs / imp-uses are superregs only, we don't care about
8282 // them.
8383 BuildMI(MBB, *MI, MI->getDebugLoc(),
84 TII->get(ARM::VMOVD), DestReg).addReg(SrcReg);
84 TII->get(ARM::VMOVDneon), DestReg).addReg(SrcReg);
8585 MBB.erase(MI);
8686 MachineBasicBlock::iterator I = prior(NextMII);
8787 MI = &*I;
3636 mov r1, #PCRELV0
3737 add r1, pc
3838 ldr r0, [r0, r1]
39 cpy pc, r0
39 mov pc, r0
4040 .align 2
4141 LJTI1_0_0:
4242 .long LBB1_3
5050 LPCRELL0:
5151 add r1, LJTI1_0_0
5252 ldr r0, [r0, r1]
53 cpy pc, r0
53 mov pc, r0
5454 .align 2
5555 LJTI1_0_0:
5656 .long LBB1_3
205205 add r5, pc
206206 ldr r6, LCPI1_1
207207 ldr r2, LCPI1_2
208 cpy r3, r6
209 cpy lr, pc
208 mov r3, r6
209 mov lr, pc
210210 bx r5
211211
212212 //===---------------------------------------------------------------------===//
320320 4) Once we added support for multiple result patterns, write indexed loads
321321 patterns instead of C++ instruction selection code.
322322
323 5) Use FLDM / FSTM to emulate indexed FP load / store.
323 5) Use VLDM / VSTM to emulate indexed FP load / store.
324324
325325 //===---------------------------------------------------------------------===//
326326
794794 if (NumBytes != 0)
795795 emitSPUpdate(MBB, MBBI, TII, dl, *this, NumBytes);
796796 } else {
797 // Unwind MBBI to point to first LDR / FLDD.
797 // Unwind MBBI to point to first LDR / VLDRD.
798798 const unsigned *CSRegs = getCalleeSavedRegs();
799799 if (MBBI != MBB.begin()) {
800800 do
None ; RUN: llc < %s -mtriple=armv6-apple-darwin10 -mattr=+vfp2 | grep fcmpezd | count 13
0 ; RUN: llc < %s -mtriple=armv6-apple-darwin10 -mattr=+vfp2 | grep vcmpe | count 13
11
22 %struct.EDGE_PAIR = type { %struct.edge_rec*, %struct.edge_rec* }
33 %struct.VEC2 = type { double, double, double }
88 br i1 %4, label %bb1, label %bb2
99
1010 bb1:
11 ;CHECK: fstdhi
11 ;CHECK: vstrhi.64
1212 store double %1, double* %y, align 4
1313 br label %bb2
1414
55 %arg0_poly16x4_t = alloca <4 x i16> ; <<4 x i16>*> [#uses=1]
66 %out_poly16_t = alloca i16 ; [#uses=1]
77 %"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
8 ; CHECK: fldd
8 ; CHECK: vldr.64
99 %0 = load <4 x i16>* %arg0_poly16x4_t, align 8 ; <<4 x i16>> [#uses=1]
1010 %1 = extractelement <4 x i16> %0, i32 1 ; [#uses=1]
1111 store i16 %1, i16* %out_poly16_t, align 2
None ; RUN: llc -mcpu=cortex-a8 < %s | grep vmov | count 1
0 ; RUN: llc -mcpu=cortex-a8 < %s | FileCheck %s
11
22 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64"
33 target triple = "armv7-eabi"
1010 %0 = getelementptr inbounds %foo* %quat_addr, i32 0, i32 0 ; <<4 x float>*> [#uses=1]
1111 store <4 x float> %quat.0, <4 x float>* %0
1212 %1 = call arm_aapcs_vfpcc <4 x float> @quux(%foo* %quat_addr) nounwind ; <<4 x float>> [#uses=3]
13 ;CHECK: vmov.f32
14 ;CHECK: vmov.f32
1315 %2 = fmul <4 x float> %1, %1 ; <<4 x float>> [#uses=2]
1416 %3 = shufflevector <4 x float> %2, <4 x float> undef, <2 x i32> ; <<2 x float>> [#uses=1]
1517 %4 = shufflevector <4 x float> %2, <4 x float> undef, <2 x i32> ; <<2 x float>> [#uses=1]
1618 %5 = call <2 x float> @llvm.arm.neon.vpadd.v2f32(<2 x float> %3, <2 x float> %4) nounwind ; <<2 x float>> [#uses=2]
1719 %6 = call <2 x float> @llvm.arm.neon.vpadd.v2f32(<2 x float> %5, <2 x float> %5) nounwind ; <<2 x float>> [#uses=2]
1820 %7 = shufflevector <2 x float> %6, <2 x float> %6, <4 x i32> ; <<4 x float>> [#uses=2]
21 ;CHECK: vmov
1922 %8 = call <4 x float> @llvm.arm.neon.vrsqrte.v4f32(<4 x float> %7) nounwind ; <<4 x float>> [#uses=3]
2023 %9 = fmul <4 x float> %8, %8 ; <<4 x float>> [#uses=1]
2124 %10 = call <4 x float> @llvm.arm.neon.vrsqrts.v4f32(<4 x float> %9, <4 x float> %7) nounwind ; <<4 x float>> [#uses=1]
0 ; RUN: llc < %s -mtriple=arm-linux-gnueabi -mattr=+vfp2 -float-abi=hard | FileCheck %s
11
22 define float @f(float %z, double %a, float %b) {
3 ; CHECK: fcpys s0, s1
3 ; CHECK: vmov.f32 s0, s1
44 %tmp = call float @g(float %b)
55 ret float %tmp
66 }
0 ; RUN: llc < %s -march=arm -mattr=+v6,+vfp2 | \
1 ; RUN: grep fcmpes
1 ; RUN: grep vcmpe.f32
22
33 define void @test3(float* %glob, i32 %X) {
44 entry:
None ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {fabss\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
0 ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {vabs.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
11 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=1 | grep -E {vabs.f32\\W*d\[0-9\]+,\\W*d\[0-9\]+} | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {fabss\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {vabs.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
33 ; RUN: llc < %s -march=arm -mcpu=cortex-a8 | grep -E {vabs.f32\\W*d\[0-9\]+,\\W*d\[0-9\]+} | count 1
4 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | grep -E {fabss\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
4 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | grep -E {vabs.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
55
66 define float @test(float %a, float %b) {
77 entry:
None ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {fadds\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
0 ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {vadd.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
11 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=1 | grep -E {vadd.f32\\W*d\[0-9\]+,\\W*d\[0-9\]+,\\W*d\[0-9\]+} | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {fadds\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {vadd.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
33 ; RUN: llc < %s -march=arm -mcpu=cortex-a8 | grep -E {vadd.f32\\W*d\[0-9\]+,\\W*d\[0-9\]+,\\W*d\[0-9\]+} | count 1
4 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | grep -E {fadds\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
4 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | grep -E {vadd.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
55
66 define float @test(float %a, float %b) {
77 entry:
0 ; RUN: llc < %s -march=arm | grep bic | count 2
11 ; RUN: llc < %s -march=arm -mattr=+v6,+vfp2 | \
2 ; RUN: grep fneg | count 2
2 ; RUN: grep vneg | count 2
33
44 define float @test1(float %x, double %y) {
55 %tmp = fpext float %x to double
None ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {fdivs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
1 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=1 | grep -E {fdivs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {fdivs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
3 ; RUN: llc < %s -march=arm -mcpu=cortex-a8 | grep -E {fdivs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
4 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | grep -E {fdivs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
0 ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {vdiv.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
1 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=1 | grep -E {vdiv.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {vdiv.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
3 ; RUN: llc < %s -march=arm -mcpu=cortex-a8 | grep -E {vdiv.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
4 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | grep -E {vdiv.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
55
66 define float @test(float %a, float %b) {
77 entry:
0 ; RUN: llc < %s -march=arm -mattr=+vfp2
1 ; RUN: llc < %s -march=arm -mattr=vfp2 | not grep fstd
1 ; RUN: llc < %s -march=arm -mattr=vfp2 | not grep vstr.64
22
33 define hidden i64 @__fixunsdfdi(double %x) nounwind readnone {
44 entry:
None ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {fmacs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
0 ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {vmla.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
11 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=1 | grep -E {vmul.f32\\W*d\[0-9\]+,\\W*d\[0-9\]+,\\W*d\[0-9\]+} | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {fmacs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {vmla.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
33 ; RUN: llc < %s -march=arm -mcpu=cortex-a8 | grep -E {vmul.f32\\W*d\[0-9\]+,\\W*d\[0-9\]+,\\W*d\[0-9\]+} | count 1
4 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | grep -E {fmacs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
4 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | grep -E {vmla.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
55
66 define float @test(float %acc, float %a, float %b) {
77 entry:
None ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {fmscs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
1 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=1 | grep -E {fmscs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {fmscs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
3 ; RUN: llc < %s -march=arm -mcpu=cortex-a8 | grep -E {fmscs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
4 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | grep -E {fmscs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
0 ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {vnmls.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
1 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=1 | grep -E {vnmls.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {vnmls.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
3 ; RUN: llc < %s -march=arm -mcpu=cortex-a8 | grep -E {vnmls.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
4 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | grep -E {vnmls.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
55
66 define float @test(float %acc, float %a, float %b) {
77 entry:
None ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {fmuls\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
0 ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {vmul.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
11 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=1 | grep -E {vmul.f32\\W*d\[0-9\]+,\\W*d\[0-9\]+,\\W*d\[0-9\]+} | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {fmuls\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {vmul.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
33 ; RUN: llc < %s -march=arm -mcpu=cortex-a8 | grep -E {vmul.f32\\W*d\[0-9\]+,\\W*d\[0-9\]+,\\W*d\[0-9\]+} | count 1
4 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | grep -E {fmuls\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
4 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | grep -E {vmul.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
55
66 define float @test(float %a, float %b) {
77 entry:
None ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {fnegs\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 2
0 ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {vneg.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 2
11 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=1 | grep -E {vneg.f32\\W*d\[0-9\]+,\\W*d\[0-9\]+} | count 2
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {fnegs\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 2
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {vneg.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 2
33 ; RUN: llc < %s -march=arm -mcpu=cortex-a8 | grep -E {vneg.f32\\W*d\[0-9\]+,\\W*d\[0-9\]+} | count 2
4 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | grep -E {fnegs\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 2
4 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | grep -E {vneg.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 2
55
66 define float @test1(float* %a) {
77 entry:
33
44 define float @test(float %acc, float %a, float %b) {
55 entry:
6 ; VFP2: fnmacs
7 ; NEON: fnmacs
6 ; VFP2: vmls.f32
7 ; NEON: vmls.f32
88
99 ; NEONFP-NOT: vmls
10 ; NEONFP-NOT: fcpys
10 ; NEONFP-NOT: vmov.f32
1111 ; NEONFP: vmul.f32
1212 ; NEONFP: vsub.f32
13 ; NEONFP: fmrs
13 ; NEONFP: vmov
1414
1515 %0 = fmul float %a, %b
1616 %1 = fsub float %acc, %0
44 ; RUN: llc < %s -march=arm -mcpu=cortex-a9 | FileCheck %s
55
66 define float @test1(float %acc, float %a, float %b) nounwind {
7 ; CHECK: fnmscs s2, s1, s0
7 ; CHECK: vnmla.f32 s2, s1, s0
88 entry:
99 %0 = fmul float %a, %b
1010 %1 = fsub float -0.0, %0
1313 }
1414
1515 define float @test2(float %acc, float %a, float %b) nounwind {
16 ; CHECK: fnmscs s2, s1, s0
16 ; CHECK: vnmla.f32 s2, s1, s0
1717 entry:
1818 %0 = fmul float %a, %b
1919 %1 = fmul float -1.0, %0
None ; RUN: llc < %s -march=arm -mattr=+v6,+vfp2 | grep fnmuld
1 ; RUN: llc < %s -march=arm -mattr=+v6,+vfp2 -enable-sign-dependent-rounding-fp-math | grep fmul
0 ; RUN: llc < %s -march=arm -mattr=+v6,+vfp2 | grep vnmul.f64
1 ; RUN: llc < %s -march=arm -mattr=+v6,+vfp2 -enable-sign-dependent-rounding-fp-math | grep vmul.f64
22
33
44 define double @t1(double %a, double %b) {
11
22 define float @f(i32 %a) {
33 ;CHECK: f:
4 ;CHECK: fmsr
5 ;CHECK-NEXT: fsitos
6 ;CHECK-NEXT: fmrs
4 ;CHECK: vmov
5 ;CHECK-NEXT: vcvt.f32.s32
6 ;CHECK-NEXT: vmov
77 entry:
88 %tmp = sitofp i32 %a to float ; [#uses=1]
99 ret float %tmp
1111
1212 define double @g(i32 %a) {
1313 ;CHECK: g:
14 ;CHECK: fmsr
15 ;CHECK-NEXT: fsitod
16 ;CHECK-NEXT: fmrrd
14 ;CHECK: vmov
15 ;CHECK-NEXT: vcvt.f64.s32
16 ;CHECK-NEXT: vmov
1717 entry:
1818 %tmp = sitofp i32 %a to double ; [#uses=1]
1919 ret double %tmp
2121
2222 define double @uint_to_double(i32 %a) {
2323 ;CHECK: uint_to_double:
24 ;CHECK: fmsr
25 ;CHECK-NEXT: fuitod
26 ;CHECK-NEXT: fmrrd
24 ;CHECK: vmov
25 ;CHECK-NEXT: vcvt.f64.u32
26 ;CHECK-NEXT: vmov
2727 entry:
2828 %tmp = uitofp i32 %a to double ; [#uses=1]
2929 ret double %tmp
3131
3232 define float @uint_to_float(i32 %a) {
3333 ;CHECK: uint_to_float:
34 ;CHECK: fmsr
35 ;CHECK-NEXT: fuitos
36 ;CHECK-NEXT: fmrs
34 ;CHECK: vmov
35 ;CHECK-NEXT: vcvt.f32.u32
36 ;CHECK-NEXT: vmov
3737 entry:
3838 %tmp = uitofp i32 %a to float ; [#uses=1]
3939 ret float %tmp
4141
4242 define double @h(double* %v) {
4343 ;CHECK: h:
44 ;CHECK: fldd
45 ;CHECK-NEXT: fmrrd
44 ;CHECK: vldr.64
45 ;CHECK-NEXT: vmov
4646 entry:
4747 %tmp = load double* %v ; [#uses=1]
4848 ret double %tmp
5757
5858 define double @f2(double %a) {
5959 ;CHECK: f2:
60 ;CHECK-NOT: fmdrr
60 ;CHECK-NOT: vmov
6161 ret double %a
6262 }
6363
6464 define void @f3() {
6565 ;CHECK: f3:
66 ;CHECK-NOT: fmdrr
66 ;CHECK-NOT: vmov
6767 ;CHECK: f4
6868 entry:
6969 %tmp = call double @f5( ) ; [#uses=1]
55
66 define i32 @test1(float %a, float %b) {
77 ; VFP2: test1:
8 ; VFP2: ftosizs s0, s0
8 ; VFP2: vcvt.s32.f32 s0, s0
99 ; NEON: test1:
1010 ; NEON: vcvt.s32.f32 d0, d0
1111 entry:
1616
1717 define i32 @test2(float %a, float %b) {
1818 ; VFP2: test2:
19 ; VFP2: ftouizs s0, s0
19 ; VFP2: vcvt.u32.f32 s0, s0
2020 ; NEON: test2:
2121 ; NEON: vcvt.u32.f32 d0, d0
2222 entry:
2727
2828 define float @test3(i32 %a, i32 %b) {
2929 ; VFP2: test3:
30 ; VFP2: fuitos s0, s0
30 ; VFP2: vcvt.f32.u32 s0, s0
3131 ; NEON: test3:
3232 ; NEON: vcvt.f32.u32 d0, d0
3333 entry:
3838
3939 define float @test4(i32 %a, i32 %b) {
4040 ; VFP2: test4:
41 ; VFP2: fsitos s0, s0
41 ; VFP2: vcvt.f32.s32 s0, s0
4242 ; NEON: test4:
4343 ; NEON: vcvt.f32.s32 d0, d0
4444 entry:
11
22 define float @f1(float %a, float %b) {
33 ;CHECK: f1:
4 ;CHECK: fadds
4 ;CHECK: vadd.f32
55 entry:
66 %tmp = fadd float %a, %b ; [#uses=1]
77 ret float %tmp
99
1010 define double @f2(double %a, double %b) {
1111 ;CHECK: f2:
12 ;CHECK: faddd
12 ;CHECK: vadd.f64
1313 entry:
1414 %tmp = fadd double %a, %b ; [#uses=1]
1515 ret double %tmp
1717
1818 define float @f3(float %a, float %b) {
1919 ;CHECK: f3:
20 ;CHECK: fmuls
20 ;CHECK: vmul.f32
2121 entry:
2222 %tmp = fmul float %a, %b ; [#uses=1]
2323 ret float %tmp
2525
2626 define double @f4(double %a, double %b) {
2727 ;CHECK: f4:
28 ;CHECK: fmuld
28 ;CHECK: vmul.f64
2929 entry:
3030 %tmp = fmul double %a, %b ; [#uses=1]
3131 ret double %tmp
3333
3434 define float @f5(float %a, float %b) {
3535 ;CHECK: f5:
36 ;CHECK: fsubs
36 ;CHECK: vsub.f32
3737 entry:
3838 %tmp = fsub float %a, %b ; [#uses=1]
3939 ret float %tmp
4141
4242 define double @f6(double %a, double %b) {
4343 ;CHECK: f6:
44 ;CHECK: fsubd
44 ;CHECK: vsub.f64
4545 entry:
4646 %tmp = fsub double %a, %b ; [#uses=1]
4747 ret double %tmp
5757
5858 define double @f8(double %a) {
5959 ;CHECK: f8:
60 ;CHECK: fnegd
60 ;CHECK: vneg.f64
6161 entry:
6262 %tmp1 = fsub double -0.000000e+00, %a ; [#uses=1]
6363 ret double %tmp1
6565
6666 define float @f9(float %a, float %b) {
6767 ;CHECK: f9:
68 ;CHECK: fdivs
68 ;CHECK: vdiv.f32
6969 entry:
7070 %tmp1 = fdiv float %a, %b ; [#uses=1]
7171 ret float %tmp1
7373
7474 define double @f10(double %a, double %b) {
7575 ;CHECK: f10:
76 ;CHECK: fdivd
76 ;CHECK: vdiv.f64
7777 entry:
7878 %tmp1 = fdiv double %a, %b ; [#uses=1]
7979 ret double %tmp1
9191
9292 define double @f12(double %a) {
9393 ;CHECK: f12:
94 ;CHECK: fabsd
94 ;CHECK: vabs.f64
9595 entry:
9696 %tmp1 = call double @fabs( double %a ) ; [#uses=1]
9797 ret double %tmp1
11
22 define i32 @f1(float %a) {
33 ;CHECK: f1:
4 ;CHECK: fcmpes
4 ;CHECK: vcmpe.f32
55 ;CHECK: movmi
66 entry:
77 %tmp = fcmp olt float %a, 1.000000e+00 ; [#uses=1]
1111
1212 define i32 @f2(float %a) {
1313 ;CHECK: f2:
14 ;CHECK: fcmpes
14 ;CHECK: vcmpe.f32
1515 ;CHECK: moveq
1616 entry:
1717 %tmp = fcmp oeq float %a, 1.000000e+00 ; [#uses=1]
2121
2222 define i32 @f3(float %a) {
2323 ;CHECK: f3:
24 ;CHECK: fcmpes
24 ;CHECK: vcmpe.f32
2525 ;CHECK: movgt
2626 entry:
2727 %tmp = fcmp ogt float %a, 1.000000e+00 ; [#uses=1]
3131
3232 define i32 @f4(float %a) {
3333 ;CHECK: f4:
34 ;CHECK: fcmpes
34 ;CHECK: vcmpe.f32
3535 ;CHECK: movge
3636 entry:
3737 %tmp = fcmp oge float %a, 1.000000e+00 ; [#uses=1]
4141
4242 define i32 @f5(float %a) {
4343 ;CHECK: f5:
44 ;CHECK: fcmpes
44 ;CHECK: vcmpe.f32
4545 ;CHECK: movls
4646 entry:
4747 %tmp = fcmp ole float %a, 1.000000e+00 ; [#uses=1]
5151
5252 define i32 @f6(float %a) {
5353 ;CHECK: f6:
54 ;CHECK: fcmpes
54 ;CHECK: vcmpe.f32
5555 ;CHECK: movne
5656 entry:
5757 %tmp = fcmp une float %a, 1.000000e+00 ; [#uses=1]
6161
6262 define i32 @g1(double %a) {
6363 ;CHECK: g1:
64 ;CHECK: fcmped
64 ;CHECK: vcmpe.f64
6565 ;CHECK: movmi
6666 entry:
6767 %tmp = fcmp olt double %a, 1.000000e+00 ; [#uses=1]
22
33 define float @f1(double %x) {
44 ;CHECK-VFP: f1:
5 ;CHECK-VFP: fcvtsd
5 ;CHECK-VFP: vcvt.f32.f64
66 ;CHECK: f1:
77 ;CHECK: truncdfsf2
88 entry:
1212
1313 define double @f2(float %x) {
1414 ;CHECK-VFP: f2:
15 ;CHECK-VFP: fcvtds
15 ;CHECK-VFP: vcvt.f64.f32
1616 ;CHECK: f2:
1717 ;CHECK: extendsfdf2
1818 entry:
2222
2323 define i32 @f3(float %x) {
2424 ;CHECK-VFP: f3:
25 ;CHECK-VFP: ftosizs
25 ;CHECK-VFP: vcvt.s32.f32
2626 ;CHECK: f3:
2727 ;CHECK: fixsfsi
2828 entry:
3232
3333 define i32 @f4(float %x) {
3434 ;CHECK-VFP: f4:
35 ;CHECK-VFP: ftouizs
35 ;CHECK-VFP: vcvt.u32.f32
3636 ;CHECK: f4:
3737 ;CHECK: fixunssfsi
3838 entry:
4242
4343 define i32 @f5(double %x) {
4444 ;CHECK-VFP: f5:
45 ;CHECK-VFP: ftosizd
45 ;CHECK-VFP: vcvt.s32.f64
4646 ;CHECK: f5:
4747 ;CHECK: fixdfsi
4848 entry:
5252
5353 define i32 @f6(double %x) {
5454 ;CHECK-VFP: f6:
55 ;CHECK-VFP: ftouizd
55 ;CHECK-VFP: vcvt.u32.f64
5656 ;CHECK: f6:
5757 ;CHECK: fixunsdfsi
5858 entry:
6262
6363 define float @f7(i32 %a) {
6464 ;CHECK-VFP: f7:
65 ;CHECK-VFP: fsitos
65 ;CHECK-VFP: vcvt.f32.s32
6666 ;CHECK: f7:
6767 ;CHECK: floatsisf
6868 entry:
7272
7373 define double @f8(i32 %a) {
7474 ;CHECK-VFP: f8:
75 ;CHECK-VFP: fsitod
75 ;CHECK-VFP: vcvt.f64.s32
7676 ;CHECK: f8:
7777 ;CHECK: floatsidf
7878 entry:
8282
8383 define float @f9(i32 %a) {
8484 ;CHECK-VFP: f9:
85 ;CHECK-VFP: fuitos
85 ;CHECK-VFP: vcvt.f32.u32
8686 ;CHECK: f9:
8787 ;CHECK: floatunsisf
8888 entry:
9292
9393 define double @f10(i32 %a) {
9494 ;CHECK-VFP: f10:
95 ;CHECK-VFP: fuitod
95 ;CHECK-VFP: vcvt.f64.u32
9696 ;CHECK: f10:
9797 ;CHECK: floatunsidf
9898 entry:
77
88 define float @f2(float* %v, float %u) {
99 ; CHECK: f2:
10 ; CHECK: flds{{.*}}[
10 ; CHECK: vldr.32{{.*}}[
1111 %tmp = load float* %v ; [#uses=1]
1212 %tmp1 = fadd float %tmp, %u ; [#uses=1]
1313 ret float %tmp1
1515
1616 define void @f3(float %a, float %b, float* %v) {
1717 ; CHECK: f3:
18 ; CHECK: fsts{{.*}}[
18 ; CHECK: vstr.32{{.*}}[
1919 %tmp = fadd float %a, %b ; [#uses=1]
2020 store float %tmp, float* %v
2121 ret void
None ; RUN: llc < %s -march=arm -mattr=+v6,+vfp2 | grep fmrs | count 1
0 ; RUN: llc < %s -march=arm -mattr=+v6,+vfp2 | grep -E {vmov\\W*r\[0-9\]+,\\W*s\[0-9\]+} | count 1
11 ; RUN: llc < %s -march=arm -mattr=+v6,+vfp2 | not grep fmrrd
22
33 @i = weak global i32 0 ; [#uses=2]
None ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {fsubs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
0 ; RUN: llc < %s -march=arm -mattr=+vfp2 | grep -E {vsub.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
11 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=1 | grep -E {vsub.f32\\W*d\[0-9\]+,\\W*d\[0-9\]+,\\W*d\[0-9\]+} | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {fsubs\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon -arm-use-neon-fp=0 | grep -E {vsub.f32\\W*s\[0-9\]+,\\W*s\[0-9\]+,\\W*s\[0-9\]+} | count 1
33
44 define float @test(float %a, float %b) {
55 entry:
1010
1111 define void @t1(i32 %a, i32 %b) {
1212 ; CHECK: t1:
13 ; CHECK: ldmltfd sp!, {r7, pc}
13 ; CHECK: ldmfdlt sp!, {r7, pc}
1414 entry:
1515 %tmp1 = icmp sgt i32 %a, 10 ; [#uses=1]
1616 br i1 %tmp1, label %cond_true, label %UnifiedReturnBlock
0 ; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \
11 ; RUN: grep cmpne | count 1
22 ; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \
3 ; RUN: grep ldmhi | count 1
3 ; RUN: grep ldmfdhi | count 1
44
55 define void @foo(i32 %X, i32 %Y) {
66 entry:
22 ; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \
33 ; RUN: grep moveq | count 1
44 ; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \
5 ; RUN: grep ldmeq | count 1
5 ; RUN: grep ldmfdeq | count 1
66 ; FIXME: Need post-ifcvt branch folding to get rid of the extra br at end of BB1.
77
88 %struct.quad_struct = type { i32, i32, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct*, %struct.quad_struct* }
0 ; RUN: llc < %s -march=arm -mtriple=arm-apple-darwin | \
1 ; RUN: grep ldmne | count 1
1 ; RUN: grep ldmfdne | count 1
22
33 %struct.SString = type { i8*, i32, i32 }
44
None ; RUN: llc < %s -march=arm -mattr=+neon | grep fldd | count 4
1 ; RUN: llc < %s -march=arm -mattr=+neon | grep fstd
2 ; RUN: llc < %s -march=arm -mattr=+neon | grep fmrrd
0 ; RUN: llc < %s -march=arm -mattr=+neon | grep vldr.64 | count 4
1 ; RUN: llc < %s -march=arm -mattr=+neon | grep vstr.64
2 ; RUN: llc < %s -march=arm -mattr=+neon | grep vmov
33
44 define void @t1(<2 x i32>* %r, <4 x i16>* %a, <4 x i16>* %b) nounwind {
55 entry:
0 ; RUN: llc < %s -march=arm -mattr=+neon | grep vldmia | count 4
11 ; RUN: llc < %s -march=arm -mattr=+neon | grep vstmia | count 1
2 ; RUN: llc < %s -march=arm -mattr=+neon | grep fmrrd | count 2
2 ; RUN: llc < %s -march=arm -mattr=+neon | grep vmov | count 2
33
44 define void @t1(<4 x i32>* %r, <2 x i64>* %a, <2 x i64>* %b) nounwind {
55 entry:
5959 ;CHECK: movlt
6060 ;CHECK: movlt
6161 ;CHECK-VFP: f7:
62 ;CHECK-VFP: fcpydmi
62 ;CHECK-VFP: vmovmi
6363 %tmp = fcmp olt double %a, 1.234e+00
6464 %tmp1 = select i1 %tmp, double -1.000e+00, double %b
6565 ret double %tmp1
1414 define void @test_abs(float* %P, double* %D) {
1515 ;CHECK: test_abs:
1616 %a = load float* %P ; [#uses=1]
17 ;CHECK: fabss
17 ;CHECK: vabs.f32
1818 %b = call float @fabsf( float %a ) ; [#uses=1]
1919 store float %b, float* %P
2020 %A = load double* %D ; [#uses=1]
21 ;CHECK: fabsd
21 ;CHECK: vabs.f64
2222 %B = call double @fabs( double %A ) ; [#uses=1]
2323 store double %B, double* %D
2424 ret void
3838 define void @test_ext_round(float* %P, double* %D) {
3939 ;CHECK: test_ext_round:
4040 %a = load float* %P ; [#uses=1]
41 ;CHECK: fcvtds
41 ;CHECK: vcvt.f64.f32
4242 %b = fpext float %a to double ; [#uses=1]
4343 %A = load double* %D ; [#uses=1]
44 ;CHECK: fcvtsd
44 ;CHECK: vcvt.f32.f64
4545 %B = fptrunc double %A to float ; [#uses=1]
4646 store double %b, double* %D
4747 store float %B, float* %P
5353 %a1 = load float* %P1 ; [#uses=1]
5454 %a2 = load float* %P2 ; [#uses=1]
5555 %a3 = load float* %P3 ; [#uses=1]
56 ;CHECK: fmscs
56 ;CHECK: vnmls.f32
5757 %X = fmul float %a1, %a2 ; [#uses=1]
5858 %Y = fsub float %X, %a3 ; [#uses=1]
5959 store float %Y, float* %P1
6363 define i32 @test_ftoi(float* %P1) {
6464 ;CHECK: test_ftoi:
6565 %a1 = load float* %P1 ; [#uses=1]
66 ;CHECK: ftosizs
66 ;CHECK: vcvt.s32.f32
6767 %b1 = fptosi float %a1 to i32 ; [#uses=1]
6868 ret i32 %b1
6969 }
7171 define i32 @test_ftou(float* %P1) {
7272 ;CHECK: test_ftou:
7373 %a1 = load float* %P1 ; [#uses=1]
74 ;CHECK: ftouizs
74 ;CHECK: vcvt.u32.f32
7575 %b1 = fptoui float %a1 to i32 ; [#uses=1]
7676 ret i32 %b1
7777 }
7979 define i32 @test_dtoi(double* %P1) {
8080 ;CHECK: test_dtoi:
8181 %a1 = load double* %P1 ; [#uses=1]
82 ;CHECK: ftosizd
82 ;CHECK: vcvt.s32.f64
8383 %b1 = fptosi double %a1 to i32 ; [#uses=1]
8484 ret i32 %b1
8585 }
8787 define i32 @test_dtou(double* %P1) {
8888 ;CHECK: test_dtou:
8989 %a1 = load double* %P1 ; [#uses=1]
90 ;CHECK: ftouizd
90 ;CHECK: vcvt.u32.f64
9191 %b1 = fptoui double %a1 to i32 ; [#uses=1]
9292 ret i32 %b1
9393 }
9494
9595 define void @test_utod(double* %P1, i32 %X) {
9696 ;CHECK: test_utod:
97 ;CHECK: fuitod
97 ;CHECK: vcvt.f64.u32
9898 %b1 = uitofp i32 %X to double ; [#uses=1]
9999 store double %b1, double* %P1
100100 ret void
102102
103103 define void @test_utod2(double* %P1, i8 %X) {
104104 ;CHECK: test_utod2:
105 ;CHECK: fuitod
105 ;CHECK: vcvt.f64.u32
106106 %b1 = uitofp i8 %X to double ; [#uses=1]
107107 store double %b1, double* %P1
108108 ret void
140140 ;CHECK: test_cmpfp0:
141141 entry:
142142 %tmp = load float* %glob ; [#uses=1]
143 ;CHECK: fcmpezs
143 ;CHECK: vcmpe.f32
144144 %tmp.upgrd.3 = fcmp ogt float %tmp, 0.000000e+00 ; [#uses=1]
145145 br i1 %tmp.upgrd.3, label %cond_true, label %cond_false
146146
203203
204204 define arm_aapcs_vfpcc <2 x float> @test_vset_lanef32(float %arg0_float32_t, <2 x float> %arg1_float32x2_t) nounwind {
205205 ;CHECK: test_vset_lanef32:
206 ;CHECK: fcpys
207 ;CHECK: fcpys
206 ;CHECK: vmov.f32
207 ;CHECK: vmov.f32
208208 entry:
209209 %0 = insertelement <2 x float> %arg1_float32x2_t, float %arg0_float32_t, i32 1 ; <<2 x float>> [#uses=1]
210210 ret <2 x float> %0
None ; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 | grep fcpys | count 4
0 ; RUN: llc < %s -mtriple=thumbv7-apple-darwin9 -mcpu=cortex-a8 | grep vmov.f32 | count 4
11
22 define arm_apcscc void @fht(float* nocapture %fz, i16 signext %n) nounwind {
33 entry: