aboutsummaryrefslogtreecommitdiff
path: root/src/arch/x86_64/CodeGen.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-03-21 23:54:36 +0100
committerGitHub <noreply@github.com>2022-03-21 23:54:36 +0100
commitd71bd0300bb4dd7f1f90c1e517d197c71abeb277 (patch)
tree89f567182eafa6e41ea38ef4319c9f3758caeef4 /src/arch/x86_64/CodeGen.zig
parenta9b6de693ce04f73f8aecce91e8033951024c123 (diff)
parent355d0d0e7e061c86fbc08247f49900488e98acd1 (diff)
downloadzig-d71bd0300bb4dd7f1f90c1e517d197c71abeb277.tar.gz
zig-d71bd0300bb4dd7f1f90c1e517d197c71abeb277.zip
Merge pull request #11195 from mparadinha/float-to-int
stage2: x86_64: implement `@floatToInt` for `f32` and `f64`
Diffstat (limited to 'src/arch/x86_64/CodeGen.zig')
-rw-r--r--src/arch/x86_64/CodeGen.zig55
1 files changed, 50 insertions, 5 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig
index ce049a4541..72f12cf4e9 100644
--- a/src/arch/x86_64/CodeGen.zig
+++ b/src/arch/x86_64/CodeGen.zig
@@ -5481,11 +5481,56 @@ fn airIntToFloat(self: *Self, inst: Air.Inst.Index) !void {
fn airFloatToInt(self: *Self, inst: Air.Inst.Index) !void {
const ty_op = self.air.instructions.items(.data)[inst].ty_op;
- const result: MCValue = if (self.liveness.isUnused(inst))
- .dead
- else
- return self.fail("TODO implement airFloatToInt for {}", .{self.target.cpu.arch});
- return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
+ if (self.liveness.isUnused(inst))
+ return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
+
+ const src_ty = self.air.typeOf(ty_op.operand);
+ const dst_ty = self.air.typeOfIndex(inst);
+ const operand = try self.resolveInst(ty_op.operand);
+
+ // move float src to ST(0)
+ const stack_offset = switch (operand) {
+ .stack_offset, .ptr_stack_offset => |offset| offset,
+ else => blk: {
+ const offset = @intCast(i32, try self.allocMem(
+ inst,
+ @intCast(u32, src_ty.abiSize(self.target.*)),
+ src_ty.abiAlignment(self.target.*),
+ ));
+ try self.genSetStack(src_ty, offset, operand, .{});
+ break :blk offset;
+ },
+ };
+ _ = try self.addInst(.{
+ .tag = .fld,
+ .ops = (Mir.Ops{
+ .flags = switch (src_ty.abiSize(self.target.*)) {
+ 4 => 0b01,
+ 8 => 0b10,
+ else => |size| return self.fail("TODO load ST(0) with abiSize={}", .{size}),
+ },
+ .reg1 = .rbp,
+ }).encode(),
+ .data = .{ .imm = @bitCast(u32, -stack_offset) },
+ });
+
+ // convert
+ const stack_dst = try self.allocRegOrMem(inst, false);
+ _ = try self.addInst(.{
+ .tag = .fisttp,
+ .ops = (Mir.Ops{
+ .flags = switch (dst_ty.abiSize(self.target.*)) {
+ 1...2 => 0b00,
+ 3...4 => 0b01,
+ 5...8 => 0b10,
+ else => |size| return self.fail("TODO convert float with abiSize={}", .{size}),
+ },
+ .reg1 = .rbp,
+ }).encode(),
+ .data = .{ .imm = @bitCast(u32, -stack_dst.stack_offset) },
+ });
+
+ return self.finishAir(inst, stack_dst, .{ ty_op.operand, .none, .none });
}
fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {