mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 11:52:19 +00:00
fix most dev backend tests
This commit is contained in:
parent
5ca3d3bcf1
commit
89472bf495
7 changed files with 120 additions and 53 deletions
|
@ -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");
|
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 {
|
pub fn fromU64C(arg: u64) callconv(.C) i128 {
|
||||||
return @call(.{ .modifier = always_inline }, RocDec.fromU64, .{arg}).toI128();
|
return @call(.{ .modifier = always_inline }, RocDec.fromU64, .{arg}).toI128();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,10 @@ comptime {
|
||||||
exportDecFn(dec.mulC, "mul_with_overflow");
|
exportDecFn(dec.mulC, "mul_with_overflow");
|
||||||
exportDecFn(dec.mulOrPanicC, "mul_or_panic");
|
exportDecFn(dec.mulOrPanicC, "mul_or_panic");
|
||||||
exportDecFn(dec.mulSaturatedC, "mul_saturated");
|
exportDecFn(dec.mulSaturatedC, "mul_saturated");
|
||||||
|
|
||||||
|
inline for (INTEGERS) |T| {
|
||||||
|
dec.exportFromInt(T, ROC_BUILTINS ++ ".dec.from_int.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// List Module
|
// List Module
|
||||||
|
|
|
@ -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_TO_STR: &str = "roc_builtins.dec.to_str";
|
||||||
pub const DEC_FROM_F64: &str = "roc_builtins.dec.from_f64";
|
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_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_TO_I128: &str = "roc_builtins.dec.to_i128";
|
||||||
pub const DEC_EQ: &str = "roc_builtins.dec.eq";
|
pub const DEC_EQ: &str = "roc_builtins.dec.eq";
|
||||||
pub const DEC_NEQ: &str = "roc_builtins.dec.neq";
|
pub const DEC_NEQ: &str = "roc_builtins.dec.neq";
|
||||||
|
|
|
@ -1560,7 +1560,7 @@ impl<
|
||||||
.load_to_general_reg(&mut self.buf, src2);
|
.load_to_general_reg(&mut self.buf, src2);
|
||||||
ASM::eq_reg_reg_reg(&mut self.buf, width, dst_reg, src1_reg, src2_reg);
|
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);
|
let dst_reg = self.storage_manager.claim_general_reg(&mut self.buf, dst);
|
||||||
|
|
||||||
// put the arguments on the stack
|
// 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)
|
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 => {
|
LayoutRepr::STR => {
|
||||||
// use a zig call
|
// use a zig call
|
||||||
self.build_fn_call(
|
self.build_fn_call(
|
||||||
|
@ -1753,54 +1752,12 @@ impl<
|
||||||
arg_layout: &InLayout<'a>,
|
arg_layout: &InLayout<'a>,
|
||||||
ret_layout: &InLayout<'a>,
|
ret_layout: &InLayout<'a>,
|
||||||
) {
|
) {
|
||||||
let dst_reg = self.storage_manager.claim_float_reg(&mut self.buf, dst);
|
match *ret_layout {
|
||||||
match (
|
Layout::F32 => self.num_to_f32(dst, src, arg_layout),
|
||||||
self.layout_interner.get_repr(*arg_layout),
|
Layout::F64 => self.num_to_f64(dst, src, arg_layout),
|
||||||
self.layout_interner.get_repr(*ret_layout),
|
Layout::DEC => self.num_to_dec(dst, src, arg_layout),
|
||||||
) {
|
|
||||||
(
|
other => todo!("NumToFrac: layout {other:?} is not Frac"),
|
||||||
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),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4048,6 +4005,84 @@ impl<
|
||||||
(unmasked_symbol, unmasked_reg)
|
(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(
|
fn compare(
|
||||||
&mut self,
|
&mut self,
|
||||||
op: CompareOperation,
|
op: CompareOperation,
|
||||||
|
@ -4099,6 +4134,12 @@ impl<
|
||||||
op,
|
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),
|
x => todo!("NumLt: layout, {:?}", x),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -681,7 +681,7 @@ impl X64_64SystemVStoreArgs {
|
||||||
single_register_integers!() => self.store_arg_general(buf, storage_manager, sym),
|
single_register_integers!() => self.store_arg_general(buf, storage_manager, sym),
|
||||||
pointer_layouts!() => 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),
|
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);
|
let (offset, _) = storage_manager.stack_offset_and_size(&sym);
|
||||||
|
|
||||||
if self.general_i + 1 < Self::GENERAL_PARAM_REGS.len() {
|
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);
|
storage_manager.complex_stack_arg(&sym, self.argument_offset, stack_size);
|
||||||
self.argument_offset += stack_size as i32;
|
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(_)) => {
|
LayoutRepr::Union(UnionLayout::NonRecursive(_)) => {
|
||||||
// for now, just also store this on the stack
|
// for now, just also store this on the stack
|
||||||
storage_manager.complex_stack_arg(&sym, self.argument_offset, stack_size);
|
storage_manager.complex_stack_arg(&sym, self.argument_offset, stack_size);
|
||||||
|
|
|
@ -1255,7 +1255,7 @@ trait Backend<'a> {
|
||||||
);
|
);
|
||||||
|
|
||||||
debug_assert!(
|
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"
|
"NumToFrac: expected to have return layout of type Float"
|
||||||
);
|
);
|
||||||
self.build_num_to_frac(sym, &args[0], &arg_layouts[0], ret_layout)
|
self.build_num_to_frac(sym, &args[0], &arg_layouts[0], ret_layout)
|
||||||
|
|
|
@ -2237,7 +2237,7 @@ fn build_int_unary_op<'a, 'ctx, 'env>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
LayoutRepr::Builtin(Builtin::Decimal) => {
|
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!"),
|
_ => internal_error!("There can only be floats here!"),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue