fix most dev backend tests

This commit is contained in:
Folkert 2023-09-11 23:08:46 +02:00
parent 5ca3d3bcf1
commit 89472bf495
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
7 changed files with 120 additions and 53 deletions

View file

@ -1125,6 +1125,23 @@ pub fn fromF64C(arg: f64) callconv(.C) i128 {
return if (@call(.{ .modifier = always_inline }, RocDec.fromF64, .{arg})) |dec| dec.num else @panic("TODO runtime exception failing convert f64 to RocDec");
}
pub fn exportFromInt(comptime T: type, comptime name: []const u8) void {
comptime var f = struct {
fn func(self: T) callconv(.C) i128 {
const this = @intCast(i128, self);
var result: i128 = undefined;
if (@mulWithOverflow(i128, this, RocDec.one_point_zero_i128, &result)) {
@panic("TODO runtime exception failing convert integer to RocDec");
} else {
return result;
}
}
}.func;
@export(f, .{ .name = name ++ @typeName(T), .linkage = .Strong });
}
pub fn fromU64C(arg: u64) callconv(.C) i128 {
return @call(.{ .modifier = always_inline }, RocDec.fromU64, .{arg}).toI128();
}

View file

@ -39,6 +39,10 @@ comptime {
exportDecFn(dec.mulC, "mul_with_overflow");
exportDecFn(dec.mulOrPanicC, "mul_or_panic");
exportDecFn(dec.mulSaturatedC, "mul_saturated");
inline for (INTEGERS) |T| {
dec.exportFromInt(T, ROC_BUILTINS ++ ".dec.from_int.");
}
}
// List Module

View file

@ -390,6 +390,7 @@ pub const DEC_FROM_STR: &str = "roc_builtins.dec.from_str";
pub const DEC_TO_STR: &str = "roc_builtins.dec.to_str";
pub const DEC_FROM_F64: &str = "roc_builtins.dec.from_f64";
pub const DEC_FROM_U64: &str = "roc_builtins.dec.from_u64";
pub const DEC_FROM_INT: IntrinsicName = int_intrinsic!("roc_builtins.dec.from_int");
pub const DEC_TO_I128: &str = "roc_builtins.dec.to_i128";
pub const DEC_EQ: &str = "roc_builtins.dec.eq";
pub const DEC_NEQ: &str = "roc_builtins.dec.neq";

View file

