/[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.44 by bellard, Wed Jun 25 16:19:50 2003 UTC revision 1.45 by bellard, Mon Jun 30 10:11:50 2003 UTC
# Line 365  static GenOpFunc *gen_op_cmov_reg_T1_T0[ Line 365  static GenOpFunc *gen_op_cmov_reg_T1_T0[
365  };  };
366    
367  static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {  static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
     gen_op_addl_T0_T1_cc,  
     gen_op_orl_T0_T1_cc,  
368      NULL,      NULL,
369        gen_op_orl_T0_T1,
370        NULL,
371        NULL,
372        gen_op_andl_T0_T1,
373        NULL,
374        gen_op_xorl_T0_T1,
375      NULL,      NULL,
     gen_op_andl_T0_T1_cc,  
     gen_op_subl_T0_T1_cc,  
     gen_op_xorl_T0_T1_cc,  
     gen_op_cmpl_T0_T1_cc,  
376  };  };
377    
378  static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = {  static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = {
# Line 748  static GenOpFunc1 *gen_op_fp_arith_STN_S Line 748  static GenOpFunc1 *gen_op_fp_arith_STN_S
748      gen_op_fdiv_STN_ST0,      gen_op_fdiv_STN_ST0,
749  };  };
750    
751  static void gen_op(DisasContext *s1, int op, int ot, int d, int s)  /* if d == OR_TMP0, it means memory operand (address in A0) */
752    static void gen_op(DisasContext *s1, int op, int ot, int d)
753  {  {
754      if (d != OR_TMP0)      GenOpFunc *gen_update_cc;
755        
756        if (d != OR_TMP0) {
757          gen_op_mov_TN_reg[ot][0][d]();          gen_op_mov_TN_reg[ot][0][d]();
758      if (s != OR_TMP1)      } else {
759          gen_op_mov_TN_reg[ot][1][s]();          gen_op_ld_T0_A0[ot]();
760      if (op == OP_ADCL || op == OP_SBBL) {      }
761        switch(op) {
762        case OP_ADCL:
763        case OP_SBBL:
764          if (s1->cc_op != CC_OP_DYNAMIC)          if (s1->cc_op != CC_OP_DYNAMIC)
765              gen_op_set_cc_op(s1->cc_op);              gen_op_set_cc_op(s1->cc_op);
766          gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();          gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
767          s1->cc_op = CC_OP_DYNAMIC;          s1->cc_op = CC_OP_DYNAMIC;
768      } else {          /* XXX: incorrect: CC_OP must also be modified AFTER memory access */
769            gen_update_cc = gen_op_update2_cc;
770            break;
771        case OP_ADDL:
772            gen_op_addl_T0_T1();
773            s1->cc_op = CC_OP_ADDB + ot;
774            gen_update_cc = gen_op_update2_cc;
775            break;
776        case OP_SUBL:
777            gen_op_subl_T0_T1();
778            s1->cc_op = CC_OP_SUBB + ot;
779            gen_update_cc = gen_op_update2_cc;
780            break;
781        default:
782        case OP_ANDL:
783        case OP_ORL:
784        case OP_XORL:
785          gen_op_arith_T0_T1_cc[op]();          gen_op_arith_T0_T1_cc[op]();
786          s1->cc_op = cc_op_arithb[op] + ot;          s1->cc_op = CC_OP_LOGICB + ot;
787            gen_update_cc = gen_op_update1_cc;
788            break;
789        case OP_CMPL:
790            gen_op_cmpl_T0_T1_cc();
791            s1->cc_op = CC_OP_SUBB + ot;
792            gen_update_cc = NULL;
793            break;
794      }      }
795      if (d != OR_TMP0 && op != OP_CMPL)      if (op != OP_CMPL) {
796          gen_op_mov_reg_T0[ot][d]();          if (d != OR_TMP0)
797  }              gen_op_mov_reg_T0[ot][d]();
798            else
799  static void gen_opi(DisasContext *s1, int op, int ot, int d, int c)              gen_op_st_T0_A0[ot]();
800  {      }
801      gen_op_movl_T1_im(c);      /* the flags update must happen after the memory write (precise
802      gen_op(s1, op, ot, d, OR_TMP1);         exception support) */
803        if (gen_update_cc)
804            gen_update_cc();
805  }  }
806    
807    /* if d == OR_TMP0, it means memory operand (address in A0) */
808  static void gen_inc(DisasContext *s1, int ot, int d, int c)  static void gen_inc(DisasContext *s1, int ot, int d, int c)
809  {  {
810      if (d != OR_TMP0)      if (d != OR_TMP0)
811          gen_op_mov_TN_reg[ot][0][d]();          gen_op_mov_TN_reg[ot][0][d]();
812        else
813            gen_op_ld_T0_A0[ot]();
814      if (s1->cc_op != CC_OP_DYNAMIC)      if (s1->cc_op != CC_OP_DYNAMIC)
815          gen_op_set_cc_op(s1->cc_op);          gen_op_set_cc_op(s1->cc_op);
816      if (c > 0) {      if (c > 0) {
817          gen_op_incl_T0_cc();          gen_op_incl_T0();
818          s1->cc_op = CC_OP_INCB + ot;          s1->cc_op = CC_OP_INCB + ot;
819      } else {      } else {
820          gen_op_decl_T0_cc();          gen_op_decl_T0();
821          s1->cc_op = CC_OP_DECB + ot;          s1->cc_op = CC_OP_DECB + ot;
822      }      }
823      if (d != OR_TMP0)      if (d != OR_TMP0)
824          gen_op_mov_reg_T0[ot][d]();          gen_op_mov_reg_T0[ot][d]();
825        else
826            gen_op_st_T0_A0[ot]();
827        gen_op_update_inc_cc();
828  }  }
829    
830  static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)  static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
# Line 1459  long disas_insn(DisasContext *s, uint8_t Line 1496  long disas_insn(DisasContext *s, uint8_t
1496                  rm = modrm & 7;                  rm = modrm & 7;
1497                  if (mod != 3) {                  if (mod != 3) {
1498                      gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);                      gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                     gen_op_ld_T0_A0[ot]();  
1499                      opreg = OR_TMP0;                      opreg = OR_TMP0;
1500                  } else {                  } else {
1501                      opreg = OR_EAX + rm;                      opreg = OR_EAX + rm;
1502                  }                  }
1503                  gen_op(s, op, ot, opreg, reg);                  gen_op_mov_TN_reg[ot][1][reg]();
1504                  if (mod != 3 && op != 7) {                  gen_op(s, op, ot, opreg);
                     gen_op_st_T0_A0[ot]();  
                 }  
