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

Diff of /qemu/target-i386/translate.c

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

revision 1.4 by bellard, Thu Oct 30 00:39:38 2003 UTC revision 1.5 by bellard, Thu Nov 13 01:43:28 2003 UTC
# Line 749  static GenOpFunc *gen_op_out_DX_T0[3] = Line 749  static GenOpFunc *gen_op_out_DX_T0[3] =
749      gen_op_outl_DX_T0,      gen_op_outl_DX_T0,
750  };  };
751    
752    static GenOpFunc *gen_op_in[3] = {
753        gen_op_inb_T0_T1,
754        gen_op_inw_T0_T1,
755        gen_op_inl_T0_T1,
756    };
757    
758    static GenOpFunc *gen_op_out[3] = {
759        gen_op_outb_T0_T1,
760        gen_op_outw_T0_T1,
761        gen_op_outl_T0_T1,
762    };
763    
764    static GenOpFunc *gen_check_io_T0[3] = {
765        gen_op_check_iob_T0,
766        gen_op_check_iow_T0,
767        gen_op_check_iol_T0,
768    };
769    
770    static GenOpFunc *gen_check_io_DX[3] = {
771        gen_op_check_iob_DX,
772        gen_op_check_iow_DX,
773        gen_op_check_iol_DX,
774    };
775    
776    static void gen_check_io(DisasContext *s, int ot, int use_dx, int cur_eip)
777    {
778        if (s->pe && (s->cpl > s->iopl || s->vm86)) {
779            if (s->cc_op != CC_OP_DYNAMIC)
780                gen_op_set_cc_op(s->cc_op);
781            gen_op_jmp_im(cur_eip);
782            if (use_dx)
783                gen_check_io_DX[ot]();
784            else
785                gen_check_io_T0[ot]();
786        }
787    }
788    
789  static inline void gen_movs(DisasContext *s, int ot)  static inline void gen_movs(DisasContext *s, int ot)
790  {  {
791      gen_string_movl_A0_ESI(s);      gen_string_movl_A0_ESI(s);
# Line 912  GEN_REPZ(outs) Line 949  GEN_REPZ(outs)
949  GEN_REPZ2(scas)  GEN_REPZ2(scas)
950  GEN_REPZ2(cmps)  GEN_REPZ2(cmps)
951    
 static GenOpFunc *gen_op_in[3] = {  
     gen_op_inb_T0_T1,  
     gen_op_inw_T0_T1,  
     gen_op_inl_T0_T1,  
 };  
   
 static GenOpFunc *gen_op_out[3] = {  
     gen_op_outb_T0_T1,  
     gen_op_outw_T0_T1,  
     gen_op_outl_T0_T1,  
 };  
   
952  enum {  enum {
953      JCC_O,      JCC_O,
954      JCC_B,      JCC_B,
# Line 3221  static uint8_t *disas_insn(DisasContext Line 3246  static uint8_t *disas_insn(DisasContext
3246          break;          break;
3247      case 0x6c: /* insS */      case 0x6c: /* insS */
3248      case 0x6d:      case 0x6d:
3249          if (s->pe && (s->cpl > s->iopl || s->vm86)) {          if ((b & 1) == 0)
3250              /* NOTE: even for (E)CX = 0 the exception is raised */              ot = OT_BYTE;
3251              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);          else
3252                ot = dflag ? OT_LONG : OT_WORD;
3253            gen_check_io(s, ot, 1, pc_start - s->cs_base);
3254            if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
3255                gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
3256          } else {          } else {
3257              if ((b & 1) == 0)              gen_ins(s, ot);
                 ot = OT_BYTE;  
             else  
                 ot = dflag ? OT_LONG : OT_WORD;  
             if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {  
                 gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);  
             } else {  
                 gen_ins(s, ot);  
             }  
3258          }          }
3259          break;          break;
3260      case 0x6e: /* outsS */      case 0x6e: /* outsS */
3261      case 0x6f:      case 0x6f:
3262          if (s->pe && (s->cpl > s->iopl || s->vm86)) {          if ((b & 1) == 0)
3263              /* NOTE: even for (E)CX = 0 the exception is raised */              ot = OT_BYTE;
3264              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);          else
3265                ot = dflag ? OT_LONG : OT_WORD;
3266            gen_check_io(s, ot, 1, pc_start - s->cs_base);
3267            if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
3268                gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
3269          } else {          } else {
3270              if ((b & 1) == 0)              gen_outs(s, ot);
                 ot = OT_BYTE;  
             else  
                 ot = dflag ? OT_LONG : OT_WORD;  
             if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {  
                 gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);  
             } else {  
                 gen_outs(s, ot);  
             }  
