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:
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",