1505                  break;                  break;
1506              case 1: /* OP Gv, Ev */              case 1: /* OP Gv, Ev */
1507                  modrm = ldub(s->pc++);                  modrm = ldub(s->pc++);
# Line 1477  long disas_insn(DisasContext *s, uint8_t Line 1511  long disas_insn(DisasContext *s, uint8_t
1511                  if (mod != 3) {                  if (mod != 3) {
1512                      gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);                      gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1513                      gen_op_ld_T1_A0[ot]();                      gen_op_ld_T1_A0[ot]();
                     opreg = OR_TMP1;  
1514                  } else {                  } else {
1515                      opreg = OR_EAX + rm;                      gen_op_mov_TN_reg[ot][1][rm]();
1516                  }                  }
1517                  gen_op(s, op, ot, reg, opreg);                  gen_op(s, op, ot, reg);
1518                  break;                  break;
1519              case 2: /* OP A, Iv */              case 2: /* OP A, Iv */
1520                  val = insn_get(s, ot);                  val = insn_get(s, ot);
1521                  gen_opi(s, op, ot, OR_EAX, val);                  gen_op_movl_T1_im(val);
1522                    gen_op(s, op, ot, OR_EAX);
1523                  break;                  break;
1524              }              }
1525          }          }
# Line 1509  long disas_insn(DisasContext *s, uint8_t Line 1543  long disas_insn(DisasContext *s, uint8_t
1543                            
1544              if (mod != 3) {              if (mod != 3) {
1545                  gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);                  gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                 gen_op_ld_T0_A0[ot]();  
1546                  opreg = OR_TMP0;                  opreg = OR_TMP0;
1547              } else {              } else {
1548                  opreg = rm + OR_EAX;                  opreg = rm + OR_EAX;
# Line 1525  long disas_insn(DisasContext *s, uint8_t Line 1558  long disas_insn(DisasContext *s, uint8_t
1558                  val = (int8_t)insn_get(s, OT_BYTE);                  val = (int8_t)insn_get(s, OT_BYTE);
1559                  break;                  break;
1560              }              }
1561                gen_op_movl_T1_im(val);
1562              gen_opi(s, op, ot, opreg, val);              gen_op(s, op, ot, opreg);
             if (op != 7 && mod != 3) {  
                 gen_op_st_T0_A0[ot]();  
             }  
