mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-13 17:38:39 +00:00
Implement codegen for flt_rounds on x86
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44183 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
917c2a6ff2
commit
45b22fa9f1
@ -205,6 +205,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
|
|||||||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
|
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
|
||||||
setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand);
|
setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand);
|
||||||
setOperationAction(ISD::FREM , MVT::f64 , Expand);
|
setOperationAction(ISD::FREM , MVT::f64 , Expand);
|
||||||
|
setOperationAction(ISD::FLT_ROUNDS , MVT::i32 , Custom);
|
||||||
|
|
||||||
setOperationAction(ISD::CTPOP , MVT::i8 , Expand);
|
setOperationAction(ISD::CTPOP , MVT::i8 , Expand);
|
||||||
setOperationAction(ISD::CTTZ , MVT::i8 , Expand);
|
setOperationAction(ISD::CTTZ , MVT::i8 , Expand);
|
||||||
@ -4940,6 +4941,66 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDOperand X86TargetLowering::LowerFLT_ROUNDS(SDOperand Op, SelectionDAG &DAG) {
|
||||||
|
/*
|
||||||
|
The rounding mode is in bits 11:10 of FPSR, and has the following
|
||||||
|
settings:
|
||||||
|
00 Round to nearest
|
||||||
|
01 Round to -inf
|
||||||
|
10 Round to +inf
|
||||||
|
11 Round to 0
|
||||||
|
|
||||||
|
FLT_ROUNDS, on the other hand, expects the following:
|
||||||
|
-1 Undefined
|
||||||
|
0 Round to 0
|
||||||
|
1 Round to nearest
|
||||||
|
2 Round to +inf
|
||||||
|
3 Round to -inf
|
||||||
|
|
||||||
|
To perform the conversion, we do:
|
||||||
|
(((((FPSR & 0x800) >> 11) | ((FPSR & 0x400) >> 9)) + 1) & 3)
|
||||||
|
*/
|
||||||
|
|
||||||
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
|
const TargetMachine &TM = MF.getTarget();
|
||||||
|
const TargetFrameInfo &TFI = *TM.getFrameInfo();
|
||||||
|
unsigned StackAlignment = TFI.getStackAlignment();
|
||||||
|
MVT::ValueType VT = Op.getValueType();
|
||||||
|
|
||||||
|
// Save FP Control Word to stack slot
|
||||||
|
int SSFI = MF.getFrameInfo()->CreateStackObject(2, StackAlignment);
|
||||||
|
SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
|
||||||
|
|
||||||
|
SDOperand Chain = DAG.getNode(X86ISD::FNSTCW16m, MVT::Other,
|
||||||
|
DAG.getEntryNode(), StackSlot);
|
||||||
|
|
||||||
|
// Load FP Control Word from stack slot
|
||||||
|
SDOperand CWD = DAG.getLoad(MVT::i16, Chain, StackSlot, NULL, 0);
|
||||||
|
|
||||||
|
// Transform as necessary
|
||||||
|
SDOperand CWD1 =
|
||||||
|
DAG.getNode(ISD::SRL, MVT::i16,
|
||||||
|
DAG.getNode(ISD::AND, MVT::i16,
|
||||||
|
CWD, DAG.getConstant(0x800, MVT::i16)),
|
||||||
|
DAG.getConstant(11, MVT::i8));
|
||||||
|
SDOperand CWD2 =
|
||||||
|
DAG.getNode(ISD::SRL, MVT::i16,
|
||||||
|
DAG.getNode(ISD::AND, MVT::i16,
|
||||||
|
CWD, DAG.getConstant(0x400, MVT::i16)),
|
||||||
|
DAG.getConstant(9, MVT::i8));
|
||||||
|
|
||||||
|
SDOperand RetVal =
|
||||||
|
DAG.getNode(ISD::AND, MVT::i16,
|
||||||
|
DAG.getNode(ISD::ADD, MVT::i16,
|
||||||
|
DAG.getNode(ISD::OR, MVT::i16, CWD1, CWD2),
|
||||||
|
DAG.getConstant(1, MVT::i16)),
|
||||||
|
DAG.getConstant(3, MVT::i16));
|
||||||
|
|
||||||
|
|
||||||
|
return DAG.getNode((MVT::getSizeInBits(VT) < 16 ?
|
||||||
|
ISD::TRUNCATE : ISD::ZERO_EXTEND), VT, RetVal);
|
||||||
|
}
|
||||||
|
|
||||||
/// LowerOperation - Provide custom lowering hooks for some operations.
|
/// LowerOperation - Provide custom lowering hooks for some operations.
|
||||||
///
|
///
|
||||||
SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
||||||
@ -4982,6 +5043,7 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
|
case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
|
||||||
case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG);
|
case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG);
|
||||||
case ISD::TRAMPOLINE: return LowerTRAMPOLINE(Op, DAG);
|
case ISD::TRAMPOLINE: return LowerTRAMPOLINE(Op, DAG);
|
||||||
|
case ISD::FLT_ROUNDS: return LowerFLT_ROUNDS(Op, DAG);
|
||||||
}
|
}
|
||||||
return SDOperand();
|
return SDOperand();
|
||||||
}
|
}
|
||||||
@ -5029,6 +5091,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||||||
case X86ISD::THREAD_POINTER: return "X86ISD::THREAD_POINTER";
|
case X86ISD::THREAD_POINTER: return "X86ISD::THREAD_POINTER";
|
||||||
case X86ISD::EH_RETURN: return "X86ISD::EH_RETURN";
|
case X86ISD::EH_RETURN: return "X86ISD::EH_RETURN";
|
||||||
case X86ISD::TC_RETURN: return "X86ISD::TC_RETURN";
|
case X86ISD::TC_RETURN: return "X86ISD::TC_RETURN";
|
||||||
|
case X86ISD::FNSTCW16m: return "X86ISD::FNSTCW16m";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +188,10 @@ namespace llvm {
|
|||||||
// operand #1 callee (register or absolute)
|
// operand #1 callee (register or absolute)
|
||||||
// operand #2 stack adjustment
|
// operand #2 stack adjustment
|
||||||
// operand #3 optional in flag
|
// operand #3 optional in flag
|
||||||
TC_RETURN
|
TC_RETURN,
|
||||||
|
|
||||||
|
// Store FP control world into i16 memory
|
||||||
|
FNSTCW16m
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,6 +480,7 @@ namespace llvm {
|
|||||||
SDOperand LowerFRAME_TO_ARGS_OFFSET(SDOperand Op, SelectionDAG &DAG);
|
SDOperand LowerFRAME_TO_ARGS_OFFSET(SDOperand Op, SelectionDAG &DAG);
|
||||||
SDOperand LowerEH_RETURN(SDOperand Op, SelectionDAG &DAG);
|
SDOperand LowerEH_RETURN(SDOperand Op, SelectionDAG &DAG);
|
||||||
SDOperand LowerTRAMPOLINE(SDOperand Op, SelectionDAG &DAG);
|
SDOperand LowerTRAMPOLINE(SDOperand Op, SelectionDAG &DAG);
|
||||||
|
SDOperand LowerFLT_ROUNDS(SDOperand Op, SelectionDAG &DAG);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ def SDTX86Fild : SDTypeProfile<1, 2, [SDTCisFP<0>, SDTCisPtrTy<1>,
|
|||||||
SDTCisVT<2, OtherVT>]>;
|
SDTCisVT<2, OtherVT>]>;
|
||||||
def SDTX86FpToIMem : SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisPtrTy<1>]>;
|
def SDTX86FpToIMem : SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisPtrTy<1>]>;
|
||||||
|
|
||||||
|
def SDTX86CwdStore : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
|
||||||
|
|
||||||
def X86fpget : SDNode<"X86ISD::FP_GET_RESULT", SDTX86FpGet,
|
def X86fpget : SDNode<"X86ISD::FP_GET_RESULT", SDTX86FpGet,
|
||||||
[SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
|
[SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
|
||||||
def X86fpset : SDNode<"X86ISD::FP_SET_RESULT", SDTX86FpSet,
|
def X86fpset : SDNode<"X86ISD::FP_SET_RESULT", SDTX86FpSet,
|
||||||
@ -47,6 +49,8 @@ def X86fp_to_i32mem : SDNode<"X86ISD::FP_TO_INT32_IN_MEM", SDTX86FpToIMem,
|
|||||||
[SDNPHasChain]>;
|
[SDNPHasChain]>;
|
||||||
def X86fp_to_i64mem : SDNode<"X86ISD::FP_TO_INT64_IN_MEM", SDTX86FpToIMem,
|
def X86fp_to_i64mem : SDNode<"X86ISD::FP_TO_INT64_IN_MEM", SDTX86FpToIMem,
|
||||||
[SDNPHasChain]>;
|
[SDNPHasChain]>;
|
||||||
|
def X86fp_cwd_get16 : SDNode<"X86ISD::FNSTCW16m", SDTX86CwdStore,
|
||||||
|
[SDNPHasChain]>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// FPStack pattern fragments
|
// FPStack pattern fragments
|
||||||
@ -524,7 +528,8 @@ def FNSTSW8r : I<0xE0, RawFrm, // AX = fp flags
|
|||||||
(outs), (ins), "fnstsw", []>, DF;
|
(outs), (ins), "fnstsw", []>, DF;
|
||||||
|
|
||||||
def FNSTCW16m : I<0xD9, MRM7m, // [mem16] = X87 control world
|
def FNSTCW16m : I<0xD9, MRM7m, // [mem16] = X87 control world
|
||||||
(outs), (ins i16mem:$dst), "fnstcw\t$dst", []>;
|
(outs), (ins i16mem:$dst), "fnstcw\t$dst",
|
||||||
|
[(X86fp_cwd_get16 addr:$dst)]>;
|
||||||
def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16]
|
def FLDCW16m : I<0xD9, MRM5m, // X87 control world = [mem16]
|
||||||
(outs), (ins i16mem:$dst), "fldcw\t$dst", []>;
|
(outs), (ins i16mem:$dst), "fldcw\t$dst", []>;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user