Commit aba9d61e34b9d43b856fd758d70f38e99e026cab

Authored by bellard
1 parent a6f37988

lcall and ljmp fixes in 64 bit mode - sysret fix


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1375 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 31 additions and 18 deletions
target-i386/translate.c
@@ -2231,6 +2231,16 @@ static void gen_movtl_T1_im(target_ulong val) @@ -2231,6 +2231,16 @@ static void gen_movtl_T1_im(target_ulong val)
2231 #endif 2231 #endif
2232 } 2232 }
2233 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 +
2234 static GenOpFunc1 *gen_ldq_env_A0[3] = { 2244 static GenOpFunc1 *gen_ldq_env_A0[3] = {
2235 gen_op_ldq_raw_env_A0, 2245 gen_op_ldq_raw_env_A0,
2236 #ifndef CONFIG_USER_ONLY 2246 #ifndef CONFIG_USER_ONLY
@@ -3382,9 +3392,13 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -3382,9 +3392,13 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
3382 goto illegal_op; 3392 goto illegal_op;
3383 } 3393 }
3384 if (CODE64(s)) { 3394 if (CODE64(s)) {
3385 - if (op >= 2 && op <= 5) { 3395 + if (op == 2 || op == 4) {
3386 /* operand size for jumps is 64 bit */ 3396 /* operand size for jumps is 64 bit */
3387 ot = OT_QUAD; 3397 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;
3388 } else if (op == 6) { 3402 } else if (op == 6) {
3389 /* default push size is 64 bit */ 3403 /* default push size is 64 bit */
3390 ot = dflag ? OT_QUAD : OT_WORD; 3404 ot = dflag ? OT_QUAD : OT_WORD;
@@ -3425,14 +3439,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -3425,14 +3439,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
3425 break; 3439 break;
3426 case 3: /* lcall Ev */ 3440 case 3: /* lcall Ev */
3427 gen_op_ld_T1_A0[ot + s->mem_index](); 3441 gen_op_ld_T1_A0[ot + s->mem_index]();
3428 - gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); 3442 + gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
3429 gen_op_ldu_T0_A0[OT_WORD + s->mem_index](); 3443 gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
3430 do_lcall: 3444 do_lcall:
3431 if (s->pe && !s->vm86) { 3445 if (s->pe && !s->vm86) {
3432 if (s->cc_op != CC_OP_DYNAMIC) 3446 if (s->cc_op != CC_OP_DYNAMIC)
3433 gen_op_set_cc_op(s->cc_op); 3447 gen_op_set_cc_op(s->cc_op);
3434 gen_jmp_im(pc_start - s->cs_base); 3448 gen_jmp_im(pc_start - s->cs_base);
3435 - gen_op_lcall_protected_T0_T1(dflag, s->pc - s->cs_base); 3449 + gen_op_lcall_protected_T0_T1(dflag, s->pc - pc_start);
3436 } else { 3450 } else {
3437 gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base); 3451 gen_op_lcall_real_T0_T1(dflag, s->pc - s->cs_base);
3438 } 3452 }
@@ -3446,14 +3460,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -3446,14 +3460,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
3446 break; 3460 break;
3447 case 5: /* ljmp Ev */ 3461 case 5: /* ljmp Ev */
3448 gen_op_ld_T1_A0[ot + s->mem_index](); 3462 gen_op_ld_T1_A0[ot + s->mem_index]();
3449 - gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); 3463 + gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
3450 gen_op_ldu_T0_A0[OT_WORD + s->mem_index](); 3464 gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
3451 do_ljmp: 3465 do_ljmp:
3452 if (s->pe && !s->vm86) { 3466 if (s->pe && !s->vm86) {
3453 if (s->cc_op != CC_OP_DYNAMIC) 3467 if (s->cc_op != CC_OP_DYNAMIC)
3454 gen_op_set_cc_op(s->cc_op); 3468 gen_op_set_cc_op(s->cc_op);
3455 gen_jmp_im(pc_start - s->cs_base); 3469 gen_jmp_im(pc_start - s->cs_base);
3456 - gen_op_ljmp_protected_T0_T1(s->pc - s->cs_base); 3470 + gen_op_ljmp_protected_T0_T1(s->pc - pc_start);
3457 } else { 3471 } else {
3458 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS])); 3472 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
3459 gen_op_movl_T0_T1(); 3473 gen_op_movl_T0_T1();
@@ -4043,7 +4057,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -4043,7 +4057,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
4043 goto illegal_op; 4057 goto illegal_op;
4044 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); 4058 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
4045 gen_op_ld_T1_A0[ot + s->mem_index](); 4059 gen_op_ld_T1_A0[ot + s->mem_index]();
4046 - gen_op_addl_A0_im(1 << (ot - OT_WORD + 1)); 4060 + gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
4047 /* load the segment first to handle exceptions properly */ 4061 /* load the segment first to handle exceptions properly */
4048 gen_op_ldu_T0_A0[OT_WORD + s->mem_index](); 4062 gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
4049 gen_movl_seg_T0(s, op, pc_start - s->cs_base); 4063 gen_movl_seg_T0(s, op, pc_start - s->cs_base);
@@ -5182,7 +5196,13 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5182,7 +5196,13 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5182 gen_op_into(s->pc - pc_start); 5196 gen_op_into(s->pc - pc_start);
5183 break; 5197 break;
5184 case 0xf1: /* icebp (undocumented, exits to external debugger) */ 5198 case 0xf1: /* icebp (undocumented, exits to external debugger) */
  5199 +#if 1
