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);
+
// Sparc has no select or setcc: expand to SELECT_CC.
setOperationAction(ISD::SELECT, MVT::i32, Expand);
setOperationAction(ISD::SELECT, MVT::f32, Expand);
setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom);
setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);
- setOperationAction(ISD::BITCAST, MVT::i32, Custom);
- setOperationAction(ISD::BITCAST, MVT::f32, Custom);
-
if (Subtarget->is64Bit()) {
setOperationAction(ISD::ADDC, MVT::i64, Custom);
setOperationAction(ISD::ADDE, MVT::i64, Custom);
setOperationAction(ISD::SUBC, MVT::i64, Custom);
setOperationAction(ISD::SUBE, MVT::i64, Custom);
+ setOperationAction(ISD::BITCAST, MVT::f64, Expand);
+ setOperationAction(ISD::BITCAST, MVT::i64, Expand);
setOperationAction(ISD::SELECT, MVT::i64, Expand);
setOperationAction(ISD::SETCC, MVT::i64, Expand);
setOperationAction(ISD::BR_CC, MVT::i64, Custom);
setOperationAction(ISD::ROTL , MVT::i64, Expand);
setOperationAction(ISD::ROTR , MVT::i64, Expand);
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Custom);
-
- setOperationAction(ISD::BITCAST, MVT::i64, Custom);
- setOperationAction(ISD::BITCAST, MVT::f64, Custom);
}
// ATOMICs.
1);
}
-SDValue SparcTargetLowering::LowerBITCAST(SDValue Op, SelectionDAG &DAG) const {
- SDLoc dl(Op);
- EVT SrcVT = Op.getOperand(0).getValueType();
-
- EVT DstVT = Op.getValueType();
-
- if (Subtarget->isVIS3()) {
- if (DstVT == MVT::f32 && SrcVT == MVT::i32) {
- return Op; // Legal
- } else if (DstVT == MVT::f64 && SrcVT == MVT::i64) {
- return (Subtarget->is64Bit())
- ? Op
- : SDValue(); // Legal on 64 bit, otherwise Expand
- } else if (DstVT == MVT::i64 && SrcVT == MVT::f64) {
- return (Subtarget->is64Bit())
- ? Op
- : SDValue(); // Legal on 64 bit, otherwise Expand
- }
- }
-
- // Expand
- return SDValue();
-}
-
-SDValue SparcTargetLowering::LowerUINT_TO_FP(SDValue Op,
- SelectionDAG &DAG) const {
+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 f128 operations to fp128 ABI calls.
- if (Op.getValueType() == MVT::f128 &&
- (!Subtarget->hasHardQuad() || !isTypeLegal(OpVT))) {
- return LowerF128Op(Op, DAG,
- getLibcallName(OpVT == MVT::i32
- ? RTLIB::UINTTOFP_I32_F128
- : RTLIB::UINTTOFP_I64_F128),
- 1);
- }
-
- // Since UINT_TO_FP is legal (it's marked custom), dag combiner won't
- // optimize it to a SINT_TO_FP when the sign bit is known zero. Perform
- // the optimization here.
- if (DAG.SignBitIsZero(Op.getOperand(0))) {
-
- EVT floatVT = MVT::f32;
- unsigned IntToFloatOpcode = SPISD::ITOF;
-
- if (OpVT == MVT::i64) {
- floatVT = MVT::f64;
- IntToFloatOpcode = SPISD::XTOF;
- }
-
- // Convert the int value to FP in an FP register.
- SDValue FloatTmp = DAG.getNode(ISD::BITCAST, dl, floatVT, Op.getOperand(0));
-
- return DAG.getNode(IntToFloatOpcode, dl, Op.getValueType(), FloatTmp);
- }
-
- if (OpVT == MVT::i32 && Subtarget->is64Bit()) {
-
- SDValue Int64Tmp =
- DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i64, Op.getOperand(0));
-
- SDValue Float64Tmp = DAG.getNode(ISD::BITCAST, dl, MVT::f64, Int64Tmp);
-
- return DAG.getNode(SPISD::XTOF, dl, Op.getValueType(), Float64Tmp);
- }
+ // Expand if it does not involve f128 or the target has support for
+ // quad floating point instructions and the operand type is legal.
+ if (Op.getValueType() != MVT::f128 || (hasHardQuad && TLI.isTypeLegal(OpVT)))
+ return SDValue();
- return SDValue();
+ return TLI.LowerF128Op(Op, DAG,
+ TLI.getLibcallName(OpVT == MVT::i32
+ ? RTLIB::UINTTOFP_I32_F128
+ : RTLIB::UINTTOFP_I64_F128),
+ 1);
}
static SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG,
hasHardQuad);
case ISD::FP_TO_UINT: return LowerFP_TO_UINT(Op, DAG, *this,
hasHardQuad);
- case ISD::UINT_TO_FP: return LowerUINT_TO_FP(Op, DAG);
+ case ISD::UINT_TO_FP: return LowerUINT_TO_FP(Op, DAG, *this,
+ hasHardQuad);
case ISD::BR_CC: return LowerBR_CC(Op, DAG, *this,
hasHardQuad);
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG, *this,
case ISD::ATOMIC_LOAD:
case ISD::ATOMIC_STORE: return LowerATOMIC_LOAD_STORE(Op, DAG);
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
- case ISD::BITCAST: return LowerBITCAST(Op, DAG);
}
}
(ins I64Regs:$rs2), "lzcnt $rs2, $rd", []>;
let rs1 = 0 in {
-def MOVSTOSW : VISInstFormat<0b100010011, (outs I64Regs:$rd), (ins FPRegs:$rs2),
- "movstosw $rs2, $rd",
- [(set I64Regs:$rd, (sext (i32 (bitconvert FPRegs:$rs2))))]>;
-def MOVSTOUW : VISInstFormat<0b100010001, (outs I64Regs:$rd), (ins FPRegs:$rs2),
- "movstouw $rs2, $rd",
- [(set I64Regs:$rd, (zext (i32 (bitconvert FPRegs:$rs2))))]>;
-def MOVDTOX : VISInstFormat<0b100010000, (outs I64Regs:$rd), (ins DFPRegs:$rs2),
- "movdtox $rs2, $rd",
- [(set I64Regs:$rd, (bitconvert DFPRegs:$rs2))]>;
-def MOVWTOS : VISInstFormat<0b100011001, (outs FPRegs:$rd), (ins IntRegs:$rs2),
- "movwtos $rs2, $rd",
- [(set FPRegs:$rd, (bitconvert i32:$rs2))]>;
-def MOVXTOD : VISInstFormat<0b100011000, (outs DFPRegs:$rd), (ins I64Regs:$rs2),
- "movxtod $rs2, $rd",
- [(set DFPRegs:$rd, (bitconvert I64Regs:$rs2))]>;
+def MOVSTOSW : VISInstFormat<0b100010011, (outs I64Regs:$rd),
+ (ins DFPRegs:$rs2), "movstosw $rs2, $rd", []>;
+def MOVSTOUW : VISInstFormat<0b100010001, (outs I64Regs:$rd),
+ (ins DFPRegs:$rs2), "movstouw $rs2, $rd", []>;
+def MOVDTOX : VISInstFormat<0b100010000, (outs I64Regs:$rd),
+ (ins DFPRegs:$rs2), "movdtox $rs2, $rd", []>;
+def MOVWTOS : VISInstFormat<0b100011001, (outs DFPRegs:$rd),
+ (ins I64Regs:$rs2), "movdtox $rs2, $rd", []>;
+def MOVXTOD : VISInstFormat<0b100011000, (outs DFPRegs:$rd),
+ (ins I64Regs:$rs2), "movdtox $rs2, $rd", []>;
}
def PDISTN : VISInst<0b000111111, "pdistn">;
; 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
-; RUN: llc -march=sparc -mcpu=niagara4 < %s | FileCheck %s -check-prefix=VIS3
-; RUN: llc -march=sparcv9 -mcpu=niagara4 < %s | FileCheck %s -check-prefix=VIS3-64
; V8-LABEL: test_neg:
; V8: call get_double
; V9: fstoi
; SPARC64-LABEL: test_utos_stou
-; SPARC64: fxtos
+; SPARC64: fdtos
; SPARC64: fstoi
define void @test_utos_stou(i32 %a, i32* %ptr0, float* %ptr1) {
; SPARC64-NOT: fitod
; SPARC64: fdtoi
-; VIS3-64-LABEL: test_utod_dtou
-; VIS3-64: movxtod
-
define void @test_utod_dtou(i32 %a, double %b, i32* %ptr0, double* %ptr1) {
entry:
%0 = uitofp i32 %a to double
store i32 %1, i32* %ptr0, align 8
ret void
}
-
-; V8-LABEL: test_ustod
-; V8: fitod
-
-; VIS3-LABEL: test_ustod
-; VIS3: movwtos
-
-define double @test_ustod(i16 zeroext) {
- %2 = uitofp i16 %0 to double
- ret double %2
-}
-
-; V8-LABEL: test_ustos
-; V8: fitos
-
-; VIS3-LABEL: test_ustos
-; VIS3: movwtos
-
-define float @test_ustos(i16 zeroext) {
- %2 = uitofp i16 %0 to float
- ret float %2
-}
-
-; check for movwtos used for bitcast
-;
-; VIS3-LABEL: test_bitcast_utos
-; VIS3:movwtos
-
-define float @test_bitcast_utos(i32 ) {
- %2 = bitcast i32 %0 to float
- ret float %2
-}
-
-
-; check for movxtod used for bitcast
-;
-; VIS3-64-LABEL: test_bitcast_uxtod
-; VIS3-64:movxtod
-
-define double @test_bitcast_uxtod(i64 ) {
- %2 = bitcast i64 %0 to double
- ret double %2
-}
-
-
-