diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 9e50e6b5b4e776fd984fa522f2616e0fe0325a61..ee621ffd87d1a6c6526473b24a0ed1c05a89712b 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -229,6 +229,7 @@ pub const MCValue = union(enum) { fn isRegister(mcv: MCValue) bool { return switch (mcv) { .register => true, + .register_offset => |reg_off| return reg_off.off == 0, else => false, }; } @@ -1449,7 +1450,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .shl_sat => try self.airShlSat(inst), .slice => try self.airSlice(inst), - .sqrt, .sin, .cos, .tan, @@ -1464,6 +1464,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .trunc_float, => try self.airUnaryMath(inst), + .sqrt => try self.airSqrt(inst), .neg, .fabs => try self.airFloatSign(inst), .add_with_overflow => try self.airAddSubWithOverflow(inst), @@ -4242,6 +4243,31 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void { return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none }); } +fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { + const un_op = self.air.instructions.items(.data)[inst].un_op; + const ty = self.air.typeOf(un_op); + + const src_mcv = try self.resolveInst(un_op); + const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, un_op, 0, src_mcv)) + src_mcv + else + try self.copyToRegisterWithInstTracking(inst, ty, src_mcv); + + try self.genBinOpMir(switch (ty.zigTypeTag()) { + .Float => switch (ty.floatBits(self.target.*)) { + 32 => .sqrtss, + 64 => .sqrtsd, + else => return self.fail("TODO implement airSqrt for {}", .{ + ty.fmt(self.bin_file.options.module.?), + }), + }, + else => return self.fail("TODO implement airSqrt for {}", .{ + ty.fmt(self.bin_file.options.module.?), + }), + }, ty, dst_mcv, src_mcv); + return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none }); +} + fn airUnaryMath(self: *Self, inst: Air.Inst.Index) !void { const un_op = self.air.instructions.items(.data)[inst].un_op; _ = un_op; diff --git a/src/arch/x86_64/Encoding.zig b/src/arch/x86_64/Encoding.zig index bb1757c91cedf9be8a38197ca8de9c7f65ceafce..13d7b1776dd1b023eb63fff0e99ec0d981e93308 100644 --- a/src/arch/x86_64/Encoding.zig +++ b/src/arch/x86_64/Encoding.zig @@ -277,6 +277,8 @@ pub const Mnemonic = enum { movss, mulss, orps, + sqrtps, + sqrtss, subss, ucomiss, xorps, @@ -291,6 +293,8 @@ pub const Mnemonic = enum { movq, //movd, movsd, mulsd, orpd, + sqrtpd, + sqrtsd, subsd, ucomisd, xorpd, diff --git a/src/arch/x86_64/Lower.zig b/src/arch/x86_64/Lower.zig index 03e395b17192541295a946dbb000b6c2b4088015..b369ba2a6bcdf31966b7ee97f902103f930b4ea2 100644 --- a/src/arch/x86_64/Lower.zig +++ b/src/arch/x86_64/Lower.zig @@ -105,6 +105,8 @@ pub fn lowerMir(lower: *Lower, inst: Mir.Inst) Error![]const Instruction { .mulss, .orps, .roundss, + .sqrtps, + .sqrtss, .subss, .ucomiss, .xorps, @@ -122,6 +124,8 @@ pub fn lowerMir(lower: *Lower, inst: Mir.Inst) Error![]const Instruction { .mulsd, .orpd, .roundsd, + .sqrtpd, + .sqrtsd, .subsd, .ucomisd, .xorpd, diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index f3d7a5a66f11bde9b08523d406a4a5a120d21905..95efc0a96c802a4d9b84e54c6a5a010887ba2b09 100644 --- a/src/arch/x86_64/Mir.zig +++ b/src/arch/x86_64/Mir.zig @@ -190,7 +190,11 @@ pub const Inst = struct { orps, /// Round scalar single-precision floating-point values roundss, + /// Square root of scalar single precision floating-point value + sqrtps, /// Subtract scalar single-precision floating-point values + sqrtss, + /// Square root of single precision floating-point values subss, /// Unordered compare scalar single-precision floating-point values ucomiss, @@ -224,6 +228,10 @@ pub const Inst = struct { orpd, /// Round scalar double-precision floating-point values roundsd, + /// Square root of double precision floating-point values + sqrtpd, + /// Square root of scalar double precision floating-point value + sqrtsd, /// Subtract scalar double-precision floating-point values subsd, /// Unordered compare scalar double-precision floating-point values diff --git a/src/arch/x86_64/encodings.zig b/src/arch/x86_64/encodings.zig index 35b2f13fe7fa5066bdcb20cc8cb7baa7b2a6dd45..5c443157c5edc837b5796b1b4fad13a01816beb3 100644 --- a/src/arch/x86_64/encodings.zig +++ b/src/arch/x86_64/encodings.zig @@ -856,6 +856,9 @@ pub const table = [_]Entry{ .{ .subss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x5c }, 0, .sse }, + .{ .sqrtps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x51 }, 0, .sse }, + .{ .sqrtss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0xf3, 0x0f, 0x51 }, 0, .sse }, + .{ .ucomiss, .rm, &.{ .xmm, .xmm_m32 }, &.{ 0x0f, 0x2e }, 0, .sse }, .{ .xorps, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x0f, 0x57 }, 0, .sse }, @@ -895,6 +898,9 @@ pub const table = [_]Entry{ .{ .orpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x56 }, 0, .sse2 }, + .{ .sqrtpd, .rm, &.{ .xmm, .xmm_m128 }, &.{ 0x66, 0x0f, 0x51 }, 0, .sse2 }, + .{ .sqrtsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x51 }, 0, .sse2 }, + .{ .subsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x5c }, 0, .sse2 }, .{ .movsd, .rm, &.{ .xmm, .xmm_m64 }, &.{ 0xf2, 0x0f, 0x10 }, 0, .sse2 },