5185 gen_debug(s, pc_start - s->cs_base); 5200 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
5186 break; 5206 break;
5187 case 0xfa: /* cli */ 5207 case 0xfa: /* cli */
5188 if (!s->vm86) { 5208 if (!s->vm86) {
@@ -5363,6 +5383,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5363,6 +5383,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5363 } 5383 }
5364 gen_jmp_im(pc_start - s->cs_base); 5384 gen_jmp_im(pc_start - s->cs_base);
5365 gen_op_sysret(s->dflag); 5385 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;
5366 gen_eob(s); 5389 gen_eob(s);
5367 } 5390 }
5368 break; 5391 break;
@@ -5458,12 +5481,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5458,12 +5481,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5458 else 5481 else
5459 gen_op_movl_T0_env(offsetof(CPUX86State,idt.limit)); 5482 gen_op_movl_T0_env(offsetof(CPUX86State,idt.limit));
5460 gen_op_st_T0_A0[OT_WORD + s->mem_index](); 5483 gen_op_st_T0_A0[OT_WORD + s->mem_index]();
5461 -#ifdef TARGET_X86_64  
5462 - if (CODE64(s))  
5463 - gen_op_addq_A0_im(2);  
5464 - else  
5465 -#endif  
5466 - gen_op_addl_A0_im(2); 5484 + gen_add_A0_im(s, 2);
5467 if (op == 0) 5485 if (op == 0)
5468 gen_op_movtl_T0_env(offsetof(CPUX86State,gdt.base)); 5486 gen_op_movtl_T0_env(offsetof(CPUX86State,gdt.base));
5469 else 5487 else
@@ -5481,12 +5499,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5481,12 +5499,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5481 } else { 5499 } else {
5482 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr); 5500 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5483 gen_op_ld_T1_A0[OT_WORD + s->mem_index](); 5501 gen_op_ld_T1_A0[OT_WORD + s->mem_index]();
5484 -#ifdef TARGET_X86_64  
5485 - if (CODE64(s))  
5486 - gen_op_addq_A0_im(2);  
5487 - else  
5488 -#endif  
5489 - gen_op_addl_A0_im(2); 5502 + gen_add_A0_im(s, 2);
5490 gen_op_ld_T0_A0[CODE64(s) + OT_LONG + s->mem_index](); 5503 gen_op_ld_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
5491 if (!s->dflag) 5504 if (!s->dflag)
5492 gen_op_andl_T0_im(0xffffff); 5505 gen_op_andl_T0_im(0xffffff);