From a0396faf3b8bb515e37ffb51a9c5e161953cdbbf Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Fri, 19 Sep 2025 16:26:35 -0700 Subject: [PATCH] Fix control/debug register patterns The control and debug registers are always using the default operand size. It is probably easiest to just encode it explicitly for now. Control registers are particularly weird because of the AMD "lock as REX.R" hack... Signed-off-by: H. Peter Anvin (Intel) --- asm/assemble.c | 2 +- x86/insns.dat | 12 ++++++++---- x86/preinsns.pl | 9 +++++---- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/asm/assemble.c b/asm/assemble.c index 7a832322..321f9659 100644 --- a/asm/assemble.c +++ b/asm/assemble.c @@ -2343,7 +2343,7 @@ static inline void emit_rex(struct out_data *data, insn *ins) } else if (rex & REX_P) { buf[n++] = rex; } else { - nasm_assert(!rex); + nasm_assert(!(rex & ~REX_L)); } if (ins->vex_cm) { diff --git a/x86/insns.dat b/x86/insns.dat index a0f2e33a..219e3269 100644 --- a/x86/insns.dat +++ b/x86/insns.dat @@ -469,10 +469,14 @@ $dq RDPID reg# [m: f3 !osp o# 0f c7 /7] RDPID SMSW reg64 [m: o64nw 0f 01 /4] X86_64,LONG,ND $wdq SMSW reg# [m: o# 0f 01 /4] 286 -$dq MOV reg#,reg_creg [mr: nw w# rex.l 0f 20 /r] 386,PRIV -$dq MOV reg_creg,reg# [rm: nw w# rex.l 0f 22 /r] 386,PRIV -$dq MOV reg#,reg_dreg [mr: nw w# 0f 21 /r] 386,PRIV -$dq MOV reg_dreg,reg# [rm: nw w# 0f 23 /r] 386,PRIV,NOLONG + MOV reg32,reg_creg [mr: rex.l 0f 20 /r] 386,NOLONG,PRIV + MOV reg_creg,reg32 [rm: rex.l 0f 22 /r] 386,NOLONG,PRIV + MOV reg64,reg_creg [mr: o64nw 0f 20 /r] X86_64,LONG,PRIV + MOV reg_creg,reg64 [rm: o64nw 0f 22 /r] X86_64,LONG,PRIV + MOV reg32,reg_dreg [mr: 0f 21 /r] 386,NOLONG,PRIV + MOV reg_dreg,reg32 [rm: 0f 23 /r] 386,NOLONG,PRIV + MOV reg64,reg_dreg [mr: o64nw 0f 21 /r] X86_64,LONG,PRIV + MOV reg_dreg,reg64 [rm: o64nw 0f 23 /r] X86_64,LONG,PRIV MOV reg32,reg_treg [mr: 0f 24 /r] 386,NOLONG,ND,OBSOLETE MOV reg_treg,reg32 [rm: 0f 26 /r] 386,NOLONG,ND,OBSOLETE diff --git a/x86/preinsns.pl b/x86/preinsns.pl index 16b9465c..992eb973 100755 --- a/x86/preinsns.pl +++ b/x86/preinsns.pl @@ -204,7 +204,9 @@ sub func_multisize($$$) { $o .= ',NOLONG' if ($long & 2); $o .= ',ND' if ($nd); - $o .= ',386' if ($s >= 32 && $o !~ /\B\!386\b/); + if ($s >= 32 && $o !~ /\B\!386\b/ && $o =~ /\b(8086|[12]86)\b/) { + $o .= ',386'; + } push(@ol, $o); } @@ -499,10 +501,9 @@ sub adjust_instruction_flags(@) { return undef; } - if ($i[2] =~ /\ba16\b/) { + if ($i[2] =~ /\b(a16|rex\.l)\b/) { add_flag($i[3], 'NOLONG'); - } - if ($i[2] =~ /\b(o64(nw)?\b|rex2?|a64\b)/) { + } elsif ($i[2] =~ /\b(o64(nw)?\b|rex2?|a64\b)/) { add_flag($i[3], 'LONG'); } if (has_flag($i[3], 'NOLONG') && has_flag($i[3], 'LONG')) {