diff options
| author | mparadinha <miguel.p.paradinha@gmail.com> | 2022-03-16 21:19:08 +0000 |
|---|---|---|
| committer | mparadinha <miguel.p.paradinha@gmail.com> | 2022-03-16 21:27:50 +0000 |
| commit | 355d0d0e7e061c86fbc08247f49900488e98acd1 (patch) | |
| tree | 9045904a383164b19b0eb87e527ea3422292c8fa /src | |
| parent | 66ef630006523c673e46a1e8d2496a99881e2452 (diff) | |
| download | zig-355d0d0e7e061c86fbc08247f49900488e98acd1.tar.gz zig-355d0d0e7e061c86fbc08247f49900488e98acd1.zip | |
stage2: x86_64: floatToInt for f32 and f64
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/x86_64/CodeGen.zig | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 63c85a5a9e..a1bf128cce 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -5437,11 +5437,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 { |