1563          }          }
1564          break;          break;
1565    
# Line 1577  long disas_insn(DisasContext *s, uint8_t Line 1607  long disas_insn(DisasContext *s, uint8_t
1607              }              }
1608              break;              break;
1609          case 3: /* neg */          case 3: /* neg */
1610              gen_op_negl_T0_cc();              gen_op_negl_T0();
1611              if (mod != 3) {              if (mod != 3) {
1612                  gen_op_st_T0_A0[ot]();                  gen_op_st_T0_A0[ot]();
1613              } else {              } else {
1614                  gen_op_mov_reg_T0[ot][rm]();                  gen_op_mov_reg_T0[ot][rm]();
1615              }              }
1616                gen_op_update_neg_cc();
1617              s->cc_op = CC_OP_SUBB + ot;              s->cc_op = CC_OP_SUBB + ot;
1618              break;              break;
1619          case 4: /* mul */          case 4: /* mul */
# Line 1664  long disas_insn(DisasContext *s, uint8_t Line 1695  long disas_insn(DisasContext *s, uint8_t
1695          }          }
1696          if (mod != 3) {          if (mod != 3) {
1697              gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);              gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1698              if (op != 3 && op != 5)              if (op >= 2 && op != 3 && op != 5)
1699                  gen_op_ld_T0_A0[ot]();                  gen_op_ld_T0_A0[ot]();
1700          } else {          } else {
1701              gen_op_mov_TN_reg[ot][0][rm]();              gen_op_mov_TN_reg[ot][0][rm]();
# Line 1672  long disas_insn(DisasContext *s, uint8_t Line 1703  long disas_insn(DisasContext *s, uint8_t
1703    
1704          switch(op) {          switch(op) {
1705          case 0: /* inc Ev */          case 0: /* inc Ev */
             gen_inc(s, ot, OR_TMP0, 1);  
1706              if (mod != 3)              if (mod != 3)
1707                  gen_op_st_T0_A0[ot]();                  opreg = OR_TMP0;
1708              else              else
1709                  gen_op_mov_reg_T0[ot][rm]();                  opreg = rm;
1710                gen_inc(s, ot, opreg, 1);
1711              break;              break;
1712          case 1: /* dec Ev */          case 1: /* dec Ev */
             gen_inc(s, ot, OR_TMP0, -1);  
1713              if (mod != 3)              if (mod != 3)
1714                  gen_op_st_T0_A0[ot]();                  opreg = OR_TMP0;
1715              else              else
1716                  gen_op_mov_reg_T0[ot][rm]();                  opreg = rm;
1717                gen_inc(s, ot, opreg, -1);
1718              break;              break;
1719          case 2: /* call Ev */          case 2: /* call Ev */
1720              /* XXX: optimize if memory (no and is necessary) */              /* XXX: optimize if memory (no and is necessary) */
# Line 1822  long disas_insn(DisasContext *s, uint8_t Line 1853  long disas_insn(DisasContext *s, uint8_t
1853              rm = modrm & 7;              rm = modrm & 7;
1854              gen_op_mov_TN_reg[ot][0][reg]();              gen_op_mov_TN_reg[ot][0][reg]();
1855              gen_op_mov_TN_reg[ot][1][rm]();              gen_op_mov_TN_reg[ot][1][rm]();
1856              gen_op_addl_T0_T1_cc();              gen_op_addl_T0_T1();
1857              gen_op_mov_reg_T0[ot][rm]();              gen_op_mov_reg_T0[ot][rm]();
1858              gen_op_mov_reg_T1[ot][reg]();              gen_op_mov_reg_T1[ot][reg]();
1859          } else {          } else {
1860              gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);              gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1861              gen_op_mov_TN_reg[ot][0][reg]();              gen_op_mov_TN_reg[ot][0][reg]();
1862              gen_op_ld_T1_A0[ot]();              gen_op_ld_T1_A0[ot]();
1863              gen_op_addl_T0_T1_cc();              gen_op_addl_T0_T1();
1864              gen_op_st_T0_A0[ot]();              gen_op_st_T0_A0[ot]();
1865              gen_op_mov_reg_T1[ot][reg]();              gen_op_mov_reg_T1[ot][reg]();
1866          }          }
1867            gen_op_update2_cc();
1868          s->cc_op = CC_OP_ADDB + ot;          s->cc_op = CC_OP_ADDB + ot;
1869          break;          break;
1870      case 0x1b0:      case 0x1b0:
# Line 3607  static uint16_t opc_read_flags[NB_OPS] = Line 3639  static uint16_t opc_read_flags[NB_OPS] =
3639      [INDEX_op_sbbl_T0_T1_cc] = CC_C,      [INDEX_op_sbbl_T0_T1_cc] = CC_C,
3640    
3641      /* subtle: due to the incl/decl implementation, C is used */      /* subtle: due to the incl/decl implementation, C is used */
3642      [INDEX_op_incl_T0_cc] = CC_C,      [INDEX_op_update_inc_cc] = CC_C,
     [INDEX_op_decl_T0_cc] = CC_C,  
