summaryrefslogtreecommitdiff
path: root/target-i386/translate.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2013-01-10 13:29:23 -0800
committerRichard Henderson <rth@twiddle.net>2013-02-18 15:39:38 -0800
commit4a6fd938f5457ee161d2acbd9364608a2a68b7a1 (patch)
tree8c35fbfb0e3a34045bafe18500a82a0c3bc62ab1 /target-i386/translate.c
parent988c3eb0d6f41ac13f4ec145c637f12c776de602 (diff)
downloadqemu-4a6fd938f5457ee161d2acbd9364608a2a68b7a1.tar.gz
qemu-4a6fd938f5457ee161d2acbd9364608a2a68b7a1.tar.bz2
qemu-4a6fd938f5457ee161d2acbd9364608a2a68b7a1.zip
target-i386: Tidy prefix parsing
Avoid duplicating switch statement between 32 and 64-bit modes. Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-i386/translate.c')
-rw-r--r--target-i386/translate.c134
1 files changed, 52 insertions, 82 deletions
diff --git a/target-i386/translate.c b/target-i386/translate.c
index f667f9333b..e5cda94805 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -4267,44 +4267,44 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
next_byte:
b = cpu_ldub_code(env, s->pc);
s->pc++;
- /* check prefixes */
+ /* Collect prefixes. */
+ switch (b) {
+ case 0xf3:
+ prefixes |= PREFIX_REPZ;
+ goto next_byte;
+ case 0xf2:
+ prefixes |= PREFIX_REPNZ;
+ goto next_byte;
+ case 0xf0:
+ prefixes |= PREFIX_LOCK;
+ goto next_byte;
+ case 0x2e:
+ s->override = R_CS;
+ goto next_byte;
+ case 0x36:
+ s->override = R_SS;
+ goto next_byte;
+ case 0x3e:
+ s->override = R_DS;
+ goto next_byte;
+ case 0x26:
+ s->override = R_ES;
+ goto next_byte;
+ case 0x64:
+ s->override = R_FS;
+ goto next_byte;
+ case 0x65:
+ s->override = R_GS;
+ goto next_byte;
+ case 0x66:
+ prefixes |= PREFIX_DATA;
+ goto next_byte;
+ case 0x67:
+ prefixes |= PREFIX_ADR;
+ goto next_byte;
#ifdef TARGET_X86_64
- if (CODE64(s)) {
- switch (b) {
- case 0xf3:
- prefixes |= PREFIX_REPZ;
- goto next_byte;
- case 0xf2:
- prefixes |= PREFIX_REPNZ;
- goto next_byte;
- case 0xf0:
- prefixes |= PREFIX_LOCK;
- goto next_byte;
- case 0x2e:
- s->override = R_CS;
- goto next_byte;
- case 0x36:
- s->override = R_SS;
- goto next_byte;
- case 0x3e:
- s->override = R_DS;
- goto next_byte;
- case 0x26:
- s->override = R_ES;
- goto next_byte;
- case 0x64:
- s->override = R_FS;
- goto next_byte;
- case 0x65:
- s->override = R_GS;
- goto next_byte;
- case 0x66:
- prefixes |= PREFIX_DATA;
- goto next_byte;
- case 0x67:
- prefixes |= PREFIX_ADR;
- goto next_byte;
- case 0x40 ... 0x4f:
+ case 0x40 ... 0x4f:
+ if (CODE64(s)) {
/* REX prefix */
rex_w = (b >> 3) & 1;
rex_r = (b & 0x4) << 1;
@@ -4313,58 +4313,28 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
x86_64_hregs = 1; /* select uniform byte register addressing */
goto next_byte;
}
+ break;
+#endif
+ }
+
+ /* Post-process prefixes. */
+ if (prefixes & PREFIX_DATA) {
+ dflag ^= 1;
+ }
+ if (prefixes & PREFIX_ADR) {
+ aflag ^= 1;
+ }
+#ifdef TARGET_X86_64
+ if (CODE64(s)) {
if (rex_w == 1) {
/* 0x66 is ignored if rex.w is set */
dflag = 2;
- } else {
- if (prefixes & PREFIX_DATA)
- dflag ^= 1;
}
- if (!(prefixes & PREFIX_ADR))
+ if (!(prefixes & PREFIX_ADR)) {
aflag = 2;
- } else
-#endif
- {
- switch (b) {
- case 0xf3:
- prefixes |= PREFIX_REPZ;
- goto next_byte;
- case 0xf2:
- prefixes |= PREFIX_REPNZ;
- goto next_byte;
- case 0xf0:
- prefixes |= PREFIX_LOCK;
- goto next_byte;
- case 0x2e:
- s->override = R_CS;
- goto next_byte;
- case 0x36:
- s->override = R_SS;
- goto next_byte;
- case 0x3e:
- s->override = R_DS;
- goto next_byte;
- case 0x26:
- s->override = R_ES;
- goto next_byte;
- case 0x64:
- s->override = R_FS;
- goto next_byte;
- case 0x65:
- s->override = R_GS;
- goto next_byte;
- case 0x66:
- prefixes |= PREFIX_DATA;
- goto next_byte;
- case 0x67:
- prefixes |= PREFIX_ADR;
- goto next_byte;
}
- if (prefixes & PREFIX_DATA)
- dflag ^= 1;
- if (prefixes & PREFIX_ADR)
- aflag ^= 1;
}
+#endif
s->prefix = prefixes;
s->aflag = aflag;