zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit ef619fdec89ff7124deccb1e9878ef34c479a4ee (tree)
parent d2c301cc955a8a62a5c05bebfdbfd438c6793cf8
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date:   Sun, 15 Feb 2026 20:41:19 +0000

x86_64: fix RoundMode immediate encoding for vroundss/vcvtps2ph

The RoundMode packed struct had Direction as enum(u4) occupying bits 3:0,
which pushed the precision exception suppress field to bit 4. Per Intel
SDM, the ROUNDSS/VROUNDSS/VCVTPS2PH immediate layout is:

  bits 1:0 = rounding mode
  bit 2    = rounding source (MXCSR.RC vs immediate)
  bit 3    = precision exception suppress
  bits 7:4 = reserved (must be 0)

The old encoding emitted e.g. vroundss $0x12 for ceil-suppress (bit 4
set, reserved), which CPUs silently ignore but valgrind 3.26.0 correctly
rejects with SIGILL. Fix by changing Direction to enum(u3) so precision
lands at bit 3, producing the correct $0x0a encoding.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Diffstat:
Msrc/arch/x86_64/bits.zig | 18++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/src/arch/x86_64/bits.zig b/src/arch/x86_64/bits.zig @@ -178,25 +178,27 @@ pub const Condition = enum(u5) { } }; -/// The immediate operand of vcvtps2ph. -pub const RoundMode = packed struct(u5) { +/// The immediate operand of vroundss/vroundps/vcvtps2ph. +/// Intel SDM layout: bits 1:0 = rounding mode, bit 2 = use MXCSR.RC, +/// bit 3 = precision exception suppress. +pub const RoundMode = packed struct(u4) { direction: Direction = .mxcsr, precision: enum(u1) { normal = 0b0, inexact = 0b1, } = .normal, - pub const Direction = enum(u4) { + pub const Direction = enum(u3) { /// Round to nearest (even) - nearest = 0b0_00, + nearest = 0b000, /// Round down (toward -∞) - down = 0b0_01, + down = 0b001, /// Round up (toward +∞) - up = 0b0_10, + up = 0b010, /// Round toward zero (truncate) - zero = 0b0_11, + zero = 0b011, /// Use current rounding mode of MXCSR.RC - mxcsr = 0b1_00, + mxcsr = 0b100, }; pub fn imm(mode: RoundMode) Immediate {