mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 19:12:56 +02:00
[WebAssembly] Support f16 libcalls
Add support for f16 libcalls in WebAssembly. This entails adding signatures for the remaining F16 libcalls, and renaming gnu_f2h_ieee/gnu_h2f_ieee to truncsfhf2/extendhfsf2 for consistency between f32 and f64/f128 (compiler-rt already supports this). Differential Revision: https://reviews.llvm.org/D61287 Reviewer: dschuff llvm-svn: 359600
This commit is contained in:
parent
a8d5ccc21f
commit
cba920454e
@ -271,6 +271,11 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
|
||||
MaxStoresPerMemsetOptSize = 1;
|
||||
}
|
||||
|
||||
// Override the __gnu_f2h_ieee/__gnu_h2f_ieee names so that the f32 name is
|
||||
// consistent with the f64 and f128 names.
|
||||
setLibcallName(RTLIB::FPEXT_F16_F32, "__extendhfsf2");
|
||||
setLibcallName(RTLIB::FPROUND_F32_F16, "__truncsfhf2");
|
||||
|
||||
// Always convert switches to br_tables unless there is only one case, which
|
||||
// is equivalent to a simple branch. This reduces code size for wasm, and we
|
||||
// defer possible jump table optimizations to the VM.
|
||||
|
@ -51,6 +51,8 @@ enum RuntimeLibcallSignature {
|
||||
f64_func_f64_i32,
|
||||
f64_func_i64_i64,
|
||||
i16_func_f32,
|
||||
i16_func_f64,
|
||||
i16_func_i64_i64,
|
||||
i8_func_i8_i8,
|
||||
func_f32_iPTR_iPTR,
|
||||
func_f64_iPTR_iPTR,
|
||||
@ -228,13 +230,15 @@ struct RuntimeLibcallSignatureTable {
|
||||
Table[RTLIB::FMAX_F128] = func_iPTR_i64_i64_i64_i64;
|
||||
|
||||
// Conversion
|
||||
// All F80 and PPCF128 routines are unspported.
|
||||
// All F80 and PPCF128 routines are unsupported.
|
||||
Table[RTLIB::FPEXT_F64_F128] = func_iPTR_f64;
|
||||
Table[RTLIB::FPEXT_F32_F128] = func_iPTR_f32;
|
||||
Table[RTLIB::FPEXT_F32_F64] = f64_func_f32;
|
||||
Table[RTLIB::FPEXT_F16_F32] = f32_func_i16;
|
||||
Table[RTLIB::FPROUND_F32_F16] = i16_func_f32;
|
||||
Table[RTLIB::FPROUND_F64_F16] = i16_func_f64;
|
||||
Table[RTLIB::FPROUND_F64_F32] = f32_func_f64;
|
||||
Table[RTLIB::FPROUND_F128_F16] = i16_func_i64_i64;
|
||||
Table[RTLIB::FPROUND_F128_F32] = f32_func_i64_i64;
|
||||
Table[RTLIB::FPROUND_F128_F64] = f64_func_i64_i64;
|
||||
Table[RTLIB::FPTOSINT_F32_I32] = i32_func_f32;
|
||||
@ -482,6 +486,10 @@ struct StaticLibcallNameMap {
|
||||
Map[NameLibcall.first] = NameLibcall.second;
|
||||
}
|
||||
}
|
||||
// Override the __gnu_f2h_ieee/__gnu_h2f_ieee names so that the f32 name is
|
||||
// consistent with the f64 and f128 names.
|
||||
Map["__extendhfsf2"] = RTLIB::FPEXT_F16_F32;
|
||||
Map["__truncsfhf2"] = RTLIB::FPROUND_F32_F16;
|
||||
}
|
||||
};
|
||||
|
||||
@ -595,6 +603,15 @@ void llvm::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
|
||||
Rets.push_back(wasm::ValType::I32);
|
||||
Params.push_back(wasm::ValType::F32);
|
||||
break;
|
||||
case i16_func_f64:
|
||||
Rets.push_back(wasm::ValType::I32);
|
||||
Params.push_back(wasm::ValType::F64);
|
||||
break;
|
||||
case i16_func_i64_i64:
|
||||
Rets.push_back(wasm::ValType::I32);
|
||||
Params.push_back(wasm::ValType::I64);
|
||||
Params.push_back(wasm::ValType::I64);
|
||||
break;
|
||||
case i8_func_i8_i8:
|
||||
Rets.push_back(wasm::ValType::I32);
|
||||
Params.push_back(wasm::ValType::I32);
|
||||
|
@ -6,22 +6,65 @@
|
||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||
target triple = "wasm32-unknown-unknown"
|
||||
|
||||
; CHECK-LABEL: demote:
|
||||
; CHECK-NEXT: .functype demote (f32) -> (f32){{$}}
|
||||
; CHECK-LABEL: demote.f32:
|
||||
; CHECK-NEXT: .functype demote.f32 (f32) -> (f32){{$}}
|
||||
; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
|
||||
; CHECK-NEXT: i32.call $push[[L1:[0-9]+]]=, __gnu_f2h_ieee, $pop[[L0]]{{$}}
|
||||
; CHECK-NEXT: f32.call $push[[L2:[0-9]+]]=, __gnu_h2f_ieee, $pop[[L1]]{{$}}
|
||||
; CHECK-NEXT: i32.call $push[[L1:[0-9]+]]=, __truncsfhf2, $pop[[L0]]{{$}}
|
||||
; CHECK-NEXT: f32.call $push[[L2:[0-9]+]]=, __extendhfsf2, $pop[[L1]]{{$}}
|
||||
; CHECK-NEXT: return $pop[[L2]]{{$}}
|
||||
define half @demote(float %f) {
|
||||
define half @demote.f32(float %f) {
|
||||
%t = fptrunc float %f to half
|
||||
ret half %t
|
||||
}
|
||||
|
||||
; CHECK-LABEL: promote:
|
||||
; CHECK-NEXT: .functype promote (f32) -> (f32){{$}}
|
||||
; CHECK-LABEL: promote.f32:
|
||||
; CHECK-NEXT: .functype promote.f32 (f32) -> (f32){{$}}
|
||||
; CHECK-NEXT: local.get $push0=, 0{{$}}
|
||||
; CHECK-NEXT: return $pop0{{$}}
|
||||
define float @promote(half %f) {
|
||||
define float @promote.f32(half %f) {
|
||||
%t = fpext half %f to float
|
||||
ret float %t
|
||||
}
|
||||
|
||||
; CHECK-LABEL: demote.f64:
|
||||
; CHECK-NEXT: .functype demote.f64 (f64) -> (f32){{$}}
|
||||
; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
|
||||
; CHECK-NEXT: i32.call $push[[L1:[0-9]+]]=, __truncdfhf2, $pop[[L0]]{{$}}
|
||||
; CHECK-NEXT: f32.call $push[[L2:[0-9]+]]=, __extendhfsf2, $pop[[L1]]{{$}}
|
||||
; CHECK-NEXT: return $pop[[L2]]{{$}}
|
||||
define half @demote.f64(double %f) {
|
||||
%t = fptrunc double %f to half
|
||||
ret half %t
|
||||
}
|
||||
|
||||
; CHECK-LABEL: promote.f64:
|
||||
; CHECK-NEXT: .functype promote.f64 (f32) -> (f64){{$}}
|
||||
; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
|
||||
; CHECK-NEXT: f64.promote_f32 $push[[L1:[0-9]+]]=, $pop[[L0]]{{$}}
|
||||
; CHECK-NEXT: return $pop[[L1]]{{$}}
|
||||
define double @promote.f64(half %f) {
|
||||
%t = fpext half %f to double
|
||||
ret double %t
|
||||
}
|
||||
|
||||
; CHECK-LABEL: demote.f128:
|
||||
; CHECK-NEXT: .functype demote.f128 (i64, i64) -> (f32){{$}}
|
||||
; CHECK-NEXT: local.get $push[[L0:[0-9]+]]=, 0{{$}}
|
||||
; CHECK-NEXT: local.get $push[[L1:[0-9]+]]=, 1{{$}}
|
||||
; CHECK-NEXT: i32.call $push[[L2:[0-9]+]]=, __trunctfhf2, $pop[[L0]], $pop[[L1]]{{$}}
|
||||
; CHECK-NEXT: f32.call $push[[L3:[0-9]+]]=, __extendhfsf2, $pop[[L2]]{{$}}
|
||||
; CHECK-NEXT: return $pop[[L3]]{{$}}
|
||||
define half @demote.f128(fp128 %f) {
|
||||
%t = fptrunc fp128 %f to half
|
||||
ret half %t
|
||||
}
|
||||
|
||||
; CHECK-LABEL: promote.f128:
|
||||
; CHECK-NEXT: .functype promote.f128 (i32, f32) -> (){{$}}
|
||||
; CHECK: call __extendsftf2
|
||||
; CHECK: i64.store
|
||||
; CHECK: i64.store
|
||||
define fp128 @promote.f128(half %f) {
|
||||
%t = fpext half %f to fp128
|
||||
ret fp128 %t
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user