From e818cab3f1fc4a3d4d0b8e2c9424fb2e7b1dff70 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Fri, 2 Aug 2024 01:20:40 +0200 Subject: *: use a generic UserRegs type everywhere I'm storing registers mostly inspired by Plan 9's Ureg, probably obvious from the name --- src/kernel/arch/amd64/regs.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/kernel/arch/amd64/regs.c (limited to 'src/kernel/arch/amd64/regs.c') diff --git a/src/kernel/arch/amd64/regs.c b/src/kernel/arch/amd64/regs.c new file mode 100644 index 0000000..bb4e5aa --- /dev/null +++ b/src/kernel/arch/amd64/regs.c @@ -0,0 +1,26 @@ +#include +#include + +void +regs_safecopy(UserRegs *dst, const UserRegs *src) +{ + /* preserved flags: (see intel vol 1 3.4.3.) + * 1<<0 = CF, carry flag + * 1<<2 = PF, parity flag + * 1<<4 = AC, auxilary carry + * 1<<6 = ZF, zero flag + * 1<<7 = SF, sign flag + * 1<<11 = OF, overflow flag + * 1<<10 = DF, direction flag + */ + static_assert( + ((1<<0) | (1<<2) | (1<<4) | (1<<6) | (1<<7) | (1<<10) | (1<<11)) + == 0xCD5 + ); + + uint64_t newflags = (src->flags & 0xCD5) | (dst->flags & ~0xCD5); + /* I "spelled it out" directly instead of using memcpy hoping that gcc + * maybe would notice it can skip copying the last 8 bytes. It didn't :( */ + *dst = *src; + dst->flags = newflags; +} -- cgit v1.2.3