authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-04 03:36:28-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-08 07:36:19-04:00
log9bea854dc2af293cba1d000b31f6e82d9c431285
tree463b368e8bda2ce13688836c666f46f8484f8369
parentb18b4db7095f58b1e8b3f5ac4993bda38231c2af

x86_64: implement `@floor`, `@ceil`, and `@trunc`


1 files changed, 41 insertions(+), 3 deletions(-)

src/arch/x86_64/CodeGen.zig+41-3
...@@ -1480,12 +1480,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -1480,12 +1480,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
1480 .log,1480 .log,
1481 .log2,1481 .log2,
1482 .log10,1482 .log10,
1483 .floor,
1484 .ceil,
1485 .round,1483 .round,
1486 .trunc_float,
1487 => try self.airUnaryMath(inst),1484 => try self.airUnaryMath(inst),
14881485
1486 .floor => try self.airRound(inst, Immediate.u(0b1_0_01)),
1487 .ceil => try self.airRound(inst, Immediate.u(0b1_0_10)),
1488 .trunc_float => try self.airRound(inst, Immediate.u(0b1_0_11)),
1489 .sqrt => try self.airSqrt(inst),1489 .sqrt => try self.airSqrt(inst),
1490 .neg, .fabs => try self.airFloatSign(inst),1490 .neg, .fabs => try self.airFloatSign(inst),
14911491
...@@ -4258,6 +4258,44 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {...@@ -4258,6 +4258,44 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
4258 return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none });4258 return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none });
4259}4259}
42604260
4261fn airRound(self: *Self, inst: Air.Inst.Index, mode: Immediate) !void {
4262 const un_op = self.air.instructions.items(.data)[inst].un_op;
4263 const ty = self.air.typeOf(un_op);
4264
4265 if (!Target.x86.featureSetHas(self.target.cpu.features, .sse4_1))
4266 return self.fail("TODO implement airRound without sse4_1 feature", .{});
4267
4268 const src_mcv = try self.resolveInst(un_op);
4269 const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, un_op, 0, src_mcv))
4270 src_mcv
4271 else
4272 try self.copyToRegisterWithInstTracking(inst, ty, src_mcv);
4273
4274 const mir_tag: Mir.Inst.Tag = switch (ty.zigTypeTag()) {
4275 .Float => switch (ty.floatBits(self.target.*)) {
4276 32 => .roundss,
4277 64 => .roundsd,
4278 else => return self.fail("TODO implement airRound for {}", .{
4279 ty.fmt(self.bin_file.options.module.?),
4280 }),
4281 },
4282 else => return self.fail("TODO implement airRound for {}", .{
4283 ty.fmt(self.bin_file.options.module.?),
4284 }),
4285 };
4286 assert(dst_mcv.isRegister());
4287 if (src_mcv.isRegister())
4288 try self.asmRegisterRegisterImmediate(mir_tag, dst_mcv.getReg().?, src_mcv.getReg().?, mode)
4289 else
4290 try self.asmRegisterMemoryImmediate(
4291 mir_tag,
4292 dst_mcv.getReg().?,
4293 src_mcv.mem(Memory.PtrSize.fromSize(@intCast(u32, ty.abiSize(self.target.*)))),
4294 mode,
4295 );
4296 return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none });
4297}
4298
4261fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {4299fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
4262 const un_op = self.air.instructions.items(.data)[inst].un_op;4300 const un_op = self.air.instructions.items(.data)[inst].un_op;
4263 const ty = self.air.typeOf(un_op);4301 const ty = self.air.typeOf(un_op);