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) |