╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ zig.h ────────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
3641 uint16_t byte_offset = 0; 3642 uint16_t remaining_bytes = zig_int_bytes(bits); 3643 (void)is_signed; 3644 3645 while (remaining_bytes >= 128 / CHAR_BIT) { 3646 zig_u128 res_limb; 3647 zig_u128 lhs_limb; 3648 zig_u128 rhs_limb; 3649 3650 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 3651 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 3652 res_limb = zig_xor_u128(lhs_limb, rhs_limb); 3653 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3654 3655 remaining_bytes -= 128 / CHAR_BIT; 3656 byte_offset += 128 / CHAR_BIT; 3657 } 3658 3659 while (remaining_bytes >= 64 / CHAR_BIT) { 3660 uint64_t res_limb; 3661 uint64_t lhs_limb; 3662 uint64_t rhs_limb; 3663 3664 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 3665 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 3666 res_limb = zig_xor_u64(lhs_limb, rhs_limb); 3667 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3668 3669 remaining_bytes -= 64 / CHAR_BIT; 3670 byte_offset += 64 / CHAR_BIT; 3671 } 3672 3673 while (remaining_bytes >= 32 / CHAR_BIT) { 3674 uint32_t res_limb; 3675 uint32_t lhs_limb; 3676 uint32_t rhs_limb; 3677 3678 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 3679 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 3680 res_limb = zig_xor_u32(lhs_limb, rhs_limb); 3681 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3682 3683 remaining_bytes -= 32 / CHAR_BIT; 3684 byte_offset += 32 / CHAR_BIT; 3685 } 3686 3687 while (remaining_bytes >= 16 / CHAR_BIT) { 3688 uint16_t res_limb; 3689 uint16_t lhs_limb; 3690 uint16_t rhs_limb; 3691 3692 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 3693 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 3694 res_limb = zig_xor_u16(lhs_limb, rhs_limb); 3695 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3696 3697 remaining_bytes -= 16 / CHAR_BIT; 3698 byte_offset += 16 / CHAR_BIT; 3699 } 3700 3701 while (remaining_bytes >= 8 / CHAR_BIT) { 3702 uint8_t res_limb; 3703 uint8_t lhs_limb; 3704 uint8_t rhs_limb; 3705 3706 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 3707 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 3708 res_limb = zig_xor_u8(lhs_limb, rhs_limb); 3709 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3710 3711 remaining_bytes -= 8 / CHAR_BIT; 3712 byte_offset += 8 / CHAR_BIT; 3713 } 3714 } 3715 3716 static inline void zig_increment_big(void *res, bool is_signed, uint16_t bits) { 3717 uint8_t *res_bytes = res; 3718 uint16_t byte_offset = 0; 3719 uint16_t remaining_bytes = zig_int_bytes(bits); 3720 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); 3721 3722 #if zig_big_endian 3723 byte_offset = remaining_bytes; 3724 #endif 3725 3726 while (remaining_bytes >= 128 / CHAR_BIT) { 3727 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); 3728 3729 #if zig_big_endian 3730 byte_offset -= 128 / CHAR_BIT; 3731 #endif 3732 3733 { 3734 zig_u128 res_limb; 3735 bool limb_overflow; 3736 3737 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); 3738 limb_overflow = zig_addo_u128(&res_limb, res_limb, zig_make_u128(UINT64_C(0), UINT64_C(1)), limb_bits); 3739 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3740 if (!limb_overflow) return; 3741 } 3742 3743 remaining_bytes -= 128 / CHAR_BIT; 3744 3745 #if zig_little_endian 3746 byte_offset += 128 / CHAR_BIT; 3747 #endif 3748 } 3749 3750 while (remaining_bytes >= 64 / CHAR_BIT) { 3751 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); 3752 3753 #if zig_big_endian 3754 byte_offset -= 64 / CHAR_BIT; 3755 #endif 3756 3757 { 3758 uint64_t res_limb; 3759 bool limb_overflow; 3760 3761 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); 3762 limb_overflow = zig_addo_u64(&res_limb, res_limb, UINT64_C(1), limb_bits); 3763 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3764 if (!limb_overflow) return; 3765 } 3766 3767 remaining_bytes -= 64 / CHAR_BIT; 3768 3769 #if zig_little_endian 3770 byte_offset += 64 / CHAR_BIT; 3771 #endif 3772 } 3773 3774 while (remaining_bytes >= 32 / CHAR_BIT) { 3775 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); 3776 3777 #if zig_big_endian 3778 byte_offset -= 32 / CHAR_BIT; 3779 #endif 3780 3781 { 3782 uint32_t res_limb; 3783 bool limb_overflow; 3784 3785 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); 3786 limb_overflow = zig_addo_u32(&res_limb, res_limb, UINT32_C(1), limb_bits); 3787 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3788 if (!limb_overflow) return; 3789 } 3790 3791 remaining_bytes -= 32 / CHAR_BIT; 3792 3793 #if zig_little_endian 3794 byte_offset += 32 / CHAR_BIT; 3795 #endif 3796 } 3797 3798 while (remaining_bytes >= 16 / CHAR_BIT) { 3799 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); 3800 3801 #if zig_big_endian 3802 byte_offset -= 16 / CHAR_BIT; 3803 #endif 3804 3805 { 3806 uint16_t res_limb; 3807 bool limb_overflow; 3808 3809 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); 3810 limb_overflow = zig_addo_u16(&res_limb, res_limb, UINT16_C(1), limb_bits); 3811 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3812 if (!limb_overflow) return; 3813 } 3814 3815 remaining_bytes -= 16 / CHAR_BIT; 3816 3817 #if zig_little_endian 3818 byte_offset += 16 / CHAR_BIT; 3819 #endif 3820 } 3821 3822 while (remaining_bytes >= 8 / CHAR_BIT) { 3823 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); 3824 3825 #if zig_big_endian 3826 byte_offset -= 8 / CHAR_BIT; 3827 #endif 3828 3829 { 3830 uint8_t res_limb; 3831 bool limb_overflow; 3832 3833 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); 3834 limb_overflow = zig_addo_u8(&res_limb, res_limb, UINT8_C(1), limb_bits); 3835 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3836 if (!limb_overflow) return; 3837 } 3838 3839 remaining_bytes -= 8 / CHAR_BIT; 3840 3841 #if zig_little_endian 3842 byte_offset += 8 / CHAR_BIT; 3843 #endif 3844 } 3845 } 3846 3847 static inline void zig_decrement_big(void *res, bool is_signed, uint16_t bits) { 3848 uint8_t *res_bytes = res; 3849 uint16_t byte_offset = 0; 3850 uint16_t remaining_bytes = zig_int_bytes(bits); 3851 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); 3852 3853 #if zig_big_endian 3854 byte_offset = remaining_bytes; 3855 #endif 3856 3857 while (remaining_bytes >= 128 / CHAR_BIT) { 3858 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); 3859 3860 #if zig_big_endian 3861 byte_offset -= 128 / CHAR_BIT; 3862 #endif 3863 3864 { 3865 zig_u128 res_limb; 3866 bool limb_overflow; 3867 3868 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); 3869 limb_overflow = zig_subo_u128(&res_limb, res_limb, zig_make_u128(UINT64_C(0), UINT64_C(1)), limb_bits); 3870 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3871 if (!limb_overflow) return; 3872 } 3873 3874 remaining_bytes -= 128 / CHAR_BIT; 3875 3876 #if zig_little_endian 3877 byte_offset += 128 / CHAR_BIT; 3878 #endif 3879 } 3880 3881 while (remaining_bytes >= 64 / CHAR_BIT) { 3882 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); 3883 3884 #if zig_big_endian 3885 byte_offset -= 64 / CHAR_BIT; 3886 #endif 3887 3888 { 3889 uint64_t res_limb; 3890 bool limb_overflow; 3891 3892 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); 3893 limb_overflow = zig_subo_u64(&res_limb, res_limb, UINT64_C(1), limb_bits); 3894 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3895 if (!limb_overflow) return; 3896 } 3897 3898 remaining_bytes -= 64 / CHAR_BIT; 3899 3900 #if zig_little_endian 3901 byte_offset += 64 / CHAR_BIT; 3902 #endif 3903 } 3904 3905 while (remaining_bytes >= 32 / CHAR_BIT) { 3906 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); 3907 3908 #if zig_big_endian 3909 byte_offset -= 32 / CHAR_BIT; 3910 #endif 3911 3912 { 3913 uint32_t res_limb; 3914 bool limb_overflow; 3915 3916 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); 3917 limb_overflow = zig_subo_u32(&res_limb, res_limb, UINT32_C(1), limb_bits); 3918 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3919 if (!limb_overflow) return; 3920 } 3921 3922 remaining_bytes -= 32 / CHAR_BIT; 3923 3924 #if zig_little_endian 3925 byte_offset += 32 / CHAR_BIT; 3926 #endif 3927 } 3928 3929 while (remaining_bytes >= 16 / CHAR_BIT) { 3930 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); 3931 3932 #if zig_big_endian 3933 byte_offset -= 16 / CHAR_BIT; 3934 #endif 3935 3936 { 3937 uint16_t res_limb; 3938 bool limb_overflow; 3939 3940 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); 3941 limb_overflow = zig_subo_u16(&res_limb, res_limb, UINT16_C(1), limb_bits); 3942 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3943 if (!limb_overflow) return; 3944 } 3945 3946 remaining_bytes -= 16 / CHAR_BIT; 3947 3948 #if zig_little_endian 3949 byte_offset += 16 / CHAR_BIT; 3950 #endif 3951 } 3952 3953 while (remaining_bytes >= 8 / CHAR_BIT) { 3954 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); 3955 3956 #if zig_big_endian 3957 byte_offset -= 8 / CHAR_BIT; 3958 #endif 3959 3960 { 3961 uint8_t res_limb; 3962 bool limb_overflow; 3963 3964 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb)); 3965 limb_overflow = zig_subo_u8(&res_limb, res_limb, UINT8_C(1), limb_bits); 3966 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 3967 if (!limb_overflow) return; 3968 } 3969 3970 remaining_bytes -= 8 / CHAR_BIT; 3971 3972 #if zig_little_endian 3973 byte_offset += 8 / CHAR_BIT; 3974 #endif 3975 } 3976 } 3977 3978 static inline void zig_abs_big(void *res, const void *arg, bool is_signed, uint16_t bits) { 3979 uint8_t *res_bytes = res; 3980 const uint8_t *arg_bytes = arg; 3981 uint16_t byte_offset = 0; 3982 uint16_t remaining_bytes = zig_int_bytes(bits); 3983 if (zig_signFill_big(arg, is_signed, bits) >= INT8_C(0)) { 3984 memcpy(res, arg, remaining_bytes); 3985 return; 3986 } 3987 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); 3988 bool overflow = true; 3989 3990 #if zig_big_endian 3991 byte_offset = remaining_bytes; 3992 #endif 3993 3994 while (remaining_bytes >= 128 / CHAR_BIT) { 3995 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); 3996 3997 #if zig_big_endian 3998 byte_offset -= 128 / CHAR_BIT; 3999 #endif 4000 4001 { 4002 zig_u128 res_limb; 4003 zig_u128 arg_limb; 4004 4005 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 4006 overflow = zig_addo_u128(&res_limb, zig_not_u128(arg_limb, UINT8_C(128)), zig_make_u128(UINT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits); 4007 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4008 } 4009 4010 remaining_bytes -= 128 / CHAR_BIT; 4011 4012 #if zig_little_endian 4013 byte_offset += 128 / CHAR_BIT; 4014 #endif 4015 } 4016 4017 while (remaining_bytes >= 64 / CHAR_BIT) { 4018 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); 4019 4020 #if zig_big_endian 4021 byte_offset -= 64 / CHAR_BIT; 4022 #endif 4023 4024 { 4025 uint64_t res_limb; 4026 uint64_t arg_limb; 4027 4028 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 4029 overflow = zig_addo_u64(&res_limb, zig_not_u64(arg_limb, UINT8_C(64)), overflow ? UINT64_C(1) : UINT64_C(0), limb_bits); 4030 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4031 } 4032 4033 remaining_bytes -= 64 / CHAR_BIT; 4034 4035 #if zig_little_endian 4036 byte_offset += 64 / CHAR_BIT; 4037 #endif 4038 } 4039 4040 while (remaining_bytes >= 32 / CHAR_BIT) { 4041 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); 4042 4043 #if zig_big_endian 4044 byte_offset -= 32 / CHAR_BIT; 4045 #endif 4046 4047 { 4048 uint32_t res_limb; 4049 uint32_t arg_limb; 4050 4051 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 4052 overflow = zig_addo_u32(&res_limb, zig_not_u32(arg_limb, UINT8_C(32)), overflow ? UINT32_C(1) : UINT32_C(0), limb_bits); 4053 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4054 } 4055 4056 remaining_bytes -= 32 / CHAR_BIT; 4057 4058 #if zig_little_endian 4059 byte_offset += 32 / CHAR_BIT; 4060 #endif 4061 } 4062 4063 while (remaining_bytes >= 16 / CHAR_BIT) { 4064 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); 4065 4066 #if zig_big_endian 4067 byte_offset -= 16 / CHAR_BIT; 4068 #endif 4069 4070 { 4071 uint16_t res_limb; 4072 uint16_t arg_limb; 4073 4074 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 4075 overflow = zig_addo_u16(&res_limb, zig_not_u16(arg_limb, UINT8_C(16)), overflow ? UINT16_C(1) : UINT16_C(0), limb_bits); 4076 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4077 } 4078 4079 remaining_bytes -= 16 / CHAR_BIT; 4080 4081 #if zig_little_endian 4082 byte_offset += 16 / CHAR_BIT; 4083 #endif 4084 } 4085 4086 while (remaining_bytes >= 8 / CHAR_BIT) { 4087 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); 4088 4089 #if zig_big_endian 4090 byte_offset -= 8 / CHAR_BIT; 4091 #endif 4092 4093 { 4094 uint8_t res_limb; 4095 uint8_t arg_limb; 4096 4097 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 4098 overflow = zig_addo_u8(&res_limb, zig_not_u8(arg_limb, UINT8_C(8)), overflow ? UINT8_C(1) : UINT8_C(0), limb_bits); 4099 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4100 } 4101 4102 remaining_bytes -= 8 / CHAR_BIT; 4103 4104 #if zig_little_endian 4105 byte_offset += 8 / CHAR_BIT; 4106 #endif 4107 } 4108 } 4109 4110 static inline void zig_min_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { 4111 memcpy(res, zig_cmp_big(lhs, rhs, is_signed, bits) < INT32_C(0) ? lhs : rhs, zig_int_bytes(bits)); 4112 } 4113 4114 static inline void zig_max_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { 4115 memcpy(res, zig_cmp_big(lhs, rhs, is_signed, bits) >= INT32_C(0) ? lhs : rhs, zig_int_bytes(bits)); 4116 } 4117 4118 static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { 4119 uint8_t *res_bytes = res; 4120 const uint8_t *lhs_bytes = lhs; 4121 const uint8_t *rhs_bytes = rhs; 4122 uint16_t byte_offset = 0; 4123 uint16_t remaining_bytes = zig_int_bytes(bits); 4124 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); 4125 bool overflow = false; 4126 4127 #if zig_big_endian 4128 byte_offset = remaining_bytes; 4129 #endif 4130 4131 while (remaining_bytes >= 128 / CHAR_BIT) { 4132 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); 4133 4134 #if zig_big_endian 4135 byte_offset -= 128 / CHAR_BIT; 4136 #endif 4137 4138 if (remaining_bytes == 128 / CHAR_BIT && is_signed) { 4139 zig_i128 res_limb; 4140 zig_i128 tmp_limb; 4141 zig_i128 lhs_limb; 4142 zig_i128 rhs_limb; 4143 bool limb_overflow; 4144 4145 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4146 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4147 limb_overflow = zig_addo_i128(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4148 overflow = limb_overflow ^ zig_addo_i128(&res_limb, tmp_limb, zig_make_i128(INT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits); 4149 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4150 } else { 4151 zig_u128 res_limb; 4152 zig_u128 tmp_limb; 4153 zig_u128 lhs_limb; 4154 zig_u128 rhs_limb; 4155 bool limb_overflow; 4156 4157 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4158 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4159 limb_overflow = zig_addo_u128(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4160 overflow = limb_overflow ^ zig_addo_u128(&res_limb, tmp_limb, zig_make_u128(UINT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits); 4161 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4162 } 4163 4164 remaining_bytes -= 128 / CHAR_BIT; 4165 4166 #if zig_little_endian 4167 byte_offset += 128 / CHAR_BIT; 4168 #endif 4169 } 4170 4171 while (remaining_bytes >= 64 / CHAR_BIT) { 4172 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); 4173 4174 #if zig_big_endian 4175 byte_offset -= 64 / CHAR_BIT; 4176 #endif 4177 4178 if (remaining_bytes == 64 / CHAR_BIT && is_signed) { 4179 int64_t res_limb; 4180 int64_t tmp_limb; 4181 int64_t lhs_limb; 4182 int64_t rhs_limb; 4183 bool limb_overflow; 4184 4185 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4186 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4187 limb_overflow = zig_addo_i64(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4188 overflow = limb_overflow ^ zig_addo_i64(&res_limb, tmp_limb, overflow ? INT64_C(1) : INT64_C(0), limb_bits); 4189 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4190 } else { 4191 uint64_t res_limb; 4192 uint64_t tmp_limb; 4193 uint64_t lhs_limb; 4194 uint64_t rhs_limb; 4195 bool limb_overflow; 4196 4197 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4198 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4199 limb_overflow = zig_addo_u64(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4200 overflow = limb_overflow ^ zig_addo_u64(&res_limb, tmp_limb, overflow ? UINT64_C(1) : UINT64_C(0), limb_bits); 4201 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4202 } 4203 4204 remaining_bytes -= 64 / CHAR_BIT; 4205 4206 #if zig_little_endian 4207 byte_offset += 64 / CHAR_BIT; 4208 #endif 4209 } 4210 4211 while (remaining_bytes >= 32 / CHAR_BIT) { 4212 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); 4213 4214 #if zig_big_endian 4215 byte_offset -= 32 / CHAR_BIT; 4216 #endif 4217 4218 if (remaining_bytes == 32 / CHAR_BIT && is_signed) { 4219 int32_t res_limb; 4220 int32_t tmp_limb; 4221 int32_t lhs_limb; 4222 int32_t rhs_limb; 4223 bool limb_overflow; 4224 4225 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4226 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4227 limb_overflow = zig_addo_i32(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4228 overflow = limb_overflow ^ zig_addo_i32(&res_limb, tmp_limb, overflow ? INT32_C(1) : INT32_C(0), limb_bits); 4229 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4230 } else { 4231 uint32_t res_limb; 4232 uint32_t tmp_limb; 4233 uint32_t lhs_limb; 4234 uint32_t rhs_limb; 4235 bool limb_overflow; 4236 4237 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4238 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4239 limb_overflow = zig_addo_u32(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4240 overflow = limb_overflow ^ zig_addo_u32(&res_limb, tmp_limb, overflow ? UINT32_C(1) : UINT32_C(0), limb_bits); 4241 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4242 } 4243 4244 remaining_bytes -= 32 / CHAR_BIT; 4245 4246 #if zig_little_endian 4247 byte_offset += 32 / CHAR_BIT; 4248 #endif 4249 } 4250 4251 while (remaining_bytes >= 16 / CHAR_BIT) { 4252 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); 4253 4254 #if zig_big_endian 4255 byte_offset -= 16 / CHAR_BIT; 4256 #endif 4257 4258 if (remaining_bytes == 16 / CHAR_BIT && is_signed) { 4259 int16_t res_limb; 4260 int16_t tmp_limb; 4261 int16_t lhs_limb; 4262 int16_t rhs_limb; 4263 bool limb_overflow; 4264 4265 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4266 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4267 limb_overflow = zig_addo_i16(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4268 overflow = limb_overflow ^ zig_addo_i16(&res_limb, tmp_limb, overflow ? INT16_C(1) : INT16_C(0), limb_bits); 4269 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4270 } else { 4271 uint16_t res_limb; 4272 uint16_t tmp_limb; 4273 uint16_t lhs_limb; 4274 uint16_t rhs_limb; 4275 bool limb_overflow; 4276 4277 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4278 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4279 limb_overflow = zig_addo_u16(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4280 overflow = limb_overflow ^ zig_addo_u16(&res_limb, tmp_limb, overflow ? UINT16_C(1) : UINT16_C(0), limb_bits); 4281 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4282 } 4283 4284 remaining_bytes -= 16 / CHAR_BIT; 4285 4286 #if zig_little_endian 4287 byte_offset += 16 / CHAR_BIT; 4288 #endif 4289 } 4290 4291 while (remaining_bytes >= 8 / CHAR_BIT) { 4292 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); 4293 4294 #if zig_big_endian 4295 byte_offset -= 8 / CHAR_BIT; 4296 #endif 4297 4298 if (remaining_bytes == 8 / CHAR_BIT && is_signed) { 4299 int8_t res_limb; 4300 int8_t tmp_limb; 4301 int8_t lhs_limb; 4302 int8_t rhs_limb; 4303 bool limb_overflow; 4304 4305 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4306 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4307 limb_overflow = zig_addo_i8(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4308 overflow = limb_overflow ^ zig_addo_i8(&res_limb, tmp_limb, overflow ? INT8_C(1) : INT8_C(0), limb_bits); 4309 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4310 } else { 4311 uint8_t res_limb; 4312 uint8_t tmp_limb; 4313 uint8_t lhs_limb; 4314 uint8_t rhs_limb; 4315 bool limb_overflow; 4316 4317 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4318 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4319 limb_overflow = zig_addo_u8(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4320 overflow = limb_overflow ^ zig_addo_u8(&res_limb, tmp_limb, overflow ? UINT8_C(1) : UINT8_C(0), limb_bits); 4321 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4322 } 4323 4324 remaining_bytes -= 8 / CHAR_BIT; 4325 4326 #if zig_little_endian 4327 byte_offset += 8 / CHAR_BIT; 4328 #endif 4329 } 4330 4331 return overflow; 4332 } 4333 4334 static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { 4335 uint8_t *res_bytes = res; 4336 const uint8_t *lhs_bytes = lhs; 4337 const uint8_t *rhs_bytes = rhs; 4338 uint16_t byte_offset = 0; 4339 uint16_t remaining_bytes = zig_int_bytes(bits); 4340 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); 4341 bool overflow = false; 4342 4343 #if zig_big_endian 4344 byte_offset = remaining_bytes; 4345 #endif 4346 4347 while (remaining_bytes >= 128 / CHAR_BIT) { 4348 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); 4349 4350 #if zig_big_endian 4351 byte_offset -= 128 / CHAR_BIT; 4352 #endif 4353 4354 if (remaining_bytes == 128 / CHAR_BIT && is_signed) { 4355 zig_i128 res_limb; 4356 zig_i128 tmp_limb; 4357 zig_i128 lhs_limb; 4358 zig_i128 rhs_limb; 4359 bool limb_overflow; 4360 4361 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4362 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4363 limb_overflow = zig_subo_i128(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4364 overflow = limb_overflow ^ zig_subo_i128(&res_limb, tmp_limb, zig_make_i128(INT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits); 4365 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4366 } else { 4367 zig_u128 res_limb; 4368 zig_u128 tmp_limb; 4369 zig_u128 lhs_limb; 4370 zig_u128 rhs_limb; 4371 bool limb_overflow; 4372 4373 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4374 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4375 limb_overflow = zig_subo_u128(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4376 overflow = limb_overflow ^ zig_subo_u128(&res_limb, tmp_limb, zig_make_u128(UINT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits); 4377 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4378 } 4379 4380 remaining_bytes -= 128 / CHAR_BIT; 4381 4382 #if zig_little_endian 4383 byte_offset += 128 / CHAR_BIT; 4384 #endif 4385 } 4386 4387 while (remaining_bytes >= 64 / CHAR_BIT) { 4388 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); 4389 4390 #if zig_big_endian 4391 byte_offset -= 64 / CHAR_BIT; 4392 #endif 4393 4394 if (remaining_bytes == 64 / CHAR_BIT && is_signed) { 4395 int64_t res_limb; 4396 int64_t tmp_limb; 4397 int64_t lhs_limb; 4398 int64_t rhs_limb; 4399 bool limb_overflow; 4400 4401 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4402 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4403 limb_overflow = zig_subo_i64(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4404 overflow = limb_overflow ^ zig_subo_i64(&res_limb, tmp_limb, overflow ? INT64_C(1) : INT64_C(0), limb_bits); 4405 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4406 } else { 4407 uint64_t res_limb; 4408 uint64_t tmp_limb; 4409 uint64_t lhs_limb; 4410 uint64_t rhs_limb; 4411 bool limb_overflow; 4412 4413 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4414 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4415 limb_overflow = zig_subo_u64(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4416 overflow = limb_overflow ^ zig_subo_u64(&res_limb, tmp_limb, overflow ? UINT64_C(1) : UINT64_C(0), limb_bits); 4417 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4418 } 4419 4420 remaining_bytes -= 64 / CHAR_BIT; 4421 4422 #if zig_little_endian 4423 byte_offset += 64 / CHAR_BIT; 4424 #endif 4425 } 4426 4427 while (remaining_bytes >= 32 / CHAR_BIT) { 4428 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); 4429 4430 #if zig_big_endian 4431 byte_offset -= 32 / CHAR_BIT; 4432 #endif 4433 4434 if (remaining_bytes == 32 / CHAR_BIT && is_signed) { 4435 int32_t res_limb; 4436 int32_t tmp_limb; 4437 int32_t lhs_limb; 4438 int32_t rhs_limb; 4439 bool limb_overflow; 4440 4441 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4442 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4443 limb_overflow = zig_subo_i32(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4444 overflow = limb_overflow ^ zig_subo_i32(&res_limb, tmp_limb, overflow ? INT32_C(1) : INT32_C(0), limb_bits); 4445 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4446 } else { 4447 uint32_t res_limb; 4448 uint32_t tmp_limb; 4449 uint32_t lhs_limb; 4450 uint32_t rhs_limb; 4451 bool limb_overflow; 4452 4453 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4454 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4455 limb_overflow = zig_subo_u32(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4456 overflow = limb_overflow ^ zig_subo_u32(&res_limb, tmp_limb, overflow ? UINT32_C(1) : UINT32_C(0), limb_bits); 4457 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4458 } 4459 4460 remaining_bytes -= 32 / CHAR_BIT; 4461 4462 #if zig_little_endian 4463 byte_offset += 32 / CHAR_BIT; 4464 #endif 4465 } 4466 4467 while (remaining_bytes >= 16 / CHAR_BIT) { 4468 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); 4469 4470 #if zig_big_endian 4471 byte_offset -= 16 / CHAR_BIT; 4472 #endif 4473 4474 if (remaining_bytes == 16 / CHAR_BIT && is_signed) { 4475 int16_t res_limb; 4476 int16_t tmp_limb; 4477 int16_t lhs_limb; 4478 int16_t rhs_limb; 4479 bool limb_overflow; 4480 4481 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4482 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4483 limb_overflow = zig_subo_i16(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4484 overflow = limb_overflow ^ zig_subo_i16(&res_limb, tmp_limb, overflow ? INT16_C(1) : INT16_C(0), limb_bits); 4485 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4486 } else { 4487 uint16_t res_limb; 4488 uint16_t tmp_limb; 4489 uint16_t lhs_limb; 4490 uint16_t rhs_limb; 4491 bool limb_overflow; 4492 4493 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4494 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4495 limb_overflow = zig_subo_u16(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4496 overflow = limb_overflow ^ zig_subo_u16(&res_limb, tmp_limb, overflow ? UINT16_C(1) : UINT16_C(0), limb_bits); 4497 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4498 } 4499 4500 remaining_bytes -= 16 / CHAR_BIT; 4501 4502 #if zig_little_endian 4503 byte_offset += 16 / CHAR_BIT; 4504 #endif 4505 } 4506 4507 while (remaining_bytes >= 8 / CHAR_BIT) { 4508 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); 4509 4510 #if zig_big_endian 4511 byte_offset -= 8 / CHAR_BIT; 4512 #endif 4513 4514 if (remaining_bytes == 8 / CHAR_BIT && is_signed) { 4515 int8_t res_limb; 4516 int8_t tmp_limb; 4517 int8_t lhs_limb; 4518 int8_t rhs_limb; 4519 bool limb_overflow; 4520 4521 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4522 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4523 limb_overflow = zig_subo_i8(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4524 overflow = limb_overflow ^ zig_subo_i8(&res_limb, tmp_limb, overflow ? INT8_C(1) : INT8_C(0), limb_bits); 4525 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4526 } else { 4527 uint8_t res_limb; 4528 uint8_t tmp_limb; 4529 uint8_t lhs_limb; 4530 uint8_t rhs_limb; 4531 bool limb_overflow; 4532 4533 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb)); 4534 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb)); 4535 limb_overflow = zig_subo_u8(&tmp_limb, lhs_limb, rhs_limb, limb_bits); 4536 overflow = limb_overflow ^ zig_subo_u8(&res_limb, tmp_limb, overflow ? UINT8_C(1) : UINT8_C(0), limb_bits); 4537 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb)); 4538 } 4539 4540 remaining_bytes -= 8 / CHAR_BIT; 4541 4542 #if zig_little_endian 4543 byte_offset += 8 / CHAR_BIT; 4544 #endif 4545 } 4546 4547 return overflow; 4548 } 4549 4550 static inline void zig_add_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { 4551 if (zig_addo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow 4552 } 4553 4554 static inline void zig_addw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { 4555 (void)zig_addo_big(res, lhs, rhs, is_signed, bits); 4556 } 4557 4558 static inline void zig_adds_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { 4559 int8_t sat_sign = zig_signFill_big(lhs, is_signed, bits); 4560 4561 if (!zig_addo_big(res, lhs, rhs, is_signed, bits)) return; 4562 switch (sat_sign) { 4563 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits); 4564 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits); 4565 } 4566 } 4567 4568 static inline void zig_sub_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { 4569 if (zig_subo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow 4570 } 4571 4572 static inline void zig_subw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { 4573 (void)zig_subo_big(res, lhs, rhs, is_signed, bits); 4574 } 4575 4576 static inline void zig_subs_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { 4577 int8_t sat_sign = is_signed ? zig_signFill_big(lhs, is_signed, bits) : -INT8_C(1); 4578 4579 if (!zig_subo_big(res, lhs, rhs, is_signed, bits)) return; 4580 switch (sat_sign) { 4581 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits); 4582 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits); 4583 } 4584 } 4585 4586 static inline bool zig_mulo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { 4587 uint8_t *res_bytes = res; 4588 const uint8_t *lhs_bytes = lhs; 4589 const uint8_t *rhs_bytes = rhs; 4590 uint16_t size = zig_int_bytes(bits); 4591 uint16_t sign_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); 4592 uint8_t lhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(lhs, is_signed, bits), UINT8_C(8)); 4593 uint8_t rhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(rhs, is_signed, bits), UINT8_C(8)); 4594 uint16_t lhs_byte_offset = sign_byte_offset; 4595 uint16_t lhs_end_byte_offset = UINT16_C(0); 4596 bool overflow = false; 4597 4598 #if zig_big_endian 4599 lhs_byte_offset = size - lhs_byte_offset; 4600 lhs_end_byte_offset = size - lhs_end_byte_offset; 4601 #endif 4602 4603 while (lhs_byte_offset != lhs_end_byte_offset) { 4604 uint16_t rhs_byte_offset = UINT16_C(0); 4605 uint16_t end_byte_offset = sign_byte_offset; 4606 uint16_t res_byte_offset; 4607 uint16_t lhs_byte; 4608 uint8_t res_byte = UINT8_C(0); 4609 uint16_t mul_res = UINT16_C(0); 4610 uint8_t carry = UINT8_C(0); 4611 4612 #if zig_little_endian 4613 lhs_byte_offset -= UINT16_C(1); 4614 #else 4615 rhs_byte_offset = size - rhs_byte_offset; 4616 end_byte_offset = size - end_byte_offset; 4617 #endif 4618 4619 lhs_byte = zig_u16_intCast_u8(lhs_bytes[lhs_byte_offset]) ^ lhs_sign_fill; 4620 4621 #if zig_big_endian 4622 lhs_byte_offset += UINT16_C(1); 4623 #endif 4624 4625 res_byte_offset = lhs_byte_offset; 4626 4627 while (res_byte_offset != end_byte_offset) { 4628 bool res_byte_initialized = res_byte_offset != lhs_byte_offset; 4629 4630 #if zig_big_endian 4631 rhs_byte_offset -= UINT16_C(1); 4632 res_byte_offset -= UINT16_C(1); 4633 #endif 4634 4635 if (res_byte_initialized) res_byte = res_bytes[res_byte_offset]; 4636 carry = zig_addo_u8(&res_byte, res_byte, carry, UINT8_C(8)); 4637 carry += zig_addo_u8(&res_byte, res_byte, zig_u8_intCast_u16( 4638 zig_shr_u16(mul_res, UINT8_C(8)) 4639 ), UINT8_C(8)); 4640 mul_res = lhs_byte * zig_u16_intCast_u8(rhs_bytes[rhs_byte_offset] ^ rhs_sign_fill); 4641 carry += zig_addo_u8(&res_bytes[res_byte_offset], res_byte, zig_u8_truncate_u16( 4642 mul_res, 4643 UINT8_C(8) 4644 ), UINT8_C(8)); 4645 4646 #if zig_little_endian 4647 rhs_byte_offset += UINT16_C(1); 4648 res_byte_offset += UINT16_C(1); 4649 #endif 4650 } 4651 4652 while (rhs_byte_offset != end_byte_offset) { 4653 #if zig_big_endian 4654 rhs_byte_offset -= UINT16_C(1); 4655 #endif 4656 4657 carry = zig_addo_u8( 4658 &res_byte, 4659 zig_u8_intCast_u16(zig_shr_u16(mul_res, UINT8_C(8))), 4660 carry, 4661 UINT8_C(8) 4662 ); 4663 mul_res = lhs_byte * zig_u16_intCast_u8(rhs_bytes[rhs_byte_offset] ^ rhs_sign_fill); 4664 carry += zig_addo_u8(&res_byte, res_byte, zig_u8_truncate_u16( 4665 mul_res, 4666 UINT8_C(8) 4667 ), UINT8_C(8)); 4668 overflow |= res_byte != UINT8_C(0); 4669 4670 #if zig_little_endian 4671 rhs_byte_offset += UINT16_C(1); 4672 #endif 4673 } 4674 4675 overflow |= zig_shr_u16(mul_res, UINT8_C(8)) != UINT16_C(0); 4676 overflow |= carry != UINT8_C(0); 4677 } 4678 4679 #if zig_little_endian 4680 sign_byte_offset -= UINT64_C(1); 4681 #else 4682 sign_byte_offset = size - sign_byte_offset; 4683 #endif 4684 4685 if (lhs_sign_fill != rhs_sign_fill) { 4686 uint16_t byte_offset = UINT16_C(0); 4687 uint16_t end_byte_offset = sign_byte_offset; 4688 uint8_t res_byte; 4689 int8_t signed_res_byte; 4690 uint8_t carry = UINT8_C(0); 4691 4692 #if zig_big_endian 4693 byte_offset = size - byte_offset; 4694 end_byte_offset += UINT16_C(1); 4695 #endif 4696 4697 while (byte_offset != end_byte_offset) { 4698 #if zig_big_endian 4699 byte_offset -= UINT16_C(1); 4700 #endif 4701 4702 carry = zig_subo_u8(&res_byte, UINT8_C(0), carry, UINT8_C(8)); 4703 carry += zig_subo_u8(&res_byte, res_byte, res_bytes[byte_offset], UINT8_C(8)); 4704 carry += zig_subo_u8( 4705 &res_bytes[byte_offset], 4706 res_byte, 4707 (lhs_sign_fill == UINT8_C(0) ? lhs_bytes : rhs_bytes)[byte_offset], 4708 UINT8_C(8) 4709 ); 4710 4711 #if zig_little_endian 4712 byte_offset += UINT16_C(1); 4713 #endif 4714 } 4715 4716 #if zig_big_endian 4717 byte_offset -= UINT16_C(1); 4718 #endif 4719 4720 signed_res_byte = zig_i8_bitCast_u8(res_bytes[byte_offset], UINT8_C(8)); 4721 overflow |= signed_res_byte < INT8_C(0); 4722 overflow |= zig_subo_i8(&signed_res_byte, INT8_C(0), signed_res_byte, UINT8_C(8)); 4723 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_intCast_u8(carry), UINT8_C(8)); 4724 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8( 4725 (lhs_sign_fill == UINT8_C(0) ? lhs_bytes : rhs_bytes)[byte_offset], 4726 UINT8_C(8) 4727 ), UINT8_C(8)); 4728 res_bytes[byte_offset] = zig_i8_bitCast_u8(signed_res_byte, UINT8_C(8)); 4729 } else if (lhs_sign_fill != UINT8_C(0)) { 4730 uint16_t byte_offset = UINT16_C(0); 4731 uint16_t end_byte_offset = sign_byte_offset; 4732 uint8_t res_byte; 4733 int8_t signed_res_byte; 4734 uint8_t carry = UINT8_C(1); 4735 4736 #if zig_big_endian 4737 byte_offset = size - byte_offset; 4738 end_byte_offset += UINT16_C(1); 4739 #endif 4740 4741 while (byte_offset != end_byte_offset) { 4742 #if zig_big_endian 4743 byte_offset -= UINT16_C(1); 4744 #endif 4745 4746 carry = zig_subo_u8(&res_byte, res_bytes[byte_offset], carry, UINT8_C(8)); 4747 carry += zig_subo_u8(&res_byte, res_byte, lhs_bytes[byte_offset], UINT8_C(8)); 4748 carry += zig_subo_u8(&res_bytes[byte_offset], res_byte, rhs_bytes[byte_offset], UINT8_C(8)); 4749 4750 #if zig_little_endian 4751 byte_offset += UINT16_C(1); 4752 #endif 4753 } 4754 4755 #if zig_big_endian 4756 byte_offset -= UINT16_C(1); 4757 #endif 4758 4759 signed_res_byte = zig_i8_bitCast_u8(res_bytes[byte_offset], UINT8_C(8)); 4760 overflow |= signed_res_byte < INT8_C(0); 4761 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_intCast_u8(carry), UINT8_C(8)); 4762 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8( 4763 lhs_bytes[byte_offset], 4764 UINT8_C(8) 4765 ), UINT8_C(8)); 4766 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8( 4767 rhs_bytes[byte_offset], 4768 UINT8_C(8) 4769 ), UINT8_C(8)); 4770 res_bytes[byte_offset] = zig_i8_bitCast_u8(signed_res_byte, UINT8_C(8)); 4771 } else if (is_signed) { 4772 int8_t signed_res_byte = zig_i8_bitCast_u8(res_bytes[sign_byte_offset], UINT8_C(8)); 4773 4774 overflow |= signed_res_byte < INT8_C(0); 4775 } 4776 4777 { 4778 uint8_t truncate_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); 4779 uint8_t fill_byte = UINT8_C(0); 4780 4781 if (is_signed) { 4782 int8_t sign_byte = zig_i8_bitCast_u8(res_bytes[sign_byte_offset], UINT8_C(8)); 4783 int8_t truncated = zig_i8_truncate_i8(sign_byte, truncate_bits); 4784 4785 overflow |= sign_byte != truncated; 4786 res_bytes[sign_byte_offset] = zig_u8_bitCast_i8(truncated, UINT8_C(8)); 4787 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(truncated, UINT8_C(7)), UINT8_C(8)); 4788 } else { 4789 uint8_t sign_byte = res_bytes[sign_byte_offset]; 4790 uint8_t truncated = zig_u8_truncate_u8(sign_byte, truncate_bits); 4791 4792 overflow |= sign_byte != truncated; 4793 res_bytes[sign_byte_offset] = truncated; 4794 } 4795 4796 #if zig_little_endian 4797 sign_byte_offset += UINT16_C(1); 4798 memset(&res_bytes[sign_byte_offset], fill_byte, size - sign_byte_offset); 4799 #else 4800 memset(&res_bytes[0], fill_byte, sign_byte_offset); 4801 #endif 4802 } 4803 4804 return overflow; 4805 } 4806 4807 static inline void zig_mul_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { 4808 if (zig_mulo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow 4809 } 4810 4811 static inline void zig_mulw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { 4812 (void)zig_mulo_big(res, lhs, rhs, is_signed, bits); 4813 } 4814 4815 static inline void zig_muls_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) { 4816 int8_t sat_sign = zig_signFill_big(lhs, is_signed, bits) ^ zig_signFill_big(rhs, is_signed, bits); 4817 4818 if (!zig_mulo_big(res, lhs, rhs, is_signed, bits)) return; 4819 switch (sat_sign) { 4820 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits); 4821 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits); 4822 } 4823 } 4824 4825 static inline void zig_divTrunc_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { 4826 if (is_signed) { 4827 zig_extern void __divei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits); 4828 __divei5(res, lhs, rhs, temp, bits); 4829 } else { 4830 zig_extern void __udivei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits); 4831 __udivei5(res, lhs, rhs, temp, bits); 4832 } 4833 } 4834 4835 static inline void zig_rem_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { 4836 if (is_signed) { 4837 zig_extern void __modei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits); 4838 __modei5(res, lhs, rhs, temp, bits); 4839 } else { 4840 zig_extern void __umodei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits); 4841 __umodei5(res, lhs, rhs, temp, bits); 4842 } 4843 } 4844 4845 static inline void zig_divFloor_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { 4846 bool decrement = false; 4847 4848 if (is_signed) { 4849 zig_rem_big(res, lhs, rhs, temp, is_signed, bits); 4850 decrement = zig_u32_bitCast_i32(zig_xor_i32( 4851 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits), 4852 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32) 4853 ), UINT8_C(32)) > zig_u32_bitCast_i32(zig_minInt_i32, UINT8_C(32)); 4854 } 4855 zig_divTrunc_big(res, lhs, rhs, temp, is_signed, bits); 4856 if (decrement) zig_decrement_big(res, is_signed, bits); 4857 } 4858 4859 static inline void zig_divCeil_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { 4860 bool increment = false; 4861 4862 zig_rem_big(res, lhs, rhs, temp, is_signed, bits); 4863 increment = zig_xor_i32( 4864 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits), 4865 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32) 4866 ) > INT32_C(0); 4867 zig_divTrunc_big(res, lhs, rhs, temp, is_signed, bits); 4868 if (increment) zig_increment_big(res, is_signed, bits); 4869 } 4870 4871 static inline void zig_mod_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) { 4872 bool fixup = false; 4873 4874 zig_rem_big(res, lhs, rhs, temp, is_signed, bits); 4875 if (is_signed && zig_u32_bitCast_i32(zig_xor_i32( 4876 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits), 4877 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32) 4878 ), UINT8_C(32)) > zig_u32_bitCast_i32(zig_minInt_i32, UINT8_C(32))) zig_add_big(res, res, rhs, is_signed, bits); 4879 } 4880 4881 static inline void zig_shr_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) { 4882 uint8_t *res_bytes = res; 4883 const uint8_t *lhs_bytes = lhs; 4884 uint16_t size = zig_int_bytes(bits); 4885 uint16_t res_byte_offset = UINT16_C(0); 4886 uint16_t lhs_byte_offset = zig_shr_u16(rhs, UINT8_C(3)); 4887 uint16_t end_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); 4888 uint8_t lhs_prev_byte; 4889 uint8_t byte_shift = zig_u8_truncate_u16(rhs, UINT8_C(3)); 4890 4891 #if zig_big_endian 4892 res_byte_offset = size - res_byte_offset; 4893 lhs_byte_offset = size - lhs_byte_offset; 4894 end_byte_offset = size - end_byte_offset; 4895 #endif 4896 4897 { 4898 #if zig_big_endian 4899 lhs_byte_offset -= UINT16_C(1); 4900 #endif 4901 4902 lhs_prev_byte = lhs_bytes[lhs_byte_offset]; 4903 4904 #if zig_little_endian 4905 lhs_byte_offset += UINT16_C(1); 4906 #endif 4907 } 4908 4909 while (lhs_byte_offset != end_byte_offset) { 4910 #if zig_big_endian 4911 res_byte_offset -= UINT16_C(1); 4912 lhs_byte_offset -= UINT16_C(1); 4913 #endif 4914 4915 { 4916 uint8_t lhs_byte = lhs_bytes[lhs_byte_offset]; 4917 4918 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16( 4919 zig_shl_u16(zig_u16_intCast_u8(lhs_byte), UINT8_C(8)), 4920 zig_u16_intCast_u8(lhs_prev_byte) 4921 ), byte_shift)); 4922 lhs_prev_byte = lhs_byte; 4923 } 4924 4925 #if zig_little_endian 4926 res_byte_offset += UINT16_C(1); 4927 lhs_byte_offset += UINT16_C(1); 4928 #endif 4929 } 4930 4931 { 4932 uint8_t lhs_sign_fill = UINT8_C(0); 4933 4934 #if zig_big_endian 4935 res_byte_offset -= UINT16_C(1); 4936 #endif 4937 4938 if (is_signed) { 4939 int8_t signed_byte = zig_i8_bitCast_u8(lhs_prev_byte, UINT8_C(8)); 4940 4941 res_bytes[res_byte_offset] = zig_shr_i8(signed_byte, byte_shift); 4942 lhs_sign_fill = zig_u8_bitCast_i8(zig_shr_i8(signed_byte, UINT8_C(7)), UINT8_C(8)); 4943 } else { 4944 res_bytes[res_byte_offset] = zig_shr_u8(lhs_prev_byte, byte_shift); 4945 } 4946 4947 #if zig_little_endian 4948 res_byte_offset += UINT16_C(1); 4949 memset(&res_bytes[res_byte_offset], lhs_sign_fill, size - res_byte_offset); 4950 #else 4951 memset(&res_bytes[0], lhs_sign_fill, res_byte_offset); 4952 #endif 4953 } 4954 } 4955 4956 static inline bool zig_shlo_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) { 4957 uint8_t *res_bytes = res; 4958 const uint8_t *lhs_bytes = lhs; 4959 uint8_t lhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(lhs, is_signed, bits), UINT8_C(8)); 4960 uint16_t size = zig_int_bytes(bits); 4961 uint16_t res_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); 4962 uint16_t lhs_byte_offset = UINT16_C(0); 4963 uint16_t end_byte_offset = res_byte_offset - UINT16_C(1) - zig_shr_u16(rhs, UINT8_C(3)); 4964 uint8_t lhs_prev_byte = lhs_sign_fill; 4965 uint8_t byte_shift = UINT8_C(8) - zig_u8_truncate_u16(rhs, UINT8_C(3)); 4966 bool overflow = false; 4967 4968 #if zig_little_endian 4969 lhs_byte_offset = size - lhs_byte_offset; 4970 #else 4971 res_byte_offset = size - res_byte_offset; 4972 end_byte_offset = size - end_byte_offset; 4973 #endif 4974 4975 while (lhs_byte_offset != end_byte_offset) { 4976 #if zig_little_endian 4977 lhs_byte_offset -= UINT16_C(1); 4978 #endif 4979 4980 overflow |= lhs_prev_byte != lhs_sign_fill; 4981 lhs_prev_byte = lhs_bytes[lhs_byte_offset]; 4982 4983 #if zig_big_endian 4984 lhs_byte_offset += UINT16_C(1); 4985 #endif 4986 } 4987 4988 #if zig_little_endian 4989 end_byte_offset = UINT16_C(0); 4990 #else 4991 end_byte_offset = size; 4992 #endif 4993 4994 { 4995 bool lhs_more_bytes = lhs_byte_offset != end_byte_offset; 4996 4997 #if zig_little_endian 4998 if (lhs_more_bytes) lhs_byte_offset -= UINT16_C(1); 4999 #endif 5000 5001 { 5002 uint8_t lhs_byte = UINT8_C(0); 5003 5004 if (lhs_more_bytes) lhs_byte = lhs_bytes[lhs_byte_offset]; 5005 5006 if (is_signed) { 5007 int16_t shifted = zig_shr_i16(zig_or_i16( 5008 zig_shl_i16(zig_i16_intCast_u8(lhs_prev_byte), UINT8_C(8)), 5009 zig_i16_intCast_u8(lhs_byte) 5010 ), byte_shift); 5011 int8_t truncated = zig_i8_truncate_i16( 5012 shifted, 5013 zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1) 5014 ); 5015 uint8_t fill = zig_u8_bitCast_i8(zig_shr_i8(truncated, UINT8_C(7)), UINT8_C(8)); 5016 5017 overflow |= zig_i16_intCast_i8(truncated) != shifted; 5018 #if zig_little_endian 5019 memset(&res_bytes[res_byte_offset], fill, size - res_byte_offset); 5020 res_byte_offset -= UINT16_C(1); 5021 #else 5022 memset(&res_bytes[0], fill, res_byte_offset); 5023 #endif 5024 res_bytes[res_byte_offset] = zig_u8_bitCast_i8(truncated, UINT8_C(8)); 5025 } else { 5026 uint16_t shifted = zig_shr_u16(zig_or_u16( 5027 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)), 5028 zig_u16_intCast_u8(lhs_byte) 5029 ), byte_shift); 5030 uint8_t truncated = zig_u8_truncate_u16( 5031 shifted, 5032 zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1) 5033 ); 5034 5035 overflow |= zig_u16_intCast_u8(truncated) != shifted; 5036 #if zig_little_endian 5037 memset(&res_bytes[res_byte_offset], zig_minInt_u8, size - res_byte_offset); 5038 res_byte_offset -= UINT16_C(1); 5039 #else 5040 memset(&res_bytes[0], zig_minInt_u8, res_byte_offset); 5041 #endif 5042 res_bytes[res_byte_offset] = truncated; 5043 } 5044 5045 lhs_prev_byte = lhs_byte; 5046 } 5047 5048 #if zig_big_endian 5049 res_byte_offset += UINT16_C(1); 5050 if (lhs_more_bytes) lhs_byte_offset += UINT16_C(1); 5051 #endif 5052 } 5053 5054 while (lhs_byte_offset != end_byte_offset) { 5055 #if zig_little_endian 5056 res_byte_offset -= UINT16_C(1); 5057 lhs_byte_offset -= UINT16_C(1); 5058 #endif 5059 5060 { 5061 uint8_t lhs_byte = lhs_bytes[lhs_byte_offset]; 5062 5063 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16( 5064 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)), 5065 zig_u16_intCast_u8(lhs_byte) 5066 ), byte_shift)); 5067 lhs_prev_byte = lhs_byte; 5068 } 5069 5070 #if zig_big_endian 5071 res_byte_offset += UINT16_C(1); 5072 lhs_byte_offset += UINT16_C(1); 5073 #endif 5074 } 5075 5076 { 5077 #if zig_little_endian 5078 res_byte_offset -= UINT16_C(1); 5079 #endif 5080 5081 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16( 5082 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)), 5083 byte_shift 5084 )); 5085 5086 #if zig_big_endian 5087 res_byte_offset += UINT16_C(1); 5088 #endif 5089 } 5090 5091 #if zig_little_endian 5092 memset(&res_bytes[0], zig_minInt_u8, res_byte_offset); 5093 #else 5094 memset(&res_bytes[res_byte_offset], zig_minInt_u8, size - res_byte_offset); 5095 #endif 5096 5097 return overflow; 5098 } 5099 5100 static inline void zig_shl_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) { 5101 if (zig_shlo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: left shift overflowed bits 5102 } 5103 5104 static inline void zig_shlw_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) { 5105 (void)zig_shlo_big(res, lhs, rhs, is_signed, bits); 5106 } 5107 5108 #define zig_big_shls_builtin(w) \ 5109 static inline uint##w##_t zig_shls_u##w##_big(uint##w##_t lhs, const void *rhs, \ 5110 uint8_t lhs_bits, bool rhs_is_signed, uint16_t rhs_bits) { \ 5111 uint##w##_t res; \ 5112 const uint8_t *rhs_bytes = rhs; \ 5113 if (zig_cmp_big_u8(rhs, lhs_bits, rhs_is_signed, rhs_bits) < INT32_C(0) && \ 5114 !zig_shlo_u##w(&res, lhs, rhs_bytes[0], lhs_bits)) return res; \ 5115 return lhs == INT##w##_C(0) ? zig_minInt_u(w, lhs_bits) : zig_maxInt_u(w, lhs_bits); \ 5116 } \ 5117 \ 5118 static inline int##w##_t zig_shls_i##w##_big(int##w##_t lhs, const void *rhs, \ 5119 uint8_t lhs_bits, bool rhs_is_signed, uint16_t rhs_bits) { \ 5120 int##w##_t res; \ 5121 const uint8_t *rhs_bytes = rhs; \ 5122 if (zig_cmp_big_u8(rhs, lhs_bits, rhs_is_signed, rhs_bits) < INT32_C(0) && \ 5123 !zig_shlo_i##w(&res, lhs, rhs_bytes[0], lhs_bits)) return res; \ 5124 return lhs == INT##w##_C(0) ? INT##w##_C(0) : \ 5125 lhs < INT##w##_C(0) ? zig_minInt_i(w, lhs_bits) : zig_maxInt_i(w, lhs_bits); \ 5126 } \ 5127 \ 5128 static inline void zig_shls_big_u##w(void *res, const void *lhs, uint##w##_t rhs, bool is_signed, uint16_t bits) { \ 5129 const uint8_t *lhs_bytes = lhs; \ 5130 if (rhs < bits && !zig_shlo_big(res, lhs, zig_u16_intCast_u##w(rhs), is_signed, bits)) return; \ 5131 switch (zig_cmp_big_u8(lhs, UINT8_C(0), is_signed, bits)) { \ 5132 case -INT32_C(1): return zig_minInt_big(res, is_signed, bits); \ 5133 case INT32_C(0): return zig_minInt_big(res, false, bits); \ 5134 case INT32_C(1): return zig_maxInt_big(res, is_signed, bits); \ 5135 default: zig_unreachable(); \ 5136 } \ 5137 } 5138 zig_big_shls_builtin(8) 5139 zig_big_shls_builtin(16) 5140 zig_big_shls_builtin(32) 5141 zig_big_shls_builtin(64) 5142 5143 static inline void zig_byteSwap_big(void *res, const void *arg, bool is_signed, uint16_t bits) { 5144 uint8_t *res_bytes = res; 5145 const uint8_t *arg_bytes = arg; 5146 uint16_t res_byte_offset = UINT16_C(0); 5147 uint16_t arg_byte_offset = bits / CHAR_BIT; 5148 uint16_t end_byte_offset = UINT16_C(1); 5149 uint16_t size = zig_int_bytes(bits); 5150 5151 #if zig_big_endian 5152 res_byte_offset = size - res_byte_offset; 5153 arg_byte_offset = size - arg_byte_offset; 5154 end_byte_offset = size - end_byte_offset; 5155 #endif 5156 5157 while (arg_byte_offset != end_byte_offset) { 5158 #if zig_little_endian 5159 arg_byte_offset -= UINT16_C(1); 5160 #else 5161 res_byte_offset -= UINT16_C(1); 5162 #endif 5163 5164 res_bytes[res_byte_offset] = arg_bytes[arg_byte_offset]; 5165 5166 #if zig_little_endian 5167 res_byte_offset += UINT16_C(1); 5168 #else 5169 arg_byte_offset += UINT16_C(1); 5170 #endif 5171 } 5172 5173 { 5174 #if zig_little_endian 5175 arg_byte_offset -= UINT16_C(1); 5176 #else 5177 res_byte_offset -= UINT16_C(1); 5178 #endif 5179 5180 { 5181 uint8_t byte = arg_bytes[arg_byte_offset]; 5182 uint8_t fill = is_signed 5183 ? zig_u8_bitCast_i8(zig_shr_i8(zig_i8_bitCast_u8(byte, UINT8_C(8)), UINT8_C(7)), UINT8_C(8)) 5184 : UINT8_C(0); 5185 5186 res_bytes[res_byte_offset] = byte; 5187 5188 #if zig_little_endian 5189 res_byte_offset += UINT16_C(1); 5190 memset(&res_bytes[res_byte_offset], fill, size - res_byte_offset); 5191 #else 5192 memset(&res_bytes[0], fill, res_byte_offset); 5193 #endif 5194 } 5195 } 5196 } 5197 5198 static inline void zig_bitReverse_big(void *res, const void *arg, bool is_signed, uint16_t bits) { 5199 uint8_t *res_bytes = res; 5200 const uint8_t *arg_bytes = arg; 5201 uint16_t size = zig_int_bytes(bits); 5202 uint16_t res_byte_offset = UINT16_C(0); 5203 uint16_t arg_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); 5204 uint16_t end_byte_offset = UINT16_C(0); 5205 uint8_t arg_prev_byte; 5206 uint8_t byte_shift = zig_u8_intCast_u16(zig_subw_u16(UINT16_C(0), bits, UINT8_C(3))); 5207 5208 #if zig_big_endian 5209 res_byte_offset = size - res_byte_offset; 5210 arg_byte_offset = size - arg_byte_offset; 5211 end_byte_offset = size - end_byte_offset; 5212 #endif 5213 5214 { 5215 #if zig_little_endian 5216 arg_byte_offset -= UINT16_C(1); 5217 #endif 5218 5219 arg_prev_byte = zig_bitReverse_u8(arg_bytes[arg_byte_offset], UINT8_C(8)); 5220 5221 #if zig_big_endian 5222 arg_byte_offset += UINT16_C(1); 5223 #endif 5224 } 5225 5226 while (arg_byte_offset != end_byte_offset) { 5227 #if zig_big_endian 5228 res_byte_offset -= UINT16_C(1); 5229 #else 5230 arg_byte_offset -= UINT16_C(1); 5231 #endif 5232 5233 { 5234 uint8_t arg_byte = zig_bitReverse_u8(arg_bytes[arg_byte_offset], UINT8_C(8)); 5235 5236 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16( 5237 zig_shl_u16(zig_u16_intCast_u8(arg_byte), UINT8_C(8)), 5238 zig_u16_intCast_u8(arg_prev_byte) 5239 ), byte_shift)); 5240 arg_prev_byte = arg_byte; 5241 } 5242 5243 #if zig_little_endian 5244 res_byte_offset += UINT16_C(1); 5245 #else 5246 arg_byte_offset += UINT16_C(1); 5247 #endif 5248 } 5249 5250 { 5251 uint8_t arg_sign_fill = UINT8_C(0); 5252 5253 #if zig_big_endian 5254 res_byte_offset -= UINT16_C(1); 5255 #endif 5256 5257 if (is_signed) { 5258 int8_t signed_byte = zig_i8_bitCast_u8(arg_prev_byte, UINT8_C(8)); 5259 5260 res_bytes[res_byte_offset] = zig_shr_i8(signed_byte, byte_shift); 5261 arg_sign_fill = zig_u8_bitCast_i8(zig_shr_i8(signed_byte, UINT8_C(7)), UINT8_C(8)); 5262 } else { 5263 res_bytes[res_byte_offset] = zig_shr_u8(arg_prev_byte, byte_shift); 5264 } 5265 5266 #if zig_little_endian 5267 res_byte_offset += UINT16_C(1); 5268 memset(&res_bytes[res_byte_offset], arg_sign_fill, size - res_byte_offset); 5269 #else 5270 memset(&res_bytes[0], arg_sign_fill, res_byte_offset); 5271 #endif 5272 } 5273 } 5274 5275 static inline uint16_t zig_popCount_big(const void *arg, bool is_signed, uint16_t bits) { 5276 const uint8_t *arg_bytes = arg; 5277 uint16_t byte_offset = 0; 5278 uint16_t remaining_bytes = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); 5279 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); 5280 uint16_t total_pc = 0; 5281 (void)is_signed; 5282 5283 #if zig_big_endian 5284 byte_offset = zig_int_bytes(bits); 5285 #endif 5286 5287 while (remaining_bytes >= 128 / CHAR_BIT) { 5288 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); 5289 5290 #if zig_big_endian 5291 byte_offset -= 128 / CHAR_BIT; 5292 #endif 5293 5294 { 5295 zig_u128 arg_limb; 5296 5297 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5298 total_pc += zig_popCount_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits); 5299 } 5300 5301 remaining_bytes -= 128 / CHAR_BIT; 5302 5303 #if zig_little_endian 5304 byte_offset += 128 / CHAR_BIT; 5305 #endif 5306 } 5307 5308 while (remaining_bytes >= 64 / CHAR_BIT) { 5309 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); 5310 5311 #if zig_big_endian 5312 byte_offset -= 64 / CHAR_BIT; 5313 #endif 5314 5315 { 5316 uint64_t arg_limb; 5317 5318 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5319 total_pc += zig_popCount_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits); 5320 } 5321 5322 remaining_bytes -= 64 / CHAR_BIT; 5323 5324 #if zig_little_endian 5325 byte_offset += 64 / CHAR_BIT; 5326 #endif 5327 } 5328 5329 while (remaining_bytes >= 32 / CHAR_BIT) { 5330 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); 5331 5332 #if zig_big_endian 5333 byte_offset -= 32 / CHAR_BIT; 5334 #endif 5335 5336 { 5337 uint32_t arg_limb; 5338 5339 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5340 total_pc += zig_popCount_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits); 5341 } 5342 5343 remaining_bytes -= 32 / CHAR_BIT; 5344 5345 #if zig_little_endian 5346 byte_offset += 32 / CHAR_BIT; 5347 #endif 5348 } 5349 5350 while (remaining_bytes >= 16 / CHAR_BIT) { 5351 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); 5352 5353 #if zig_big_endian 5354 byte_offset -= 16 / CHAR_BIT; 5355 #endif 5356 5357 { 5358 uint16_t arg_limb; 5359 5360 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5361 total_pc += zig_popCount_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits); 5362 } 5363 5364 remaining_bytes -= 16 / CHAR_BIT; 5365 5366 #if zig_little_endian 5367 byte_offset += 16 / CHAR_BIT; 5368 #endif 5369 } 5370 5371 while (remaining_bytes >= 8 / CHAR_BIT) { 5372 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); 5373 5374 #if zig_big_endian 5375 byte_offset -= 8 / CHAR_BIT; 5376 #endif 5377 5378 { 5379 uint8_t arg_limb; 5380 5381 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5382 total_pc += zig_popCount_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits); 5383 } 5384 5385 remaining_bytes -= 8 / CHAR_BIT; 5386 5387 #if zig_little_endian 5388 byte_offset += 8 / CHAR_BIT; 5389 #endif 5390 } 5391 5392 return total_pc; 5393 } 5394 5395 static inline uint16_t zig_ctz_big(const void *arg, bool is_signed, uint16_t bits) { 5396 const uint8_t *arg_bytes = arg; 5397 uint16_t byte_offset = UINT16_C(0); 5398 uint16_t remaining_bytes = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); 5399 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); 5400 uint16_t total_tz = UINT16_C(0); 5401 uint16_t limb_tz; 5402 (void)is_signed; 5403 5404 #if zig_big_endian 5405 byte_offset = zig_int_bytes(bits); 5406 #endif 5407 5408 while (remaining_bytes >= 128 / CHAR_BIT) { 5409 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0); 5410 5411 #if zig_big_endian 5412 byte_offset -= 128 / CHAR_BIT; 5413 #endif 5414 5415 { 5416 zig_u128 arg_limb; 5417 5418 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5419 limb_tz = zig_ctz_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits); 5420 } 5421 5422 total_tz += limb_tz; 5423 if (limb_tz < limb_bits) return total_tz; 5424 remaining_bytes -= 128 / CHAR_BIT; 5425 5426 #if zig_little_endian 5427 byte_offset += 128 / CHAR_BIT; 5428 #endif 5429 } 5430 5431 while (remaining_bytes >= 64 / CHAR_BIT) { 5432 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0); 5433 5434 #if zig_big_endian 5435 byte_offset -= 64 / CHAR_BIT; 5436 #endif 5437 5438 { 5439 uint64_t arg_limb; 5440 5441 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5442 limb_tz = zig_ctz_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits); 5443 } 5444 5445 total_tz += limb_tz; 5446 if (limb_tz < limb_bits) return total_tz; 5447 remaining_bytes -= 64 / CHAR_BIT; 5448 5449 #if zig_little_endian 5450 byte_offset += 64 / CHAR_BIT; 5451 #endif 5452 } 5453 5454 while (remaining_bytes >= 32 / CHAR_BIT) { 5455 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0); 5456 5457 #if zig_big_endian 5458 byte_offset -= 32 / CHAR_BIT; 5459 #endif 5460 5461 { 5462 uint32_t arg_limb; 5463 5464 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5465 limb_tz = zig_ctz_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits); 5466 } 5467 5468 total_tz += limb_tz; 5469 if (limb_tz < limb_bits) return total_tz; 5470 remaining_bytes -= 32 / CHAR_BIT; 5471 5472 #if zig_little_endian 5473 byte_offset += 32 / CHAR_BIT; 5474 #endif 5475 } 5476 5477 while (remaining_bytes >= 16 / CHAR_BIT) { 5478 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0); 5479 5480 #if zig_big_endian 5481 byte_offset -= 16 / CHAR_BIT; 5482 #endif 5483 5484 { 5485 uint16_t arg_limb; 5486 5487 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5488 limb_tz = zig_ctz_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits); 5489 } 5490 5491 total_tz += limb_tz; 5492 if (limb_tz < limb_bits) return total_tz; 5493 remaining_bytes -= 16 / CHAR_BIT; 5494 5495 #if zig_little_endian 5496 byte_offset += 16 / CHAR_BIT; 5497 #endif 5498 } 5499 5500 while (remaining_bytes >= 8 / CHAR_BIT) { 5501 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0); 5502 5503 #if zig_big_endian 5504 byte_offset -= 8 / CHAR_BIT; 5505 #endif 5506 5507 { 5508 uint8_t arg_limb; 5509 5510 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5511 limb_tz = zig_ctz_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits); 5512 } 5513 5514 total_tz += limb_tz; 5515 if (limb_tz < limb_bits) return total_tz; 5516 remaining_bytes -= 8 / CHAR_BIT; 5517 5518 #if zig_little_endian 5519 byte_offset += 8 / CHAR_BIT; 5520 #endif 5521 } 5522 5523 return total_tz; 5524 } 5525 5526 static inline uint16_t zig_clz_big(const void *arg, bool is_signed, uint16_t bits) { 5527 const uint8_t *arg_bytes = arg; 5528 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1); 5529 uint16_t remaining_bytes = byte_offset; 5530 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits); 5531 bool sign_limb = true; 5532 uint16_t total_lz = UINT16_C(0); 5533 uint16_t limb_lz; 5534 (void)is_signed; 5535 5536 #if zig_big_endian 5537 byte_offset = zig_int_bytes(bits) - remaining_bytes; 5538 #endif 5539 5540 while (remaining_bytes >= 128 / CHAR_BIT) { 5541 uint8_t limb_bits = UINT8_C(128) - (sign_limb ? top_bits : UINT8_C(0)); 5542 5543 #if zig_little_endian 5544 byte_offset -= 128 / CHAR_BIT; 5545 #endif 5546 5547 { 5548 zig_u128 arg_limb; 5549 5550 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5551 limb_lz = zig_clz_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits); 5552 } 5553 5554 total_lz += limb_lz; 5555 if (limb_lz < limb_bits) return total_lz; 5556 sign_limb = false; 5557 remaining_bytes -= 128 / CHAR_BIT; 5558 5559 #if zig_big_endian 5560 byte_offset += 128 / CHAR_BIT; 5561 #endif 5562 } 5563 5564 while (remaining_bytes >= 64 / CHAR_BIT) { 5565 uint8_t limb_bits = UINT8_C(64) - (sign_limb ? top_bits : UINT8_C(0)); 5566 5567 #if zig_little_endian 5568 byte_offset -= 64 / CHAR_BIT; 5569 #endif 5570 5571 { 5572 uint64_t arg_limb; 5573 5574 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5575 limb_lz = zig_clz_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits); 5576 } 5577 5578 total_lz += limb_lz; 5579 if (limb_lz < limb_bits) return total_lz; 5580 sign_limb = false; 5581 remaining_bytes -= 64 / CHAR_BIT; 5582 5583 #if zig_big_endian 5584 byte_offset += 64 / CHAR_BIT; 5585 #endif 5586 } 5587 5588 while (remaining_bytes >= 32 / CHAR_BIT) { 5589 uint8_t limb_bits = UINT8_C(32) - (sign_limb ? top_bits : UINT8_C(0)); 5590 5591 #if zig_little_endian 5592 byte_offset -= 32 / CHAR_BIT; 5593 #endif 5594 5595 { 5596 uint32_t arg_limb; 5597 5598 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5599 limb_lz = zig_clz_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits); 5600 } 5601 5602 total_lz += limb_lz; 5603 if (limb_lz < limb_bits) return total_lz; 5604 sign_limb = false; 5605 remaining_bytes -= 32 / CHAR_BIT; 5606 5607 #if zig_big_endian 5608 byte_offset += 32 / CHAR_BIT; 5609 #endif 5610 } 5611 5612 while (remaining_bytes >= 16 / CHAR_BIT) { 5613 uint8_t limb_bits = UINT8_C(16) - (sign_limb ? top_bits : UINT8_C(0)); 5614 5615 #if zig_little_endian 5616 byte_offset -= 16 / CHAR_BIT; 5617 #endif 5618 5619 { 5620 uint16_t arg_limb; 5621 5622 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5623 limb_lz = zig_clz_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits); 5624 } 5625 5626 total_lz += limb_lz; 5627 if (limb_lz < limb_bits) return total_lz; 5628 sign_limb = false; 5629 remaining_bytes -= 16 / CHAR_BIT; 5630 5631 #if zig_big_endian 5632 byte_offset += 16 / CHAR_BIT; 5633 #endif 5634 } 5635 5636 while (remaining_bytes >= 8 / CHAR_BIT) { 5637 uint8_t limb_bits = UINT8_C(8) - (sign_limb ? top_bits : UINT8_C(0)); 5638 5639 #if zig_little_endian 5640 byte_offset -= 8 / CHAR_BIT; 5641 #endif 5642 5643 { 5644 uint8_t arg_limb; 5645 5646 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb)); 5647 limb_lz = zig_clz_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits); 5648 } 5649 5650 total_lz += limb_lz; 5651 if (limb_lz < limb_bits) return total_lz; 5652 sign_limb = false; 5653 remaining_bytes -= 8 / CHAR_BIT; 5654 5655 #if zig_big_endian 5656 byte_offset += 8 / CHAR_BIT; 5657 #endif 5658 } 5659 5660 return total_lz; 5661 } 5662 5663 /* ========================= Floating Point Support ========================= */ 5664 5665 #ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ 5666 #define __STDC_WANT_IEC_60559_TYPES_EXT__ 5667 #endif 5668 5669 #include <float.h> 5670 5671 #if defined(zig_msvc) 5672 float __cdecl nanf(char const* input); 5673 double __cdecl nan(char const* input); 5674 long double __cdecl nanl(char const* input); 5675 5676 #define zig_msvc_flt_inf ((double)(1e+300 * 1e+300)) 5677 #define zig_msvc_flt_inff ((float)(1e+300 * 1e+300)) 5678 #define zig_msvc_flt_infl ((long double)(1e+300 * 1e+300)) 5679 #define zig_msvc_flt_nan ((double)(zig_msvc_flt_inf * 0.f)) 5680 #define zig_msvc_flt_nanf ((float)(zig_msvc_flt_inf * 0.f)) 5681 #define zig_msvc_flt_nanl ((long double)(zig_msvc_flt_inf * 0.f)) 5682 #define __builtin_nan(str) nan(str) 5683 #define __builtin_nanf(str) nanf(str) 5684 #define __builtin_nanl(str) nanl(str) 5685 #define __builtin_inf() zig_msvc_flt_inf 5686 #define __builtin_inff() zig_msvc_flt_inff 5687 #define __builtin_infl() zig_msvc_flt_infl 5688 #endif 5689 5690 #if (zig_has_builtin(nan) && zig_has_builtin(nans) && zig_has_builtin(inf)) || defined(zig_gcc) 5691 #define zig_make_special_f16(sign, name, arg, repr) sign zig_make_f16 (__builtin_##name, )(arg) 5692 #define zig_make_special_f32(sign, name, arg, repr) sign zig_make_f32 (__builtin_##name, )(arg) 5693 #define zig_make_special_f64(sign, name, arg, repr) sign zig_make_f64 (__builtin_##name, )(arg) 5694 #define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80 (__builtin_##name, )(arg) 5695 #define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg) 5696 #else 5697 #define zig_make_special_f16(sign, name, arg, repr) zig_f16_bitCast_u16 (repr) 5698 #define zig_make_special_f32(sign, name, arg, repr) zig_f32_bitCast_u32 (repr) 5699 #define zig_make_special_f64(sign, name, arg, repr) zig_f64_bitCast_u64 (repr) 5700 #define zig_make_special_f80(sign, name, arg, repr) zig_f80_bitCast_u128(repr) 5701 #define zig_make_special_f128(sign, name, arg, repr) zig_f128_bitCast_u128(repr) 5702 #endif 5703 5704 #define zig_has_f16 1 5705 #define zig_libc_name_f16(name) __##name##h 5706 #define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr) 5707 #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT_MANT_DIG == 11 5708 typedef float zig_f16; 5709 #define zig_make_f16(fp, repr) fp##f 5710 #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && DBL_MANT_DIG == 11 5711 typedef double zig_f16; 5712 #define zig_make_f16(fp, repr) fp 5713 #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && LDBL_MANT_DIG == 11 5714 typedef long double zig_f16; 5715 #define zig_make_f16(fp, repr) fp##l 5716 #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gcc)) 5717 typedef _Float16 zig_f16; 5718 #define zig_make_f16(fp, repr) fp##f16 5719 #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && defined(__SIZEOF_FP16__) 5720 typedef __fp16 zig_f16; 5721 #define zig_make_f16(fp, repr) fp##f16 5722 #else 5723 #undef zig_has_f16 5724 #define zig_has_f16 0 5725 #define zig_repr_f16 u16 5726 typedef uint16_t zig_f16; 5727 #define zig_make_f16(fp, repr) repr 5728 #undef zig_make_special_f16 5729 #define zig_make_special_f16(sign, name, arg, repr) repr 5730 #undef zig_init_special_f16 5731 #define zig_init_special_f16(sign, name, arg, repr) repr 5732 #endif 5733 5734 #define zig_has_f32 1 5735 #define zig_libc_name_f32(name) name##f 5736 #if defined(zig_msvc) 5737 #define zig_init_special_f32(sign, name, arg, repr) sign zig_make_f32(zig_msvc_flt_##name, ) 5738 #else 5739 #define zig_init_special_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr) 5740 #endif 5741 #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT_MANT_DIG == 24 5742 typedef float zig_f32; 5743 #define zig_make_f32(fp, repr) fp##f 5744 #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && DBL_MANT_DIG == 24 5745 typedef double zig_f32; 5746 #define zig_make_f32(fp, repr) fp 5747 #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && LDBL_MANT_DIG == 24 5748 typedef long double zig_f32; 5749 #define zig_make_f32(fp, repr) fp##l 5750 #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT32_MANT_DIG == 24 5751 typedef _Float32 zig_f32; 5752 #define zig_make_f32(fp, repr) fp##f32 5753 #else 5754 #undef zig_has_f32 5755 #define zig_has_f32 0 5756 #define zig_repr_f32 u32 5757 typedef uint32_t zig_f32; 5758 #define zig_make_f32(fp, repr) repr 5759 #undef zig_make_special_f32 5760 #define zig_make_special_f32(sign, name, arg, repr) repr 5761 #undef zig_init_special_f32 5762 #define zig_init_special_f32(sign, name, arg, repr) repr 5763 #endif 5764 5765 #define zig_has_f64 1 5766 #define zig_libc_name_f64(name) name 5767 5768 #if defined(zig_msvc) 5769 #define zig_init_special_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, ) 5770 #else 5771 #define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr) 5772 #endif 5773 #if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT_MANT_DIG == 53 5774 typedef float zig_f64; 5775 #define zig_make_f64(fp, repr) fp##f 5776 #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && DBL_MANT_DIG == 53 5777 typedef double zig_f64; 5778 #define zig_make_f64(fp, repr) fp 5779 #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && LDBL_MANT_DIG == 53 5780 typedef long double zig_f64; 5781 #define zig_make_f64(fp, repr) fp##l 5782 #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT64_MANT_DIG == 53 5783 typedef _Float64 zig_f64; 5784 #define zig_make_f64(fp, repr) fp##f64 5785 #elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT32X_MANT_DIG == 53 5786 typedef _Float32x zig_f64; 5787 #define zig_make_f64(fp, repr) fp##f32x 5788 #else 5789 #undef zig_has_f64 5790 #define zig_has_f64 0 5791 #define zig_repr_f64 u64 5792 typedef uint64_t zig_f64; 5793 #define zig_make_f64(fp, repr) repr 5794 #undef zig_make_special_f64 5795 #define zig_make_special_f64(sign, name, arg, repr) repr 5796 #undef zig_init_special_f64 5797 #define zig_init_special_f64(sign, name, arg, repr) repr 5798 #endif 5799 5800 #define zig_has_f80 1 5801 #define zig_libc_name_f80(name) __##name##x 5802 #define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr) 5803 #ifdef ZIG_TARGET_SOFT_COMPILER_RT_F80_ABI 5804 #undef zig_has_f80 5805 typedef struct { uint64_t mantissa; uint16_t exponent; } zig_f80; 5806 #define zig_init_repr_f80(mantissa, exponent) { .mant##issa = mantissa, .expo##nent = exponent } 5807 #define zig_make_repr_f80(mantissa, exponent) (zig_f80)zig_init_repr_f80(mantissa, exponent) 5808 #define zig_mantissa_repr_f80(arg) (arg).mantissa 5809 #define zig_exponent_repr_f80(arg) (arg).exponent 5810 #elif FLT_MANT_DIG == 64 5811 typedef float zig_f80; 5812 #define zig_make_f80(fp, repr) fp##f 5813 #elif DBL_MANT_DIG == 64 5814 typedef double zig_f80; 5815 #define zig_make_f80(fp, repr) fp 5816 #elif LDBL_MANT_DIG == 64 5817 typedef long double zig_f80; 5818 #define zig_make_f80(fp, repr) fp##l 5819 #elif FLT80_MANT_DIG == 64 5820 typedef _Float80 zig_f80; 5821 #define zig_make_f80(fp, repr) fp##f80 5822 #elif FLT64X_MANT_DIG == 64 5823 typedef _Float64x zig_f80; 5824 #define zig_make_f80(fp, repr) fp##f64x 5825 #elif defined(__SIZEOF_FLOAT80__) 5826 typedef __float80 zig_f80; 5827 #define zig_make_f80(fp, repr) fp##l 5828 #else 5829 #undef zig_has_f80 5830 typedef zig_u128 zig_f80; 5831 #define zig_init_repr_f80(mantissa, exponent) zig_init_u128(exponent, mantissa) 5832 #define zig_make_repr_f80(mantissa, exponent) zig_make_u128(exponent, mantissa) 5833 #define zig_mantissa_repr_f80(arg) zig_lo_u128(arg) 5834 #define zig_exponent_repr_f80(arg) (uint16_t)zig_hi_u128(arg) 5835 #endif 5836 #ifndef zig_has_f80 5837 #define zig_has_f80 0 5838 #define zig_make_f80(fp, repr) repr 5839 #ifndef zig_make_repr_f80 5840 #define zig_make_repr_f80(mantissa, exponent) (zig_f80)zig_init_repr_f80(mantissa, exponent) 5841 #endif 5842 #undef zig_make_special_f80 5843 #define zig_make_special_f80(sign, name, arg, repr) repr 5844 #undef zig_init_special_f80 5845 #define zig_init_special_f80(sign, name, arg, repr) repr 5846 #endif 5847 5848 #define zig_has_f128 1 5849 #define zig_libc_name_f128(name) name##f128 5850 #define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr) 5851 #ifdef ZIG_TARGET_SOFT_COMPILER_RT_F128_ABI 5852 #undef zig_has_f128 5853 #if zig_little_endian 5854 typedef struct { uint64_t lo, hi; } zig_f128; 5855 #else 5856 typedef struct { uint64_t hi, lo; } zig_f128; 5857 #endif 5858 #define zig_init_repr_f128(hi, lo) { .h##i = hi, .l##o = lo } 5859 #define zig_lo_repr_f128(arg) (arg).lo 5860 #define zig_hi_repr_f128(arg) (arg).hi 5861 #elif FLT_MANT_DIG == 113 5862 typedef float zig_f128; 5863 #define zig_make_f128(fp, repr) fp##f 5864 #elif DBL_MANT_DIG == 113 5865 typedef double zig_f128; 5866 #define zig_make_f128(fp, repr) fp 5867 #elif LDBL_MANT_DIG == 113 5868 typedef long double zig_f128; 5869 #define zig_make_f128(fp, repr) fp##l 5870 #elif FLT128_MANT_DIG == 113 5871 typedef _Float128 zig_f128; 5872 #define zig_make_f128(fp, repr) fp##f128 5873 #elif FLT64X_MANT_DIG == 113 5874 typedef _Float64x zig_f128; 5875 #define zig_make_f128(fp, repr) fp##f64x 5876 #elif defined(__SIZEOF_FLOAT128__) 5877 typedef __float128 zig_f128; 5878 #define zig_make_f128(fp, repr) fp##q 5879 #undef zig_make_special_f128 5880 #define zig_make_special_f128(sign, name, arg, repr) sign __builtin_##name##f128(arg) 5881 #else 5882 #undef zig_has_f128 5883 #if defined(zig_x86_64) && defined(ZIG_TARGET_ABI_MSVC) 5884 #if defined(zig_msvc) && !defined(__clang__) 5885 #include <emmintrin.h> 5886 typedef __m128i zig_f128; 5887 #define zig_init_repr_f128(hi, lo) { .m128i_u64 = { lo, hi } } 5888 #define zig_lo_repr_f128(arg) (arg).m128i_u64[0] 5889 #define zig_hi_repr_f128(arg) (arg).m128i_u64[1] 5890 #else 5891 typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_f128; 5892 #define zig_init_repr_f128(hi, lo) { lo, hi } 5893 #define zig_lo_repr_f128(arg) (arg)[0] 5894 #define zig_hi_repr_f128(arg) (arg)[1] 5895 #endif 5896 #else 5897 typedef zig_u128 zig_f128; 5898 #define zig_init_repr_f128(hi, lo) zig_init_u128(hi, lo) 5899 #define zig_make_repr_f128(hi, lo) zig_make_u128(hi, lo) 5900 #define zig_lo_repr_f128(arg) zig_lo_u128(arg) 5901 #define zig_hi_repr_f128(arg) zig_hi_u128(arg) 5902 #endif 5903 #endif 5904 #ifndef zig_has_f128 5905 #define zig_has_f128 0 5906 #define zig_make_f128(fp, repr) repr 5907 #ifndef zig_make_repr_f128 5908 #define zig_make_repr_f128(hi, lo) (zig_f128)zig_init_repr_f128(hi, lo) 5909 #endif 5910 #undef zig_make_special_f128 5911 #define zig_make_special_f128(sign, name, arg, repr) repr 5912 #undef zig_init_special_f128 5913 #define zig_init_special_f128(sign, name, arg, repr) repr 5914 #endif 5915 5916 #if !defined(zig_msvc) && defined(ZIG_TARGET_ABI_MSVC) 5917 /* Emulate msvc abi on a gnu compiler */ 5918 typedef zig_f64 zig_c_longdouble; 5919 #elif defined(zig_msvc) && !defined(ZIG_TARGET_ABI_MSVC) 5920 /* Emulate gnu abi on an msvc compiler */ 5921 typedef zig_f128 zig_c_longdouble; 5922 #else 5923 /* Target and compiler abi match */ 5924 typedef long double zig_c_longdouble; 5925 #endif 5926 5927 #if __AVR__ 5928 typedef signed char zig_FloatCompareResult; 5929 #elif defined(zig_aarch64) 5930 typedef signed int zig_FloatCompareResult; 5931 #elif __SIZEOF_LONG__ >= __SIZEOF_POINTER__ 5932 typedef signed long zig_FloatCompareResult; 5933 #else 5934 typedef signed long long zig_FloatCompareResult; 5935 #endif 5936 5937 #define zig_bitCast_float(w, iw, UnsignedReprType, SignedReprType) \ 5938 static inline zig_f##w zig_f##w##_bitCast_u##iw(UnsignedReprType arg) { \ 5939 zig_f##w res; \ 5940 memcpy(&res, &arg, sizeof(zig_f##w)); \ 5941 return res; \ 5942 } \ 5943 static inline zig_f##w zig_f##w##_bitCast_i##iw(SignedReprType arg) { \ 5944 zig_f##w res; \ 5945 memcpy(&res, &arg, sizeof(zig_f##w)); \ 5946 return res; \ 5947 } \ 5948 static inline UnsignedReprType zig_u##iw##_bitCast_f##w(zig_f##w arg) { \ 5949 UnsignedReprType res; \ 5950 memcpy(&res, &arg, sizeof(zig_f##w)); \ 5951 return zig_u##iw##_truncate_u##iw(res, w); \ 5952 } \ 5953 static inline SignedReprType zig_i##iw##_bitCast_f##w(zig_f##w arg) { \ 5954 SignedReprType res; \ 5955 memcpy(&res, &arg, sizeof(zig_f##w)); \ 5956 return zig_i##iw##_truncate_i##iw(res, w); \ 5957 } 5958 zig_bitCast_float(16, 16, uint16_t, int16_t) 5959 zig_bitCast_float(32, 32, uint32_t, int32_t) 5960 zig_bitCast_float(64, 64, uint64_t, int64_t) 5961 #if zig_has_f80 5962 zig_bitCast_float(80, 128, zig_u128, zig_i128) 5963 #else 5964 static inline zig_f80 zig_f80_bitCast_u128(zig_u128 arg) { 5965 return zig_make_repr_f80(zig_lo_u128(arg), (uint16_t)zig_hi_u128(arg)); 5966 } 5967 static inline zig_f80 zig_f80_bitCast_i128(zig_i128 arg) { 5968 return zig_make_repr_f80(zig_lo_i128(arg), (uint16_t)zig_hi_i128(arg)); 5969 } 5970 static inline zig_u128 zig_u128_bitCast_f80(zig_f80 arg) { 5971 return zig_make_u128(zig_exponent_repr_f80(arg), zig_mantissa_repr_f80(arg)); 5972 } 5973 static inline zig_i128 zig_i128_bitCast_f80(zig_f80 arg) { 5974 return zig_make_i128((int16_t)zig_exponent_repr_f80(arg), zig_mantissa_repr_f80(arg)); 5975 } 5976 #endif 5977 static inline zig_f80 zig_f80_bitCast_big(const void *arg) { 5978 return zig_f80_bitCast_u128(zig_u128_truncate_big(arg, UINT8_C(80), false, UINT16_C(80))); 5979 } 5980 static inline void zig_big_bitCast_f80(void *res, zig_f80 arg, bool res_is_signed, uint16_t res_bits) { 5981 if (res_is_signed) { 5982 zig_big_truncate_i128(res, zig_i128_bitCast_f80(arg), res_is_signed, res_bits); 5983 } else { 5984 zig_big_truncate_u128(res, zig_u128_bitCast_f80(arg), res_is_signed, res_bits); 5985 } 5986 } 5987 #if zig_has_f128 5988 zig_bitCast_float(128, 128, zig_u128, zig_i128) 5989 #else 5990 static inline zig_f128 zig_f128_bitCast_u128(zig_u128 arg) { 5991 return zig_make_repr_f128(zig_hi_u128(arg), zig_lo_u128(arg)); 5992 } 5993 static inline zig_f128 zig_f128_bitCast_i128(zig_i128 arg) { 5994 return zig_make_repr_f128((uint64_t)zig_hi_i128(arg), zig_lo_i128(arg)); 5995 } 5996 static inline zig_u128 zig_u128_bitCast_f128(zig_f128 arg) { 5997 return zig_make_u128(zig_hi_repr_f128(arg), zig_lo_repr_f128(arg)); 5998 } 5999 static inline zig_i128 zig_i128_bitCast_f128(zig_f128 arg) { 6000 return zig_make_i128((int64_t)zig_hi_repr_f128(arg), zig_lo_repr_f128(arg)); 6001 } 6002 #endif 6003 6004 #define zig_convert_float_00(ResType, operation, ArgType, version) \ 6005 zig_extern ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ 6006 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ArgType arg); \ 6007 return zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \ 6008 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(arg) 6009 #define zig_convert_float_01(ResType, operation, ArgType, version) \ 6010 zig_convert_float_00(ResType, operation, ArgType, version) 6011 #define zig_convert_float_10(ResType, operation, ArgType, version) \ 6012 zig_convert_float_00(ResType, operation, ArgType, version) 6013 #define zig_convert_float_11(ResType, operation, ArgType, version) \ 6014 return (ResType)arg 6015 #define zig_convert_float(res_when, ResType, operation, arg_when, ArgType, version) \ 6016 static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \ 6017 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \ 6018 zig_expand_concat(zig_expand_concat(zig_convert_float_, zig_has_##res_when), \ 6019 zig_has_##arg_when)(ResType, operation, ArgType, version); \ 6020 } 6021 6022 #define zig_convert_floats(SmallType, BigType) \ 6023 zig_convert_float(SmallType, zig_##SmallType, trunc, BigType, zig_##BigType, 2) \ 6024 zig_convert_float(BigType, zig_##BigType, extend, SmallType, zig_##SmallType, 2) 6025 zig_convert_floats(f16, f32) 6026 zig_convert_floats(f16, f64) 6027 zig_convert_floats(f16, f80) 6028 zig_convert_floats(f16, f128) 6029 zig_convert_floats(f32, f64) 6030 zig_convert_floats(f32, f80) 6031 zig_convert_floats(f32, f128) 6032 zig_convert_floats(f64, f80) 6033 zig_convert_floats(f64, f128) 6034 zig_convert_floats(f80, f128) 6035 6036 #define zig_float_negate_builtin_0(w, sb) \ 6037 zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, sb)) 6038 #define zig_float_negate_builtin_1(w, sb) -arg 6039 #define zig_float_negate_builtin(w, sb) \ 6040 static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \ 6041 return zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w, sb); \ 6042 } 6043 zig_float_negate_builtin(16, UINT16_C(1) << 15) 6044 zig_float_negate_builtin(32, UINT32_C(1) << 31) 6045 zig_float_negate_builtin(64, UINT64_C(1) << 63) 6046 6047 #undef zig_float_negate_builtin_0 6048 #define zig_float_negate_builtin_0(w, sb) \ 6049 zig_make_repr_f##w(zig_mantissa_repr_f##w(arg), zig_xor_u16(zig_exponent_repr_f##w(arg), sb)) 6050 zig_float_negate_builtin(80, UINT16_C(1) << 15) 6051 6052 #undef zig_float_negate_builtin_0 6053 #define zig_float_negate_builtin_0(w, sb) \ 6054 zig_make_repr_f##w(zig_xor_u64(zig_hi_repr_f##w(arg), sb), zig_lo_repr_f##w(arg)) 6055 zig_float_negate_builtin(128, UINT64_C(1) << 63) 6056 6057 #define zig_float_less_builtin_0(Type, operation) \ 6058 zig_extern zig_FloatCompareResult zig_expand_concat(zig_expand_concat(__##operation, \ 6059 zig_compiler_rt_abbrev_zig_##Type), 2)(zig_##Type, zig_##Type); \ 6060 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ 6061 return (int32_t)zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_zig_##Type), 2)(lhs, rhs); \ 6062 } 6063 #define zig_float_less_builtin_1(Type, operation) \ 6064 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ 6065 return (!(lhs <= rhs) - (lhs < rhs)); \ 6066 } 6067 6068 #define zig_float_greater_builtin_0(Type, operation) \ 6069 zig_float_less_builtin_0(Type, operation) 6070 #define zig_float_greater_builtin_1(Type, operation) \ 6071 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ 6072 return ((lhs > rhs) - !(lhs >= rhs)); \ 6073 } 6074 6075 #define zig_float_binary_builtin_0(Type, operation, operator) \ 6076 zig_extern zig_##Type zig_expand_concat(zig_expand_concat(__##operation, \ 6077 zig_compiler_rt_abbrev_zig_##Type), 3)(zig_##Type, zig_##Type); \ 6078 static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ 6079 return zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_zig_##Type), 3)(lhs, rhs); \ 6080 } 6081 #define zig_float_binary_builtin_1(Type, operation, operator) \ 6082 static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ 6083 return lhs operator rhs; \ 6084 } 6085 6086 #define zig_float_builtins(w) \ 6087 zig_common_float_builtins(w) \ 6088 zig_convert_float(f##w, zig_f##w, float, int128, zig_i128, ) \ 6089 zig_convert_float(f##w, zig_f##w, floatun, int128, zig_u128, ) 6090 #define zig_common_float_builtins(w) \ 6091 zig_convert_float(always, int32_t, fix, f##w, zig_f##w, ) \ 6092 zig_convert_float(always, int64_t, fix, f##w, zig_f##w, ) \ 6093 zig_convert_float(int128, zig_i128, fix, f##w, zig_f##w, ) \ 6094 zig_convert_float(always, uint32_t, fixuns, f##w, zig_f##w, ) \ 6095 zig_convert_float(always, uint64_t, fixuns, f##w, zig_f##w, ) \ 6096 zig_convert_float(int128, zig_u128, fixuns, f##w, zig_f##w, ) \ 6097 zig_convert_float(f##w, zig_f##w, float, always, int32_t, ) \ 6098 zig_convert_float(f##w, zig_f##w, float, always, int64_t, ) \ 6099 zig_convert_float(f##w, zig_f##w, floatun, always, uint32_t, ) \ 6100 zig_convert_float(f##w, zig_f##w, floatun, always, uint64_t, ) \ 6101 \ 6102 static inline void zig_expand_concat(zig_expand_concat(zig_fix, \ 6103 zig_compiler_rt_abbrev_zig_f##w), ei)(void *res, zig_f##w arg, uint16_t bits) { \ 6104 zig_extern void zig_expand_concat(zig_expand_concat(__fix, \ 6105 zig_compiler_rt_abbrev_zig_f##w), ei)(uint8_t *res, uintptr_t bits, zig_f##w arg); \ 6106 zig_expand_concat(zig_expand_concat(__fix, \ 6107 zig_compiler_rt_abbrev_zig_f##w), ei)(res, bits, arg); \ 6108 } \ 6109 \ 6110 static inline void zig_expand_concat(zig_expand_concat(zig_fixuns, \ 6111 zig_compiler_rt_abbrev_zig_f##w), ei)(void *res, zig_f##w arg, uint16_t bits) { \ 6112 zig_extern void zig_expand_concat(zig_expand_concat(__fixuns, \ 6113 zig_compiler_rt_abbrev_zig_f##w), ei)(uint8_t *res, uintptr_t bits, zig_f##w arg); \ 6114 zig_expand_concat(zig_expand_concat(__fixuns, \ 6115 zig_compiler_rt_abbrev_zig_f##w), ei)(res, bits, arg); \ 6116 } \ 6117 \ 6118 static inline zig_f##w zig_expand_concat(zig_floatei, \ 6119 zig_compiler_rt_abbrev_zig_f##w)(void *res, uint16_t bits) { \ 6120 zig_extern zig_f##w zig_expand_concat(__floatei, \ 6121 zig_compiler_rt_abbrev_zig_f##w)(const uint8_t *arg, uintptr_t bits); \ 6122 return zig_expand_concat(__floatei, zig_compiler_rt_abbrev_zig_f##w)(res, bits); \ 6123 } \ 6124 \ 6125 static inline zig_f##w zig_expand_concat(zig_floatunei, \ 6126 zig_compiler_rt_abbrev_zig_f##w)(void *res, uint16_t bits) { \ 6127 zig_extern zig_f##w zig_expand_concat(__floatunei, \ 6128 zig_compiler_rt_abbrev_zig_f##w)(const uint8_t *arg, uintptr_t bits); \ 6129 return zig_expand_concat(__floatunei, zig_compiler_rt_abbrev_zig_f##w)(res, bits); \ 6130 } \ 6131 \ 6132 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \ 6133 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \ 6134 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \ 6135 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, lt) \ 6136 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, le) \ 6137 zig_expand_concat(zig_float_greater_builtin_, zig_has_f##w)(f##w, gt) \ 6138 zig_expand_concat(zig_float_greater_builtin_, zig_has_f##w)(f##w, ge) \ 6139 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, add, +) \ 6140 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, sub, -) \ 6141 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, mul, *) \ 6142 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, div, /) \ 6143 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(sqrt)))(zig_f##w, zig_sqrt_f##w, zig_libc_name_f##w(sqrt), (zig_f##w x), (x)) \ 6144 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(sin)))(zig_f##w, zig_sin_f##w, zig_libc_name_f##w(sin), (zig_f##w x), (x)) \ 6145 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(cos)))(zig_f##w, zig_cos_f##w, zig_libc_name_f##w(cos), (zig_f##w x), (x)) \ 6146 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(tan)))(zig_f##w, zig_tan_f##w, zig_libc_name_f##w(tan), (zig_f##w x), (x)) \ 6147 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(exp)))(zig_f##w, zig_exp_f##w, zig_libc_name_f##w(exp), (zig_f##w x), (x)) \ 6148 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(exp2)))(zig_f##w, zig_exp2_f##w, zig_libc_name_f##w(exp2), (zig_f##w x), (x)) \ 6149 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(log)))(zig_f##w, zig_log_f##w, zig_libc_name_f##w(log), (zig_f##w x), (x)) \ 6150 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(log2)))(zig_f##w, zig_log2_f##w, zig_libc_name_f##w(log2), (zig_f##w x), (x)) \ 6151 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(log10)))(zig_f##w, zig_log10_f##w, zig_libc_name_f##w(log10), (zig_f##w x), (x)) \ 6152 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fabs)))(zig_f##w, zig_abs_f##w, zig_libc_name_f##w(fabs), (zig_f##w x), (x)) \ 6153 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(floor)))(zig_f##w, zig_floor_f##w, zig_libc_name_f##w(floor), (zig_f##w x), (x)) \ 6154 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(ceil)))(zig_f##w, zig_ceil_f##w, zig_libc_name_f##w(ceil), (zig_f##w x), (x)) \ 6155 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(round)))(zig_f##w, zig_round_f##w, zig_libc_name_f##w(round), (zig_f##w x), (x)) \ 6156 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(trunc)))(zig_f##w, zig_trunc_f##w, zig_libc_name_f##w(trunc), (zig_f##w x), (x)) \ 6157 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmod)))(zig_f##w, zig_fmod_f##w, zig_libc_name_f##w(fmod), (zig_f##w x, zig_f##w y), (x, y)) \ 6158 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmin)))(zig_f##w, zig_min_f##w, zig_libc_name_f##w(fmin), (zig_f##w x, zig_f##w y), (x, y)) \ 6159 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmax)))(zig_f##w, zig_max_f##w, zig_libc_name_f##w(fmax), (zig_f##w x, zig_f##w y), (x, y)) \ 6160 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fma)))(zig_f##w, zig_fma_f##w, zig_libc_name_f##w(fma), (zig_f##w x, zig_f##w y, zig_f##w z), (x, y, z)) \ 6161 \ 6162 static inline zig_f##w zig_divTrunc_f##w(zig_f##w lhs, zig_f##w rhs) { \ 6163 return zig_trunc_f##w(zig_div_f##w(lhs, rhs)); \ 6164 } \ 6165 \ 6166 static inline zig_f##w zig_divFloor_f##w(zig_f##w lhs, zig_f##w rhs) { \ 6167 return zig_floor_f##w(zig_div_f##w(lhs, rhs)); \ 6168 } \ 6169 \ 6170 static inline zig_f##w zig_divCeil_f##w(zig_f##w lhs, zig_f##w rhs) { \ 6171 return zig_ceil_f##w(zig_div_f##w(lhs, rhs)); \ 6172 } \ 6173 \ 6174 static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \ 6175 return zig_sub_f##w(lhs, zig_mul_f##w(zig_divFloor_f##w(lhs, rhs), rhs)); \ 6176 } 6177 zig_float_builtins(16) 6178 zig_float_builtins(32) 6179 zig_float_builtins(64) 6180 zig_float_builtins(80) 6181 #if defined(zig_x86_32) 6182 zig_common_float_builtins(128) 6183 static inline zig_f128 zig_floattitf(zig_i128 arg) { 6184 extern zig_f128 __floattitf(zig_f128 arg); 6185 return __floattitf(zig_f128_bitCast_i128(arg)); 6186 } 6187 static inline zig_f128 zig_floatuntitf(zig_u128 arg) { 6188 extern zig_f128 __floatuntitf(zig_f128 arg); 6189 return __floatuntitf(zig_f128_bitCast_u128(arg)); 6190 } 6191 #elif defined(zig_x86_64) && defined(zig_windows) 6192 zig_common_float_builtins(128) 6193 static inline zig_f128 zig_floattitf(zig_i128 arg) { 6194 extern zig_f128 __floattitf(zig_i128 arg); 6195 return __floattitf(arg); 6196 } 6197 static inline zig_f128 zig_floatuntitf(zig_u128 arg) { 6198 extern zig_f128 __floatuntitf(uint64_t arg_lo, uint64_t arg_hi); 6199 return __floatuntitf(zig_lo_u128(arg), zig_hi_u128(arg)); 6200 } 6201 #else 6202 zig_float_builtins(128) 6203 #endif 6204 6205 /* ============================ Atomics Support ============================= */ 6206 6207 /* Note that atomics should be implemented as macros because most 6208 compilers silently discard runtime atomic order information. */ 6209 6210 /* Define fallback implementations first that can later be undef'd on compilers with builtin support. */ 6211 /* Note that zig_atomicrmw_expected is needed to handle aliasing between res and arg. */ 6212 #define zig_atomicrmw_xchg_float(res, obj, arg, order, Type, ReprType) do { \ 6213 zig_##Type zig_atomicrmw_expected; \ 6214 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \ 6215 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, zig_memory_order_relaxed, Type, ReprType)); \ 6216 res = zig_atomicrmw_expected; \ 6217 } while (0) 6218 #define zig_atomicrmw_add_float(res, obj, arg, order, Type, ReprType) do { \ 6219 zig_##Type zig_atomicrmw_expected; \ 6220 zig_##Type zig_atomicrmw_desired; \ 6221 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \ 6222 do { \ 6223 zig_atomicrmw_desired = zig_add_##Type(zig_atomicrmw_expected, arg); \ 6224 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \ 6225 res = zig_atomicrmw_expected; \ 6226 } while (0) 6227 #define zig_atomicrmw_sub_float(res, obj, arg, order, Type, ReprType) do { \ 6228 zig_##Type zig_atomicrmw_expected; \ 6229 zig_##Type zig_atomicrmw_desired; \ 6230 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \ 6231 do { \ 6232 zig_atomicrmw_desired = zig_sub_##Type(zig_atomicrmw_expected, arg); \ 6233 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \ 6234 res = zig_atomicrmw_expected; \ 6235 } while (0) 6236 #define zig_atomicrmw_min_float(res, obj, arg, order, Type, ReprType) do { \ 6237 zig_##Type zig_atomicrmw_expected; \ 6238 zig_##Type zig_atomicrmw_desired; \ 6239 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \ 6240 do { \ 6241 zig_atomicrmw_desired = zig_min_##Type(zig_atomicrmw_expected, arg); \ 6242 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \ 6243 res = zig_atomicrmw_expected; \ 6244 } while (0) 6245 #define zig_atomicrmw_max_float(res, obj, arg, order, Type, ReprType) do { \ 6246 zig_##Type zig_atomicrmw_expected; \ 6247 zig_##Type zig_atomicrmw_desired; \ 6248 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \ 6249 do { \ 6250 zig_atomicrmw_desired = zig_max_##Type(zig_atomicrmw_expected, arg); \ 6251 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \ 6252 res = zig_atomicrmw_expected; \ 6253 } while (0) 6254 6255 #define zig_atomicrmw_xchg_int128(res, obj, arg, order, Type, ReprType) do { \ 6256 zig_##Type zig_atomicrmw_expected; \ 6257 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \ 6258 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, zig_memory_order_relaxed, Type, ReprType)); \ 6259 res = zig_atomicrmw_expected; \ 6260 } while (0) 6261 #define zig_atomicrmw_add_int128(res, obj, arg, order, Type, ReprType) do { \ 6262 zig_##Type zig_atomicrmw_expected; \ 6263 zig_##Type zig_atomicrmw_desired; \ 6264 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \ 6265 do { \ 6266 zig_atomicrmw_desired = zig_add_##Type(zig_atomicrmw_expected, arg); \ 6267 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \ 6268 res = zig_atomicrmw_expected; \ 6269 } while (0) 6270 #define zig_atomicrmw_sub_int128(res, obj, arg, order, Type, ReprType) do { \ 6271 zig_##Type zig_atomicrmw_expected; \ 6272 zig_##Type zig_atomicrmw_desired; \ 6273 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \ 6274 do { \ 6275 zig_atomicrmw_desired = zig_sub_##Type(zig_atomicrmw_expected, arg); \ 6276 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \ 6277 res = zig_atomicrmw_expected; \ 6278 } while (0) 6279 #define zig_atomicrmw_and_int128(res, obj, arg, order, Type, ReprType) do { \ 6280 zig_##Type zig_atomicrmw_expected; \ 6281 zig_##Type zig_atomicrmw_desired; \ 6282 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \ 6283 do { \ 6284 zig_atomicrmw_desired = zig_and_##Type(zig_atomicrmw_expected, arg); \ 6285 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \ 6286 res = zig_atomicrmw_expected; \ 6287 } while (0) 6288 #define zig_atomicrmw_nand_int128(res, obj, arg, order, Type, ReprType) do { \ 6289 zig_##Type zig_atomicrmw_expected; \ 6290 zig_##Type zig_atomicrmw_desired; \ 6291 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \ 6292 do { \ 6293 zig_atomicrmw_desired = zig_not_##Type(zig_and_##Type(zig_atomicrmw_expected, arg), 128); \ 6294 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \ 6295 res = zig_atomicrmw_expected; \ 6296 } while (0) 6297 #define zig_atomicrmw_or_int128(res, obj, arg, order, Type, ReprType) do { \ 6298 zig_##Type zig_atomicrmw_expected; \ 6299 zig_##Type zig_atomicrmw_desired; \ 6300 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \ 6301 do { \ 6302 zig_atomicrmw_desired = zig_or_##Type(zig_atomicrmw_expected, arg); \ 6303 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \ 6304 res = zig_atomicrmw_expected; \ 6305 } while (0) 6306 #define zig_atomicrmw_xor_int128(res, obj, arg, order, Type, ReprType) do { \ 6307 zig_##Type zig_atomicrmw_expected; \ 6308 zig_##Type zig_atomicrmw_desired; \ 6309 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \ 6310 do { \ 6311 zig_atomicrmw_desired = zig_xor_##Type(zig_atomicrmw_expected, arg); \ 6312 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \ 6313 res = zig_atomicrmw_expected; \ 6314 } while (0) 6315 #define zig_atomicrmw_min_int128(res, obj, arg, order, Type, ReprType) do { \ 6316 zig_##Type zig_atomicrmw_expected; \ 6317 zig_##Type zig_atomicrmw_desired; \ 6318 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \ 6319 do { \ 6320 zig_atomicrmw_desired = zig_min_##Type(zig_atomicrmw_expected, arg); \ 6321 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \ 6322 res = zig_atomicrmw_expected; \ 6323 } while (0) 6324 #define zig_atomicrmw_max_int128(res, obj, arg, order, Type, ReprType) do { \ 6325 zig_##Type zig_atomicrmw_expected; \ 6326 zig_##Type zig_atomicrmw_desired; \ 6327 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \ 6328 do { \ 6329 zig_atomicrmw_desired = zig_max_##Type(zig_atomicrmw_expected, arg); \ 6330 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \ 6331 res = zig_atomicrmw_expected; \ 6332 } while (0) 6333 6334 #if (__STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)) || (zig_has_include(<stdatomic.h>) && !defined(zig_msvc)) 6335 #define zig_c11_atomics 6336 #endif 6337 6338 #if defined(zig_c11_atomics) 6339 #include <stdatomic.h> 6340 typedef enum memory_order zig_memory_order; 6341 #define zig_memory_order_relaxed memory_order_relaxed 6342 #define zig_memory_order_acquire memory_order_acquire 6343 #define zig_memory_order_release memory_order_release 6344 #define zig_memory_order_acq_rel memory_order_acq_rel 6345 #define zig_memory_order_seq_cst memory_order_seq_cst 6346 #define zig_atomic(Type) _Atomic(Type) 6347 #define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail) 6348 #define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail) 6349 #define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) res = atomic_exchange_explicit (obj, arg, order) 6350 #define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = atomic_fetch_add_explicit (obj, arg, order) 6351 #define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = atomic_fetch_sub_explicit (obj, arg, order) 6352 #define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = atomic_fetch_or_explicit (obj, arg, order) 6353 #define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = atomic_fetch_xor_explicit (obj, arg, order) 6354 #define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = atomic_fetch_and_explicit (obj, arg, order) 6355 #define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_nand(obj, arg, order) 6356 #define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_min (obj, arg, order) 6357 #define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_max (obj, arg, order) 6358 #define zig_atomic_store( obj, arg, order, Type, ReprType) atomic_store_explicit (obj, arg, order) 6359 #define zig_atomic_load(res, obj, order, Type, ReprType) res = atomic_load_explicit (obj, order) 6360 #undef zig_atomicrmw_xchg_float 6361 #define zig_atomicrmw_xchg_float zig_atomicrmw_xchg 6362 #undef zig_atomicrmw_add_float 6363 #define zig_atomicrmw_add_float zig_atomicrmw_add 6364 #undef zig_atomicrmw_sub_float 6365 #define zig_atomicrmw_sub_float zig_atomicrmw_sub 6366 #elif defined(zig_gnuc) 6367 typedef int zig_memory_order; 6368 #define zig_memory_order_relaxed __ATOMIC_RELAXED 6369 #define zig_memory_order_acquire __ATOMIC_ACQUIRE 6370 #define zig_memory_order_release __ATOMIC_RELEASE 6371 #define zig_memory_order_acq_rel __ATOMIC_ACQ_REL 6372 #define zig_memory_order_seq_cst __ATOMIC_SEQ_CST 6373 #define zig_atomic(Type) Type 6374 #define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, (ReprType *)&(expected), (ReprType *)&(desired), false, succ, fail) 6375 #define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, (ReprType *)&(expected), (ReprType *)&(desired), true, succ, fail) 6376 #define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) __atomic_exchange(obj, (ReprType *)&(arg), &(res), order) 6377 #define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_add (obj, arg, order) 6378 #define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_sub (obj, arg, order) 6379 #define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_or (obj, arg, order) 6380 #define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_xor (obj, arg, order) 6381 #define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_and (obj, arg, order) 6382 #define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_nand(obj, arg, order) 6383 #define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_min (obj, arg, order) 6384 #define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_max (obj, arg, order) 6385 #define zig_atomic_store( obj, arg, order, Type, ReprType) __atomic_store (obj, (ReprType *)&(arg), order) 6386 #define zig_atomic_load(res, obj, order, Type, ReprType) __atomic_load (obj, &(res), order) 6387 #undef zig_atomicrmw_xchg_float 6388 #define zig_atomicrmw_xchg_float zig_atomicrmw_xchg 6389 #elif defined(zig_msvc) && defined(zig_x86) 6390 #define zig_memory_order_relaxed 0 6391 #define zig_memory_order_acquire 2 6392 #define zig_memory_order_release 3 6393 #define zig_memory_order_acq_rel 4 6394 #define zig_memory_order_seq_cst 5 6395 #define zig_atomic(Type) Type 6396 #define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_msvc_cmpxchg_##Type(obj, &(expected), desired) 6397 #define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) zig_cmpxchg_strong(obj, expected, desired, succ, fail, Type, ReprType) 6398 #define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_xchg_##Type(obj, arg) 6399 #define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_add_ ##Type(obj, arg) 6400 #define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_sub_ ##Type(obj, arg) 6401 #define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_or_ ##Type(obj, arg) 6402 #define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_xor_ ##Type(obj, arg) 6403 #define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_and_ ##Type(obj, arg) 6404 #define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_nand_##Type(obj, arg) 6405 #define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_min_ ##Type(obj, arg) 6406 #define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_max_ ##Type(obj, arg) 6407 #define zig_atomic_store( obj, arg, order, Type, ReprType) zig_msvc_atomic_store_ ##Type(obj, arg) 6408 #define zig_atomic_load(res, obj, order, Type, ReprType) res = zig_msvc_atomic_load_ ##order##_##Type(obj) 6409 /* TODO: zig_msvc && (zig_thumb || zig_aarch64) */ 6410 #else 6411 #define zig_memory_order_relaxed 0 6412 #define zig_memory_order_acquire 2 6413 #define zig_memory_order_release 3 6414 #define zig_memory_order_acq_rel 4 6415 #define zig_memory_order_seq_cst 5 6416 #define zig_atomic(Type) Type 6417 #define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable 6418 #define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable 6419 #define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable 6420 #define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable 6421 #define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable 6422 #define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable 6423 #define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable 6424 #define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable 6425 #define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable 6426 #define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable 6427 #define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable 6428 #define zig_atomic_store( obj, arg, order, Type, ReprType) zig_atomics_unavailable 6429 #define zig_atomic_load(res, obj, order, Type, ReprType) zig_atomics_unavailable 6430 #endif 6431 6432 #if !defined(zig_c11_atomics) && defined(zig_msvc) && defined(zig_x86) 6433 6434 /* TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 */ 6435 6436 #define zig_msvc_atomics(ZigType, Type, SigType, suffix, iso_suffix) \ 6437 static inline bool zig_msvc_cmpxchg_##ZigType(Type volatile* obj, Type* expected, Type desired) { \ 6438 Type comparand = *expected; \ 6439 Type initial = _InterlockedCompareExchange##suffix((SigType volatile*)obj, (SigType)desired, (SigType)comparand); \ 6440 bool exchanged = initial == comparand; \ 6441 if (!exchanged) { \ 6442 *expected = initial; \ 6443 } \ 6444 return exchanged; \ 6445 } \ 6446 static inline Type zig_msvc_atomicrmw_xchg_##ZigType(Type volatile* obj, Type value) { \ 6447 return _InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \ 6448 } \ 6449 static inline Type zig_msvc_atomicrmw_add_##ZigType(Type volatile* obj, Type value) { \ 6450 return _InterlockedExchangeAdd##suffix((SigType volatile*)obj, (SigType)value); \ 6451 } \ 6452 static inline Type zig_msvc_atomicrmw_sub_##ZigType(Type volatile* obj, Type value) { \ 6453 bool success = false; \ 6454 Type new; \ 6455 Type prev; \ 6456 while (!success) { \ 6457 prev = *obj; \ 6458 new = prev - value; \ 6459 success = zig_msvc_cmpxchg_##ZigType(obj, &prev, new); \ 6460 } \ 6461 return prev; \ 6462 } \ 6463 static inline Type zig_msvc_atomicrmw_or_##ZigType(Type volatile* obj, Type value) { \ 6464 return _InterlockedOr##suffix((SigType volatile*)obj, (SigType)value); \ 6465 } \ 6466 static inline Type zig_msvc_atomicrmw_xor_##ZigType(Type volatile* obj, Type value) { \ 6467 return _InterlockedXor##suffix((SigType volatile*)obj, (SigType)value); \ 6468 } \ 6469 static inline Type zig_msvc_atomicrmw_and_##ZigType(Type volatile* obj, Type value) { \ 6470 return _InterlockedAnd##suffix((SigType volatile*)obj, (SigType)value); \ 6471 } \ 6472 static inline Type zig_msvc_atomicrmw_nand_##ZigType(Type volatile* obj, Type value) { \ 6473 bool success = false; \ 6474 Type new; \ 6475 Type prev; \ 6476 while (!success) { \ 6477 prev = *obj; \ 6478 new = ~(prev & value); \ 6479 success = zig_msvc_cmpxchg_##ZigType(obj, &prev, new); \ 6480 } \ 6481 return prev; \ 6482 } \ 6483 static inline Type zig_msvc_atomicrmw_min_##ZigType(Type volatile* obj, Type value) { \ 6484 bool success = false; \ 6485 Type new; \ 6486 Type prev; \ 6487 while (!success) { \ 6488 prev = *obj; \ 6489 new = value < prev ? value : prev; \ 6490 success = zig_msvc_cmpxchg_##ZigType(obj, &prev, new); \ 6491 } \ 6492 return prev; \ 6493 } \ 6494 static inline Type zig_msvc_atomicrmw_max_##ZigType(Type volatile* obj, Type value) { \ 6495 bool success = false; \ 6496 Type new; \ 6497 Type prev; \ 6498 while (!success) { \ 6499 prev = *obj; \ 6500 new = value > prev ? value : prev; \ 6501 success = zig_msvc_cmpxchg_##ZigType(obj, &prev, new); \ 6502 } \ 6503 return prev; \ 6504 } \ 6505 static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \ 6506 (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \ 6507 } \ 6508 static inline Type zig_msvc_atomic_load_zig_memory_order_relaxed_##ZigType(Type volatile* obj) { \ 6509 return __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ 6510 } \ 6511 static inline Type zig_msvc_atomic_load_zig_memory_order_acquire_##ZigType(Type volatile* obj) { \ 6512 Type value = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ 6513 _ReadWriteBarrier(); \ 6514 return value; \ 6515 } \ 6516 static inline Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##ZigType(Type volatile* obj) { \ 6517 Type value = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ 6518 _ReadWriteBarrier(); \ 6519 return value; \ 6520 } 6521 6522 zig_msvc_atomics( u8, uint8_t, char, 8, 8) 6523 zig_msvc_atomics( i8, int8_t, char, 8, 8) 6524 zig_msvc_atomics(u16, uint16_t, short, 16, 16) 6525 zig_msvc_atomics(i16, int16_t, short, 16, 16) 6526 zig_msvc_atomics(u32, uint32_t, long, , 32) 6527 zig_msvc_atomics(i32, int32_t, long, , 32) 6528 6529 #if defined(zig_x86_64) 6530 zig_msvc_atomics(u64, uint64_t, __int64, 64, 64) 6531 zig_msvc_atomics(i64, int64_t, __int64, 64, 64) 6532 #endif 6533 6534 #define zig_msvc_flt_atomics(Type, SigType, suffix, iso_suffix) \ 6535 static inline bool zig_msvc_cmpxchg_##Type(zig_##Type volatile* obj, zig_##Type* expected, zig_##Type desired) { \ 6536 SigType exchange; \ 6537 SigType comparand; \ 6538 SigType initial; \ 6539 bool success; \ 6540 memcpy(&comparand, expected, sizeof(comparand)); \ 6541 memcpy(&exchange, &desired, sizeof(exchange)); \ 6542 initial = _InterlockedCompareExchange##suffix((SigType volatile*)obj, exchange, comparand); \ 6543 success = initial == comparand; \ 6544 if (!success) memcpy(expected, &initial, sizeof(*expected)); \ 6545 return success; \ 6546 } \ 6547 static inline void zig_msvc_atomic_store_##Type(zig_##Type volatile* obj, zig_##Type arg) { \ 6548 SigType value; \ 6549 memcpy(&value, &arg, sizeof(value)); \ 6550 (void)_InterlockedExchange##suffix((SigType volatile*)obj, value); \ 6551 } \ 6552 static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_relaxed_##Type(zig_##Type volatile* obj) { \ 6553 zig_##Type result; \ 6554 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ 6555 memcpy(&result, &initial, sizeof(result)); \ 6556 return result; \ 6557 } \ 6558 static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_acquire_##Type(zig_##Type volatile* obj) { \ 6559 zig_##Type result; \ 6560 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ 6561 _ReadWriteBarrier(); \ 6562 memcpy(&result, &initial, sizeof(result)); \ 6563 return result; \ 6564 } \ 6565 static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##Type(zig_##Type volatile* obj) { \ 6566 zig_##Type result; \ 6567 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \ 6568 _ReadWriteBarrier(); \ 6569 memcpy(&result, &initial, sizeof(result)); \ 6570 return result; \ 6571 } 6572 6573 zig_msvc_flt_atomics(f32, long, , 32) 6574 #if defined(zig_x86_64) 6575 zig_msvc_flt_atomics(f64, int64_t, 64, 64) 6576 #endif 6577 6578 #if defined(zig_x86_32) 6579 static inline void zig_msvc_atomic_barrier() { 6580 int32_t barrier; 6581 __asm { 6582 xchg barrier, eax 6583 } 6584 } 6585 6586 static inline void* zig_msvc_atomicrmw_xchg_p32(void volatile* obj, void* arg) { 6587 return _InterlockedExchangePointer(obj, arg); 6588 } 6589 6590 static inline void zig_msvc_atomic_store_p32(void volatile* obj, void* arg) { 6591 (void)_InterlockedExchangePointer(obj, arg); 6592 } 6593 6594 static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p32(void volatile* obj) { 6595 return (void*)__iso_volatile_load32(obj); 6596 } 6597 6598 static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p32(void volatile* obj) { 6599 void* value = (void*)__iso_volatile_load32(obj); 6600 _ReadWriteBarrier(); 6601 return value; 6602 } 6603 6604 static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p32(void volatile* obj) { 6605 return zig_msvc_atomic_load_zig_memory_order_acquire_p32(obj); 6606 } 6607 6608 static inline bool zig_msvc_cmpxchg_p32(void volatile* obj, void* expected, void* desired) { 6609 void* comparand = *(void**)expected; 6610 void* initial = _InterlockedCompareExchangePointer(obj, desired, comparand); 6611 bool success = initial == comparand; 6612 if (!success) *(void**)expected = initial; 6613 return success; 6614 } 6615 #else /* zig_x86_32 */ 6616 static inline void* zig_msvc_atomicrmw_xchg_p64(void volatile* obj, void* arg) { 6617 return _InterlockedExchangePointer(obj, arg); 6618 } 6619 6620 static inline void zig_msvc_atomic_store_p64(void volatile* obj, void* arg) { 6621 (void)_InterlockedExchangePointer(obj, arg); 6622 } 6623 6624 static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p64(void volatile* obj) { 6625 return (void*)__iso_volatile_load64(obj); 6626 } 6627 6628 static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p64(void volatile* obj) { 6629 void* value = (void*)__iso_volatile_load64(obj); 6630 _ReadWriteBarrier(); 6631 return value; 6632 } 6633 6634 static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p64(void volatile* obj) { 6635 return zig_msvc_atomic_load_zig_memory_order_acquire_p64(obj); 6636 } 6637 6638 static inline bool zig_msvc_cmpxchg_p64(void volatile* obj, void* expected, void* desired) { 6639 void* comparand = *(void**)expected; 6640 void* initial = _InterlockedCompareExchangePointer(obj, desired, comparand); 6641 bool success = initial == comparand; 6642 if (!success) *(void**)expected = initial; 6643 return success; 6644 } 6645 6646 static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128* expected, zig_u128 desired) { 6647 return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_u128(desired), (__int64)zig_lo_u128(desired), (__int64*)expected); 6648 } 6649 6650 static inline zig_u128 zig_msvc_atomic_load_u128(zig_u128 volatile* obj) { 6651 zig_u128 expected = zig_make_u128(UINT64_C(0), UINT64_C(0)); 6652 (void)zig_cmpxchg_strong(obj, expected, expected, zig_memory_order_seq_cst, zig_memory_order_seq_cst, u128, zig_u128); 6653 return expected; 6654 } 6655 6656 static inline void zig_msvc_atomic_store_u128(zig_u128 volatile* obj, zig_u128 arg) { 6657 zig_u128 expected = zig_make_u128(UINT64_C(0), UINT64_C(0)); 6658 while (!zig_cmpxchg_weak(obj, expected, arg, zig_memory_order_seq_cst, zig_memory_order_seq_cst, u128, zig_u128)); 6659 } 6660 6661 static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) { 6662 return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_i128(desired), (__int64)zig_lo_i128(desired), (__int64*)expected); 6663 } 6664 6665 static inline zig_i128 zig_msvc_atomic_load_i128(zig_i128 volatile* obj) { 6666 zig_i128 expected = zig_make_i128(INT64_C(0), UINT64_C(0)); 6667 (void)zig_cmpxchg_strong(obj, expected, expected, zig_memory_order_seq_cst, zig_memory_order_seq_cst, i128, zig_i128); 6668 return expected; 6669 } 6670 6671 static inline void zig_msvc_atomic_store_i128(zig_i128 volatile* obj, zig_i128 arg) { 6672 zig_i128 expected = zig_make_i128(INT64_C(0), UINT64_C(0)); 6673 while (!zig_cmpxchg_weak(obj, expected, arg, zig_memory_order_seq_cst, zig_memory_order_seq_cst, i128, zig_i128)); 6674 } 6675 6676 #endif /* zig_x86_32 */ 6677 6678 #endif /* !zig_c11_atomics && zig_msvc && zig_x86 */ 6679 6680 /* ======================== Special Case Intrinsics ========================= */ 6681 6682 #if defined(zig_msvc) 6683 #include <intrin.h> 6684 #endif 6685 6686 static inline void* zig_e_zig_windows_teb(void) zig_mangled(zig_e_zig_windows_teb, "zig_windows_teb"); 6687 static inline void* zig_e_zig_windows_peb(void) zig_mangled(zig_e_zig_windows_peb, "zig_windows_peb"); 6688 6689 #if defined(zig_thumb) 6690 6691 static inline void* zig_e_zig_windows_teb(void) { 6692 void* teb = 0; 6693 #if defined(zig_msvc) 6694 teb = (void*)_MoveFromCoprocessor(15, 0, 13, 0, 2); 6695 #elif defined(zig_gnuc_asm) 6696 __asm__ ("mrc p15, 0, %[ptr], c13, c0, 2" : [ptr] "=r" (teb)); 6697 #endif 6698 return teb; 6699 } 6700 6701 #elif defined(zig_aarch64) 6702 6703 static inline void* zig_e_zig_windows_teb(void) { 6704 void* teb = 0; 6705 #if defined(zig_msvc) 6706 teb = (void*)__readx18qword(0x0); 6707 #elif defined(zig_gnuc_asm) 6708 __asm__ ("mov %[ptr], x18" : [ptr] "=r" (teb)); 6709 #endif 6710 return teb; 6711 } 6712 6713 #elif defined(zig_x86_32) 6714 6715 static inline void* zig_e_zig_windows_teb(void) { 6716 void* teb = 0; 6717 #if defined(zig_msvc) 6718 teb = (void*)__readfsdword(0x18); 6719 #elif defined(zig_gnuc_asm) 6720 __asm__ ("movl %%fs:0x18, %[ptr]" : [ptr] "=r" (teb)); 6721 #endif 6722 return teb; 6723 } 6724 6725 static inline void* zig_e_zig_windows_peb(void) { 6726 void* peb = 0; 6727 #if defined(zig_msvc) 6728 peb = (void*)__readfsdword(0x30); 6729 #elif defined(zig_gnuc_asm) 6730 __asm__ ("movl %%fs:0x30, %[ptr]" : [ptr] "=r" (peb)); 6731 #endif 6732 return peb; 6733 } 6734 6735 #elif defined(zig_x86_64) 6736 6737 static inline void* zig_e_zig_windows_teb(void) { 6738 void* teb = 0; 6739 #if defined(zig_msvc) 6740 teb = (void*)__readgsqword(0x30); 6741 #elif defined(zig_gnuc_asm) 6742 __asm__ ("movq %%gs:0x30, %[ptr]" : [ptr] "=r" (teb)); 6743 #endif 6744 return teb; 6745 } 6746 6747 static inline void* zig_e_zig_windows_peb(void) { 6748 void* peb = 0; 6749 #if defined(zig_msvc) 6750 peb = (void*)__readgsqword(0x60); 6751 #elif defined(zig_gnuc_asm) 6752 __asm__ ("movq %%gs:0x60, %[ptr]" : [ptr] "=r" (peb)); 6753 #endif 6754 return peb; 6755 } 6756 6757 #endif 6758 6759 #if defined(zig_x86) && !defined(zig_x86_16) 6760 6761 static inline void zig_e_zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) zig_mangled(zig_e_zig_x86_cpuid, "zig_x86_cpuid"); 6762 static inline uint32_t zig_e_zig_x86_get_xcr0(void) zig_mangled(zig_e_zig_x86_get_xcr0, "zig_x86_get_xcr0"); 6763 6764 static inline void zig_e_zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) { 6765 #if defined(zig_msvc) 6766 int cpu_info[4]; 6767 __cpuidex(cpu_info, leaf_id, subid); 6768 *eax = (uint32_t)cpu_info[0]; 6769 *ebx = (uint32_t)cpu_info[1]; 6770 *ecx = (uint32_t)cpu_info[2]; 6771 *edx = (uint32_t)cpu_info[3]; 6772 #elif defined(zig_gnuc_asm) 6773 __asm__("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "a" (leaf_id), "c" (subid)); 6774 #else 6775 *eax = 0; 6776 *ebx = 0; 6777 *ecx = 0; 6778 *edx = 0; 6779 #endif 6780 } 6781 6782 static inline uint32_t zig_e_zig_x86_get_xcr0(void) { 6783 #if defined(zig_msvc) 6784 return (uint32_t)_xgetbv(0); 6785 #elif defined(zig_gnuc_asm) 6786 uint32_t eax; 6787 uint32_t edx; 6788 __asm__("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0)); 6789 return eax; 6790 #else 6791 return 0; 6792 #endif 6793 } 6794 6795 #endif 6796