mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-19 13:06:56 +00:00
[RISCV][GISel] Support fp128 arithmetic and conversion for RV64. (#118707)
We can support these via libcalls in libgcc/compiler-rt or integer operations for fneg/fabs/fcopysign. fp128 values will be passed in two 64-bit GPRs according to the psABI. Supporting RV32 requires sret which is not supported by libcall handling in LegalizerHelper.cpp yet. It doesn't call canLowerReturn.
This commit is contained in:
parent
dba0861cd7
commit
3e0e1c13ce
@ -778,6 +778,11 @@ public:
|
||||
LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) {
|
||||
return actionFor(LegalizeAction::Libcall, Types);
|
||||
}
|
||||
LegalizeRuleSet &libcallFor(bool Pred, std::initializer_list<LLT> Types) {
|
||||
if (!Pred)
|
||||
return *this;
|
||||
return actionFor(LegalizeAction::Libcall, Types);
|
||||
}
|
||||
LegalizeRuleSet &
|
||||
libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
|
||||
return actionFor(LegalizeAction::Libcall, Types);
|
||||
|
@ -491,21 +491,24 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
|
||||
|
||||
// FP Operations
|
||||
|
||||
// FIXME: Support s128 for rv32 when libcall handling is able to use sret.
|
||||
getActionDefinitionsBuilder(
|
||||
{G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FMA, G_FSQRT, G_FMAXNUM, G_FMINNUM})
|
||||
.legalFor(ST.hasStdExtF(), {s32})
|
||||
.legalFor(ST.hasStdExtD(), {s64})
|
||||
.legalFor(ST.hasStdExtZfh(), {s16})
|
||||
.libcallFor({s32, s64});
|
||||
.libcallFor({s32, s64})
|
||||
.libcallFor(ST.is64Bit(), {s128});
|
||||
|
||||
getActionDefinitionsBuilder({G_FNEG, G_FABS})
|
||||
.legalFor(ST.hasStdExtF(), {s32})
|
||||
.legalFor(ST.hasStdExtD(), {s64})
|
||||
.legalFor(ST.hasStdExtZfh(), {s16})
|
||||
.lowerFor({s32, s64});
|
||||
.lowerFor({s32, s64, s128});
|
||||
|
||||
getActionDefinitionsBuilder(G_FREM)
|
||||
.libcallFor({s32, s64})
|
||||
.libcallFor(ST.is64Bit(), {s128})
|
||||
.minScalar(0, s32)
|
||||
.scalarize(0);
|
||||
|
||||
@ -521,19 +524,22 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
|
||||
.legalFor(ST.hasStdExtD(), {{s32, s64}})
|
||||
.legalFor(ST.hasStdExtZfh(), {{s16, s32}})
|
||||
.legalFor(ST.hasStdExtZfh() && ST.hasStdExtD(), {{s16, s64}})
|
||||
.libcallFor({{s32, s64}});
|
||||
.libcallFor({{s32, s64}})
|
||||
.libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}});
|
||||
getActionDefinitionsBuilder(G_FPEXT)
|
||||
.legalFor(ST.hasStdExtD(), {{s64, s32}})
|
||||
.legalFor(ST.hasStdExtZfh(), {{s32, s16}})
|
||||
.legalFor(ST.hasStdExtZfh() && ST.hasStdExtD(), {{s64, s16}})
|
||||
.libcallFor({{s64, s32}});
|
||||
.libcallFor({{s64, s32}})
|
||||
.libcallFor(ST.is64Bit(), {{s128, s32}, {s128, s64}});
|
||||
|
||||
getActionDefinitionsBuilder(G_FCMP)
|
||||
.legalFor(ST.hasStdExtF(), {{sXLen, s32}})
|
||||
.legalFor(ST.hasStdExtD(), {{sXLen, s64}})
|
||||
.legalFor(ST.hasStdExtZfh(), {{sXLen, s16}})
|
||||
.clampScalar(0, sXLen, sXLen)
|
||||
.libcallFor({{sXLen, s32}, {sXLen, s64}});
|
||||
.libcallFor({{sXLen, s32}, {sXLen, s64}})
|
||||
.libcallFor(ST.is64Bit(), {{sXLen, s128}});
|
||||
|
||||
// TODO: Support vector version of G_IS_FPCLASS.
|
||||
getActionDefinitionsBuilder(G_IS_FPCLASS)
|
||||
@ -546,7 +552,7 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
|
||||
.legalFor(ST.hasStdExtF(), {s32})
|
||||
.legalFor(ST.hasStdExtD(), {s64})
|
||||
.legalFor(ST.hasStdExtZfh(), {s16})
|
||||
.lowerFor({s32, s64});
|
||||
.lowerFor({s32, s64, s128});
|
||||
|
||||
getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
|
||||
.legalFor(ST.hasStdExtF(), {{sXLen, s32}})
|
||||
@ -558,7 +564,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
|
||||
.widenScalarToNextPow2(0)
|
||||
.minScalar(0, s32)
|
||||
.libcallFor({{s32, s32}, {s64, s32}, {s32, s64}, {s64, s64}})
|
||||
.libcallFor(ST.is64Bit(), {{s128, s32}, {s128, s64}});
|
||||
.libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}}) // FIXME RV32.
|
||||
.libcallFor(ST.is64Bit(), {{s128, s32}, {s128, s64}, {s128, s128}});
|
||||
|
||||
getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
|
||||
.legalFor(ST.hasStdExtF(), {{s32, sXLen}})
|
||||
@ -579,7 +586,8 @@ RISCVLegalizerInfo::RISCVLegalizerInfo(const RISCVSubtarget &ST)
|
||||
// Otherwise only promote to s32 since we have si libcalls.
|
||||
.minScalar(1, s32)
|
||||
.libcallFor({{s32, s32}, {s64, s32}, {s32, s64}, {s64, s64}})
|
||||
.libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}});
|
||||
.libcallFor(ST.is64Bit(), {{s128, s32}, {s128, s64}}) // FIXME RV32.
|
||||
.libcallFor(ST.is64Bit(), {{s32, s128}, {s64, s128}, {s128, s128}});
|
||||
|
||||
// FIXME: We can do custom inline expansion like SelectionDAG.
|
||||
// FIXME: Legal with Zfa.
|
||||
|
538
llvm/test/CodeGen/RISCV/GlobalISel/fp128.ll
Normal file
538
llvm/test/CodeGen/RISCV/GlobalISel/fp128.ll
Normal file
@ -0,0 +1,538 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=riscv64 -global-isel < %s \
|
||||
; RUN: | FileCheck -check-prefixes=CHECK,RV64I %s
|
||||
; RUN: llc -mtriple=riscv64 -global-isel -mattr=+d < %s \
|
||||
; RUN: | FileCheck -check-prefixes=CHECK,RV64D %s
|
||||
|
||||
; FIXME: Support RV32.
|
||||
|
||||
define fp128 @fadd(fp128 %x, fp128 %y) nounwind {
|
||||
; CHECK-LABEL: fadd:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __addtf3
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fadd fp128 %x, %y
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @fsub(fp128 %x, fp128 %y) nounwind {
|
||||
; CHECK-LABEL: fsub:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __subtf3
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fsub fp128 %x, %y
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @fmul(fp128 %x, fp128 %y) nounwind {
|
||||
; CHECK-LABEL: fmul:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __multf3
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fmul fp128 %x, %y
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @fdiv(fp128 %x, fp128 %y) nounwind {
|
||||
; CHECK-LABEL: fdiv:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __divtf3
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fdiv fp128 %x, %y
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @frem(fp128 %x, fp128 %y) nounwind {
|
||||
; CHECK-LABEL: frem:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call fmodl
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = frem fp128 %x, %y
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @fma(fp128 %x, fp128 %y, fp128 %z) nounwind {
|
||||
; CHECK-LABEL: fma:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call fmal
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = call fp128 @llvm.fma.f128(fp128 %x, fp128 %y, fp128 %z)
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @fneg(fp128 %x) {
|
||||
; CHECK-LABEL: fneg:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: li a2, -1
|
||||
; CHECK-NEXT: slli a2, a2, 63
|
||||
; CHECK-NEXT: xor a1, a1, a2
|
||||
; CHECK-NEXT: ret
|
||||
%a = fneg fp128 %x
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @fabs(fp128 %x) {
|
||||
; CHECK-LABEL: fabs:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: li a2, -1
|
||||
; CHECK-NEXT: srli a2, a2, 1
|
||||
; CHECK-NEXT: and a1, a1, a2
|
||||
; CHECK-NEXT: ret
|
||||
%a = call fp128 @llvm.fabs.f128(fp128 %x)
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @fcopysign(fp128 %x, fp128 %y) {
|
||||
; CHECK-LABEL: fcopysign:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: li a2, -1
|
||||
; CHECK-NEXT: slli a4, a2, 63
|
||||
; CHECK-NEXT: srli a2, a2, 1
|
||||
; CHECK-NEXT: and a1, a1, a2
|
||||
; CHECK-NEXT: and a3, a3, a4
|
||||
; CHECK-NEXT: or a1, a1, a3
|
||||
; CHECK-NEXT: ret
|
||||
%a = call fp128 @llvm.copysign.f128(fp128 %x, fp128 %y)
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define i1 @fcmp(fp128 %x, fp128 %y) nounwind {
|
||||
; CHECK-LABEL: fcmp:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __eqtf2
|
||||
; CHECK-NEXT: slli a0, a0, 32
|
||||
; CHECK-NEXT: srli a0, a0, 32
|
||||
; CHECK-NEXT: seqz a0, a0
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fcmp oeq fp128 %x, %y
|
||||
ret i1 %a
|
||||
}
|
||||
|
||||
define fp128 @constant(fp128 %x) nounwind {
|
||||
; CHECK-LABEL: constant:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: lui a2, %hi(.LCPI10_0)
|
||||
; CHECK-NEXT: addi a3, a2, %lo(.LCPI10_0)
|
||||
; CHECK-NEXT: ld a2, 0(a3)
|
||||
; CHECK-NEXT: ld a3, 8(a3)
|
||||
; CHECK-NEXT: call __addtf3
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fadd fp128 %x, 0xL00000000000000007FFF000000000000
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @fpext_f32(float %x, float %y) nounwind {
|
||||
; RV64I-LABEL: fpext_f32:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: addi sp, sp, -16
|
||||
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; RV64I-NEXT: call __addsf3
|
||||
; RV64I-NEXT: call __extendsftf2
|
||||
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; RV64I-NEXT: addi sp, sp, 16
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64D-LABEL: fpext_f32:
|
||||
; RV64D: # %bb.0:
|
||||
; RV64D-NEXT: addi sp, sp, -16
|
||||
; RV64D-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; RV64D-NEXT: fadd.s fa0, fa0, fa1
|
||||
; RV64D-NEXT: call __extendsftf2
|
||||
; RV64D-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; RV64D-NEXT: addi sp, sp, 16
|
||||
; RV64D-NEXT: ret
|
||||
%a = fadd float %x, %y
|
||||
%b = fpext float %a to fp128
|
||||
ret fp128 %b
|
||||
}
|
||||
|
||||
define fp128 @fpext_f64(double %x, double %y) nounwind {
|
||||
; RV64I-LABEL: fpext_f64:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: addi sp, sp, -16
|
||||
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; RV64I-NEXT: call __adddf3
|
||||
; RV64I-NEXT: call __extenddftf2
|
||||
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; RV64I-NEXT: addi sp, sp, 16
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64D-LABEL: fpext_f64:
|
||||
; RV64D: # %bb.0:
|
||||
; RV64D-NEXT: addi sp, sp, -16
|
||||
; RV64D-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; RV64D-NEXT: fadd.d fa0, fa0, fa1
|
||||
; RV64D-NEXT: call __extenddftf2
|
||||
; RV64D-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; RV64D-NEXT: addi sp, sp, 16
|
||||
; RV64D-NEXT: ret
|
||||
%a = fadd double %x, %y
|
||||
%b = fpext double %a to fp128
|
||||
ret fp128 %b
|
||||
}
|
||||
|
||||
define float @fptrunc_f32(fp128 %x, float %y) nounwind {
|
||||
; RV64I-LABEL: fptrunc_f32:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: addi sp, sp, -16
|
||||
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
|
||||
; RV64I-NEXT: mv s0, a2
|
||||
; RV64I-NEXT: call __trunctfsf2
|
||||
; RV64I-NEXT: mv a1, s0
|
||||
; RV64I-NEXT: call __addsf3
|
||||
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
|
||||
; RV64I-NEXT: addi sp, sp, 16
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64D-LABEL: fptrunc_f32:
|
||||
; RV64D: # %bb.0:
|
||||
; RV64D-NEXT: addi sp, sp, -16
|
||||
; RV64D-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; RV64D-NEXT: fsd fs0, 0(sp) # 8-byte Folded Spill
|
||||
; RV64D-NEXT: fmv.s fs0, fa0
|
||||
; RV64D-NEXT: call __trunctfsf2
|
||||
; RV64D-NEXT: fadd.s fa0, fa0, fs0
|
||||
; RV64D-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; RV64D-NEXT: fld fs0, 0(sp) # 8-byte Folded Reload
|
||||
; RV64D-NEXT: addi sp, sp, 16
|
||||
; RV64D-NEXT: ret
|
||||
%a = fptrunc fp128 %x to float
|
||||
%b = fadd float %a, %y
|
||||
ret float %b
|
||||
}
|
||||
|
||||
define double @fptrunc_f64(fp128 %x, double %y) nounwind {
|
||||
; RV64I-LABEL: fptrunc_f64:
|
||||
; RV64I: # %bb.0:
|
||||
; RV64I-NEXT: addi sp, sp, -16
|
||||
; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; RV64I-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
|
||||
; RV64I-NEXT: mv s0, a2
|
||||
; RV64I-NEXT: call __trunctfdf2
|
||||
; RV64I-NEXT: mv a1, s0
|
||||
; RV64I-NEXT: call __adddf3
|
||||
; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; RV64I-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
|
||||
; RV64I-NEXT: addi sp, sp, 16
|
||||
; RV64I-NEXT: ret
|
||||
;
|
||||
; RV64D-LABEL: fptrunc_f64:
|
||||
; RV64D: # %bb.0:
|
||||
; RV64D-NEXT: addi sp, sp, -16
|
||||
; RV64D-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; RV64D-NEXT: fsd fs0, 0(sp) # 8-byte Folded Spill
|
||||
; RV64D-NEXT: fmv.d fs0, fa0
|
||||
; RV64D-NEXT: call __trunctfdf2
|
||||
; RV64D-NEXT: fadd.d fa0, fa0, fs0
|
||||
; RV64D-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; RV64D-NEXT: fld fs0, 0(sp) # 8-byte Folded Reload
|
||||
; RV64D-NEXT: addi sp, sp, 16
|
||||
; RV64D-NEXT: ret
|
||||
%a = fptrunc fp128 %x to double
|
||||
%b = fadd double %a, %y
|
||||
ret double %b
|
||||
}
|
||||
|
||||
define i8 @fptosi_i8(fp128 %x) nounwind {
|
||||
; CHECK-LABEL: fptosi_i8:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __fixtfsi
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fptosi fp128 %x to i8
|
||||
ret i8 %a
|
||||
}
|
||||
|
||||
define i16 @fptosi_i16(fp128 %x) nounwind {
|
||||
; CHECK-LABEL: fptosi_i16:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __fixtfsi
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fptosi fp128 %x to i16
|
||||
ret i16 %a
|
||||
}
|
||||
|
||||
define i32 @fptosi_i32(fp128 %x) nounwind {
|
||||
; CHECK-LABEL: fptosi_i32:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __fixtfsi
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fptosi fp128 %x to i32
|
||||
ret i32 %a
|
||||
}
|
||||
|
||||
define i64 @fptosi_i64(fp128 %x) nounwind {
|
||||
; CHECK-LABEL: fptosi_i64:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __fixtfdi
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fptosi fp128 %x to i64
|
||||
ret i64 %a
|
||||
}
|
||||
|
||||
define i128 @fptosi_i128(fp128 %x) nounwind {
|
||||
; CHECK-LABEL: fptosi_i128:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __fixtfti
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fptosi fp128 %x to i128
|
||||
ret i128 %a
|
||||
}
|
||||
|
||||
define i8 @fptoui_i8(fp128 %x) nounwind {
|
||||
; CHECK-LABEL: fptoui_i8:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __fixunstfsi
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fptoui fp128 %x to i8
|
||||
ret i8 %a
|
||||
}
|
||||
|
||||
define i16 @fptoui_i16(fp128 %x) nounwind {
|
||||
; CHECK-LABEL: fptoui_i16:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __fixunstfsi
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fptoui fp128 %x to i16
|
||||
ret i16 %a
|
||||
}
|
||||
|
||||
define i32 @fptoui_i32(fp128 %x) nounwind {
|
||||
; CHECK-LABEL: fptoui_i32:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __fixunstfsi
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fptoui fp128 %x to i32
|
||||
ret i32 %a
|
||||
}
|
||||
|
||||
define i64 @fptoui_i64(fp128 %x) nounwind {
|
||||
; CHECK-LABEL: fptoui_i64:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __fixunstfdi
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fptoui fp128 %x to i64
|
||||
ret i64 %a
|
||||
}
|
||||
|
||||
define i128 @fptoui_i128(fp128 %x) nounwind {
|
||||
; CHECK-LABEL: fptoui_i128:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __fixunstfti
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = fptoui fp128 %x to i128
|
||||
ret i128 %a
|
||||
}
|
||||
|
||||
define fp128 @sitofp_i8(i8 %x) nounwind {
|
||||
; CHECK-LABEL: sitofp_i8:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: slli a0, a0, 56
|
||||
; CHECK-NEXT: srai a0, a0, 56
|
||||
; CHECK-NEXT: call __floatsitf
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = sitofp i8 %x to fp128
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @sitofp_i16(i16 %x) nounwind {
|
||||
; CHECK-LABEL: sitofp_i16:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: slli a0, a0, 48
|
||||
; CHECK-NEXT: srai a0, a0, 48
|
||||
; CHECK-NEXT: call __floatsitf
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = sitofp i16 %x to fp128
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @sitofp_i32(i32 %x) nounwind {
|
||||
; CHECK-LABEL: sitofp_i32:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: sext.w a0, a0
|
||||
; CHECK-NEXT: call __floatsitf
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = sitofp i32 %x to fp128
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @sitofp_i64(i64 %x) nounwind {
|
||||
; CHECK-LABEL: sitofp_i64:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __floatditf
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = sitofp i64 %x to fp128
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @sitofp_i128(i128 %x) nounwind {
|
||||
; CHECK-LABEL: sitofp_i128:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __floattitf
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = sitofp i128 %x to fp128
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @uitofp_i8(i8 %x) nounwind {
|
||||
; CHECK-LABEL: uitofp_i8:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: andi a0, a0, 255
|
||||
; CHECK-NEXT: call __floatunsitf
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = uitofp i8 %x to fp128
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @uitofp_i16(i16 %x) nounwind {
|
||||
; CHECK-LABEL: uitofp_i16:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: lui a1, 16
|
||||
; CHECK-NEXT: addiw a1, a1, -1
|
||||
; CHECK-NEXT: and a0, a0, a1
|
||||
; CHECK-NEXT: call __floatunsitf
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = uitofp i16 %x to fp128
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @uitofp_i32(i32 %x) nounwind {
|
||||
; CHECK-LABEL: uitofp_i32:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: sext.w a0, a0
|
||||
; CHECK-NEXT: call __floatunsitf
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = uitofp i32 %x to fp128
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @uitofp_i64(i64 %x) nounwind {
|
||||
; CHECK-LABEL: uitofp_i64:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __floatunditf
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = uitofp i64 %x to fp128
|
||||
ret fp128 %a
|
||||
}
|
||||
|
||||
define fp128 @uitofp_i128(i128 %x) nounwind {
|
||||
; CHECK-LABEL: uitofp_i128:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: addi sp, sp, -16
|
||||
; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
|
||||
; CHECK-NEXT: call __floatuntitf
|
||||
; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
|
||||
; CHECK-NEXT: addi sp, sp, 16
|
||||
; CHECK-NEXT: ret
|
||||
%a = uitofp i128 %x to fp128
|
||||
ret fp128 %a
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user