mirror of
https://github.com/Motorhead1991/qemu.git
synced 2026-02-12 11:59:28 -07:00
target/i386: ignore misplaced REX prefixes
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
ac2c4d3aed
commit
336dbe8e99
1 changed files with 27 additions and 9 deletions
|
|
@ -2542,7 +2542,13 @@ static void disas_insn(DisasContext *s, CPUState *cpu)
|
|||
s->has_modrm = false;
|
||||
s->prefix = 0;
|
||||
|
||||
next_byte:
|
||||
next_byte:;
|
||||
#ifdef TARGET_X86_64
|
||||
/* clear any REX prefix followed by other prefixes. */
|
||||
int rex;
|
||||
rex = -1;
|
||||
next_byte_rex:
|
||||
#endif
|
||||
b = x86_ldub_code(env, s);
|
||||
|
||||
/* Collect prefixes. */
|
||||
|
|
@ -2585,13 +2591,12 @@ static void disas_insn(DisasContext *s, CPUState *cpu)
|
|||
#ifdef TARGET_X86_64
|
||||
case 0x40 ... 0x4f:
|
||||
if (CODE64(s)) {
|
||||
/* REX prefix */
|
||||
s->prefix |= PREFIX_REX;
|
||||
s->vex_w = (b >> 3) & 1;
|
||||
s->rex_r = (b & 0x4) << 1;
|
||||
s->rex_x = (b & 0x2) << 2;
|
||||
s->rex_b = (b & 0x1) << 3;
|
||||
goto next_byte;
|
||||
/*
|
||||
* REX prefix; ignored unless it is the last prefix, so
|
||||
* for now just stash it
|
||||
*/
|
||||
rex = b;
|
||||
goto next_byte_rex;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
|
@ -2618,10 +2623,13 @@ static void disas_insn(DisasContext *s, CPUState *cpu)
|
|||
|
||||
/* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
|
||||
if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ
|
||||
| PREFIX_LOCK | PREFIX_DATA | PREFIX_REX)) {
|
||||
| PREFIX_LOCK | PREFIX_DATA)) {
|
||||
goto illegal_op;
|
||||
}
|
||||
#ifdef TARGET_X86_64
|
||||
if (rex != -1) {
|
||||
goto illegal_op;
|
||||
}
|
||||
s->rex_r = (~vex2 >> 4) & 8;
|
||||
#endif
|
||||
if (b == 0xc5) {
|
||||
|
|
@ -2661,6 +2669,16 @@ static void disas_insn(DisasContext *s, CPUState *cpu)
|
|||
|
||||
/* Post-process prefixes. */
|
||||
if (CODE64(s)) {
|
||||
#ifdef TARGET_X86_64
|
||||
if (rex != -1) {
|
||||
s->prefix |= PREFIX_REX;
|
||||
s->vex_w = (rex >> 3) & 1;
|
||||
s->rex_r = (rex & 0x4) << 1;
|
||||
s->rex_x = (rex & 0x2) << 2;
|
||||
s->rex_b = (rex & 0x1) << 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* In 64-bit mode, the default data size is 32-bit. Select 64-bit
|
||||
* data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue