| ... | ... | @@ -1480,12 +1480,12 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 1480 | 1480 | .log, |
| 1481 | 1481 | .log2, |
| 1482 | 1482 | .log10, |
| 1483 | | .floor, |
| 1484 | | .ceil, |
| 1485 | 1483 | .round, |
| 1486 | | .trunc_float, |
| 1487 | 1484 | => try self.airUnaryMath(inst), |
| 1488 | 1485 | |
| 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 | 1489 | .sqrt => try self.airSqrt(inst), |
| 1490 | 1490 | .neg, .fabs => try self.airFloatSign(inst), |
| 1491 | 1491 | |
| ... | ... | @@ -4258,6 +4258,44 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void { |
| 4258 | 4258 | return self.finishAir(inst, dst_mcv, .{ un_op, .none, .none }); |
| 4259 | 4259 | } |
| 4260 | 4260 | |
| 4261 | fn 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 | |
| 4261 | 4299 | fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { |
| 4262 | 4300 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 4263 | 4301 | const ty = self.air.typeOf(un_op); |