Commit 6893f90887
Changed files (5)
src
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;
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,
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 },
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,
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