llvm.org GIT mirror llvm / 567d14f
Missed pieces for ARM HardFP ABI. Patch by Sandeep Patel! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78225 91177308-0d34-0410-b5e6-96231b3b80d8 Anton Korobeynikov 11 years ago
5 changed file(s) with 54 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
110110 CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType>,
111111 CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType>,
112112
113 CCIfType<[v2f64], CCAssignToReg<[Q0, Q1, Q2, Q3]>>,
113114 CCIfType<[f64], CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7]>>,
114115 CCIfType<[f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7, S8,
115116 S9, S10, S11, S12, S13, S14, S15]>>,
121122 CCIfType<[v1i64, v2i32, v4i16, v8i8, v2f32], CCBitConvertToType>,
122123 CCIfType<[v2i64, v4i32, v8i16, v16i8, v4f32], CCBitConvertToType>,
123124
125 CCIfType<[v2f64], CCAssignToReg<[Q0, Q1, Q2, Q3]>>,
124126 CCIfType<[f64], CCAssignToReg<[D0, D1, D2, D3, D4, D5, D6, D7]>>,
125127 CCIfType<[f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7, S8,
126128 S9, S10, S11, S12, S13, S14, S15]>>,
661661 /// CCAssignFnForNode - Selects the correct CCAssignFn for a the
662662 /// given CallingConvention value.
663663 CCAssignFn *ARMTargetLowering::CCAssignFnForNode(unsigned CC,
664 bool Return) const {
664 bool Return,
665 bool isVarArg) const {
665666 switch (CC) {
666667 default:
667 llvm_unreachable("Unsupported calling convention");
668 llvm_unreachable("Unsupported calling convention");
668669 case CallingConv::C:
669670 case CallingConv::Fast:
670 // Use target triple & subtarget features to do actual dispatch.
671 if (Subtarget->isAAPCS_ABI()) {
672 if (Subtarget->hasVFP2() &&
673 FloatABIType == FloatABI::Hard)
674 return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
675 else
676 return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
677 } else
678 return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
671 // Use target triple & subtarget features to do actual dispatch.
672 if (Subtarget->isAAPCS_ABI()) {
673 if (Subtarget->hasVFP2() &&
674 FloatABIType == FloatABI::Hard && !isVarArg)
675 return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
676 else
677 return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
678 } else
679 return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
679680 case CallingConv::ARM_AAPCS_VFP:
680 return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
681 return (Return ? RetCC_ARM_AAPCS_VFP: CC_ARM_AAPCS_VFP);
681682 case CallingConv::ARM_AAPCS:
682 return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
683 return (Return ? RetCC_ARM_AAPCS: CC_ARM_AAPCS);
683684 case CallingConv::ARM_APCS:
684 return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
685 return (Return ? RetCC_ARM_APCS: CC_ARM_APCS);
685686 }
686687 }
687688
699700 CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
700701 RVLocs, *DAG.getContext());
701702 CCInfo.AnalyzeCallResult(Ins,
702 CCAssignFnForNode(CallConv, /* Return*/ true));
703 CCAssignFnForNode(CallConv, /* Return*/ true,
704 isVarArg));
703705
704706 // Copy all of the result registers out of their specified physreg.
705707 for (unsigned i = 0; i != RVLocs.size(); ++i) {
831833 CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs,
832834 *DAG.getContext());
833835 CCInfo.AnalyzeCallOperands(Outs,
834 CCAssignFnForNode(CallConv, /* Return*/ false));
836 CCAssignFnForNode(CallConv, /* Return*/ false,
837 isVarArg));
835838
836839 // Get a count of how many bytes are to be pushed on the stack.
837840 unsigned NumBytes = CCInfo.getNextStackOffset();
872875 break;
873876 }
874877
875 // f64 and v2f64 are passed in i32 pairs and must be split into pieces
878 // f64 and v2f64 might be passed in i32 pairs and must be split into pieces
876879 if (VA.needsCustom()) {
877880 if (VA.getLocVT() == MVT::v2f64) {
878881 SDValue Op0 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, MVT::f64, Arg,
10331036 *DAG.getContext());
10341037
10351038 // Analyze outgoing return values.
1036 CCInfo.AnalyzeReturn(Outs, CCAssignFnForNode(CallConv, /* Return */ true));
1039 CCInfo.AnalyzeReturn(Outs, CCAssignFnForNode(CallConv, /* Return */ true,
1040 isVarArg));
10371041
10381042 // If this is the first return lowered for this function, add
10391043 // the regs to the liveout set for the function.
14211425 CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs,
14221426 *DAG.getContext());
14231427 CCInfo.AnalyzeFormalArguments(Ins,
1424 CCAssignFnForNode(CallConv, /* Return*/ false));
1428 CCAssignFnForNode(CallConv, /* Return*/ false,
1429 isVarArg));
14251430
14261431 SmallVector ArgValues;
14271432
14541459
14551460 } else {
14561461 TargetRegisterClass *RC;
1457 if (FloatABIType == FloatABI::Hard && RegVT == MVT::f32)
1462 bool IsHardFloatCC = (CallConv == CallingConv::ARM_AAPCS_VFP);
1463
1464 if (IsHardFloatCC && RegVT == MVT::f32)
14581465 RC = ARM::SPRRegisterClass;
1459 else if (FloatABIType == FloatABI::Hard && RegVT == MVT::f64)
1466 else if (IsHardFloatCC && RegVT == MVT::f64)
14601467 RC = ARM::DPRRegisterClass;
1468 else if (IsHardFloatCC && RegVT == MVT::v2f64)
1469 RC = ARM::QPRRegisterClass;
14611470 else if (AFI->isThumb1OnlyFunction())
14621471 RC = ARM::tGPRRegisterClass;
14631472 else
14641473 RC = ARM::GPRRegisterClass;
14651474
14661475 assert((RegVT == MVT::i32 || RegVT == MVT::f32 ||
1467 (FloatABIType == FloatABI::Hard && RegVT == MVT::f64)) &&
1468 "RegVT not supported by formal arguments Lowering");
1476 (IsHardFloatCC &&
1477 ((RegVT == MVT::f64) || (RegVT == MVT::v2f64)))) &&
1478 "RegVT not supported by FORMAL_ARGUMENTS Lowering");
14691479
14701480 // Transform the arguments in physical registers into virtual ones.
14711481 unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC);
234234 SDValue GetF64FormalArgument(CCValAssign &VA, CCValAssign &NextVA,
235235 SDValue &Root, SelectionDAG &DAG, DebugLoc dl);
236236
237 CCAssignFn *CCAssignFnForNode(unsigned CC, bool Return) const;
237 CCAssignFn *CCAssignFnForNode(unsigned CC, bool Return, bool isVarArg) const;
238238 SDValue LowerMemOpCallTo(SDValue Chain, SDValue StackPtr, SDValue Arg,
239239 DebugLoc dl, SelectionDAG &DAG,
240240 const CCValAssign &VA,
11071107 O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_align8_needed << ", 1\n"
11081108 << "\t.eabi_attribute " << ARMBuildAttrs::ABI_align8_preserved << ", 1\n";
11091109
1110 // Hard float. Use both S and D registers and conform to AAPCS-VFP.
1111 if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard)
1112 O << "\t.eabi_attribute " << ARMBuildAttrs::ABI_HardFP_use << ", 3\n"
1113 << "\t.eabi_attribute " << ARMBuildAttrs::ABI_VFP_args << ", 1\n";
1114
11101115 // FIXME: Should we signal R9 usage?
11111116 }
11121117
0 ; RUN: llvm-as < %s | llc -mtriple=arm-linux-gnueabi -mattr=+neon -float-abi=hard
1
2 define <16 x i8> @vmulQi8_reg(<16 x i8> %A, <16 x i8> %B) nounwind {
3 %tmp1 = mul <16 x i8> %A, %B
4 ret <16 x i8> %tmp1
5 }
6
7 define <16 x i8> @f(<16 x i8> %a, <16 x i8> %b) {
8 %tmp = call <16 x i8> @g(<16 x i8> %b)
9 ret <16 x i8> %tmp
10 }
11
12 declare <16 x i8> @g(<16 x i8>)