diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-05-10 21:35:30 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-05-10 21:35:30 +0000 |
commit | 2792c4f2afda061645ef122dc179f0d058a43484 (patch) | |
tree | 573704b77be3a63baf14da4d93730f31d9e53a70 /op-i386.c | |
parent | 447db2139a6f6883183a7a750c5849145fd29899 (diff) |
added EIP return to INTO - fixed SHL C flag computation - added LAR/LSL
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@148 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'op-i386.c')
-rw-r--r-- | op-i386.c | 71 |
1 files changed, 66 insertions, 5 deletions
@@ -634,6 +634,7 @@ void OPPROTO op_into(void) int eflags; eflags = cc_table[CC_OP].compute_all(); if (eflags & CC_O) { + EIP = PARAM1; raise_exception(EXCP04_INTO); } FORCE_RET(); @@ -1136,6 +1137,66 @@ void OPPROTO op_addl_A0_seg(void) A0 += *(unsigned long *)((char *)env + PARAM1); } +void helper_lsl(void) +{ + unsigned int selector, limit; + SegmentDescriptorTable *dt; + int index; + uint32_t e1, e2; + uint8_t *ptr; + + CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; + selector = T0 & 0xffff; + if (selector & 0x4) + dt = &env->ldt; + else + dt = &env->gdt; + index = selector & ~7; + if ((index + 7) > dt->limit) + return; + ptr = dt->base + index; + e1 = ldl(ptr); + e2 = ldl(ptr + 4); + limit = (e1 & 0xffff) | (e2 & 0x000f0000); + if (e2 & (1 << 23)) + limit = (limit << 12) | 0xfff; + T1 = limit; + CC_SRC |= CC_Z; +} + +void OPPROTO op_lsl(void) +{ + helper_lsl(); +} + +void helper_lar(void) +{ + unsigned int selector; + SegmentDescriptorTable *dt; + int index; + uint32_t e2; + uint8_t *ptr; + + CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; + selector = T0 & 0xffff; + if (selector & 0x4) + dt = &env->ldt; + else + dt = &env->gdt; + index = selector & ~7; + if ((index + 7) > dt->limit) + return; + ptr = dt->base + index; + e2 = ldl(ptr + 4); + T1 = e2 & 0x00f0ff00; + CC_SRC |= CC_Z; +} + +void OPPROTO op_lar(void) +{ + helper_lar(); +} + /* flags handling */ /* slow jumps cases (compute x86 flags) */ @@ -1490,13 +1551,13 @@ CCTable cc_table[CC_OP_NB] = { [CC_OP_DECW] = { compute_all_decw, compute_c_incl }, [CC_OP_DECL] = { compute_all_decl, compute_c_incl }, - [CC_OP_SHLB] = { compute_all_shlb, compute_c_shll }, - [CC_OP_SHLW] = { compute_all_shlw, compute_c_shll }, + [CC_OP_SHLB] = { compute_all_shlb, compute_c_shlb }, + [CC_OP_SHLW] = { compute_all_shlw, compute_c_shlw }, [CC_OP_SHLL] = { compute_all_shll, compute_c_shll }, - [CC_OP_SARB] = { compute_all_sarb, compute_c_shll }, - [CC_OP_SARW] = { compute_all_sarw, compute_c_shll }, - [CC_OP_SARL] = { compute_all_sarl, compute_c_shll }, + [CC_OP_SARB] = { compute_all_sarb, compute_c_sarl }, + [CC_OP_SARW] = { compute_all_sarw, compute_c_sarl }, + [CC_OP_SARL] = { compute_all_sarl, compute_c_sarl }, }; /* floating point support. Some of the code for complicated x87 |