Commit 2792c4f2afda061645ef122dc179f0d058a43484
1 parent
447db213
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
Showing
1 changed file
with
66 additions
and
5 deletions
op-i386.c
... | ... | @@ -634,6 +634,7 @@ void OPPROTO op_into(void) |
634 | 634 | int eflags; |
635 | 635 | eflags = cc_table[CC_OP].compute_all(); |
636 | 636 | if (eflags & CC_O) { |
637 | + EIP = PARAM1; | |
637 | 638 | raise_exception(EXCP04_INTO); |
638 | 639 | } |
639 | 640 | FORCE_RET(); |
... | ... | @@ -1136,6 +1137,66 @@ void OPPROTO op_addl_A0_seg(void) |
1136 | 1137 | A0 += *(unsigned long *)((char *)env + PARAM1); |
1137 | 1138 | } |
1138 | 1139 | |
1140 | +void helper_lsl(void) | |
1141 | +{ | |
1142 | + unsigned int selector, limit; | |
1143 | + SegmentDescriptorTable *dt; | |
1144 | + int index; | |
1145 | + uint32_t e1, e2; | |
1146 | + uint8_t *ptr; | |
1147 | + | |
1148 | + CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; | |
1149 | + selector = T0 & 0xffff; | |
1150 | + if (selector & 0x4) | |
1151 | + dt = &env->ldt; | |
1152 | + else | |
1153 | + dt = &env->gdt; | |
1154 | + index = selector & ~7; | |
1155 | + if ((index + 7) > dt->limit) | |
1156 | + return; | |
1157 | + ptr = dt->base + index; | |
1158 | + e1 = ldl(ptr); | |
1159 | + e2 = ldl(ptr + 4); | |
1160 | + limit = (e1 & 0xffff) | (e2 & 0x000f0000); | |
1161 | + if (e2 & (1 << 23)) | |
1162 | + limit = (limit << 12) | 0xfff; | |
1163 | + T1 = limit; | |
1164 | + CC_SRC |= CC_Z; | |
1165 | +} | |
1166 | + | |
1167 | +void OPPROTO op_lsl(void) | |
1168 | +{ | |
1169 | + helper_lsl(); | |
1170 | +} | |
1171 | + | |
1172 | +void helper_lar(void) | |
1173 | +{ | |
1174 | + unsigned int selector; | |
1175 | + SegmentDescriptorTable *dt; | |
1176 | + int index; | |
1177 | + uint32_t e2; | |
1178 | + uint8_t *ptr; | |
1179 | + | |
1180 | + CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z; | |
1181 | + selector = T0 & 0xffff; | |
1182 | + if (selector & 0x4) | |
1183 | + dt = &env->ldt; | |
1184 | + else | |
1185 | + dt = &env->gdt; | |
1186 | + index = selector & ~7; | |
1187 | + if ((index + 7) > dt->limit) | |
1188 | + return; | |
1189 | + ptr = dt->base + index; | |
1190 | + e2 = ldl(ptr + 4); | |
1191 | + T1 = e2 & 0x00f0ff00; | |
1192 | + CC_SRC |= CC_Z; | |
1193 | +} | |
1194 | + | |
1195 | +void OPPROTO op_lar(void) | |
1196 | +{ | |
1197 | + helper_lar(); | |
1198 | +} | |
1199 | + | |
1139 | 1200 | /* flags handling */ |
1140 | 1201 | |
1141 | 1202 | /* slow jumps cases (compute x86 flags) */ |
... | ... | @@ -1490,13 +1551,13 @@ CCTable cc_table[CC_OP_NB] = { |
1490 | 1551 | [CC_OP_DECW] = { compute_all_decw, compute_c_incl }, |
1491 | 1552 | [CC_OP_DECL] = { compute_all_decl, compute_c_incl }, |
1492 | 1553 | |
1493 | - [CC_OP_SHLB] = { compute_all_shlb, compute_c_shll }, | |
1494 | - [CC_OP_SHLW] = { compute_all_shlw, compute_c_shll }, | |
1554 | + [CC_OP_SHLB] = { compute_all_shlb, compute_c_shlb }, | |
1555 | + [CC_OP_SHLW] = { compute_all_shlw, compute_c_shlw }, | |
1495 | 1556 | [CC_OP_SHLL] = { compute_all_shll, compute_c_shll }, |
1496 | 1557 | |
1497 | - [CC_OP_SARB] = { compute_all_sarb, compute_c_shll }, | |
1498 | - [CC_OP_SARW] = { compute_all_sarw, compute_c_shll }, | |
1499 | - [CC_OP_SARL] = { compute_all_sarl, compute_c_shll }, | |
1558 | + [CC_OP_SARB] = { compute_all_sarb, compute_c_sarl }, | |
1559 | + [CC_OP_SARW] = { compute_all_sarw, compute_c_sarl }, | |
1560 | + [CC_OP_SARL] = { compute_all_sarl, compute_c_sarl }, | |
1500 | 1561 | }; |
1501 | 1562 | |
1502 | 1563 | /* floating point support. Some of the code for complicated x87 | ... | ... |