0
0
mirror of https://github.com/netwide-assembler/nasm.git synced 2025-09-22 10:43:39 -04:00

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) <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin
2025-09-19 16:26:35 -07:00
parent b390ce4bb8
commit a0396faf3b
3 changed files with 14 additions and 9 deletions

View File

@@ -2343,7 +2343,7 @@ static inline void emit_rex(struct out_data *data, insn *ins)
} else if (rex & REX_P) { } else if (rex & REX_P) {
buf[n++] = rex; buf[n++] = rex;
} else { } else {
nasm_assert(!rex); nasm_assert(!(rex & ~REX_L));
} }
if (ins->vex_cm) { if (ins->vex_cm) {

View File

@@ -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 SMSW reg64 [m: o64nw 0f 01 /4] X86_64,LONG,ND
$wdq SMSW reg# [m: o# 0f 01 /4] 286 $wdq SMSW reg# [m: o# 0f 01 /4] 286
$dq MOV reg#,reg_creg [mr: nw w# rex.l 0f 20 /r] 386,PRIV MOV reg32,reg_creg [mr: rex.l 0f 20 /r] 386,NOLONG,PRIV
$dq MOV reg_creg,reg# [rm: nw w# rex.l 0f 22 /r] 386,PRIV MOV reg_creg,reg32 [rm: rex.l 0f 22 /r] 386,NOLONG,PRIV
$dq MOV reg#,reg_dreg [mr: nw w# 0f 21 /r] 386,PRIV MOV reg64,reg_creg [mr: o64nw 0f 20 /r] X86_64,LONG,PRIV
$dq MOV reg_dreg,reg# [rm: nw w# 0f 23 /r] 386,PRIV,NOLONG 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 reg32,reg_treg [mr: 0f 24 /r] 386,NOLONG,ND,OBSOLETE
MOV reg_treg,reg32 [rm: 0f 26 /r] 386,NOLONG,ND,OBSOLETE MOV reg_treg,reg32 [rm: 0f 26 /r] 386,NOLONG,ND,OBSOLETE

View File

@@ -204,7 +204,9 @@ sub func_multisize($$$) {
$o .= ',NOLONG' if ($long & 2); $o .= ',NOLONG' if ($long & 2);
$o .= ',ND' if ($nd); $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); push(@ol, $o);
} }
@@ -499,10 +501,9 @@ sub adjust_instruction_flags(@) {
return undef; return undef;
} }
if ($i[2] =~ /\ba16\b/) { if ($i[2] =~ /\b(a16|rex\.l)\b/) {
add_flag($i[3], 'NOLONG'); add_flag($i[3], 'NOLONG');
} } elsif ($i[2] =~ /\b(o64(nw)?\b|rex2?|a64\b)/) {
if ($i[2] =~ /\b(o64(nw)?\b|rex2?|a64\b)/) {
add_flag($i[3], 'LONG'); add_flag($i[3], 'LONG');
} }
if (has_flag($i[3], 'NOLONG') && has_flag($i[3], 'LONG')) { if (has_flag($i[3], 'NOLONG') && has_flag($i[3], 'LONG')) {