zig

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

commit 767f28d7a631cc0e235dc3f6bbd260395a911010 (tree)
parent 09aa4add2a00454077b5421204acf5e96b6d51cf
Author: Alex Rønne Petersen <alex@alexrp.com>
Date:   Thu, 30 Oct 2025 01:41:32 +0100

Merge pull request #25733 from GasInfinity-Forks/x86_16-cpu_context

* fix: add `i86` cpu in `update_cpu_features`
* feat: add `x86_16` debug `cpu_context`
Diffstat:
Mlib/std/Target/x86.zig | 4+++-
Mlib/std/debug/cpu_context.zig | 41+++++++++++++++++++++++++++++++++++++++++
Mtools/update_cpu_features.zig | 7+++++++
3 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/lib/std/Target/x86.zig b/lib/std/Target/x86.zig @@ -3084,7 +3084,9 @@ pub const cpu = struct { pub const @"i86": CpuModel = .{ .name = "i86", .llvm_name = null, - .features = featureSet(&[_]Feature{}), + .features = featureSet(&[_]Feature{ + .@"16bit_mode", + }), }; pub const @"i386": CpuModel = .{ .name = "i386", diff --git a/lib/std/debug/cpu_context.zig b/lib/std/debug/cpu_context.zig @@ -19,6 +19,7 @@ else switch (native_arch) { .riscv32, .riscv32be, .riscv64, .riscv64be => Riscv, .ve => Ve, .s390x => S390x, + .x86_16 => X86_16, .x86 => X86, .x86_64 => X86_64, else => noreturn, @@ -1350,6 +1351,46 @@ const Ve = extern struct { } }; +const X86_16 = struct { + pub const Register = enum { + // zig fmt: off + sp, bp, ss, + ip, cs, + // zig fmt: on + }; + + regs: std.enums.EnumArray(Register, u16), + + pub inline fn current() X86_16 { + var ctx: X86_16 = undefined; + asm volatile ( + \\ movw %%sp, 0x00(%%di) + \\ movw %%bp, 0x02(%%di) + \\ movw %%ss, 0x04(%%di) + \\ pushw %%cs + \\ call 1f + \\1: + \\ popw 0x06(%%di) + \\ popw 0x08(%%di) + : + : [gprs] "{di}" (&ctx.regs.values), + : .{ .memory = true }); + return ctx; + } + + // NOTE: There doesn't seem to be any standard for DWARF x86-16 so we'll just reuse the ones for x86. + pub fn dwarfRegisterBytes(ctx: *X86_16, register_num: u16) DwarfRegisterError![]u8 { + switch (register_num) { + 4 => return @ptrCast(ctx.regs.getPtr(.sp)), + 5 => return @ptrCast(ctx.regs.getPtr(.bp)), + 6 => return @ptrCast(ctx.regs.getPtr(.ip)), + 41 => return @ptrCast(ctx.regs.getPtr(.cs)), + 42 => return @ptrCast(ctx.regs.getPtr(.ss)), + else => return error.InvalidRegister, + } + } +}; + const X86 = struct { /// The first 8 registers here intentionally match the order of registers in the x86 instruction /// encoding. This order is inherited by the PUSHA instruction and the DWARF register mappings, diff --git a/tools/update_cpu_features.zig b/tools/update_cpu_features.zig @@ -1563,6 +1563,13 @@ const targets = [_]ArchTarget{ .deps = &.{}, }, }, + .extra_cpus = &.{ + .{ + .llvm_name = null, + .zig_name = "i86", + .features = &.{"16bit_mode"}, + }, + }, .omit_cpus = &.{ // LLVM defines a bunch of dumb aliases with foreach loops in X86.td. "pentium_mmx",