2771 |
if (s->cpl > s->iopl || s->vm86) { |
if (s->cpl > s->iopl || s->vm86) { |
2772 |
/* NOTE: even for (E)CX = 0 the exception is raised */ |
/* NOTE: even for (E)CX = 0 the exception is raised */ |
2773 |
gen_op_gpf(pc_start - s->cs_base); |
gen_op_gpf(pc_start - s->cs_base); |
2774 |
|
s->is_jmp = 1; |
2775 |
} else { |
} else { |
2776 |
if ((b & 1) == 0) |
if ((b & 1) == 0) |
2777 |
ot = OT_BYTE; |
ot = OT_BYTE; |
2789 |
if (s->cpl > s->iopl || s->vm86) { |
if (s->cpl > s->iopl || s->vm86) { |
2790 |
/* NOTE: even for (E)CX = 0 the exception is raised */ |
/* NOTE: even for (E)CX = 0 the exception is raised */ |
2791 |
gen_op_gpf(pc_start - s->cs_base); |
gen_op_gpf(pc_start - s->cs_base); |
2792 |
|
s->is_jmp = 1; |
2793 |
} else { |
} else { |
2794 |
if ((b & 1) == 0) |
if ((b & 1) == 0) |
2795 |
ot = OT_BYTE; |
ot = OT_BYTE; |
2809 |
case 0xe5: |
case 0xe5: |
2810 |
if (s->cpl > s->iopl || s->vm86) { |
if (s->cpl > s->iopl || s->vm86) { |
2811 |
gen_op_gpf(pc_start - s->cs_base); |
gen_op_gpf(pc_start - s->cs_base); |
2812 |
|
s->is_jmp = 1; |
2813 |
} else { |
} else { |
2814 |
if ((b & 1) == 0) |
if ((b & 1) == 0) |
2815 |
ot = OT_BYTE; |
ot = OT_BYTE; |
2825 |
case 0xe7: |
case 0xe7: |
2826 |
if (s->cpl > s->iopl || s->vm86) { |
if (s->cpl > s->iopl || s->vm86) { |
2827 |
gen_op_gpf(pc_start - s->cs_base); |
gen_op_gpf(pc_start - s->cs_base); |
2828 |
|
s->is_jmp = 1; |
2829 |
} else { |
} else { |
2830 |
if ((b & 1) == 0) |
if ((b & 1) == 0) |
2831 |
ot = OT_BYTE; |
ot = OT_BYTE; |
2841 |
case 0xed: |
case 0xed: |
2842 |
if (s->cpl > s->iopl || s->vm86) { |
if (s->cpl > s->iopl || s->vm86) { |
2843 |
gen_op_gpf(pc_start - s->cs_base); |
gen_op_gpf(pc_start - s->cs_base); |
2844 |
|
s->is_jmp = 1; |
2845 |
} else { |
} else { |
2846 |
if ((b & 1) == 0) |
if ((b & 1) == 0) |
2847 |
ot = OT_BYTE; |
ot = OT_BYTE; |
2856 |
case 0xef: |
case 0xef: |
2857 |
if (s->cpl > s->iopl || s->vm86) { |
if (s->cpl > s->iopl || s->vm86) { |
2858 |
gen_op_gpf(pc_start - s->cs_base); |
gen_op_gpf(pc_start - s->cs_base); |
2859 |
|
s->is_jmp = 1; |
2860 |
} else { |
} else { |
2861 |
if ((b & 1) == 0) |
if ((b & 1) == 0) |
2862 |
ot = OT_BYTE; |
ot = OT_BYTE; |
2907 |
gen_pop_update(s); |
gen_pop_update(s); |
2908 |
/* add stack offset */ |
/* add stack offset */ |
2909 |
if (s->ss32) |
if (s->ss32) |
2910 |
gen_op_addl_ESP_im(val + (2 << s->dflag)); |
gen_op_addl_ESP_im(val); |
2911 |
else |
else |
2912 |
gen_op_addw_ESP_im(val + (2 << s->dflag)); |
gen_op_addw_ESP_im(val); |
2913 |
s->is_jmp = 1; |
s->is_jmp = 1; |
2914 |
break; |
break; |
2915 |
case 0xcb: /* lret */ |
case 0xcb: /* lret */ |
2927 |
s->is_jmp = 1; |
s->is_jmp = 1; |
2928 |
break; |
break; |
2929 |
case 0xcf: /* iret */ |
case 0xcf: /* iret */ |
2930 |
/* XXX: not restartable */ |
if (s->vm86 && s->iopl != 3) { |
2931 |
/* pop offset */ |
gen_op_gpf(pc_start - s->cs_base); |
2932 |
gen_pop_T0(s); |
s->is_jmp = 1; |
|
if (s->dflag == 0) |
|
|
gen_op_andl_T0_ffff(); |
|
|
gen_op_jmp_T0(); |
|
|
gen_pop_update(s); |
|
|
/* pop selector */ |
|
|
gen_pop_T0(s); |
|
|
gen_movl_seg_T0(s, R_CS); |
|
|
gen_pop_update(s); |
|
|
/* pop eflags */ |
|
|
gen_pop_T0(s); |
|
|
if (s->dflag) { |
|
|
if (s->vm86) |
|
|
gen_op_movl_eflags_T0_vm(pc_start - s->cs_base); |
|
|
else |
|
|
gen_op_movl_eflags_T0(); |
|
2933 |
} else { |
} else { |
2934 |
if (s->vm86) |
/* XXX: not restartable */ |
2935 |
gen_op_movw_eflags_T0_vm(pc_start - s->cs_base); |
/* pop offset */ |
2936 |
else |
gen_pop_T0(s); |
2937 |
|
if (s->dflag == 0) |
2938 |
|
gen_op_andl_T0_ffff(); |
2939 |
|
gen_op_jmp_T0(); |
2940 |
|
gen_pop_update(s); |
2941 |
|
/* pop selector */ |
2942 |
|
gen_pop_T0(s); |
2943 |
|
gen_movl_seg_T0(s, R_CS); |
2944 |
|
gen_pop_update(s); |
2945 |
|
/* pop eflags */ |
2946 |
|
gen_pop_T0(s); |
2947 |
|
if (s->dflag) { |
2948 |
|
gen_op_movl_eflags_T0(); |
2949 |
|
} else { |
2950 |
gen_op_movw_eflags_T0(); |
gen_op_movw_eflags_T0(); |
2951 |
|
} |
2952 |
|
gen_pop_update(s); |
2953 |
|
s->cc_op = CC_OP_EFLAGS; |
2954 |
} |
} |
|
gen_pop_update(s); |
|
|
s->cc_op = CC_OP_EFLAGS; |
|
2955 |
s->is_jmp = 1; |
s->is_jmp = 1; |
2956 |
break; |
break; |
2957 |
case 0xe8: /* call im */ |
case 0xe8: /* call im */ |
3065 |
/************************/ |
/************************/ |
3066 |
/* flags */ |
/* flags */ |
3067 |
case 0x9c: /* pushf */ |
case 0x9c: /* pushf */ |
3068 |
if (s->cc_op != CC_OP_DYNAMIC) |
if (s->vm86 && s->iopl != 3) { |
3069 |
gen_op_set_cc_op(s->cc_op); |
gen_op_gpf(pc_start - s->cs_base); |
3070 |
if (s->vm86) |
s->is_jmp = 1; |
3071 |
gen_op_movl_T0_eflags_vm(); |
} else { |
3072 |
else |
if (s->cc_op != CC_OP_DYNAMIC) |
3073 |
|
gen_op_set_cc_op(s->cc_op); |
3074 |
gen_op_movl_T0_eflags(); |
gen_op_movl_T0_eflags(); |
3075 |
gen_push_T0(s); |
gen_push_T0(s); |
3076 |
|
} |
3077 |
break; |
break; |
3078 |
case 0x9d: /* popf */ |
case 0x9d: /* popf */ |
3079 |
gen_pop_T0(s); |
if (s->vm86 && s->iopl != 3) { |
3080 |
if (s->dflag) { |
gen_op_gpf(pc_start - s->cs_base); |
3081 |
if (s->vm86) |
s->is_jmp = 1; |
|
gen_op_movl_eflags_T0_vm(pc_start - s->cs_base); |
|
|
else |
|
|
gen_op_movl_eflags_T0(); |
|
3082 |
} else { |
} else { |
3083 |
if (s->vm86) |
gen_pop_T0(s); |
3084 |
gen_op_movw_eflags_T0_vm(pc_start - s->cs_base); |
if (s->dflag) { |
3085 |
else |
gen_op_movl_eflags_T0(); |
3086 |
|
} else { |
3087 |
gen_op_movw_eflags_T0(); |
gen_op_movw_eflags_T0(); |
3088 |
|
} |
3089 |
|
gen_pop_update(s); |
3090 |
|
s->cc_op = CC_OP_EFLAGS; |
3091 |
} |
} |
|
gen_pop_update(s); |
|
|
s->cc_op = CC_OP_EFLAGS; |
|
3092 |
break; |
break; |
3093 |
case 0x9e: /* sahf */ |
case 0x9e: /* sahf */ |
3094 |
gen_op_mov_TN_reg[OT_BYTE][0][R_AH](); |
gen_op_mov_TN_reg[OT_BYTE][0][R_AH](); |
3263 |
break; |
break; |
3264 |
case 0xfa: /* cli */ |
case 0xfa: /* cli */ |
3265 |
if (!s->vm86) { |
if (!s->vm86) { |
3266 |
if (s->cpl <= s->iopl) |
if (s->cpl <= s->iopl) { |
3267 |
gen_op_cli(); |
gen_op_cli(); |
3268 |
else |
} else { |
3269 |
gen_op_gpf(pc_start - s->cs_base); |
gen_op_gpf(pc_start - s->cs_base); |
3270 |
|
s->is_jmp = 1; |
3271 |
|
} |
3272 |
} else { |
} else { |
3273 |
if (s->iopl == 3) |
if (s->iopl == 3) { |
3274 |
gen_op_cli(); |
gen_op_cli(); |
3275 |
else |
} else { |
3276 |
gen_op_cli_vm(); |
gen_op_gpf(pc_start - s->cs_base); |
3277 |
|
s->is_jmp = 1; |
3278 |
|
} |
3279 |
} |
} |
3280 |
break; |
break; |
3281 |
case 0xfb: /* sti */ |
case 0xfb: /* sti */ |
3282 |
if (!s->vm86) { |
if (!s->vm86) { |
3283 |
if (s->cpl <= s->iopl) |
if (s->cpl <= s->iopl) { |
3284 |
gen_op_sti(); |
gen_op_sti(); |
3285 |
else |
} else { |
3286 |
gen_op_gpf(pc_start - s->cs_base); |
gen_op_gpf(pc_start - s->cs_base); |
3287 |
|
s->is_jmp = 1; |
3288 |
|
} |
3289 |
} else { |
} else { |
3290 |
if (s->iopl == 3) |
if (s->iopl == 3) { |
3291 |
gen_op_sti(); |
gen_op_sti(); |
3292 |
else |
} else { |
3293 |
gen_op_sti_vm(pc_start - s->cs_base); |
gen_op_gpf(pc_start - s->cs_base); |
3294 |
|
s->is_jmp = 1; |
3295 |
|
} |
3296 |
} |
} |
3297 |
break; |
break; |
3298 |
case 0x62: /* bound */ |
case 0x62: /* bound */ |
3342 |
gen_op_cpuid(); |
gen_op_cpuid(); |
3343 |
break; |
break; |
3344 |
case 0xf4: /* hlt */ |
case 0xf4: /* hlt */ |
3345 |
if (s->cpl == 0) { |
/* XXX: if cpl == 0, then should do something else */ |
3346 |
/* ignored */ |
gen_op_gpf(pc_start - s->cs_base); |
3347 |
} else { |
s->is_jmp = 1; |
|
gen_op_gpf(pc_start - s->cs_base); |
|
|
} |
|
3348 |
break; |
break; |
3349 |
default: |
default: |
3350 |
goto illegal_op; |
goto illegal_op; |
3829 |
{ |
{ |
3830 |
free(env); |
free(env); |
3831 |
} |
} |
3832 |
|
|
3833 |
|
static const char *cc_op_str[] = { |
3834 |
|
"DYNAMIC", |
3835 |
|
"EFLAGS", |
3836 |
|
"MUL", |
3837 |
|
"ADDB", |
3838 |
|
"ADDW", |
3839 |
|
"ADDL", |
3840 |
|
"ADCB", |
3841 |
|
"ADCW", |
3842 |
|
"ADCL", |
3843 |
|
"SUBB", |
3844 |
|
"SUBW", |
3845 |
|
"SUBL", |
3846 |
|
"SBBB", |
3847 |
|
"SBBW", |
3848 |
|
"SBBL", |
3849 |
|
"LOGICB", |
3850 |
|
"LOGICW", |
3851 |
|
"LOGICL", |
3852 |
|
"INCB", |
3853 |
|
"INCW", |
3854 |
|
"INCL", |
3855 |
|
"DECB", |
3856 |
|
"DECW", |
3857 |
|
"DECL", |
3858 |
|
"SHLB", |
3859 |
|
"SHLW", |
3860 |
|
"SHLL", |
3861 |
|
"SARB", |
3862 |
|
"SARW", |
3863 |
|
"SARL", |
3864 |
|
}; |
3865 |
|
|
3866 |
|
void cpu_x86_dump_state(CPUX86State *env, FILE *f, int flags) |
3867 |
|
{ |
3868 |
|
int eflags; |
3869 |
|
char cc_op_name[32]; |
3870 |
|
|
3871 |
|
eflags = env->eflags; |
3872 |
|
fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n" |
3873 |
|
"ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n" |
3874 |
|
"EIP=%08x EFL=%08x [%c%c%c%c%c%c%c]\n", |
3875 |
|
env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX], |
3876 |
|
env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], env->regs[R_ESP], |
3877 |
|
env->eip, eflags, |
3878 |
|
eflags & DF_MASK ? 'D' : '-', |
3879 |
|
eflags & CC_O ? 'O' : '-', |
3880 |
|
eflags & CC_S ? 'S' : '-', |
3881 |
|
eflags & CC_Z ? 'Z' : '-', |
3882 |
|
eflags & CC_A ? 'A' : '-', |
3883 |
|
eflags & CC_P ? 'P' : '-', |
3884 |
|
eflags & CC_C ? 'C' : '-'); |
3885 |
|
fprintf(f, "CS=%04x SS=%04x DS=%04x ES=%04x FS=%04x GS=%04x\n", |
3886 |
|
env->segs[R_CS], |
3887 |
|
env->segs[R_SS], |
3888 |
|
env->segs[R_DS], |
3889 |
|
env->segs[R_ES], |
3890 |
|
env->segs[R_FS], |
3891 |
|
env->segs[R_GS]); |
3892 |
|
if (flags & X86_DUMP_CCOP) { |
3893 |
|
if ((unsigned)env->cc_op < CC_OP_NB) |
3894 |
|
strcpy(cc_op_name, cc_op_str[env->cc_op]); |
3895 |
|
else |
3896 |
|
snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op); |
3897 |
|
fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n", |
3898 |
|
env->cc_src, env->cc_dst, cc_op_name); |
3899 |
|
} |
3900 |
|
if (flags & X86_DUMP_FPU) { |
3901 |
|
fprintf(f, "ST0=%f ST1=%f ST2=%f ST3=%f\n", |
3902 |
|
(double)env->fpregs[0], |
3903 |
|
(double)env->fpregs[1], |
3904 |
|
(double)env->fpregs[2], |
3905 |
|
(double)env->fpregs[3]); |
3906 |
|
fprintf(f, "ST4=%f ST5=%f ST6=%f ST7=%f\n", |
3907 |
|
(double)env->fpregs[4], |
3908 |
|
(double)env->fpregs[5], |
3909 |
|
(double)env->fpregs[7], |
3910 |
|
(double)env->fpregs[8]); |
3911 |
|
} |
3912 |
|
} |