Revision 2c1794c4 translate-i386.c
b/translate-i386.c | ||
---|---|---|
1832 | 1832 |
s->is_jmp = 1; |
1833 | 1833 |
break; |
1834 | 1834 |
case 3: /* lcall Ev */ |
1835 |
/* push return segment + offset */ |
|
1836 |
gen_op_movl_T0_seg(R_CS); |
|
1837 |
gen_push_T0(s); |
|
1838 |
next_eip = s->pc - s->cs_base; |
|
1839 |
gen_op_movl_T0_im(next_eip); |
|
1840 |
gen_push_T0(s); |
|
1841 |
|
|
1842 | 1835 |
gen_op_ld_T1_A0[ot](); |
1843 | 1836 |
gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); |
1844 | 1837 |
gen_op_lduw_T0_A0(); |
1845 |
gen_movl_seg_T0(s, R_CS, pc_start - s->cs_base); |
|
1846 |
gen_op_movl_T0_T1(); |
|
1847 |
gen_op_jmp_T0(); |
|
1838 |
do_lcall: |
|
1839 |
if (s->pe && !s->vm86) { |
|
1840 |
if (s->cc_op != CC_OP_DYNAMIC) |
|
1841 |
gen_op_set_cc_op(s->cc_op); |
|
1842 |
gen_op_jmp_im(pc_start - s->cs_base); |
|
1843 |
gen_op_lcall_protected_T0_T1(dflag, s->pc - s->cs_base); |
|
1844 |
} else { |
|
1845 |
gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base); |
|
1846 |
} |
|
1848 | 1847 |
s->is_jmp = 1; |
1849 | 1848 |
break; |
1850 | 1849 |
case 4: /* jmp Ev */ |
... | ... | |
1857 | 1856 |
gen_op_ld_T1_A0[ot](); |
1858 | 1857 |
gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); |
1859 | 1858 |
gen_op_lduw_T0_A0(); |
1859 |
do_ljmp: |
|
1860 | 1860 |
if (s->pe && !s->vm86) { |
1861 |
/* we compute EIP to handle the exception case */ |
|
1861 |
if (s->cc_op != CC_OP_DYNAMIC) |
|
1862 |
gen_op_set_cc_op(s->cc_op); |
|
1862 | 1863 |
gen_op_jmp_im(pc_start - s->cs_base); |
1863 |
gen_op_ljmp_T0_T1(); |
|
1864 |
gen_op_ljmp_protected_T0_T1();
|
|
1864 | 1865 |
} else { |
1865 | 1866 |
gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS])); |
1866 | 1867 |
gen_op_movl_T0_T1(); |
... | ... | |
2867 | 2868 |
else |
2868 | 2869 |
ot = dflag ? OT_LONG : OT_WORD; |
2869 | 2870 |
|
2870 |
if (prefixes & PREFIX_REPZ) {
|
|
2871 |
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
|
|
2871 | 2872 |
gen_string_ds(s, ot, gen_op_movs + 9); |
2872 | 2873 |
} else { |
2873 | 2874 |
gen_string_ds(s, ot, gen_op_movs); |
... | ... | |
2881 | 2882 |
else |
2882 | 2883 |
ot = dflag ? OT_LONG : OT_WORD; |
2883 | 2884 |
|
2884 |
if (prefixes & PREFIX_REPZ) {
|
|
2885 |
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
|
|
2885 | 2886 |
gen_string_es(s, ot, gen_op_stos + 9); |
2886 | 2887 |
} else { |
2887 | 2888 |
gen_string_es(s, ot, gen_op_stos); |
... | ... | |
2893 | 2894 |
ot = OT_BYTE; |
2894 | 2895 |
else |
2895 | 2896 |
ot = dflag ? OT_LONG : OT_WORD; |
2896 |
if (prefixes & PREFIX_REPZ) {
|
|
2897 |
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
|
|
2897 | 2898 |
gen_string_ds(s, ot, gen_op_lods + 9); |
2898 | 2899 |
} else { |
2899 | 2900 |
gen_string_ds(s, ot, gen_op_lods); |
... | ... | |
2952 | 2953 |
ot = OT_BYTE; |
2953 | 2954 |
else |
2954 | 2955 |
ot = dflag ? OT_LONG : OT_WORD; |
2955 |
if (prefixes & PREFIX_REPZ) {
|
|
2956 |
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
|
|
2956 | 2957 |
gen_string_es(s, ot, gen_op_ins + 9); |
2957 | 2958 |
} else { |
2958 | 2959 |
gen_string_es(s, ot, gen_op_ins); |
... | ... | |
2969 | 2970 |
ot = OT_BYTE; |
2970 | 2971 |
else |
2971 | 2972 |
ot = dflag ? OT_LONG : OT_WORD; |
2972 |
if (prefixes & PREFIX_REPZ) {
|
|
2973 |
if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
|
|
2973 | 2974 |
gen_string_ds(s, ot, gen_op_outs + 9); |
2974 | 2975 |
} else { |
2975 | 2976 |
gen_string_ds(s, ot, gen_op_outs); |
... | ... | |
3062 | 3063 |
val = ldsw(s->pc); |
3063 | 3064 |
s->pc += 2; |
3064 | 3065 |
do_lret: |
3065 |
gen_stack_A0(s); |
|
3066 |
/* pop offset */ |
|
3067 |
gen_op_ld_T0_A0[1 + s->dflag](); |
|
3068 |
if (s->dflag == 0) |
|
3069 |
gen_op_andl_T0_ffff(); |
|
3070 |
/* NOTE: keeping EIP updated is not a problem in case of |
|
3071 |
exception */ |
|
3072 |
gen_op_jmp_T0(); |
|
3073 |
/* pop selector */ |
|
3074 |
gen_op_addl_A0_im(2 << s->dflag); |
|
3075 |
gen_op_ld_T0_A0[1 + s->dflag](); |
|
3076 |
gen_movl_seg_T0(s, R_CS, pc_start - s->cs_base); |
|
3077 |
/* add stack offset */ |
|
3078 |
gen_stack_update(s, val + (4 << s->dflag)); |
|
3066 |
if (s->pe && !s->vm86) { |
|
3067 |
if (s->cc_op != CC_OP_DYNAMIC) |
|
3068 |
gen_op_set_cc_op(s->cc_op); |
|
3069 |
gen_op_jmp_im(pc_start - s->cs_base); |
|
3070 |
gen_op_lret_protected(s->dflag, val); |
|
3071 |
} else { |
|
3072 |
gen_stack_A0(s); |
|
3073 |
/* pop offset */ |
|
3074 |
gen_op_ld_T0_A0[1 + s->dflag](); |
|
3075 |
if (s->dflag == 0) |
|
3076 |
gen_op_andl_T0_ffff(); |
|
3077 |
/* NOTE: keeping EIP updated is not a problem in case of |
|
3078 |
exception */ |
|
3079 |
gen_op_jmp_T0(); |
|
3080 |
/* pop selector */ |
|
3081 |
gen_op_addl_A0_im(2 << s->dflag); |
|
3082 |
gen_op_ld_T0_A0[1 + s->dflag](); |
|
3083 |
gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS])); |
|
3084 |
/* add stack offset */ |
|
3085 |
gen_stack_update(s, val + (4 << s->dflag)); |
|
3086 |
} |
|
3079 | 3087 |
s->is_jmp = 1; |
3080 | 3088 |
break; |
3081 | 3089 |
case 0xcb: /* lret */ |
... | ... | |
3114 | 3122 |
case 0x9a: /* lcall im */ |
3115 | 3123 |
{ |
3116 | 3124 |
unsigned int selector, offset; |
3117 |
/* XXX: not restartable */ |
|
3118 | 3125 |
|
3119 | 3126 |
ot = dflag ? OT_LONG : OT_WORD; |
3120 | 3127 |
offset = insn_get(s, ot); |
3121 | 3128 |
selector = insn_get(s, OT_WORD); |
3122 | 3129 |
|
3123 |
/* push return segment + offset */ |
|
3124 |
gen_op_movl_T0_seg(R_CS); |
|
3125 |
gen_push_T0(s); |
|
3126 |
next_eip = s->pc - s->cs_base; |
|
3127 |
gen_op_movl_T0_im(next_eip); |
|
3128 |
gen_push_T0(s); |
|
3129 |
|
|
3130 |
/* change cs and pc */ |
|
3131 | 3130 |
gen_op_movl_T0_im(selector); |
3132 |
gen_movl_seg_T0(s, R_CS, pc_start - s->cs_base); |
|
3133 |
gen_op_jmp_im((unsigned long)offset); |
|
3134 |
s->is_jmp = 1; |
|
3131 |
gen_op_movl_T1_im(offset); |
|
3135 | 3132 |
} |
3136 |
break;
|
|
3133 |
goto do_lcall;
|
|
3137 | 3134 |
case 0xe9: /* jmp */ |
3138 | 3135 |
ot = dflag ? OT_LONG : OT_WORD; |
3139 | 3136 |
val = insn_get(s, ot); |
... | ... | |
3150 | 3147 |
offset = insn_get(s, ot); |
3151 | 3148 |
selector = insn_get(s, OT_WORD); |
3152 | 3149 |
|
3153 |
/* change cs and pc */ |
|
3154 | 3150 |
gen_op_movl_T0_im(selector); |
3155 |
if (s->pe && !s->vm86) { |
|
3156 |
/* we compute EIP to handle the exception case */ |
|
3157 |
gen_op_jmp_im(pc_start - s->cs_base); |
|
3158 |
gen_op_movl_T1_im(offset); |
|
3159 |
gen_op_ljmp_T0_T1(); |
|
3160 |
} else { |
|
3161 |
gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS])); |
|
3162 |
gen_op_jmp_im((unsigned long)offset); |
|
3163 |
} |
|
3164 |
s->is_jmp = 1; |
|
3151 |
gen_op_movl_T1_im(offset); |
|
3165 | 3152 |
} |
3166 |
break;
|
|
3153 |
goto do_ljmp;
|
|
3167 | 3154 |
case 0xeb: /* jmp Jb */ |
3168 | 3155 |
val = (int8_t)insn_get(s, OT_BYTE); |
3169 | 3156 |
val += s->pc - s->cs_base; |
Also available in: Unified diff