|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86/emul: Calculate not_64bit during instruction decode
commit 9b1f6622b68145931d6ff93ff4f37e6666bbcae1
Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Fri Jan 13 13:23:42 2017 +0000
Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Mon Jan 16 17:37:26 2017 +0000
x86/emul: Calculate not_64bit during instruction decode
... rather than repeating "generate_exception_if(mode_64bit(), EXC_UD);" in
the emulation switch statement.
Bloat-o-meter shows:
add/remove: 0/0 grow/shrink: 1/2 up/down: 8/-495 (-487)
function old new delta
per_cpu__state 98 106 +8
x86_decode 6782 6726 -56
x86_emulate 57160 56721 -439
The reason for x86_decode() getting smaller is that this change alters the
x86_decode_onebyte() switch statement from a chain of if()/else's to a jump
table. The jump table adds 250 bytes of data which bloat-o-meter clearly
can't see.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
xen/arch/x86/x86_emulate/x86_emulate.c | 47 +++++++++++++++++++++-------------
1 file changed, 29 insertions(+), 18 deletions(-)
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c
b/xen/arch/x86/x86_emulate/x86_emulate.c
index 445dcac..e9ac1fc 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -1907,6 +1907,7 @@ struct x86_emulate_state {
uint8_t modrm, modrm_mod, modrm_reg, modrm_rm;
uint8_t rex_prefix;
bool lock_prefix;
+ bool not_64bit; /* Instruction not available in 64bit. */
opcode_desc_t desc;
union vex vex;
union evex evex;
@@ -1957,6 +1958,30 @@ x86_decode_onebyte(
switch ( ctxt->opcode )
{
+ case 0x06: /* push %%es */
+ case 0x07: /* pop %%es */
+ case 0x0e: /* push %%cs */
+ case 0x16: /* push %%ss */
+ case 0x17: /* pop %%ss */
+ case 0x1e: /* push %%ds */
+ case 0x1f: /* pop %%ds */
+ case 0x27: /* daa */
+ case 0x2f: /* das */
+ case 0x37: /* aaa */
+ case 0x3f: /* aas */
+ case 0x60: /* pusha */
+ case 0x61: /* popa */
+ case 0x62: /* bound */
+ case 0x82: /* Grp1 (x86/32 only) */
+ case 0xc4: /* les */
+ case 0xc5: /* lds */
+ case 0xce: /* into */
+ case 0xd4: /* aam */
+ case 0xd5: /* aad */
+ case 0xd6: /* salc */
+ state->not_64bit = true;
+ break;
+
case 0x90: /* nop / pause */
if ( repe_prefix() )
ctxt->opcode |= X86EMUL_OPC_F3(0, 0);
@@ -2624,6 +2649,8 @@ x86_emulate(
d = state.desc;
#define state (&state)
+ generate_exception_if(state->not_64bit && mode_64bit(), EXC_UD);
+
if ( ea.type == OP_REG )
ea.reg = decode_register(modrm_rm, &_regs,
(d & ByteOp) && !rex_prefix);
@@ -2832,8 +2859,6 @@ x86_emulate(
case 0x0e: /* push %%cs */
case 0x16: /* push %%ss */
case 0x1e: /* push %%ds */
- generate_exception_if(mode_64bit(), EXC_UD);
- /* fall through */
case X86EMUL_OPC(0x0f, 0xa0): /* push %%fs */
case X86EMUL_OPC(0x0f, 0xa8): /* push %%gs */
fail_if(ops->read_segment == NULL);
@@ -2846,8 +2871,6 @@ x86_emulate(
case 0x07: /* pop %%es */
case 0x17: /* pop %%ss */
case 0x1f: /* pop %%ds */
- generate_exception_if(mode_64bit(), EXC_UD);
- /* fall through */
case X86EMUL_OPC(0x0f, 0xa1): /* pop %%fs */
case X86EMUL_OPC(0x0f, 0xa9): /* pop %%gs */
fail_if(ops->write_segment == NULL);
@@ -2868,7 +2891,6 @@ x86_emulate(
uint8_t al = _regs.al;
unsigned int eflags = _regs._eflags;
- generate_exception_if(mode_64bit(), EXC_UD);
_regs._eflags &= ~(EFLG_CF|EFLG_AF|EFLG_SF|EFLG_ZF|EFLG_PF);
if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) )
{
@@ -2890,7 +2912,6 @@ x86_emulate(
case 0x37: /* aaa */
case 0x3f: /* aas */
- generate_exception_if(mode_64bit(), EXC_UD);
_regs._eflags &= ~EFLG_CF;
if ( (_regs.al > 9) || (_regs._eflags & EFLG_AF) )
{
@@ -2935,7 +2956,6 @@ x86_emulate(
_regs._eax, _regs._ecx, _regs._edx, _regs._ebx,
_regs._esp, _regs._ebp, _regs._esi, _regs._edi };
- generate_exception_if(mode_64bit(), EXC_UD);
fail_if(!ops->write);
for ( i = 0; i < 8; i++ )
if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes),
@@ -2950,7 +2970,6 @@ x86_emulate(
&_regs._edi, &_regs._esi, &_regs._ebp, &dummy_esp,
&_regs._ebx, &_regs._edx, &_regs._ecx, &_regs._eax };
- generate_exception_if(mode_64bit(), EXC_UD);
for ( i = 0; i < 8; i++ )
{
if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes),
@@ -2967,8 +2986,7 @@ x86_emulate(
case 0x62: /* bound */ {
unsigned long src_val2;
int lb, ub, idx;
- generate_exception_if(mode_64bit() || (src.type != OP_MEM),
- EXC_UD);
+ generate_exception_if(src.type != OP_MEM, EXC_UD);
if ( (rc = read_ulong(src.mem.seg, src.mem.off + op_bytes,
&src_val2, op_bytes, ctxt, ops)) )
goto done;
@@ -3127,10 +3145,7 @@ x86_emulate(
adjust_bnd(ctxt, ops, vex.pfx);
break;
- case 0x82: /* Grp1 (x86/32 only) */
- generate_exception_if(mode_64bit(), EXC_UD);
- /* Fallthrough. */
- case 0x80: case 0x81: case 0x83: /* Grp1 */
+ case 0x80: case 0x81: case 0x82: case 0x83: /* Grp1 */
switch ( modrm_reg & 7 )
{
case 0: goto add;
@@ -3518,7 +3533,6 @@ x86_emulate(
case 0xc4: /* les */
case 0xc5: /* lds */
- generate_exception_if(mode_64bit(), EXC_UD);
seg = (b & 1) * 3; /* es = 0, ds = 3 */
les:
generate_exception_if(src.type != OP_MEM, EXC_UD);
@@ -3606,7 +3620,6 @@ x86_emulate(
goto done;
case 0xce: /* into */
- generate_exception_if(mode_64bit(), EXC_UD);
if ( !(_regs._eflags & EFLG_OF) )
break;
src.val = EXC_OF;
@@ -3648,7 +3661,6 @@ x86_emulate(
case 0xd5: /* aad */ {
unsigned int base = (uint8_t)src.val;
- generate_exception_if(mode_64bit(), EXC_UD);
if ( b & 0x01 )
{
uint16_t ax = _regs.ax;
@@ -3670,7 +3682,6 @@ x86_emulate(
}
case 0xd6: /* salc */
- generate_exception_if(mode_64bit(), EXC_UD);
_regs.al = (_regs._eflags & EFLG_CF) ? 0xff : 0x00;
break;
--
generated by git-patchbot for /home/xen/git/xen.git#master
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |