mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 20:29:53 +00:00
[SparcV9] Handle i64 <-> float conversions in sparcv9 mode.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193957 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0c7ba3cef2
commit
fcd5e86396
@ -949,9 +949,10 @@ static bool isFP128ABICall(const char *CalleeName)
|
||||
{ "_Q_add", "_Q_sub", "_Q_mul", "_Q_div",
|
||||
"_Q_sqrt", "_Q_neg",
|
||||
"_Q_itoq", "_Q_stoq", "_Q_dtoq", "_Q_utoq",
|
||||
"_Q_lltoq", "_Q_ulltoq",
|
||||
0
|
||||
};
|
||||
for (const char * const *I = ABICalls; I != 0; ++I)
|
||||
for (const char * const *I = ABICalls; *I != 0; ++I)
|
||||
if (strcmp(CalleeName, *I) == 0)
|
||||
return true;
|
||||
return false;
|
||||
@ -1341,7 +1342,7 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::SREM, MVT::i32, Expand);
|
||||
setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
|
||||
setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
|
||||
|
||||
|
||||
// ... nor does SparcV9.
|
||||
if (Subtarget->is64Bit()) {
|
||||
setOperationAction(ISD::UREM, MVT::i64, Expand);
|
||||
@ -1353,10 +1354,14 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
|
||||
// Custom expand fp<->sint
|
||||
setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
|
||||
setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
|
||||
setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
|
||||
setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
|
||||
|
||||
// Custom Expand fp<->uint
|
||||
setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
|
||||
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
|
||||
setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
|
||||
setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
|
||||
|
||||
setOperationAction(ISD::BITCAST, MVT::f32, Expand);
|
||||
setOperationAction(ISD::BITCAST, MVT::i32, Expand);
|
||||
@ -1497,6 +1502,14 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::FNEG, MVT::f128, Custom);
|
||||
setOperationAction(ISD::FABS, MVT::f128, Custom);
|
||||
}
|
||||
|
||||
if (!Subtarget->is64Bit()) {
|
||||
setLibcallName(RTLIB::FPTOSINT_F128_I64, "_Q_qtoll");
|
||||
setLibcallName(RTLIB::FPTOUINT_F128_I64, "_Q_qtoull");
|
||||
setLibcallName(RTLIB::SINTTOFP_I64_F128, "_Q_lltoq");
|
||||
setLibcallName(RTLIB::UINTTOFP_I64_F128, "_Q_ulltoq");
|
||||
}
|
||||
|
||||
} else {
|
||||
// Custom legalize f128 operations.
|
||||
|
||||
@ -1523,6 +1536,10 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
|
||||
setLibcallName(RTLIB::FPTOUINT_F128_I32, "_Qp_qtoui");
|
||||
setLibcallName(RTLIB::SINTTOFP_I32_F128, "_Qp_itoq");
|
||||
setLibcallName(RTLIB::UINTTOFP_I32_F128, "_Qp_uitoq");
|
||||
setLibcallName(RTLIB::FPTOSINT_F128_I64, "_Qp_qtox");
|
||||
setLibcallName(RTLIB::FPTOUINT_F128_I64, "_Qp_qtoux");
|
||||
setLibcallName(RTLIB::SINTTOFP_I64_F128, "_Qp_xtoq");
|
||||
setLibcallName(RTLIB::UINTTOFP_I64_F128, "_Qp_uxtoq");
|
||||
setLibcallName(RTLIB::FPEXT_F32_F128, "_Qp_stoq");
|
||||
setLibcallName(RTLIB::FPEXT_F64_F128, "_Qp_dtoq");
|
||||
setLibcallName(RTLIB::FPROUND_F128_F32, "_Qp_qtos");
|
||||
@ -1537,6 +1554,10 @@ SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
|
||||
setLibcallName(RTLIB::FPTOUINT_F128_I32, "_Q_qtou");
|
||||
setLibcallName(RTLIB::SINTTOFP_I32_F128, "_Q_itoq");
|
||||
setLibcallName(RTLIB::UINTTOFP_I32_F128, "_Q_utoq");
|
||||
setLibcallName(RTLIB::FPTOSINT_F128_I64, "_Q_qtoll");
|
||||
setLibcallName(RTLIB::FPTOUINT_F128_I64, "_Q_qtoull");
|
||||
setLibcallName(RTLIB::SINTTOFP_I64_F128, "_Q_lltoq");
|
||||
setLibcallName(RTLIB::UINTTOFP_I64_F128, "_Q_ulltoq");
|
||||
setLibcallName(RTLIB::FPEXT_F32_F128, "_Q_stoq");
|
||||
setLibcallName(RTLIB::FPEXT_F64_F128, "_Q_dtoq");
|
||||
setLibcallName(RTLIB::FPROUND_F128_F32, "_Q_qtos");
|
||||
@ -1564,6 +1585,8 @@ const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
||||
case SPISD::Lo: return "SPISD::Lo";
|
||||
case SPISD::FTOI: return "SPISD::FTOI";
|
||||
case SPISD::ITOF: return "SPISD::ITOF";
|
||||
case SPISD::FTOX: return "SPISD::FTOX";
|
||||
case SPISD::XTOF: return "SPISD::XTOF";
|
||||
case SPISD::CALL: return "SPISD::CALL";
|
||||
case SPISD::RET_FLAG: return "SPISD::RET_FLAG";
|
||||
case SPISD::GLOBAL_BASE_REG: return "SPISD::GLOBAL_BASE_REG";
|
||||
@ -2055,59 +2078,97 @@ static SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG,
|
||||
const SparcTargetLowering &TLI,
|
||||
bool hasHardQuad) {
|
||||
SDLoc dl(Op);
|
||||
// Convert the fp value to integer in an FP register.
|
||||
assert(Op.getValueType() == MVT::i32);
|
||||
EVT VT = Op.getValueType();
|
||||
assert(VT == MVT::i32 || VT == MVT::i64);
|
||||
|
||||
if (Op.getOperand(0).getValueType() == MVT::f128 && !hasHardQuad)
|
||||
return TLI.LowerF128Op(Op, DAG,
|
||||
TLI.getLibcallName(RTLIB::FPTOSINT_F128_I32), 1);
|
||||
// Expand f128 operations to fp128 abi calls.
|
||||
if (Op.getOperand(0).getValueType() == MVT::f128
|
||||
&& (!hasHardQuad || !TLI.isTypeLegal(VT))) {
|
||||
const char *libName = TLI.getLibcallName(VT == MVT::i32
|
||||
? RTLIB::FPTOSINT_F128_I32
|
||||
: RTLIB::FPTOSINT_F128_I64);
|
||||
return TLI.LowerF128Op(Op, DAG, libName, 1);
|
||||
}
|
||||
|
||||
Op = DAG.getNode(SPISD::FTOI, dl, MVT::f32, Op.getOperand(0));
|
||||
return DAG.getNode(ISD::BITCAST, dl, MVT::i32, Op);
|
||||
// Expand if the resulting type is illegal.
|
||||
if (!TLI.isTypeLegal(VT))
|
||||
return SDValue(0, 0);
|
||||
|
||||
// Otherwise, Convert the fp value to integer in an FP register.
|
||||
if (VT == MVT::i32)
|
||||
Op = DAG.getNode(SPISD::FTOI, dl, MVT::f32, Op.getOperand(0));
|
||||
else
|
||||
Op = DAG.getNode(SPISD::FTOX, dl, MVT::f64, Op.getOperand(0));
|
||||
|
||||
return DAG.getNode(ISD::BITCAST, dl, VT, Op);
|
||||
}
|
||||
|
||||
static SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG,
|
||||
const SparcTargetLowering &TLI,
|
||||
bool hasHardQuad) {
|
||||
SDLoc dl(Op);
|
||||
assert(Op.getOperand(0).getValueType() == MVT::i32);
|
||||
SDValue Tmp = DAG.getNode(ISD::BITCAST, dl, MVT::f32, Op.getOperand(0));
|
||||
// Convert the int value to FP in an FP register.
|
||||
if (Op.getValueType() == MVT::f128 && !hasHardQuad)
|
||||
return TLI.LowerF128Op(Op, DAG,
|
||||
TLI.getLibcallName(RTLIB::SINTTOFP_I32_F128), 1);
|
||||
return DAG.getNode(SPISD::ITOF, dl, Op.getValueType(), Tmp);
|
||||
EVT OpVT = Op.getOperand(0).getValueType();
|
||||
assert(OpVT == MVT::i32 || (OpVT == MVT::i64));
|
||||
|
||||
EVT floatVT = (OpVT == MVT::i32) ? MVT::f32 : MVT::f64;
|
||||
|
||||
// Expand f128 operations to fp128 ABI calls.
|
||||
if (Op.getValueType() == MVT::f128
|
||||
&& (!hasHardQuad || !TLI.isTypeLegal(OpVT))) {
|
||||
const char *libName = TLI.getLibcallName(OpVT == MVT::i32
|
||||
? RTLIB::SINTTOFP_I32_F128
|
||||
: RTLIB::SINTTOFP_I64_F128);
|
||||
return TLI.LowerF128Op(Op, DAG, libName, 1);
|
||||
}
|
||||
|
||||
// Expand if the operand type is illegal.
|
||||
if (!TLI.isTypeLegal(OpVT))
|
||||
return SDValue(0, 0);
|
||||
|
||||
// Otherwise, Convert the int value to FP in an FP register.
|
||||
SDValue Tmp = DAG.getNode(ISD::BITCAST, dl, floatVT, Op.getOperand(0));
|
||||
unsigned opcode = (OpVT == MVT::i32)? SPISD::ITOF : SPISD::XTOF;
|
||||
return DAG.getNode(opcode, dl, Op.getValueType(), Tmp);
|
||||
}
|
||||
|
||||
static SDValue LowerFP_TO_UINT(SDValue Op, SelectionDAG &DAG,
|
||||
const SparcTargetLowering &TLI,
|
||||
bool hasHardQuad) {
|
||||
SDLoc dl(Op);
|
||||
EVT VT = Op.getValueType();
|
||||
|
||||
// Expand if it does not involve f128 or the target has support for
|
||||
// quad floating point instructions.
|
||||
if (Op.getOperand(0).getValueType() != MVT::f128 || hasHardQuad)
|
||||
// quad floating point instructions and the resulting type is legal.
|
||||
if (Op.getOperand(0).getValueType() != MVT::f128 ||
|
||||
(hasHardQuad && TLI.isTypeLegal(VT)))
|
||||
return SDValue(0, 0);
|
||||
|
||||
SDLoc dl(Op);
|
||||
assert(Op.getValueType() == MVT::i32);
|
||||
assert(VT == MVT::i32 || VT == MVT::i64);
|
||||
|
||||
return TLI.LowerF128Op(Op, DAG,
|
||||
TLI.getLibcallName(RTLIB::FPTOUINT_F128_I32), 1);
|
||||
TLI.getLibcallName(VT == MVT::i32
|
||||
? RTLIB::FPTOUINT_F128_I32
|
||||
: RTLIB::FPTOUINT_F128_I64),
|
||||
1);
|
||||
}
|
||||
|
||||
|
||||
static SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG,
|
||||
const SparcTargetLowering &TLI,
|
||||
bool hasHardQuad) {
|
||||
SDLoc dl(Op);
|
||||
EVT OpVT = Op.getOperand(0).getValueType();
|
||||
assert(OpVT == MVT::i32 || OpVT == MVT::i64);
|
||||
|
||||
// Expand if it does not involve f128 or the target has support for
|
||||
// quad floating point instructions.
|
||||
if (Op.getValueType() != MVT::f128 || hasHardQuad)
|
||||
// quad floating point instructions and the operand type is legal.
|
||||
if (Op.getValueType() != MVT::f128 || (hasHardQuad && TLI.isTypeLegal(OpVT)))
|
||||
return SDValue(0, 0);
|
||||
|
||||
SDLoc dl(Op);
|
||||
assert(Op.getOperand(0).getValueType() == MVT::i32);
|
||||
|
||||
return TLI.LowerF128Op(Op, DAG,
|
||||
TLI.getLibcallName(RTLIB::UINTTOFP_I32_F128), 1);
|
||||
TLI.getLibcallName(OpVT == MVT::i32
|
||||
? RTLIB::UINTTOFP_I32_F128
|
||||
: RTLIB::UINTTOFP_I64_F128),
|
||||
1);
|
||||
}
|
||||
|
||||
static SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG,
|
||||
@ -2702,3 +2763,50 @@ SparcTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
|
||||
// The Sparc target isn't yet aware of offsets.
|
||||
return false;
|
||||
}
|
||||
|
||||
void SparcTargetLowering::ReplaceNodeResults(SDNode *N,
|
||||
SmallVectorImpl<SDValue>& Results,
|
||||
SelectionDAG &DAG) const {
|
||||
|
||||
SDLoc dl(N);
|
||||
|
||||
RTLIB::Libcall libCall = RTLIB::UNKNOWN_LIBCALL;
|
||||
|
||||
switch (N->getOpcode()) {
|
||||
default:
|
||||
llvm_unreachable("Do not know how to custom type legalize this operation!");
|
||||
|
||||
case ISD::FP_TO_SINT:
|
||||
case ISD::FP_TO_UINT:
|
||||
// Custom lower only if it involves f128 or i64.
|
||||
if (N->getOperand(0).getValueType() != MVT::f128
|
||||
|| N->getValueType(0) != MVT::i64)
|
||||
return;
|
||||
libCall = ((N->getOpcode() == ISD::FP_TO_SINT)
|
||||
? RTLIB::FPTOSINT_F128_I64
|
||||
: RTLIB::FPTOUINT_F128_I64);
|
||||
|
||||
Results.push_back(LowerF128Op(SDValue(N, 0),
|
||||
DAG,
|
||||
getLibcallName(libCall),
|
||||
1));
|
||||
return;
|
||||
|
||||
case ISD::SINT_TO_FP:
|
||||
case ISD::UINT_TO_FP:
|
||||
// Custom lower only if it involves f128 or i64.
|
||||
if (N->getValueType(0) != MVT::f128
|
||||
|| N->getOperand(0).getValueType() != MVT::i64)
|
||||
return;
|
||||
|
||||
libCall = ((N->getOpcode() == ISD::SINT_TO_FP)
|
||||
? RTLIB::SINTTOFP_I64_F128
|
||||
: RTLIB::UINTTOFP_I64_F128);
|
||||
|
||||
Results.push_back(LowerF128Op(SDValue(N, 0),
|
||||
DAG,
|
||||
getLibcallName(libCall),
|
||||
1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ namespace llvm {
|
||||
|
||||
FTOI, // FP to Int within a FP register.
|
||||
ITOF, // Int to FP within a FP register.
|
||||
FTOX, // FP to Int64 within a FP register.
|
||||
XTOF, // Int64 to FP within a FP register.
|
||||
|
||||
CALL, // A call instruction.
|
||||
RET_FLAG, // Return with a flag operand.
|
||||
@ -149,6 +151,10 @@ namespace llvm {
|
||||
// (ldd, call _Q_fdtoq) is more expensive than two ldds.
|
||||
return VT != MVT::f128;
|
||||
}
|
||||
|
||||
virtual void ReplaceNodeResults(SDNode *N,
|
||||
SmallVectorImpl<SDValue>& Results,
|
||||
SelectionDAG &DAG) const;
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
|
@ -344,6 +344,42 @@ def FMOVD_XCC : Pseudo<(outs DFPRegs:$rd),
|
||||
(SPselectxcc f64:$rs2, f64:$f, imm:$cond))]>;
|
||||
} // Uses, Constraints
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// 64-bit Floating Point Conversions.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Predicates = [Is64Bit] in {
|
||||
|
||||
def FXTOS : F3_3u<2, 0b110100, 0b010000100,
|
||||
(outs FPRegs:$dst), (ins DFPRegs:$src),
|
||||
"fxtos $src, $dst",
|
||||
[(set FPRegs:$dst, (SPxtof DFPRegs:$src))]>;
|
||||
def FXTOD : F3_3u<2, 0b110100, 0b010001000,
|
||||
(outs DFPRegs:$dst), (ins DFPRegs:$src),
|
||||
"fxtod $src, $dst",
|
||||
[(set DFPRegs:$dst, (SPxtof DFPRegs:$src))]>;
|
||||
def FXTOQ : F3_3u<2, 0b110100, 0b010001100,
|
||||
(outs QFPRegs:$dst), (ins DFPRegs:$src),
|
||||
"fxtoq $src, $dst",
|
||||
[(set QFPRegs:$dst, (SPxtof DFPRegs:$src))]>,
|
||||
Requires<[HasHardQuad]>;
|
||||
|
||||
def FSTOX : F3_3u<2, 0b110100, 0b010000001,
|
||||
(outs DFPRegs:$dst), (ins FPRegs:$src),
|
||||
"fstox $src, $dst",
|
||||
[(set DFPRegs:$dst, (SPftox FPRegs:$src))]>;
|
||||
def FDTOX : F3_3u<2, 0b110100, 0b010000010,
|
||||
(outs DFPRegs:$dst), (ins DFPRegs:$src),
|
||||
"fdtox $src, $dst",
|
||||
[(set DFPRegs:$dst, (SPftox DFPRegs:$src))]>;
|
||||
def FQTOX : F3_3u<2, 0b110100, 0b010000011,
|
||||
(outs DFPRegs:$dst), (ins QFPRegs:$src),
|
||||
"fqtox $src, $dst",
|
||||
[(set DFPRegs:$dst, (SPftox QFPRegs:$src))]>,
|
||||
Requires<[HasHardQuad]>;
|
||||
|
||||
} // Predicates = [Is64Bit]
|
||||
|
||||
def : Pat<(SPselectxcc i64:$t, i64:$f, imm:$cond),
|
||||
(MOVXCCrr $t, $f, imm:$cond)>;
|
||||
def : Pat<(SPselectxcc (i64 simm11:$t), i64:$f, imm:$cond),
|
||||
|
@ -107,6 +107,10 @@ def SDTSPFTOI :
|
||||
SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>;
|
||||
def SDTSPITOF :
|
||||
SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>;
|
||||
def SDTSPFTOX :
|
||||
SDTypeProfile<1, 1, [SDTCisVT<0, f64>, SDTCisFP<1>]>;
|
||||
def SDTSPXTOF :
|
||||
SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f64>]>;
|
||||
|
||||
def SDTSPtlsadd :
|
||||
SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisPtrTy<2>]>;
|
||||
@ -124,6 +128,8 @@ def SPlo : SDNode<"SPISD::Lo", SDTIntUnaryOp>;
|
||||
|
||||
def SPftoi : SDNode<"SPISD::FTOI", SDTSPFTOI>;
|
||||
def SPitof : SDNode<"SPISD::ITOF", SDTSPITOF>;
|
||||
def SPftox : SDNode<"SPISD::FTOX", SDTSPFTOX>;
|
||||
def SPxtof : SDNode<"SPISD::XTOF", SDTSPXTOF>;
|
||||
|
||||
def SPselecticc : SDNode<"SPISD::SELECT_ICC", SDTSPselectcc, [SDNPInGlue]>;
|
||||
def SPselectxcc : SDNode<"SPISD::SELECT_XCC", SDTSPselectcc, [SDNPInGlue]>;
|
||||
|
@ -1,7 +1,7 @@
|
||||
; RUN: llc -march=sparc < %s | FileCheck %s -check-prefix=V8
|
||||
; RUN: llc -march=sparc -O0 < %s | FileCheck %s -check-prefix=V8-UNOPT
|
||||
; RUN: llc -march=sparc -mattr=v9 < %s | FileCheck %s -check-prefix=V9
|
||||
|
||||
; RUN: llc -mtriple=sparc64-unknown-linux < %s | FileCheck %s -check-prefix=SPARC64
|
||||
|
||||
; V8-LABEL: test_neg:
|
||||
; V8: call get_double
|
||||
@ -16,6 +16,9 @@
|
||||
; V9-LABEL: test_neg:
|
||||
; V9: fnegd %f0, %f0
|
||||
|
||||
; SPARC64-LABEL: test_neg:
|
||||
; SPARC64: fnegd %f0, %f0
|
||||
|
||||
define double @test_neg() {
|
||||
entry:
|
||||
%0 = tail call double @get_double()
|
||||
@ -35,6 +38,10 @@ entry:
|
||||
; V9-LABEL: test_abs:
|
||||
; V9: fabsd %f0, %f0
|
||||
|
||||
|
||||
; SPARC64-LABEL: test_abs:
|
||||
; SPARC64: fabsd %f0, %f0
|
||||
|
||||
define double @test_abs() {
|
||||
entry:
|
||||
%0 = tail call double @get_double()
|
||||
@ -56,6 +63,10 @@ declare double @llvm.fabs.f64(double) nounwind readonly
|
||||
; V9: faddd {{.+}}, {{.+}}, [[R:%f((3(2|4|6|8))|((4|5)(0|2|4|6|8))|(60|62))]]
|
||||
; V9: fmovd [[R]], %f0
|
||||
|
||||
; SPARC64-LABEL: test_v9_floatreg:
|
||||
; SPARC64: fsubd {{.+}}, {{.+}}, {{.+}}
|
||||
; SPARC64: faddd {{.+}}, {{.+}}, [[R:%f((3(2|4|6|8))|((4|5)(0|2|4|6|8))|(60|62))]]
|
||||
; SPARC64: fmovd [[R]], %f0
|
||||
|
||||
define double @test_v9_floatreg() {
|
||||
entry:
|
||||
@ -67,4 +78,172 @@ entry:
|
||||
ret double %3
|
||||
}
|
||||
|
||||
; V8-LABEL: test_xtos_stox
|
||||
; V8: call __floatdisf
|
||||
; V8: call __fixsfdi
|
||||
|
||||
; V9-LABEL: test_xtos_stox
|
||||
; V9: call __floatdisf
|
||||
; V9: call __fixsfdi
|
||||
|
||||
; SPARC64-LABEL: test_xtos_stox
|
||||
; SPARC64: fxtos
|
||||
; SPARC64: fstox
|
||||
|
||||
define void @test_xtos_stox(i64 %a, i64* %ptr0, float* %ptr1) {
|
||||
entry:
|
||||
%0 = sitofp i64 %a to float
|
||||
store float %0, float* %ptr1, align 8
|
||||
%1 = fptosi float %0 to i64
|
||||
store i64 %1, i64* %ptr0, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
; V8-LABEL: test_itos_stoi
|
||||
; V8: fitos
|
||||
; V8: fstoi
|
||||
|
||||
; V9-LABEL: test_itos_stoi
|
||||
; V9: fitos
|
||||
; V9: fstoi
|
||||
|
||||
; SPARC64-LABEL: test_itos_stoi
|
||||
; SPARC64: fitos
|
||||
; SPARC64: fstoi
|
||||
|
||||
define void @test_itos_stoi(i32 %a, i32* %ptr0, float* %ptr1) {
|
||||
entry:
|
||||
%0 = sitofp i32 %a to float
|
||||
store float %0, float* %ptr1, align 8
|
||||
%1 = fptosi float %0 to i32
|
||||
store i32 %1, i32* %ptr0, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
; V8-LABEL: test_xtod_dtox
|
||||
; V8: call __floatdidf
|
||||
; V8: call __fixdfdi
|
||||
|
||||
; V9-LABEL: test_xtod_dtox
|
||||
; V9: call __floatdidf
|
||||
; V9: call __fixdfdi
|
||||
|
||||
; SPARC64-LABEL: test_xtod_dtox
|
||||
; SPARC64: fxtod
|
||||
; SPARC64: fdtox
|
||||
|
||||
define void @test_xtod_dtox(i64 %a, i64* %ptr0, double* %ptr1) {
|
||||
entry:
|
||||
%0 = sitofp i64 %a to double
|
||||
store double %0, double* %ptr1, align 8
|
||||
%1 = fptosi double %0 to i64
|
||||
store i64 %1, i64* %ptr0, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
; V8-LABEL: test_itod_dtoi
|
||||
; V8: fitod
|
||||
; V8: fdtoi
|
||||
|
||||
; V9-LABEL: test_itod_dtoi
|
||||
; V9: fitod
|
||||
; V9: fdtoi
|
||||
|
||||
; SPARC64-LABEL: test_itod_dtoi
|
||||
; SPARC64: fitod
|
||||
; SPARC64: fdtoi
|
||||
|
||||
define void @test_itod_dtoi(i32 %a, i32* %ptr0, double* %ptr1) {
|
||||
entry:
|
||||
%0 = sitofp i32 %a to double
|
||||
store double %0, double* %ptr1, align 8
|
||||
%1 = fptosi double %0 to i32
|
||||
store i32 %1, i32* %ptr0, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
; V8-LABEL: test_uxtos_stoux
|
||||
; V8: call __floatundisf
|
||||
; V8: call __fixunssfdi
|
||||
|
||||
; V9-LABEL: test_uxtos_stoux
|
||||
; V9: call __floatundisf
|
||||
; V9: call __fixunssfdi
|
||||
|
||||
; SPARC64-LABEL: test_uxtos_stoux
|
||||
; SPARC64-NOT: call __floatundisf
|
||||
; SPARC64-NOT: call __fixunssfdi
|
||||
|
||||
define void @test_uxtos_stoux(i64 %a, i64* %ptr0, float* %ptr1) {
|
||||
entry:
|
||||
%0 = uitofp i64 %a to float
|
||||
store float %0, float* %ptr1, align 8
|
||||
%1 = fptoui float %0 to i64
|
||||
store i64 %1, i64* %ptr0, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
; V8-LABEL: test_utos_stou
|
||||
; V8: fdtos
|
||||
; V8: fstoi
|
||||
|
||||
; V9-LABEL: test_utos_stou
|
||||
; V9: fdtos
|
||||
; V9: fstoi
|
||||
|
||||
; SPARC64-LABEL: test_utos_stou
|
||||
; SPARC64: fdtos
|
||||
; SPARC64: fstoi
|
||||
|
||||
define void @test_utos_stou(i32 %a, i32* %ptr0, float* %ptr1) {
|
||||
entry:
|
||||
%0 = uitofp i32 %a to float
|
||||
store float %0, float* %ptr1, align 8
|
||||
%1 = fptoui float %0 to i32
|
||||
store i32 %1, i32* %ptr0, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
; V8-LABEL: test_uxtod_dtoux
|
||||
; V8: call __floatundidf
|
||||
; V8: call __fixunsdfdi
|
||||
|
||||
; V9-LABEL: test_uxtod_dtoux
|
||||
; V9: call __floatundidf
|
||||
; V9: call __fixunsdfdi
|
||||
|
||||
; SPARC64-LABEL: test_uxtod_dtoux
|
||||
; SPARC64-NOT: call __floatundidf
|
||||
; SPARC64-NOT: call __floatunsdfdi
|
||||
|
||||
define void @test_uxtod_dtoux(i64 %a, i64* %ptr0, double* %ptr1) {
|
||||
entry:
|
||||
%0 = uitofp i64 %a to double
|
||||
store double %0, double* %ptr1, align 8
|
||||
%1 = fptoui double %0 to i64
|
||||
store i64 %1, i64* %ptr0, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
; V8-LABEL: test_utod_dtou
|
||||
; V8-NOT: fitod
|
||||
; V8: fdtoi
|
||||
|
||||
; V9-LABEL: test_utod_dtou
|
||||
; V9-NOT: fitod
|
||||
; V9: fdtoi
|
||||
|
||||
; SPARC64-LABEL: test_utod_dtou
|
||||
; SPARC64-NOT: fitod
|
||||
; SPARC64: fdtoi
|
||||
|
||||
define void @test_utod_dtou(i32 %a, double %b, i32* %ptr0, double* %ptr1) {
|
||||
entry:
|
||||
%0 = uitofp i32 %a to double
|
||||
store double %0, double* %ptr1, align 8
|
||||
%1 = fptoui double %b to i32
|
||||
store i32 %1, i32* %ptr0, align 8
|
||||
ret void
|
||||
}
|
||||
|
@ -180,3 +180,55 @@ entry:
|
||||
%4 = add i32 %2, %3
|
||||
ret i32 %4
|
||||
}
|
||||
|
||||
; HARD-LABEL: test_itoq_qtoi
|
||||
; HARD: call _Q_lltoq
|
||||
; HARD: call _Q_qtoll
|
||||
; HARD: fitoq
|
||||
; HARD: fqtoi
|
||||
|
||||
; SOFT-LABEL: test_itoq_qtoi
|
||||
; SOFT: call _Q_lltoq
|
||||
; SOFT: call _Q_qtoll
|
||||
; SOFT: call _Q_itoq
|
||||
; SOFT: call _Q_qtoi
|
||||
|
||||
define void @test_itoq_qtoi(i64 %a, i32 %b, i64* %ptr0, fp128* %ptr1) {
|
||||
entry:
|
||||
%0 = sitofp i64 %a to fp128
|
||||
store fp128 %0, fp128* %ptr1, align 8
|
||||
%1 = fptosi fp128 %0 to i64
|
||||
store i64 %1, i64* %ptr0, align 8
|
||||
%2 = sitofp i32 %b to fp128
|
||||
store fp128 %2, fp128* %ptr1, align 8
|
||||
%3 = fptosi fp128 %2 to i32
|
||||
%4 = bitcast i64* %ptr0 to i32*
|
||||
store i32 %3, i32* %4, align 8
|
||||
ret void
|
||||
}
|
||||
|
||||
; HARD-LABEL: test_utoq_qtou
|
||||
; HARD-DAG: call _Q_ulltoq
|
||||
; HARD-DAG: call _Q_qtoull
|
||||
; HARD-DAG: fdtoq
|
||||
; HARD-DAG: fqtoi
|
||||
|
||||
; SOFT-LABEL: test_utoq_qtou
|
||||
; SOFT-DAG: call _Q_ulltoq
|
||||
; SOFT-DAG: call _Q_qtoull
|
||||
; SOFT-DAG: call _Q_utoq
|
||||
; SOFT-DAG: call _Q_qtou
|
||||
|
||||
define void @test_utoq_qtou(i64 %a, i32 %b, i64* %ptr0, fp128* %ptr1) {
|
||||
entry:
|
||||
%0 = uitofp i64 %a to fp128
|
||||
store fp128 %0, fp128* %ptr1, align 8
|
||||
%1 = fptoui fp128 %0 to i64
|
||||
store i64 %1, i64* %ptr0, align 8
|
||||
%2 = uitofp i32 %b to fp128
|
||||
store fp128 %2, fp128* %ptr1, align 8
|
||||
%3 = fptoui fp128 %2 to i32
|
||||
%4 = bitcast i64* %ptr0 to i32*
|
||||
store i32 %3, i32* %4, align 8
|
||||
ret void
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user