3271          }          }
3272          break;          break;
3273    
# Line 3258  static uint8_t *disas_insn(DisasContext Line 3275  static uint8_t *disas_insn(DisasContext
3275          /* port I/O */          /* port I/O */
3276      case 0xe4:      case 0xe4:
3277      case 0xe5:      case 0xe5:
3278          if (s->pe && (s->cpl > s->iopl || s->vm86)) {          if ((b & 1) == 0)
3279              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);              ot = OT_BYTE;
3280          } else {          else
3281              if ((b & 1) == 0)              ot = dflag ? OT_LONG : OT_WORD;
3282                  ot = OT_BYTE;          val = ldub_code(s->pc++);
3283              else          gen_op_movl_T0_im(val);
3284                  ot = dflag ? OT_LONG : OT_WORD;          gen_check_io(s, ot, 0, pc_start - s->cs_base);
3285              val = ldub_code(s->pc++);          gen_op_in[ot]();
3286              gen_op_movl_T0_im(val);          gen_op_mov_reg_T1[ot][R_EAX]();
             gen_op_in[ot]();  
             gen_op_mov_reg_T1[ot][R_EAX]();  
         }  
3287          break;          break;
3288      case 0xe6:      case 0xe6:
3289      case 0xe7:      case 0xe7:
3290          if (s->pe && (s->cpl > s->iopl || s->vm86)) {          if ((b & 1) == 0)
3291              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);              ot = OT_BYTE;
3292          } else {          else
3293              if ((b & 1) == 0)              ot = dflag ? OT_LONG : OT_WORD;
3294                  ot = OT_BYTE;          val = ldub_code(s->pc++);
3295              else          gen_op_movl_T0_im(val);
3296                  ot = dflag ? OT_LONG : OT_WORD;          gen_check_io(s, ot, 0, pc_start - s->cs_base);
3297              val = ldub_code(s->pc++);          gen_op_mov_TN_reg[ot][1][R_EAX]();
3298              gen_op_movl_T0_im(val);          gen_op_out[ot]();
             gen_op_mov_TN_reg[ot][1][R_EAX]();  
             gen_op_out[ot]();  
         }  
3299          break;          break;
3300      case 0xec:      case 0xec:
3301      case 0xed:      case 0xed:
3302          if (s->pe && (s->cpl > s->iopl || s->vm86)) {          if ((b & 1) == 0)
3303              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);              ot = OT_BYTE;
3304          } else {          else
3305              if ((b & 1) == 0)              ot = dflag ? OT_LONG : OT_WORD;
3306                  ot = OT_BYTE;          gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
3307              else          gen_check_io(s, ot, 0, pc_start - s->cs_base);
3308                  ot = dflag ? OT_LONG : OT_WORD;          gen_op_in[ot]();
3309              gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();          gen_op_mov_reg_T1[ot][R_EAX]();
             gen_op_in[ot]();  
             gen_op_mov_reg_T1[ot][R_EAX]();  
         }  
3310          break;          break;
3311      case 0xee:      case 0xee:
3312      case 0xef:      case 0xef:
3313          if (s->pe && (s->cpl > s->iopl || s->vm86)) {          if ((b & 1) == 0)
3314              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);              ot = OT_BYTE;
3315          } else {          else
3316              if ((b & 1) == 0)              ot = dflag ? OT_LONG : OT_WORD;
3317                  ot = OT_BYTE;          gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
3318              else          gen_check_io(s, ot, 0, pc_start - s->cs_base);
3319                  ot = dflag ? OT_LONG : OT_WORD;          gen_op_mov_TN_reg[ot][1][R_EAX]();
3320              gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();          gen_op_out[ot]();
             gen_op_mov_TN_reg[ot][1][R_EAX]();  
             gen_op_out[ot]();  
         }  
