add support in llvm/wasm backends

This commit is contained in:
Folkert 2024-01-29 16:16:06 +01:00
parent db3b40a07b
commit 2e648cfdd5
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
2 changed files with 44 additions and 25 deletions

View file

@ -2189,11 +2189,13 @@ fn build_dec_unary_op<'a, 'ctx>(
_layout_interner: &STLayoutInterner<'a>,
_parent: FunctionValue<'ctx>,
arg: BasicValueEnum<'ctx>,
_return_layout: InLayout<'a>,
return_layout: InLayout<'a>,
op: LowLevel,
) -> BasicValueEnum<'ctx> {
use roc_module::low_level::LowLevel::*;
let int_width = || return_layout.to_int_width();
match op {
NumAbs => dec_unary_op(env, bitcode::DEC_ABS, arg),
NumAcos => dec_unary_op(env, bitcode::DEC_ACOS, arg),
@ -2203,6 +2205,10 @@ fn build_dec_unary_op<'a, 'ctx>(
NumSin => dec_unary_op(env, bitcode::DEC_SIN, arg),
NumTan => dec_unary_op(env, bitcode::DEC_TAN, arg),
NumRound => dec_unary_op(env, &bitcode::DEC_ROUND[int_width()], arg),
NumFloor => dec_unary_op(env, &bitcode::DEC_FLOOR[int_width()], arg),
NumCeiling => dec_unary_op(env, &bitcode::DEC_CEILING[int_width()], arg),
_ => {
unreachable!("Unrecognized dec unary operation: {:?}", op);
}
@ -2684,42 +2690,39 @@ fn build_float_unary_op<'a, 'ctx>(
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
_ => internal_error!("Ceiling return layout is not int: {:?}", layout),
};
match float_width {
FloatWidth::F32 => {
call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_CEILING_F32[int_width])
}
FloatWidth::F64 => {
call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_CEILING_F64[int_width])
}
}
let intrinsic = match float_width {
FloatWidth::F32 => &bitcode::NUM_CEILING_F32[int_width],
FloatWidth::F64 => &bitcode::NUM_CEILING_F64[int_width],
};
call_bitcode_fn(env, &[arg.into()], intrinsic)
}
NumFloor => {
let int_width = match layout_interner.get_repr(layout) {
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
_ => internal_error!("Floor return layout is not int: {:?}", layout),
};
match float_width {
FloatWidth::F32 => {
call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_FLOOR_F32[int_width])
}
FloatWidth::F64 => {
call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_FLOOR_F64[int_width])
}
}
let intrinsic = match float_width {
FloatWidth::F32 => &bitcode::NUM_FLOOR_F32[int_width],
FloatWidth::F64 => &bitcode::NUM_FLOOR_F64[int_width],
};
call_bitcode_fn(env, &[arg.into()], intrinsic)
}
NumRound => {
let int_width = match layout_interner.get_repr(layout) {
LayoutRepr::Builtin(Builtin::Int(int_width)) => int_width,
_ => internal_error!("Round return layout is not int: {:?}", layout),
};
match float_width {
FloatWidth::F32 => {
call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_ROUND_F32[int_width])
}
FloatWidth::F64 => {
call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_ROUND_F64[int_width])
}
}
let intrinsic = match float_width {
FloatWidth::F32 => &bitcode::NUM_ROUND_F32[int_width],
FloatWidth::F64 => &bitcode::NUM_ROUND_F64[int_width],
};
call_bitcode_fn(env, &[arg.into()], intrinsic)
}
NumIsNan => call_bitcode_fn(env, &[arg.into()], &bitcode::NUM_IS_NAN[float_width]),
NumIsInfinite => {

View file

@ -1636,6 +1636,7 @@ impl<'a> LowLevelCall<'a> {
match arg_type {
F32 => self.load_args_and_call_zig(backend, &bitcode::NUM_ROUND_F32[width]),
F64 => self.load_args_and_call_zig(backend, &bitcode::NUM_ROUND_F64[width]),
Decimal => self.load_args_and_call_zig(backend, &bitcode::DEC_ROUND[width]),
_ => internal_error!("Invalid argument type for round: {:?}", arg_type),
}
}
@ -1643,6 +1644,14 @@ impl<'a> LowLevelCall<'a> {
self.load_args(backend);
let arg_type = CodeGenNumType::for_symbol(backend, self.arguments[0]);
let ret_type = CodeGenNumType::from(self.ret_layout);
let width = match ret_type {
CodeGenNumType::I32 => IntWidth::I32,
CodeGenNumType::I64 => IntWidth::I64,
CodeGenNumType::I128 => todo!("{:?} for I128", self.lowlevel),
_ => internal_error!("Invalid return type for round: {:?}", ret_type),
};
match (arg_type, self.lowlevel) {
(F32, NumCeiling) => {
backend.code_builder.f32_ceil();
@ -1650,14 +1659,21 @@ impl<'a> LowLevelCall<'a> {
(F64, NumCeiling) => {
backend.code_builder.f64_ceil();
}
(Decimal, NumCeiling) => {
return self.load_args_and_call_zig(backend, &bitcode::DEC_CEILING[width]);
}
(F32, NumFloor) => {
backend.code_builder.f32_floor();
}
(F64, NumFloor) => {
backend.code_builder.f64_floor();
}
(Decimal, NumFloor) => {
return self.load_args_and_call_zig(backend, &bitcode::DEC_FLOOR[width]);
}
_ => internal_error!("Invalid argument type for ceiling: {:?}", arg_type),
}
match (ret_type, arg_type) {
// TODO: unsigned truncation
(I32, F32) => backend.code_builder.i32_trunc_s_f32(),