3643    
3644      [INDEX_op_into] = CC_O,      [INDEX_op_into] = CC_O,
3645    
# Line 3688  static uint16_t opc_read_flags[NB_OPS] = Line 3719  static uint16_t opc_read_flags[NB_OPS] =
3719    
3720  /* flags written by an operation */  /* flags written by an operation */
3721  static uint16_t opc_write_flags[NB_OPS] = {  static uint16_t opc_write_flags[NB_OPS] = {
3722      [INDEX_op_addl_T0_T1_cc] = CC_OSZAPC,      [INDEX_op_update2_cc] = CC_OSZAPC,
3723      [INDEX_op_orl_T0_T1_cc] = CC_OSZAPC,      [INDEX_op_update1_cc] = CC_OSZAPC,
3724      [INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC,      [INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC,
3725      [INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC,      [INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC,
3726      [INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC,      [INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC,
3727      [INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC,      [INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC,
3728      [INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC,      [INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC,
3729      [INDEX_op_sbbl_T0_T1_cc] = CC_OSZAPC,      [INDEX_op_sbbl_T0_T1_cc] = CC_OSZAPC,
     [INDEX_op_andl_T0_T1_cc] = CC_OSZAPC,  
     [INDEX_op_subl_T0_T1_cc] = CC_OSZAPC,  
     [INDEX_op_xorl_T0_T1_cc] = CC_OSZAPC,  
3730      [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,      [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
3731      [INDEX_op_negl_T0_cc] = CC_OSZAPC,      [INDEX_op_update_neg_cc] = CC_OSZAPC,
3732      /* subtle: due to the incl/decl implementation, C is used */      /* subtle: due to the incl/decl implementation, C is used */
3733      [INDEX_op_incl_T0_cc] = CC_OSZAPC,      [INDEX_op_update_inc_cc] = CC_OSZAPC,
     [INDEX_op_decl_T0_cc] = CC_OSZAPC,  
3734      [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,      [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
3735    
3736      [INDEX_op_mulb_AL_T0] = CC_OSZAPC,      [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
# Line 3812  static uint16_t opc_write_flags[NB_OPS] Line 3839  static uint16_t opc_write_flags[NB_OPS]
3839    
3840  /* simpler form of an operation if no flags need to be generated */  /* simpler form of an operation if no flags need to be generated */
3841  static uint16_t opc_simpler[NB_OPS] = {  static uint16_t opc_simpler[NB_OPS] = {
3842      [INDEX_op_addl_T0_T1_cc] = INDEX_op_addl_T0_T1,      [INDEX_op_update2_cc] = INDEX_op_nop,
3843      [INDEX_op_orl_T0_T1_cc] = INDEX_op_orl_T0_T1,      [INDEX_op_update1_cc] = INDEX_op_nop,
3844      [INDEX_op_andl_T0_T1_cc] = INDEX_op_andl_T0_T1,      [INDEX_op_update_neg_cc] = INDEX_op_nop,
3845      [INDEX_op_subl_T0_T1_cc] = INDEX_op_subl_T0_T1,      [INDEX_op_update_inc_cc] = INDEX_op_nop,
     [INDEX_op_xorl_T0_T1_cc] = INDEX_op_xorl_T0_T1,  
     [INDEX_op_negl_T0_cc] = INDEX_op_negl_T0,  
     [INDEX_op_incl_T0_cc] = INDEX_op_incl_T0,  
     [INDEX_op_decl_T0_cc] = INDEX_op_decl_T0,  
3846    
3847      [INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1,      [INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1,
3848      [INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1,      [INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1,

Legend:
Removed from v.1.44  
changed lines
  Added in v.1.45

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