| 285 |
|
|
| 286 |
/* XXX: check that enough room is available */ |
/* XXX: check that enough room is available */ |
| 287 |
if (new_stack) { |
if (new_stack) { |
| 288 |
old_esp = env->regs[R_ESP]; |
old_esp = ESP; |
| 289 |
old_ss = env->segs[R_SS].selector; |
old_ss = env->segs[R_SS].selector; |
| 290 |
load_seg(R_SS, ss, env->eip); |
load_seg(R_SS, ss, env->eip); |
| 291 |
} else { |
} else { |
| 292 |
old_esp = 0; |
old_esp = 0; |
| 293 |
old_ss = 0; |
old_ss = 0; |
| 294 |
esp = env->regs[R_ESP]; |
esp = ESP; |
| 295 |
} |
} |
| 296 |
if (is_int) |
if (is_int) |
| 297 |
old_eip = next_eip; |
old_eip = next_eip; |
| 300 |
old_cs = env->segs[R_CS].selector; |
old_cs = env->segs[R_CS].selector; |
| 301 |
load_seg(R_CS, selector, env->eip); |
load_seg(R_CS, selector, env->eip); |
| 302 |
env->eip = offset; |
env->eip = offset; |
| 303 |
env->regs[R_ESP] = esp - push_size; |
ESP = esp - push_size; |
| 304 |
ssp = env->segs[R_SS].base + esp; |
ssp = env->segs[R_SS].base + esp; |
| 305 |
if (shift == 1) { |
if (shift == 1) { |
| 306 |
int old_eflags; |
int old_eflags; |
| 374 |
ptr = dt->base + intno * 4; |
ptr = dt->base + intno * 4; |
| 375 |
offset = lduw(ptr); |
offset = lduw(ptr); |
| 376 |
selector = lduw(ptr + 2); |
selector = lduw(ptr + 2); |
| 377 |
esp = env->regs[R_ESP]; |
esp = ESP; |
| 378 |
ssp = env->segs[R_SS].base; |
ssp = env->segs[R_SS].base; |
| 379 |
if (is_int) |
if (is_int) |
| 380 |
old_eip = next_eip; |
old_eip = next_eip; |
| 389 |
stw(ssp + (esp & 0xffff), old_eip); |
stw(ssp + (esp & 0xffff), old_eip); |
| 390 |
|
|
| 391 |
/* update processor state */ |
/* update processor state */ |
| 392 |
env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | (esp & 0xffff); |
ESP = (ESP & ~0xffff) | (esp & 0xffff); |
| 393 |
env->eip = offset; |
env->eip = offset; |
| 394 |
env->segs[R_CS].selector = selector; |
env->segs[R_CS].selector = selector; |
| 395 |
env->segs[R_CS].base = (uint8_t *)(selector << 4); |
env->segs[R_CS].base = (uint8_t *)(selector << 4); |
| 784 |
|
|
| 785 |
new_cs = T0; |
new_cs = T0; |
| 786 |
new_eip = T1; |
new_eip = T1; |
| 787 |
esp = env->regs[R_ESP]; |
esp = ESP; |
| 788 |
esp_mask = 0xffffffff; |
esp_mask = 0xffffffff; |
| 789 |
if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
| 790 |
esp_mask = 0xffff; |
esp_mask = 0xffff; |
| 802 |
} |
} |
| 803 |
|
|
| 804 |
if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
| 805 |
env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | (esp & 0xffff); |
ESP = (ESP & ~0xffff) | (esp & 0xffff); |
| 806 |
else |
else |
| 807 |
env->regs[R_ESP] = esp; |
ESP = esp; |
| 808 |
env->eip = new_eip; |
env->eip = new_eip; |
| 809 |
env->segs[R_CS].selector = new_cs; |
env->segs[R_CS].selector = new_cs; |
| 810 |
env->segs[R_CS].base = (uint8_t *)(new_cs << 4); |
env->segs[R_CS].base = (uint8_t *)(new_cs << 4); |
| 846 |
if (!(e2 & DESC_P_MASK)) |
if (!(e2 & DESC_P_MASK)) |
| 847 |
raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc); |
raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc); |
| 848 |
|
|
| 849 |
sp = env->regs[R_ESP]; |
sp = ESP; |
| 850 |
if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
| 851 |
sp &= 0xffff; |
sp &= 0xffff; |
| 852 |
ssp = env->segs[R_SS].base + sp; |
ssp = env->segs[R_SS].base + sp; |
| 868 |
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); |
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); |
| 869 |
/* from this point, not restartable */ |
/* from this point, not restartable */ |
| 870 |
if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
| 871 |
env->regs[R_ESP] = (env->regs[R_ESP] & 0xffff0000) | (sp & 0xffff); |
ESP = (ESP & 0xffff0000) | (sp & 0xffff); |
| 872 |
else |
else |
| 873 |
env->regs[R_ESP] = sp; |
ESP = sp; |
| 874 |
env->segs[R_CS].base = sc1.base; |
env->segs[R_CS].base = sc1.base; |
| 875 |
env->segs[R_CS].limit = sc1.limit; |
env->segs[R_CS].limit = sc1.limit; |
| 876 |
env->segs[R_CS].flags = sc1.flags; |
env->segs[R_CS].flags = sc1.flags; |
| 938 |
param_count = e2 & 0x1f; |
param_count = e2 & 0x1f; |
| 939 |
push_size = ((param_count * 2) + 8) << shift; |
push_size = ((param_count * 2) + 8) << shift; |
| 940 |
|
|
| 941 |
old_esp = env->regs[R_ESP]; |
old_esp = ESP; |
| 942 |
old_ss = env->segs[R_SS].selector; |
old_ss = env->segs[R_SS].selector; |
| 943 |
if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
| 944 |
old_esp &= 0xffff; |
old_esp &= 0xffff; |
| 995 |
load_seg(R_CS, selector, env->eip); |
load_seg(R_CS, selector, env->eip); |
| 996 |
/* from this point, not restartable if same priviledge */ |
/* from this point, not restartable if same priviledge */ |
| 997 |
if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
| 998 |
env->regs[R_ESP] = (env->regs[R_ESP] & 0xffff0000) | (sp & 0xffff); |
ESP = (ESP & 0xffff0000) | (sp & 0xffff); |
| 999 |
else |
else |
| 1000 |
env->regs[R_ESP] = sp; |
ESP = sp; |
| 1001 |
EIP = offset; |
EIP = offset; |
| 1002 |
} |
} |
| 1003 |
} |
} |
| 1020 |
uint8_t *ssp; |
uint8_t *ssp; |
| 1021 |
int eflags_mask; |
int eflags_mask; |
| 1022 |
|
|
| 1023 |
sp = env->regs[R_ESP] & 0xffff; |
sp = ESP & 0xffff; |
| 1024 |
ssp = env->segs[R_SS].base + sp; |
ssp = env->segs[R_SS].base + sp; |
| 1025 |
if (shift == 1) { |
if (shift == 1) { |
| 1026 |
/* 32 bits */ |
/* 32 bits */ |
| 1034 |
new_eip = lduw(ssp); |
new_eip = lduw(ssp); |
| 1035 |
} |
} |
| 1036 |
new_esp = sp + (6 << shift); |
new_esp = sp + (6 << shift); |
| 1037 |
env->regs[R_ESP] = (env->regs[R_ESP] & 0xffff0000) | |
ESP = (ESP & 0xffff0000) | |
| 1038 |
(new_esp & 0xffff); |
(new_esp & 0xffff); |
| 1039 |
load_seg_vm(R_CS, new_cs); |
load_seg_vm(R_CS, new_cs); |
| 1040 |
env->eip = new_eip; |
env->eip = new_eip; |
| 1053 |
int cpl, dpl, rpl, eflags_mask; |
int cpl, dpl, rpl, eflags_mask; |
| 1054 |
uint8_t *ssp; |
uint8_t *ssp; |
| 1055 |
|
|
| 1056 |
sp = env->regs[R_ESP]; |
sp = ESP; |
| 1057 |
if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
if (!(env->segs[R_SS].flags & DESC_B_MASK)) |
| 1058 |
sp &= 0xffff; |
sp &= 0xffff; |
| 1059 |
ssp = env->segs[R_SS].base + sp; |
ssp = env->segs[R_SS].base + sp; |
| 1129 |
load_seg(R_SS, new_ss, env->eip); |
load_seg(R_SS, new_ss, env->eip); |
| 1130 |
} |
} |
| 1131 |
if (env->segs[R_SS].flags & DESC_B_MASK) |
if (env->segs[R_SS].flags & DESC_B_MASK) |
| 1132 |
env->regs[R_ESP] = new_esp; |
ESP = new_esp; |
| 1133 |
else |
else |
| 1134 |
env->regs[R_ESP] = (env->regs[R_ESP] & 0xffff0000) | |
ESP = (ESP & 0xffff0000) | |
| 1135 |
(new_esp & 0xffff); |
(new_esp & 0xffff); |
| 1136 |
env->eip = new_eip; |
env->eip = new_eip; |
| 1137 |
if (is_iret) { |
if (is_iret) { |
| 1164 |
load_seg_vm(R_GS, new_gs); |
load_seg_vm(R_GS, new_gs); |
| 1165 |
|
|
| 1166 |
env->eip = new_eip; |
env->eip = new_eip; |
| 1167 |
env->regs[R_ESP] = new_esp; |
ESP = new_esp; |
| 1168 |
} |
} |
| 1169 |
|
|
| 1170 |
void helper_iret_protected(int shift) |
void helper_iret_protected(int shift) |