/[qemu]/qemu/translate-i386.c
ViewVC logotype

Diff of /qemu/translate-i386.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.54 by bellard, Sat Jul 26 20:34:00 2003 UTC revision 1.55 by bellard, Sun Jul 27 21:11:27 2003 UTC
# Line 1832  long disas_insn(DisasContext *s, uint8_t Line 1832  long disas_insn(DisasContext *s, uint8_t
1832              s->is_jmp = 1;              s->is_jmp = 1;
1833              break;              break;
1834          case 3: /* lcall Ev */          case 3: /* lcall Ev */
             /* push return segment + offset */  
             gen_op_movl_T0_seg(R_CS);  
             gen_push_T0(s);  
             next_eip = s->pc - s->cs_base;  
             gen_op_movl_T0_im(next_eip);  
             gen_push_T0(s);  
   
1835              gen_op_ld_T1_A0[ot]();              gen_op_ld_T1_A0[ot]();
1836              gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));              gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
1837              gen_op_lduw_T0_A0();              gen_op_lduw_T0_A0();
1838              gen_movl_seg_T0(s, R_CS, pc_start - s->cs_base);          do_lcall:
1839              gen_op_movl_T0_T1();              if (s->pe && !s->vm86) {
1840              gen_op_jmp_T0();                  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                }
1847              s->is_jmp = 1;              s->is_jmp = 1;
1848              break;              break;
1849          case 4: /* jmp Ev */          case 4: /* jmp Ev */
# Line 1857  long disas_insn(DisasContext *s, uint8_t Line 1856  long disas_insn(DisasContext *s, uint8_t
1856              gen_op_ld_T1_A0[ot]();              gen_op_ld_T1_A0[ot]();
1857              gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));              gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
1858              gen_op_lduw_T0_A0();              gen_op_lduw_T0_A0();
1859            do_ljmp:
1860              if (s->pe && !s->vm86) {              if (s->pe && !s->vm86) {
1861                  /* we compute EIP to handle the exception case */                  if (s->cc_op != CC_OP_DYNAMIC)
1862                        gen_op_set_cc_op(s->cc_op);
1863                  gen_op_jmp_im(pc_start - s->cs_base);                  gen_op_jmp_im(pc_start - s->cs_base);
1864                  gen_op_ljmp_T0_T1();                  gen_op_ljmp_protected_T0_T1();
1865              } else {              } else {
1866                  gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));                  gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
1867                  gen_op_movl_T0_T1();                  gen_op_movl_T0_T1();
# Line 2867  long disas_insn(DisasContext *s, uint8_t Line 2868  long disas_insn(DisasContext *s, uint8_t
2868          else          else
2869              ot = dflag ? OT_LONG : OT_WORD;              ot = dflag ? OT_LONG : OT_WORD;
2870    
2871          if (prefixes & PREFIX_REPZ) {          if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2872              gen_string_ds(s, ot, gen_op_movs + 9);              gen_string_ds(s, ot, gen_op_movs + 9);
2873          } else {          } else {
2874              gen_string_ds(s, ot, gen_op_movs);              gen_string_ds(s, ot, gen_op_movs);
# Line 2881  long disas_insn(DisasContext *s, uint8_t Line 2882  long disas_insn(DisasContext *s, uint8_t
2882          else          else
2883              ot = dflag ? OT_LONG : OT_WORD;              ot = dflag ? OT_LONG : OT_WORD;
2884    
2885          if (prefixes & PREFIX_REPZ) {          if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2886              gen_string_es(s, ot, gen_op_stos + 9);              gen_string_es(s, ot, gen_op_stos + 9);
2887          } else {          } else {
2888              gen_string_es(s, ot, gen_op_stos);              gen_string_es(s, ot, gen_op_stos);
# Line 2893  long disas_insn(DisasContext *s, uint8_t Line 2894  long disas_insn(DisasContext *s, uint8_t
2894              ot = OT_BYTE;              ot = OT_BYTE;
2895          else          else
2896              ot = dflag ? OT_LONG : OT_WORD;              ot = dflag ? OT_LONG : OT_WORD;
2897          if (prefixes & PREFIX_REPZ) {          if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2898              gen_string_ds(s, ot, gen_op_lods + 9);              gen_string_ds(s, ot, gen_op_lods + 9);
2899          } else {          } else {
2900              gen_string_ds(s, ot, gen_op_lods);              gen_string_ds(s, ot, gen_op_lods);
# Line 2952  long disas_insn(DisasContext *s, uint8_t Line 2953  long disas_insn(DisasContext *s, uint8_t
2953                  ot = OT_BYTE;                  ot = OT_BYTE;
2954              else              else
2955                  ot = dflag ? OT_LONG : OT_WORD;                  ot = dflag ? OT_LONG : OT_WORD;
2956              if (prefixes & PREFIX_REPZ) {              if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2957                  gen_string_es(s, ot, gen_op_ins + 9);                  gen_string_es(s, ot, gen_op_ins + 9);
2958              } else {              } else {
2959                  gen_string_es(s, ot, gen_op_ins);                  gen_string_es(s, ot, gen_op_ins);
# Line 2969  long disas_insn(DisasContext *s, uint8_t Line 2970  long disas_insn(DisasContext *s, uint8_t
2970                  ot = OT_BYTE;                  ot = OT_BYTE;
2971              else              else
2972                  ot = dflag ? OT_LONG : OT_WORD;                  ot = dflag ? OT_LONG : OT_WORD;
2973              if (prefixes & PREFIX_REPZ) {              if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2974                  gen_string_ds(s, ot, gen_op_outs + 9);                  gen_string_ds(s, ot, gen_op_outs + 9);
2975              } else {              } else {
2976                  gen_string_ds(s, ot, gen_op_outs);                  gen_string_ds(s, ot, gen_op_outs);
# Line 3062  long disas_insn(DisasContext *s, uint8_t Line 3063  long disas_insn(DisasContext *s, uint8_t
3063          val = ldsw(s->pc);          val = ldsw(s->pc);
3064          s->pc += 2;          s->pc += 2;
3065      do_lret:      do_lret:
3066          gen_stack_A0(s);          if (s->pe && !s->vm86) {
3067          /* pop offset */              if (s->cc_op != CC_OP_DYNAMIC)
3068          gen_op_ld_T0_A0[1 + s->dflag]();                  gen_op_set_cc_op(s->cc_op);
3069          if (s->dflag == 0)              gen_op_jmp_im(pc_start - s->cs_base);
3070              gen_op_andl_T0_ffff();              gen_op_lret_protected(s->dflag, val);
3071          /* NOTE: keeping EIP updated is not a problem in case of          } else {
3072             exception */              gen_stack_A0(s);
3073          gen_op_jmp_T0();              /* pop offset */
3074          /* pop selector */              gen_op_ld_T0_A0[1 + s->dflag]();
3075          gen_op_addl_A0_im(2 << s->dflag);              if (s->dflag == 0)
3076          gen_op_ld_T0_A0[1 + s->dflag]();                  gen_op_andl_T0_ffff();
3077          gen_movl_seg_T0(s, R_CS, pc_start - s->cs_base);              /* NOTE: keeping EIP updated is not a problem in case of
3078          /* add stack offset */                 exception */
3079          gen_stack_update(s, val + (4 << s->dflag));              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            }
3087          s->is_jmp = 1;          s->is_jmp = 1;
3088          break;          break;
3089      case 0xcb: /* lret */      case 0xcb: /* lret */
# Line 3114  long disas_insn(DisasContext *s, uint8_t Line 3122  long disas_insn(DisasContext *s, uint8_t
3122      case 0x9a: /* lcall im */      case 0x9a: /* lcall im */
3123          {          {
3124              unsigned int selector, offset;              unsigned int selector, offset;
             /* XXX: not restartable */  
3125    
3126              ot = dflag ? OT_LONG : OT_WORD;              ot = dflag ? OT_LONG : OT_WORD;
3127              offset = insn_get(s, ot);              offset = insn_get(s, ot);
3128              selector = insn_get(s, OT_WORD);              selector = insn_get(s, OT_WORD);
3129                            
             /* push return segment + offset */  
             gen_op_movl_T0_seg(R_CS);  
             gen_push_T0(s);  
             next_eip = s->pc - s->cs_base;  
             gen_op_movl_T0_im(next_eip);  
             gen_push_T0(s);  
   
             /* change cs and pc */  
3130              gen_op_movl_T0_im(selector);              gen_op_movl_T0_im(selector);
3131              gen_movl_seg_T0(s, R_CS, pc_start - s->cs_base);              gen_op_movl_T1_im(offset);
             gen_op_jmp_im((unsigned long)offset);  
             s->is_jmp = 1;  
3132          }          }
3133          break;          goto do_lcall;
3134      case 0xe9: /* jmp */      case 0xe9: /* jmp */
3135          ot = dflag ? OT_LONG : OT_WORD;          ot = dflag ? OT_LONG : OT_WORD;
3136          val = insn_get(s, ot);          val = insn_get(s, ot);
# Line 3150  long disas_insn(DisasContext *s, uint8_t Line 3147  long disas_insn(DisasContext *s, uint8_t
3147              offset = insn_get(s, ot);              offset = insn_get(s, ot);
3148              selector = insn_get(s, OT_WORD);              selector = insn_get(s, OT_WORD);
3149                            
             /* change cs and pc */  
3150              gen_op_movl_T0_im(selector);              gen_op_movl_T0_im(selector);
3151              if (s->pe && !s->vm86) {              gen_op_movl_T1_im(offset);
                 /* we compute EIP to handle the exception case */  
                 gen_op_jmp_im(pc_start - s->cs_base);  
                 gen_op_movl_T1_im(offset);  
                 gen_op_ljmp_T0_T1();  
             } else {  
                 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));  
                 gen_op_jmp_im((unsigned long)offset);  
             }  
             s->is_jmp = 1;  
3152          }          }
3153          break;          goto do_ljmp;
3154      case 0xeb: /* jmp Jb */      case 0xeb: /* jmp Jb */
3155          val = (int8_t)insn_get(s, OT_BYTE);          val = (int8_t)insn_get(s, OT_BYTE);
3156          val += s->pc - s->cs_base;          val += s->pc - s->cs_base;

Legend:
Removed from v.1.54  
changed lines
  Added in v.1.55

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26