| ... | @@ -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), |
| 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 | .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), |
| 1491 | | 1491 | |
| ... | @@ -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 | } |
| 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 | fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { | 4299 | fn 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); |