3321          break;          break;
3322    
3323          /************************/          /************************/
# Line 3370  static uint8_t *disas_insn(DisasContext Line 3375  static uint8_t *disas_insn(DisasContext
3375              /* real mode */              /* real mode */
3376              gen_op_iret_real(s->dflag);              gen_op_iret_real(s->dflag);
3377              s->cc_op = CC_OP_EFLAGS;              s->cc_op = CC_OP_EFLAGS;
3378          } else if (s->vm86 && s->iopl != 3) {          } else if (s->vm86) {
3379              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);              if (s->iopl != 3) {
3380                    gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3381                } else {
3382                    gen_op_iret_real(s->dflag);
3383                    s->cc_op = CC_OP_EFLAGS;
3384                }
3385          } else {          } else {
3386              if (s->cc_op != CC_OP_DYNAMIC)              if (s->cc_op != CC_OP_DYNAMIC)
3387                  gen_op_set_cc_op(s->cc_op);                  gen_op_set_cc_op(s->cc_op);
# Line 3675  static uint8_t *disas_insn(DisasContext Line 3685  static uint8_t *disas_insn(DisasContext
3685          break;          break;
3686      case 0xcd: /* int N */      case 0xcd: /* int N */
3687          val = ldub_code(s->pc++);          val = ldub_code(s->pc++);
3688          /* XXX: add error code for vm86 GPF */          if (s->vm86 && s->iopl != 3) {
         if (!s->vm86)  
             gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);  
         else  
3689              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3690            } else {
3691                gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
3692            }
3693          break;          break;
3694      case 0xce: /* into */      case 0xce: /* into */
3695          if (s->cc_op != CC_OP_DYNAMIC)          if (s->cc_op != CC_OP_DYNAMIC)
# Line 3799  static uint8_t *disas_insn(DisasContext Line 3809  static uint8_t *disas_insn(DisasContext
3809          op = (modrm >> 3) & 7;          op = (modrm >> 3) & 7;
3810          switch(op) {          switch(op) {
3811          case 0: /* sldt */          case 0: /* sldt */
3812                if (!s->pe || s->vm86)
3813                    goto illegal_op;
3814              gen_op_movl_T0_env(offsetof(CPUX86State,ldt.selector));              gen_op_movl_T0_env(offsetof(CPUX86State,ldt.selector));
3815              ot = OT_WORD;              ot = OT_WORD;
3816              if (mod == 3)              if (mod == 3)
# Line 3806  static uint8_t *disas_insn(DisasContext Line 3818  static uint8_t *disas_insn(DisasContext
3818              gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);              gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
3819              break;              break;
3820          case 2: /* lldt */          case 2: /* lldt */
3821                if (!s->pe || s->vm86)
3822                    goto illegal_op;
3823              if (s->cpl != 0) {              if (s->cpl != 0) {
3824                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3825              } else {              } else {
# Line 3815  static uint8_t *disas_insn(DisasContext Line 3829  static uint8_t *disas_insn(DisasContext
3829              }              }
3830              break;              break;
3831          case 1: /* str */          case 1: /* str */
3832                if (!s->pe || s->vm86)
3833                    goto illegal_op;
3834              gen_op_movl_T0_env(offsetof(CPUX86State,tr.selector));              gen_op_movl_T0_env(offsetof(CPUX86State,tr.selector));
3835              ot = OT_WORD;              ot = OT_WORD;
3836              if (mod == 3)              if (mod == 3)
# Line 3822  static uint8_t *disas_insn(DisasContext Line 3838  static uint8_t *disas_insn(DisasContext
3838              gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);              gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
3839              break;              break;
3840          case 3: /* ltr */          case 3: /* ltr */
3841                if (!s->pe || s->vm86)
3842                    goto illegal_op;
3843              if (s->cpl != 0) {              if (s->cpl != 0) {
3844                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3845              } else {              } else {
# Line 3832  static uint8_t *disas_insn(DisasContext Line 3850  static uint8_t *disas_insn(DisasContext
3850              break;              break;
3851          case 4: /* verr */          case 4: /* verr */
3852          case 5: /* verw */          case 5: /* verw */
3853                if (!s->pe || s->vm86)
3854                    goto illegal_op;
3855                gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
3856                if (s->cc_op != CC_OP_DYNAMIC)
3857                    gen_op_set_cc_op(s->cc_op);
3858                if (op == 4)
3859                    gen_op_verr();
3860                else
3861                    gen_op_verw();
3862                s->cc_op = CC_OP_EFLAGS;
3863                break;
3864          default:          default:
3865              goto illegal_op;              goto illegal_op;
3866          }          }
# Line 3908  static uint8_t *disas_insn(DisasContext Line 3937  static uint8_t *disas_insn(DisasContext
3937              goto illegal_op;              goto illegal_op;
3938          }          }
3939          break;          break;
3940        case 0x63: /* arpl */
3941            if (!s->pe || s->vm86)
3942                goto illegal_op;
3943            ot = dflag ? OT_LONG : OT_WORD;
3944            modrm = ldub_code(s->pc++);
3945            reg = (modrm >> 3) & 7;
3946            mod = (modrm >> 6) & 3;
3947            rm = modrm & 7;
3948            if (mod != 3) {
3949                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3950                gen_op_ld_T0_A0[ot + s->mem_index]();
3951            } else {
3952                gen_op_mov_TN_reg[ot][0][rm]();
3953            }
3954            if (s->cc_op != CC_OP_DYNAMIC)
3955                gen_op_set_cc_op(s->cc_op);
3956            gen_op_arpl();
3957            s->cc_op = CC_OP_EFLAGS;
3958            if (mod != 3) {
3959                gen_op_st_T0_A0[ot + s->mem_index]();
3960            } else {
3961                gen_op_mov_reg_T0[ot][rm]();
3962            }
3963            gen_op_arpl_update();
3964            break;
3965      case 0x102: /* lar */      case 0x102: /* lar */
3966      case 0x103: /* lsl */      case 0x103: /* lsl */
3967          if (!s->pe || s->vm86)          if (!s->pe || s->vm86)

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

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