Skip to content

Commit

Permalink
fix(ffi): f32 were handled as f64
Browse files Browse the repository at this point in the history
closes #230
  • Loading branch information
giann committed Oct 26, 2023
1 parent e274908 commit ccb637c
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 7 deletions.
106 changes: 99 additions & 7 deletions src/mirjit.zig
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ fn buildBuzzValueToZigValue(self: *Self, buzz_type: *o.ObjTypeDef, zig_type: Zig
);

// This is a int represented by a buzz float value
self.buildValueToFloat(buzz_value, tmp_float);
self.buildValueToDouble(buzz_value, tmp_float);

// Convert it back to an int
self.D2I(dest, tmp_float);
Expand All @@ -852,7 +852,14 @@ fn buildBuzzValueToZigValue(self: *Self, buzz_type: *o.ObjTypeDef, zig_type: Zig
}
},
// TODO: float can't be truncated like ints, we need a D2F instruction
.Float => self.buildValueToFloat(buzz_value, dest),
.Float => {
if (zig_type.Float.bits == 64) {
self.buildValueToDouble(buzz_value, dest);
} else {
assert(zig_type.Float.bits == 32);
self.buildValueToFloat(buzz_value, dest);
}
},
.Bool => self.buildValueToBoolean(buzz_value, dest),
.Pointer => {
// Is it a [*:0]const u8
Expand Down Expand Up @@ -904,12 +911,19 @@ fn buildZigValueToBuzzValue(self: *Self, buzz_type: *o.ObjTypeDef, zig_type: Zig
}

// And to a buzz value
self.buildValueFromFloat(tmp_float, dest);
self.buildValueFromDouble(tmp_float, dest);
} else {
self.buildValueFromInteger(zig_value, dest);
}
},
.Float => self.buildValueFromFloat(zig_value, dest),
.Float => {
if (zig_type.Float.bits == 64) {
self.buildValueFromDouble(zig_value, dest);
} else {
assert(zig_type.Float.bits == 32);
self.buildValueFromFloat(zig_value, dest);
}
},
.Bool => self.buildValueFromBoolean(zig_value, dest),
.Void => self.MOV(dest, m.MIR_new_uint_op(self.ctx, v.Value.Void.val)),
.Union, .Struct => unreachable, // FIXME: should call an api function build a ObjForeignContainer
Expand Down Expand Up @@ -2042,6 +2056,38 @@ fn buildValueFromFloat(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) void {
const addr = self.REG("cast", m.MIR_T_I64) catch unreachable;
self.ALLOCA(addr, @sizeOf(u64));

// Put the value in it as double
self.FMOV(
m.MIR_new_mem_op(
self.ctx,
m.MIR_T_F,
0,
addr,
0,
0,
),
value,
);

// Take it out as u64
self.MOV(
dest,
m.MIR_new_mem_op(
self.ctx,
m.MIR_T_U64,
0,
addr,
0,
0,
),
);
}

fn buildValueFromDouble(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) void {
// Allocate memory
const addr = self.REG("cast", m.MIR_T_I64) catch unreachable;
self.ALLOCA(addr, @sizeOf(u64));

// Put the value in it as double
self.DMOV(
m.MIR_new_mem_op(
Expand Down Expand Up @@ -2069,7 +2115,7 @@ fn buildValueFromFloat(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) void {
);
}

fn buildValueToFloat(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) void {
fn buildValueToDouble(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) void {
// Allocate memory
const addr = self.REG("cast", m.MIR_T_I64) catch unreachable;
self.ALLOCA(addr, @sizeOf(u64));
Expand Down Expand Up @@ -2101,6 +2147,38 @@ fn buildValueToFloat(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) void {
);
}

fn buildValueToFloat(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) void {
// Allocate memory
const addr = self.REG("cast", m.MIR_T_I64) catch unreachable;
self.ALLOCA(addr, @sizeOf(u64));

// Put the value in it as u64
self.MOV(
m.MIR_new_mem_op(
self.ctx,
m.MIR_T_U64,
0,
addr,
0,
0,
),
value,
);

// Take it out as float
self.FMOV(
dest,
m.MIR_new_mem_op(
self.ctx,
m.MIR_T_F,
0,
addr,
0,
0,
),
);
}

fn buildValueToForeignContainer(self: *Self, value: m.MIR_op_t, dest: m.MIR_op_t) !void {
const index = try self.REG("index", m.MIR_T_I64);
self.MOV(
Expand Down Expand Up @@ -2133,7 +2211,7 @@ fn unwrap(self: *Self, def_type: o.ObjTypeDef.Type, value: m.MIR_op_t, dest: m.M
return switch (def_type) {
.Bool => self.buildValueToBoolean(value, dest),
.Integer => self.buildValueToInteger(value, dest),
.Float => self.buildValueToFloat(value, dest),
.Float => self.buildValueToDouble(value, dest),
.Void => self.MOV(dest, value),
.String,
.Pattern,
Expand Down Expand Up @@ -2163,7 +2241,7 @@ fn wrap(self: *Self, def_type: o.ObjTypeDef.Type, value: m.MIR_op_t, dest: m.MIR
return switch (def_type) {
.Bool => self.buildValueFromBoolean(value, dest),
.Integer => self.buildValueFromInteger(value, dest),
.Float => self.buildValueFromFloat(value, dest),
.Float => self.buildValueFromDouble(value, dest),
.Void => self.MOV(dest, m.MIR_new_uint_op(self.ctx, v.Value.Void.val)),
.String,
.Pattern,
Expand Down Expand Up @@ -5246,6 +5324,20 @@ inline fn DMOV(self: *Self, dest: m.MIR_op_t, value: m.MIR_op_t) void {
);
}

inline fn FMOV(self: *Self, dest: m.MIR_op_t, value: m.MIR_op_t) void {
self.append(
m.MIR_new_insn_arr(
self.ctx,
m.MIR_FMOV,
2,
&[_]m.MIR_op_t{
dest,
value,
},
),
);
}

inline fn EQ(self: *Self, dest: m.MIR_op_t, left: m.MIR_op_t, right: m.MIR_op_t) void {
self.append(
m.MIR_new_insn_arr(
Expand Down
4 changes: 4 additions & 0 deletions tests/058-ffi.buzz
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ zdef("tests/utils/libforeign", `
const Data = extern struct {
id: i32,
msg: [*:0]const u8,
value: f32,
};

fn get_data_msg(data: *Data) [*:0]const u8;
Expand All @@ -72,6 +73,7 @@ test "struct" {
Data data = Data{
msg = cstr("bye world"),
id = 123,
value = 42.0,
};

assert(data.msg == "bye world\0", message: "Could instanciate Zig struct");
Expand All @@ -92,6 +94,7 @@ test "write/read struct in buffer" {
Data data = Data{
msg = cstr("bye world"),
id = 123,
value = 42.0,
};

Buffer buffer = Buffer.init();
Expand Down Expand Up @@ -130,6 +133,7 @@ test "union" {
data = Data{
id = 123,
msg = cstr("hello world"),
value = 42.0,
}
};

Expand Down

0 comments on commit ccb637c

Please sign in to comment.