/[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.29 by bellard, Sat May 10 13:09:33 2003 UTC revision 1.30 by bellard, Sat May 10 15:07:51 2003 UTC
# Line 132  typedef struct DisasContext { Line 132  typedef struct DisasContext {
132      int vm86;   /* vm86 mode */      int vm86;   /* vm86 mode */
133      int cpl;      int cpl;
134      int iopl;      int iopl;
135        int tf;     /* TF cpu flag */
136  } DisasContext;  } DisasContext;
137    
138  /* i386 arith/logic operations */  /* i386 arith/logic operations */
# Line 1366  static void gen_enter(DisasContext *s, i Line 1367  static void gen_enter(DisasContext *s, i
1367      gen_op_mov_reg_T1[ot][R_ESP]();      gen_op_mov_reg_T1[ot][R_ESP]();
1368  }  }
1369    
1370    static void gen_exception(DisasContext *s, int trapno, unsigned int cur_eip)
1371    {
1372        if (s->cc_op != CC_OP_DYNAMIC)
1373            gen_op_set_cc_op(s->cc_op);
1374        gen_op_jmp_im(cur_eip);
1375        gen_op_raise_exception(trapno);
1376        s->is_jmp = 1;
1377    }
1378    
1379  /* return the next pc address. Return -1 if no insn found. *is_jmp_ptr  /* return the next pc address. Return -1 if no insn found. *is_jmp_ptr
1380     is set to true if the instruction sets the PC (last instruction of     is set to true if the instruction sets the PC (last instruction of
1381     a basic block) */     a basic block) */
# Line 2770  long disas_insn(DisasContext *s, uint8_t Line 2780  long disas_insn(DisasContext *s, uint8_t
2780      case 0x6d:      case 0x6d:
2781          if (s->cpl > s->iopl || s->vm86) {          if (s->cpl > s->iopl || s->vm86) {
2782              /* NOTE: even for (E)CX = 0 the exception is raised */              /* NOTE: even for (E)CX = 0 the exception is raised */
2783              gen_op_gpf(pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
             s->is_jmp = 1;  
2784          } else {          } else {
2785              if ((b & 1) == 0)              if ((b & 1) == 0)
2786                  ot = OT_BYTE;                  ot = OT_BYTE;
# Line 2788  long disas_insn(DisasContext *s, uint8_t Line 2797  long disas_insn(DisasContext *s, uint8_t
2797      case 0x6f:      case 0x6f:
2798          if (s->cpl > s->iopl || s->vm86) {          if (s->cpl > s->iopl || s->vm86) {
2799              /* NOTE: even for (E)CX = 0 the exception is raised */              /* NOTE: even for (E)CX = 0 the exception is raised */
2800              gen_op_gpf(pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
             s->is_jmp = 1;  
2801          } else {          } else {
2802              if ((b & 1) == 0)              if ((b & 1) == 0)
2803                  ot = OT_BYTE;                  ot = OT_BYTE;
# Line 2808  long disas_insn(DisasContext *s, uint8_t Line 2816  long disas_insn(DisasContext *s, uint8_t
2816      case 0xe4:      case 0xe4:
2817      case 0xe5:      case 0xe5:
2818          if (s->cpl > s->iopl || s->vm86) {          if (s->cpl > s->iopl || s->vm86) {
2819              gen_op_gpf(pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
             s->is_jmp = 1;  
2820          } else {          } else {
2821              if ((b & 1) == 0)              if ((b & 1) == 0)
2822                  ot = OT_BYTE;                  ot = OT_BYTE;
# Line 2824  long disas_insn(DisasContext *s, uint8_t Line 2831  long disas_insn(DisasContext *s, uint8_t
2831      case 0xe6:      case 0xe6:
2832      case 0xe7:      case 0xe7:
2833          if (s->cpl > s->iopl || s->vm86) {          if (s->cpl > s->iopl || s->vm86) {
2834              gen_op_gpf(pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
             s->is_jmp = 1;  
2835          } else {          } else {
2836              if ((b & 1) == 0)              if ((b & 1) == 0)
2837                  ot = OT_BYTE;                  ot = OT_BYTE;
# Line 2840  long disas_insn(DisasContext *s, uint8_t Line 2846  long disas_insn(DisasContext *s, uint8_t
2846      case 0xec:      case 0xec:
2847      case 0xed:      case 0xed:
2848          if (s->cpl > s->iopl || s->vm86) {          if (s->cpl > s->iopl || s->vm86) {
2849              gen_op_gpf(pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
             s->is_jmp = 1;  
2850          } else {          } else {
2851              if ((b & 1) == 0)              if ((b & 1) == 0)
2852                  ot = OT_BYTE;                  ot = OT_BYTE;
# Line 2855  long disas_insn(DisasContext *s, uint8_t Line 2860  long disas_insn(DisasContext *s, uint8_t
2860      case 0xee:      case 0xee:
2861      case 0xef:      case 0xef:
2862          if (s->cpl > s->iopl || s->vm86) {          if (s->cpl > s->iopl || s->vm86) {
2863              gen_op_gpf(pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
             s->is_jmp = 1;  
2864          } else {          } else {
2865              if ((b & 1) == 0)              if ((b & 1) == 0)
2866                  ot = OT_BYTE;                  ot = OT_BYTE;
# Line 2928  long disas_insn(DisasContext *s, uint8_t Line 2932  long disas_insn(DisasContext *s, uint8_t
2932          break;          break;
2933      case 0xcf: /* iret */      case 0xcf: /* iret */
2934          if (s->vm86 && s->iopl != 3) {          if (s->vm86 && s->iopl != 3) {
2935              gen_op_gpf(pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
             s->is_jmp = 1;  
2936          } else {          } else {
2937              /* XXX: not restartable */              /* XXX: not restartable */
2938              /* pop offset */              /* pop offset */
# Line 3066  long disas_insn(DisasContext *s, uint8_t Line 3069  long disas_insn(DisasContext *s, uint8_t
3069          /* flags */          /* flags */
3070      case 0x9c: /* pushf */      case 0x9c: /* pushf */
3071          if (s->vm86 && s->iopl != 3) {          if (s->vm86 && s->iopl != 3) {
3072              gen_op_gpf(pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
             s->is_jmp = 1;  
3073          } else {          } else {
3074              if (s->cc_op != CC_OP_DYNAMIC)              if (s->cc_op != CC_OP_DYNAMIC)
3075                  gen_op_set_cc_op(s->cc_op);                  gen_op_set_cc_op(s->cc_op);
# Line 3077  long disas_insn(DisasContext *s, uint8_t Line 3079  long disas_insn(DisasContext *s, uint8_t
3079          break;          break;
3080      case 0x9d: /* popf */      case 0x9d: /* popf */
3081          if (s->vm86 && s->iopl != 3) {          if (s->vm86 && s->iopl != 3) {
3082              gen_op_gpf(pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
             s->is_jmp = 1;  
3083          } else {          } else {
3084              gen_pop_T0(s);              gen_pop_T0(s);
3085              if (s->dflag) {              if (s->dflag) {
# Line 3248  long disas_insn(DisasContext *s, uint8_t Line 3249  long disas_insn(DisasContext *s, uint8_t
3249      case 0x90: /* nop */      case 0x90: /* nop */
3250          break;          break;
3251      case 0xcc: /* int3 */      case 0xcc: /* int3 */
3252          gen_op_int3((long)pc_start);          gen_exception(s, EXCP03_INT3, pc_start - s->cs_base);
         s->is_jmp = 1;  
3253          break;          break;
3254      case 0xcd: /* int N */      case 0xcd: /* int N */
3255          val = ldub(s->pc++);          val = ldub(s->pc++);
3256            if (s->cc_op != CC_OP_DYNAMIC)
3257                gen_op_set_cc_op(s->cc_op);
3258          gen_op_int_im(val, pc_start - s->cs_base);          gen_op_int_im(val, pc_start - s->cs_base);
3259          s->is_jmp = 1;          s->is_jmp = 1;
3260          break;          break;
# Line 3266  long disas_insn(DisasContext *s, uint8_t Line 3268  long disas_insn(DisasContext *s, uint8_t
3268              if (s->cpl <= s->iopl) {              if (s->cpl <= s->iopl) {
3269                  gen_op_cli();                  gen_op_cli();
3270              } else {              } else {
3271                  gen_op_gpf(pc_start - s->cs_base);                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                 s->is_jmp = 1;  
3272              }              }
3273          } else {          } else {
3274              if (s->iopl == 3) {              if (s->iopl == 3) {
3275                  gen_op_cli();                  gen_op_cli();
3276              } else {              } else {
3277                  gen_op_gpf(pc_start - s->cs_base);                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                 s->is_jmp = 1;  
3278              }              }
3279          }          }
3280          break;          break;
# Line 3283  long disas_insn(DisasContext *s, uint8_t Line 3283  long disas_insn(DisasContext *s, uint8_t
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_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                 s->is_jmp = 1;  
3287              }              }
3288          } else {          } else {
3289              if (s->iopl == 3) {              if (s->iopl == 3) {
3290                  gen_op_sti();                  gen_op_sti();
3291              } else {              } else {
3292                  gen_op_gpf(pc_start - s->cs_base);                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
                 s->is_jmp = 1;  
3293              }              }
3294          }          }
3295          break;          break;
# Line 3343  long disas_insn(DisasContext *s, uint8_t Line 3341  long disas_insn(DisasContext *s, uint8_t
3341          break;          break;
3342      case 0xf4: /* hlt */      case 0xf4: /* hlt */
3343          /* XXX: if cpl == 0, then should do something else */          /* XXX: if cpl == 0, then should do something else */
3344          gen_op_gpf(pc_start - s->cs_base);          gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
         s->is_jmp = 1;  
3345          break;          break;
3346      default:      default:
3347          goto illegal_op;          goto illegal_op;
# Line 3453  static uint16_t opc_read_flags[NB_OPS] = Line 3450  static uint16_t opc_read_flags[NB_OPS] =
3450      [INDEX_op_setle_T0_subl] = CC_O | CC_S | CC_Z,      [INDEX_op_setle_T0_subl] = CC_O | CC_S | CC_Z,
3451    
3452      [INDEX_op_movl_T0_eflags] = CC_OSZAPC,      [INDEX_op_movl_T0_eflags] = CC_OSZAPC,
     [INDEX_op_movl_T0_eflags_vm] = CC_OSZAPC,  
3453      [INDEX_op_cmc] = CC_C,      [INDEX_op_cmc] = CC_C,
3454      [INDEX_op_salc] = CC_C,      [INDEX_op_salc] = CC_C,
3455    
# Line 3504  static uint16_t opc_write_flags[NB_OPS] Line 3500  static uint16_t opc_write_flags[NB_OPS]
3500    
3501      [INDEX_op_movb_eflags_T0] = CC_S | CC_Z | CC_A | CC_P | CC_C,      [INDEX_op_movb_eflags_T0] = CC_S | CC_Z | CC_A | CC_P | CC_C,
3502      [INDEX_op_movw_eflags_T0] = CC_OSZAPC,      [INDEX_op_movw_eflags_T0] = CC_OSZAPC,
     [INDEX_op_movw_eflags_T0_vm] = CC_OSZAPC,  
3503      [INDEX_op_movl_eflags_T0] = CC_OSZAPC,      [INDEX_op_movl_eflags_T0] = CC_OSZAPC,
     [INDEX_op_movl_eflags_T0_vm] = CC_OSZAPC,  
3504      [INDEX_op_clc] = CC_C,      [INDEX_op_clc] = CC_C,
3505      [INDEX_op_stc] = CC_C,      [INDEX_op_stc] = CC_C,
3506      [INDEX_op_cmc] = CC_C,      [INDEX_op_cmc] = CC_C,
# Line 3726  int cpu_x86_gen_code(uint8_t *gen_code_b Line 3720  int cpu_x86_gen_code(uint8_t *gen_code_b
3720      dc->vm86 = (flags >> GEN_FLAG_VM_SHIFT) & 1;      dc->vm86 = (flags >> GEN_FLAG_VM_SHIFT) & 1;
3721      dc->cpl = (flags >> GEN_FLAG_CPL_SHIFT) & 3;      dc->cpl = (flags >> GEN_FLAG_CPL_SHIFT) & 3;
3722      dc->iopl = (flags >> GEN_FLAG_IOPL_SHIFT) & 3;      dc->iopl = (flags >> GEN_FLAG_IOPL_SHIFT) & 3;
3723        dc->tf = (flags >> GEN_FLAG_TF_SHIFT) & 1;
3724      dc->cc_op = CC_OP_DYNAMIC;      dc->cc_op = CC_OP_DYNAMIC;
3725      dc->cs_base = cs_base;      dc->cs_base = cs_base;
3726    
# Line 3747  int cpu_x86_gen_code(uint8_t *gen_code_b Line 3742  int cpu_x86_gen_code(uint8_t *gen_code_b
3742                  break;                  break;
3743          }          }
3744          pc_ptr = (void *)ret;          pc_ptr = (void *)ret;
3745            /* if single step mode, we generate only one instruction and
3746               generate an exception */
3747            if (dc->tf)
3748                break;
3749      } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end);      } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end);
3750      /* we must store the eflags state if it is not already done */      /* we must store the eflags state if it is not already done */
3751      if (dc->cc_op != CC_OP_DYNAMIC)      if (dc->cc_op != CC_OP_DYNAMIC)
# Line 3755  int cpu_x86_gen_code(uint8_t *gen_code_b Line 3754  int cpu_x86_gen_code(uint8_t *gen_code_b
3754          /* we add an additionnal jmp to update the simulated PC */          /* we add an additionnal jmp to update the simulated PC */
3755          gen_op_jmp_im(ret - (unsigned long)dc->cs_base);          gen_op_jmp_im(ret - (unsigned long)dc->cs_base);
3756      }      }
3757        if (dc->tf) {
3758            gen_op_raise_exception(EXCP01_SSTP);
3759        }
3760    
3761      *gen_opc_ptr = INDEX_op_end;      *gen_opc_ptr = INDEX_op_end;
3762    
3763  #ifdef DEBUG_DISAS  #ifdef DEBUG_DISAS

Legend:
Removed from v.1.29  
changed lines
  Added in v.1.30

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