@ -1560,7 +1560,7 @@ impl<
.load_to_general_reg(&mut self.buf, src2);
ASM::eq_reg_reg_reg(&mut self.buf, width, dst_reg, src1_reg, src2_reg);
}
LayoutRepr::U128 | LayoutRepr::I128 => {
LayoutRepr::U128 | LayoutRepr::I128 | LayoutRepr::DEC => {
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
// put the arguments on the stack
@ -1611,7 +1611,6 @@ impl<
ASM::eq_freg_freg_reg64(&mut self.buf, dst_reg, src_reg1, src_reg2, float_width)
}
LayoutRepr::DEC => todo!("NumEq: layout, {:?}", self.layout_interner.dbg(Layout::DEC)),
LayoutRepr::STR => {
// use a zig call
self.build_fn_call(
@ -1753,54 +1752,12 @@ impl<
arg_layout: &InLayout<'a>,
ret_layout: &InLayout<'a>,
) {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
match (
self.layout_interner.get_repr(*arg_layout),
self.layout_interner.get_repr(*ret_layout),
) {
(
LayoutRepr::Builtin(Builtin::Int(IntWidth::I32 | IntWidth::I64)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)),
) => {
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
ASM::to_float_freg64_reg64(&mut self.buf, dst_reg, src_reg);
}
(
LayoutRepr::Builtin(Builtin::Int(IntWidth::I32 | IntWidth::I64)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)),
) => {
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
ASM::to_float_freg32_reg64(&mut self.buf, dst_reg, src_reg);
}
(
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)),
) => {
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::to_float_freg32_freg64(&mut self.buf, dst_reg, src_reg);
}
(
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)),
) => {
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::to_float_freg64_freg32(&mut self.buf, dst_reg, src_reg);
}
(
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)),
) => {
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::mov_freg64_freg64(&mut self.buf, dst_reg, src_reg);
}
(
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)),
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)),
) => {
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::mov_freg64_freg64(&mut self.buf, dst_reg, src_reg);
}
(a, r) => todo!("NumToFrac: layout, arg {:?}, ret {:?}", a, r),
match *ret_layout {
Layout::F32 => self.num_to_f32(dst, src, arg_layout),
Layout::F64 => self.num_to_f64(dst, src, arg_layout),
Layout::DEC => self.num_to_dec(dst, src, arg_layout),
other => todo!("NumToFrac: layout {other:?} is not Frac"),
}
}
@ -4048,6 +4005,84 @@ impl<
(unmasked_symbol, unmasked_reg)
}
fn num_to_f32(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>) {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
match self.layout_interner.get_repr(*arg_layout) {
LayoutRepr::Builtin(Builtin::Int(IntWidth::I32 | IntWidth::I64)) => {
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
ASM::to_float_freg32_reg64(&mut self.buf, dst_reg, src_reg);
}
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)) => {
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::to_float_freg32_freg64(&mut self.buf, dst_reg, src_reg);
}
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)) => {
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::mov_freg64_freg64(&mut self.buf, dst_reg, src_reg);
}
arg => todo!("NumToFrac: layout, arg {arg:?}, ret {:?}", Layout::F32),
}
}
fn num_to_f64(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>) {
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
match self.layout_interner.get_repr(*arg_layout) {
LayoutRepr::Builtin(Builtin::Int(IntWidth::I32 | IntWidth::I64)) => {
let src_reg = self.storage_manager.load_to_general_reg(&mut self.buf, src);
ASM::to_float_freg64_reg64(&mut self.buf, dst_reg, src_reg);
}
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)) => {
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::to_float_freg64_freg32(&mut self.buf, dst_reg, src_reg);
}
LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)) => {
let src_reg = self.storage_manager.load_to_float_reg(&mut self.buf, src);
ASM::mov_freg64_freg64(&mut self.buf, dst_reg, src_reg);
}
arg => todo!("NumToFrac: layout, arg {arg:?}, ret {:?}", Layout::F64),
}
}
fn num_to_dec(&mut self, dst: &Symbol, src: &Symbol, arg_layout: &InLayout<'a>) {
match self.layout_interner.get_repr(*arg_layout) {
LayoutRepr::Builtin(Builtin::Int(int_width)) => {
self.build_fn_call(
dst,
bitcode::DEC_FROM_INT[int_width].to_string(),
&[*src],
&[*arg_layout],
&Layout::DEC,
);
}
arg => todo!("NumToFrac: layout, arg {arg:?}, ret {:?}", Layout::DEC),
}
}
fn compare_128bit(
&mut self,
op: CompareOperation,
dst: &Symbol,
src1: &Symbol,
src2: &Symbol,
width: IntWidth,
) {
let intrinsic = match op {
CompareOperation::LessThan => &bitcode::NUM_LESS_THAN[width],
CompareOperation::LessThanOrEqual => &bitcode::NUM_LESS_THAN_OR_EQUAL[width],
CompareOperation::GreaterThan => &bitcode::NUM_GREATER_THAN[width],
CompareOperation::GreaterThanOrEqual => &bitcode::NUM_GREATER_THAN_OR_EQUAL[width],
};
self.build_fn_call(
&dst,
intrinsic.to_string(),
&[*src1, *src2],
&[Layout::U128, Layout::U128],
&Layout::U8,
);
}
fn compare(
&mut self,
op: CompareOperation,
@ -4099,6 +4134,12 @@ impl<
op,
);
}
LayoutRepr::Builtin(Builtin::Int(width @ (IntWidth::I128 | IntWidth::U128))) => {
self.compare_128bit(op, dst, src1, src2, width);
}
LayoutRepr::Builtin(Builtin::Decimal) => {
self.compare_128bit(op, dst, src1, src2, IntWidth::I128);
}
x => todo!("NumLt: layout, {:?}", x),
}
}

View file

@ -681,7 +681,7 @@ impl X64_64SystemVStoreArgs {
single_register_integers!() => self.store_arg_general(buf, storage_manager, sym),
pointer_layouts!() => self.store_arg_general(buf, storage_manager, sym),
single_register_floats!() => self.store_arg_float(buf, storage_manager, sym),
LayoutRepr::I128 | LayoutRepr::U128 => {
LayoutRepr::I128 | LayoutRepr::U128 | LayoutRepr::DEC => {
let (offset, _) = storage_manager.stack_offset_and_size(&sym);
if self.general_i + 1 < Self::GENERAL_PARAM_REGS.len() {
@ -1004,6 +1004,10 @@ impl X64_64SystemVLoadArgs {
storage_manager.complex_stack_arg(&sym, self.argument_offset, stack_size);
self.argument_offset += stack_size as i32;
}
LayoutRepr::Builtin(Builtin::Decimal) => {
storage_manager.complex_stack_arg(&sym, self.argument_offset, stack_size);
self.argument_offset += stack_size as i32;
}
LayoutRepr::Union(UnionLayout::NonRecursive(_)) => {
// for now, just also store this on the stack
storage_manager.complex_stack_arg(&sym, self.argument_offset, stack_size);

View file

@ -1255,7 +1255,7 @@ trait Backend<'a> {
);
debug_assert!(
matches!(*ret_layout, Layout::F32 | Layout::F64),
matches!(*ret_layout, Layout::F32 | Layout::F64 | Layout::DEC),
"NumToFrac: expected to have return layout of type Float"
);
self.build_num_to_frac(sym, &args[0], &arg_layouts[0], ret_layout)

View file

@ -2237,7 +2237,7 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
)
}
LayoutRepr::Builtin(Builtin::Decimal) => {
call_bitcode_fn(env, &[arg.into()], &bitcode::DEC_FROM_U64)
call_bitcode_fn(env, &[arg.into()], &bitcode::DEC_FROM_INT[arg_width])
}
_ => internal_error!("There can only be floats here!"),
}