2231 |
#endif |
#endif |
2232 |
} |
} |
2233 |
|
|
2234 |
|
static void gen_add_A0_im(DisasContext *s, int val) |
2235 |
|
{ |
2236 |
|
#ifdef TARGET_X86_64 |
2237 |
|
if (CODE64(s)) |
2238 |
|
gen_op_addq_A0_im(val); |
2239 |
|
else |
2240 |
|
#endif |
2241 |
|
gen_op_addl_A0_im(val); |
2242 |
|
} |
2243 |
|
|
2244 |
static GenOpFunc1 *gen_ldq_env_A0[3] = { |
static GenOpFunc1 *gen_ldq_env_A0[3] = { |
2245 |
gen_op_ldq_raw_env_A0, |
gen_op_ldq_raw_env_A0, |
2246 |
#ifndef CONFIG_USER_ONLY |
#ifndef CONFIG_USER_ONLY |
3392 |
goto illegal_op; |
goto illegal_op; |
3393 |
} |
} |
3394 |
if (CODE64(s)) { |
if (CODE64(s)) { |
3395 |
if (op >= 2 && op <= 5) { |
if (op == 2 || op == 4) { |
3396 |
/* operand size for jumps is 64 bit */ |
/* operand size for jumps is 64 bit */ |
3397 |
ot = OT_QUAD; |
ot = OT_QUAD; |
3398 |
|
} else if (op == 3 || op == 5) { |
3399 |
|
/* for call calls, the operand is 16 or 32 bit, even |
3400 |
|
in long mode */ |
3401 |
|
ot = dflag ? OT_LONG : OT_WORD; |
3402 |
} else if (op == 6) { |
} else if (op == 6) { |
3403 |
/* default push size is 64 bit */ |
/* default push size is 64 bit */ |
3404 |
ot = dflag ? OT_QUAD : OT_WORD; |
ot = dflag ? OT_QUAD : OT_WORD; |
3439 |
break; |
break; |
3440 |
case 3: /* lcall Ev */ |
case 3: /* lcall Ev */ |
3441 |
gen_op_ld_T1_A0[ot + s->mem_index](); |
gen_op_ld_T1_A0[ot + s->mem_index](); |
3442 |
gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); |
gen_add_A0_im(s, 1 << (ot - OT_WORD + 1)); |
3443 |
gen_op_ldu_T0_A0[OT_WORD + s->mem_index](); |
gen_op_ldu_T0_A0[OT_WORD + s->mem_index](); |
3444 |
do_lcall: |
do_lcall: |
3445 |
if (s->pe && !s->vm86) { |
if (s->pe && !s->vm86) { |
3446 |
if (s->cc_op != CC_OP_DYNAMIC) |
if (s->cc_op != CC_OP_DYNAMIC) |
3447 |
gen_op_set_cc_op(s->cc_op); |
gen_op_set_cc_op(s->cc_op); |
3448 |
gen_jmp_im(pc_start - s->cs_base); |
gen_jmp_im(pc_start - s->cs_base); |
3449 |
gen_op_lcall_protected_T0_T1(dflag, s->pc - s->cs_base); |
gen_op_lcall_protected_T0_T1(dflag, s->pc - pc_start); |
3450 |
} else { |
} else { |
3451 |
gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base); |
gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base); |
3452 |
} |
} |
3460 |
break; |
break; |
3461 |
case 5: /* ljmp Ev */ |
case 5: /* ljmp Ev */ |
3462 |
gen_op_ld_T1_A0[ot + s->mem_index](); |
gen_op_ld_T1_A0[ot + s->mem_index](); |
3463 |
gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); |
gen_add_A0_im(s, 1 << (ot - OT_WORD + 1)); |
3464 |
gen_op_ldu_T0_A0[OT_WORD + s->mem_index](); |
gen_op_ldu_T0_A0[OT_WORD + s->mem_index](); |
3465 |
do_ljmp: |
do_ljmp: |
3466 |
if (s->pe && !s->vm86) { |
if (s->pe && !s->vm86) { |
3467 |
if (s->cc_op != CC_OP_DYNAMIC) |
if (s->cc_op != CC_OP_DYNAMIC) |
3468 |
gen_op_set_cc_op(s->cc_op); |
gen_op_set_cc_op(s->cc_op); |
3469 |
gen_jmp_im(pc_start - s->cs_base); |
gen_jmp_im(pc_start - s->cs_base); |
3470 |
gen_op_ljmp_protected_T0_T1(s->pc - s->cs_base); |
gen_op_ljmp_protected_T0_T1(s->pc - pc_start); |
3471 |
} else { |
} else { |
3472 |
gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS])); |
gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS])); |
3473 |
gen_op_movl_T0_T1(); |
gen_op_movl_T0_T1(); |
4057 |
goto illegal_op; |
goto illegal_op; |
4058 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
4059 |
gen_op_ld_T1_A0[ot + s->mem_index](); |
gen_op_ld_T1_A0[ot + s->mem_index](); |
4060 |
gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); |
gen_add_A0_im(s, 1 << (ot - OT_WORD + 1)); |
4061 |
/* load the segment first to handle exceptions properly */ |
/* load the segment first to handle exceptions properly */ |
4062 |
gen_op_ldu_T0_A0[OT_WORD + s->mem_index](); |
gen_op_ldu_T0_A0[OT_WORD + s->mem_index](); |
4063 |
gen_movl_seg_T0(s, op, pc_start - s->cs_base); |
gen_movl_seg_T0(s, op, pc_start - s->cs_base); |
5196 |
gen_op_into(s->pc - pc_start); |
gen_op_into(s->pc - pc_start); |
5197 |
break; |
break; |
5198 |
case 0xf1: /* icebp (undocumented, exits to external debugger) */ |
case 0xf1: /* icebp (undocumented, exits to external debugger) */ |
5199 |
|
#if 1 |
5200 |
gen_debug(s, pc_start - s->cs_base); |
gen_debug(s, pc_start - s->cs_base); |
5201 |
|
#else |
5202 |
|
/* start debug */ |
5203 |
|
tb_flush(cpu_single_env); |
5204 |
|
cpu_set_log(CPU_LOG_INT | CPU_LOG_TB_IN_ASM); |
5205 |
|
#endif |
5206 |
break; |
break; |
5207 |
case 0xfa: /* cli */ |
case 0xfa: /* cli */ |
5208 |
if (!s->vm86) { |
if (!s->vm86) { |
5383 |
} |
} |
5384 |
gen_jmp_im(pc_start - s->cs_base); |
gen_jmp_im(pc_start - s->cs_base); |
5385 |
gen_op_sysret(s->dflag); |
gen_op_sysret(s->dflag); |
5386 |
|
/* condition codes are modified only in long mode */ |
5387 |
|
if (s->lma) |
5388 |
|
s->cc_op = CC_OP_EFLAGS; |
5389 |
gen_eob(s); |
gen_eob(s); |
5390 |
} |
} |
5391 |
break; |
break; |
5481 |
else |
else |
5482 |
gen_op_movl_T0_env(offsetof(CPUX86State,idt.limit)); |
gen_op_movl_T0_env(offsetof(CPUX86State,idt.limit)); |
5483 |
gen_op_st_T0_A0[OT_WORD + s->mem_index](); |
gen_op_st_T0_A0[OT_WORD + s->mem_index](); |
5484 |
#ifdef TARGET_X86_64 |
gen_add_A0_im(s, 2); |
|
if (CODE64(s)) |
|
|
gen_op_addq_A0_im(2); |
|
|
else |
|
|
#endif |
|
|
gen_op_addl_A0_im(2); |
|
5485 |
if (op == 0) |
if (op == 0) |
5486 |
gen_op_movtl_T0_env(offsetof(CPUX86State,gdt.base)); |
gen_op_movtl_T0_env(offsetof(CPUX86State,gdt.base)); |
5487 |
else |
else |
5499 |
} else { |
} else { |
5500 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
5501 |
gen_op_ld_T1_A0[OT_WORD + s->mem_index](); |
gen_op_ld_T1_A0[OT_WORD + s->mem_index](); |
5502 |
#ifdef TARGET_X86_64 |
gen_add_A0_im(s, 2); |
|
if (CODE64(s)) |
|
|
gen_op_addq_A0_im(2); |
|
|
else |
|
|
#endif |
|
|
gen_op_addl_A0_im(2); |
|
5503 |
gen_op_ld_T0_A0[CODE64(s) + OT_LONG + s->mem_index](); |
gen_op_ld_T0_A0[CODE64(s) + OT_LONG + s->mem_index](); |
5504 |
if (!s->dflag) |
if (!s->dflag) |
5505 |
gen_op_andl_T0_im(0xffffff); |
gen_op_andl_T0_im(0xffffff); |