mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-20 12:31:40 +00:00
Add codegen support for FP16 on ARM
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98502 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
927411b7ce
commit
bec3dd25c7
@ -426,12 +426,20 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::FPOW, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FPOW, MVT::f32, Expand);
|
||||
|
||||
// int <-> fp are custom expanded into bit_convert + ARMISD ops.
|
||||
if (!UseSoftFloat && Subtarget->hasVFP2() && !Subtarget->isThumb1Only()) {
|
||||
setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
|
||||
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
|
||||
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
|
||||
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
|
||||
// Various VFP goodness
|
||||
if (!UseSoftFloat && !Subtarget->isThumb1Only()) {
|
||||
// int <-> fp are custom expanded into bit_convert + ARMISD ops.
|
||||
if (Subtarget->hasVFP2()) {
|
||||
setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
|
||||
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
|
||||
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
|
||||
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
|
||||
}
|
||||
// Special handling for half-precision FP.
|
||||
if (Subtarget->hasVFP3()) {
|
||||
setOperationAction(ISD::FP16_TO_FP32, MVT::f32, Custom);
|
||||
setOperationAction(ISD::FP32_TO_FP16, MVT::i32, Custom);
|
||||
}
|
||||
}
|
||||
|
||||
// We have target-specific dag combine patterns for the following nodes:
|
||||
@ -491,6 +499,8 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
case ARMISD::FTOUI: return "ARMISD::FTOUI";
|
||||
case ARMISD::SITOF: return "ARMISD::SITOF";
|
||||
case ARMISD::UITOF: return "ARMISD::UITOF";
|
||||
case ARMISD::F16_TO_F32: return "ARMISD::F16_TO_F32";
|
||||
case ARMISD::F32_TO_F16: return "ARMISD::F32_TO_F16";
|
||||
|
||||
case ARMISD::SRL_FLAG: return "ARMISD::SRL_FLAG";
|
||||
case ARMISD::SRA_FLAG: return "ARMISD::SRA_FLAG";
|
||||
@ -1972,8 +1982,21 @@ SDValue ARMTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) {
|
||||
|
||||
static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) {
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
unsigned Opc =
|
||||
Op.getOpcode() == ISD::FP_TO_SINT ? ARMISD::FTOSI : ARMISD::FTOUI;
|
||||
unsigned Opc;
|
||||
|
||||
switch (Op.getOpcode()) {
|
||||
default:
|
||||
assert(0 && "Invalid opcode!");
|
||||
case ISD::FP32_TO_FP16:
|
||||
Opc = ARMISD::F32_TO_F16;
|
||||
break;
|
||||
case ISD::FP_TO_SINT:
|
||||
Opc = ARMISD::FTOSI;
|
||||
break;
|
||||
case ISD::FP_TO_UINT:
|
||||
Opc = ARMISD::FTOUI;
|
||||
break;
|
||||
}
|
||||
Op = DAG.getNode(Opc, dl, MVT::f32, Op.getOperand(0));
|
||||
return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
|
||||
}
|
||||
@ -1981,8 +2004,21 @@ static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG) {
|
||||
static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) {
|
||||
EVT VT = Op.getValueType();
|
||||
DebugLoc dl = Op.getDebugLoc();
|
||||
unsigned Opc =
|
||||
Op.getOpcode() == ISD::SINT_TO_FP ? ARMISD::SITOF : ARMISD::UITOF;
|
||||
unsigned Opc;
|
||||
|
||||
switch (Op.getOpcode()) {
|
||||
default:
|
||||
assert(0 && "Invalid opcode!");
|
||||
case ISD::FP16_TO_FP32:
|
||||
Opc = ARMISD::F16_TO_F32;
|
||||
break;
|
||||
case ISD::SINT_TO_FP:
|
||||
Opc = ARMISD::SITOF;
|
||||
break;
|
||||
case ISD::UINT_TO_FP:
|
||||
Opc = ARMISD::UITOF;
|
||||
break;
|
||||
}
|
||||
|
||||
Op = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, Op.getOperand(0));
|
||||
return DAG.getNode(Opc, dl, VT, Op);
|
||||
@ -3042,8 +3078,10 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
|
||||
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
|
||||
case ISD::VASTART: return LowerVASTART(Op, DAG, VarArgsFrameIndex);
|
||||
case ISD::MEMBARRIER: return LowerMEMBARRIER(Op, DAG, Subtarget);
|
||||
case ISD::FP16_TO_FP32:
|
||||
case ISD::SINT_TO_FP:
|
||||
case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG);
|
||||
case ISD::FP32_TO_FP16:
|
||||
case ISD::FP_TO_SINT:
|
||||
case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG);
|
||||
case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG);
|
||||
|
@ -59,6 +59,8 @@ namespace llvm {
|
||||
FTOUI, // FP to uint within a FP register.
|
||||
SITOF, // sint to FP within a FP register.
|
||||
UITOF, // uint to FP within a FP register.
|
||||
F16_TO_F32, // Half FP to single FP within a FP register.
|
||||
F32_TO_F16, // Single FP to half FP within a FP register.
|
||||
|
||||
SRL_FLAG, // V,Flag = srl_flag X -> srl X, 1 + save carry out.
|
||||
SRA_FLAG, // V,Flag = sra_flag X -> sra X, 1 + save carry out.
|
||||
|
@ -25,6 +25,8 @@ def arm_ftoui : SDNode<"ARMISD::FTOUI", SDT_FTOI>;
|
||||
def arm_ftosi : SDNode<"ARMISD::FTOSI", SDT_FTOI>;
|
||||
def arm_sitof : SDNode<"ARMISD::SITOF", SDT_ITOF>;
|
||||
def arm_uitof : SDNode<"ARMISD::UITOF", SDT_ITOF>;
|
||||
def arm_f16tof32 : SDNode<"ARMISD::F16_TO_F32", SDT_ITOF>;
|
||||
def arm_f32tof16 : SDNode<"ARMISD::F32_TO_F16", SDT_FTOI>;
|
||||
def arm_fmstat : SDNode<"ARMISD::FMSTAT", SDTNone, [SDNPInFlag,SDNPOutFlag]>;
|
||||
def arm_cmpfp : SDNode<"ARMISD::CMPFP", SDT_ARMCmp, [SDNPOutFlag]>;
|
||||
def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0",SDT_CMPFP0, [SDNPOutFlag]>;
|
||||
@ -257,11 +259,11 @@ def VCVTSD : VFPAI<(outs SPR:$dst), (ins DPR:$a), VFPUnaryFrm,
|
||||
|
||||
def VCVTBSH : ASuI<0b11101, 0b11, 0b0010, 0b01, 0, (outs SPR:$dst), (ins SPR:$a),
|
||||
/* FIXME */ IIC_fpCVTDS, "vcvtb", ".f32.f16\t$dst, $a",
|
||||
[/* For disassembly only; pattern left blank */]>;
|
||||
[(set SPR:$dst, (f32 (arm_f32tof16 SPR:$a)))]>;
|
||||
|
||||
def VCVTBHS : ASuI<0b11101, 0b11, 0b0011, 0b01, 0, (outs SPR:$dst), (ins SPR:$a),
|
||||
/* FIXME */ IIC_fpCVTDS, "vcvtb", ".f16.f32\t$dst, $a",
|
||||
[/* For disassembly only; pattern left blank */]>;
|
||||
[(set SPR:$dst, (arm_f16tof32 SPR:$a))]>;
|
||||
|
||||
def VCVTTSH : ASuI<0b11101, 0b11, 0b0010, 0b11, 0, (outs SPR:$dst), (ins SPR:$a),
|
||||
/* FIXME */ IIC_fpCVTDS, "vcvtt", ".f32.f16\t$dst, $a",
|
||||
|
Loading…
x
Reference in New Issue
Block a user