diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 4e417173480..3f3b949464c 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -49,6 +49,8 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); + setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom); + setOperationAction(ISD::RET, MVT::Other, Custom); setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::ConstantPool, MVT::i32, Custom); @@ -88,6 +90,10 @@ namespace llvm { FSITOD, + FUITOS, + + FUITOD, + FMRRD, FMDRR @@ -124,6 +130,8 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { case ARMISD::BR: return "ARMISD::BR"; case ARMISD::FSITOS: return "ARMISD::FSITOS"; case ARMISD::FSITOD: return "ARMISD::FSITOD"; + case ARMISD::FUITOS: return "ARMISD::FUITOS"; + case ARMISD::FUITOD: return "ARMISD::FUITOD"; case ARMISD::FMRRD: return "ARMISD::FMRRD"; case ARMISD::FMDRR: return "ARMISD::FMDRR"; } @@ -545,6 +553,18 @@ static SDOperand LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) { return DAG.getNode(op, vt, Tmp); } +static SDOperand LowerUINT_TO_FP(SDOperand Op, SelectionDAG &DAG) { + SDOperand IntVal = Op.getOperand(0); + assert(IntVal.getValueType() == MVT::i32); + MVT::ValueType vt = Op.getValueType(); + assert(vt == MVT::f32 || + vt == MVT::f64); + + SDOperand Tmp = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, IntVal); + ARMISD::NodeType op = vt == MVT::f32 ? ARMISD::FUITOS : ARMISD::FUITOD; + return DAG.getNode(op, vt, Tmp); +} + SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { default: @@ -556,6 +576,8 @@ SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return LowerGlobalAddress(Op, DAG); case ISD::SINT_TO_FP: return LowerSINT_TO_FP(Op, DAG); + case ISD::UINT_TO_FP: + return LowerUINT_TO_FP(Op, DAG); case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex); case ISD::CALL: diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 5cd892e9b83..ea44773ca95 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -74,8 +74,10 @@ def armbr : SDNode<"ARMISD::BR", SDTarmbr, [SDNPHasChain, SDNPInFlag]>; def SDTVoidBinOp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; def armcmp : SDNode<"ARMISD::CMP", SDTVoidBinOp, [SDNPOutFlag]>; -def armfsitos : SDNode<"ARMISD::FSITOS", SDTUnaryOp>; +def armfsitos : SDNode<"ARMISD::FSITOS", SDTUnaryOp>; def armfsitod : SDNode<"ARMISD::FSITOD", SDTUnaryOp>; +def armfuitos : SDNode<"ARMISD::FUITOS", SDTUnaryOp>; +def armfuitod : SDNode<"ARMISD::FUITOD", SDTUnaryOp>; def SDTarmfmrrd : SDTypeProfile<0, 3, [SDTCisInt<0>, SDTCisInt<1>, SDTCisFP<2>]>; def armfmrrd : SDNode<"ARMISD::FMRRD", SDTarmfmrrd, @@ -184,6 +186,12 @@ def FSITOS : InstARM<(ops FPRegs:$dst, FPRegs:$src), def FSITOD : InstARM<(ops DFPRegs:$dst, FPRegs:$src), "fsitod $dst, $src", [(set DFPRegs:$dst, (armfsitod FPRegs:$src))]>; +def FUITOS : InstARM<(ops FPRegs:$dst, FPRegs:$src), + "fuitos $dst, $src", [(set FPRegs:$dst, (armfuitos FPRegs:$src))]>; + +def FUITOD : InstARM<(ops DFPRegs:$dst, FPRegs:$src), + "fuitod $dst, $src", [(set DFPRegs:$dst, (armfuitod FPRegs:$src))]>; + // Floating Point Arithmetic def FADDS : InstARM<(ops FPRegs:$dst, FPRegs:$a, FPRegs:$b), diff --git a/test/Regression/CodeGen/ARM/fp.ll b/test/Regression/CodeGen/ARM/fp.ll index c40e2fc8860..512f1dc15ca 100644 --- a/test/Regression/CodeGen/ARM/fp.ll +++ b/test/Regression/CodeGen/ARM/fp.ll @@ -1,12 +1,14 @@ ; RUN: llvm-as < %s | llc -march=arm && -; RUN: llvm-as < %s | llc -march=arm | grep fmsr | wc -l | grep 2 && +; RUN: llvm-as < %s | llc -march=arm | grep fmsr | wc -l | grep 4 && ; RUN: llvm-as < %s | llc -march=arm | grep fsitos && ; RUN: llvm-as < %s | llc -march=arm | grep fmrs && ; RUN: llvm-as < %s | llc -march=arm | grep fsitod && -; RUN: llvm-as < %s | llc -march=arm | grep fmrrd | wc -l | grep 4 && +; RUN: llvm-as < %s | llc -march=arm | grep fmrrd | wc -l | grep 5 && ; RUN: llvm-as < %s | llc -march=arm | grep fmdrr | wc -l | grep 2 && ; RUN: llvm-as < %s | llc -march=arm | grep fldd && ; RUN: llvm-as < %s | llc -march=arm | grep flds && +; RUN: llvm-as < %s | llc -march=arm | grep fuitod && +; RUN: llvm-as < %s | llc -march=arm | grep fuitos && ; RUN: llvm-as < %s | llc -march=arm | grep ".word.*1065353216" float %f(int %a) { @@ -21,6 +23,19 @@ entry: ret double %tmp } +double %uint_to_double(uint %a) { +entry: + %tmp = cast uint %a to double + ret double %tmp +} + +float %uint_to_float(uint %a) { +entry: + %tmp = cast uint %a to float + ret float %tmp +} + + double %h(double* %v) { entry: %tmp = load double* %v ; [#uses=1]