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

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

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

revision 1.10 by bellard, Sat Nov 26 18:47:06 2005 UTC revision 1.11 by bellard, Mon Dec 5 19:59:36 2005 UTC
# Line 338  static inline void save_cpu_state (Disas Line 338  static inline void save_cpu_state (Disas
338      }      }
339  }  }
340    
341  static inline void generate_exception (DisasContext *ctx, int excp)  static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
342  {  {
343  #if defined MIPS_DEBUG_DISAS  #if defined MIPS_DEBUG_DISAS
344      if (loglevel & CPU_LOG_TB_IN_ASM)      if (loglevel & CPU_LOG_TB_IN_ASM)
345              fprintf(logfile, "%s: raise exception %d\n", __func__, excp);              fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
346  #endif  #endif
347      save_cpu_state(ctx, 1);      save_cpu_state(ctx, 1);
348      gen_op_raise_exception(excp);      if (err == 0)
349            gen_op_raise_exception(excp);
350        else
351            gen_op_raise_exception_err(excp, err);
352      ctx->bstate = BS_EXCP;      ctx->bstate = BS_EXCP;
353  }  }
354    
355    static inline void generate_exception (DisasContext *ctx, int excp)
356    {
357        generate_exception_err (ctx, excp, 0);
358    }
359    
360  #if defined(CONFIG_USER_ONLY)  #if defined(CONFIG_USER_ONLY)
361  #define op_ldst(name)        gen_op_##name##_raw()  #define op_ldst(name)        gen_op_##name##_raw()
362  #define OP_LD_TABLE(width)  #define OP_LD_TABLE(width)
# Line 1020  static void gen_compute_branch (DisasCon Line 1028  static void gen_compute_branch (DisasCon
1028          case OPC_BLEZ:    /* 0 <= 0          */          case OPC_BLEZ:    /* 0 <= 0          */
1029          case OPC_BLEZL:   /* 0 <= 0 likely   */          case OPC_BLEZL:   /* 0 <= 0 likely   */
1030              /* Always take */              /* Always take */
1031              ctx->hflags |= MIPS_HFLAG_DS | MIPS_HFLAG_B;              ctx->hflags |= MIPS_HFLAG_B;
1032              MIPS_DEBUG("balways");              MIPS_DEBUG("balways");
1033              break;              break;
1034          case OPC_BGEZAL:  /* 0 >= 0          */          case OPC_BGEZAL:  /* 0 >= 0          */
1035          case OPC_BGEZALL: /* 0 >= 0 likely   */          case OPC_BGEZALL: /* 0 >= 0 likely   */
1036              /* Always take and link */              /* Always take and link */
1037              blink = 31;              blink = 31;
1038              ctx->hflags |= MIPS_HFLAG_DS | MIPS_HFLAG_B;              ctx->hflags |= MIPS_HFLAG_B;
1039              MIPS_DEBUG("balways and link");              MIPS_DEBUG("balways and link");
1040              break;              break;
1041          case OPC_BNE:     /* rx != rx        */          case OPC_BNE:     /* rx != rx        */
# Line 1053  static void gen_compute_branch (DisasCon Line 1061  static void gen_compute_branch (DisasCon
1061              gen_goto_tb(ctx, 0, ctx->pc + 4);              gen_goto_tb(ctx, 0, ctx->pc + 4);
1062              return;              return;
1063          case OPC_J:          case OPC_J:
1064              ctx->hflags |= MIPS_HFLAG_DS | MIPS_HFLAG_B;              ctx->hflags |= MIPS_HFLAG_B;
1065              MIPS_DEBUG("j %08x", btarget);              MIPS_DEBUG("j %08x", btarget);
1066              break;              break;
1067          case OPC_JAL:          case OPC_JAL:
1068              blink = 31;              blink = 31;
1069              ctx->hflags |= MIPS_HFLAG_DS | MIPS_HFLAG_B;              ctx->hflags |= MIPS_HFLAG_B;
1070              MIPS_DEBUG("jal %08x", btarget);              MIPS_DEBUG("jal %08x", btarget);
1071              break;              break;
1072          case OPC_JR:          case OPC_JR:
1073              ctx->hflags |= MIPS_HFLAG_DS | MIPS_HFLAG_BR;              ctx->hflags |= MIPS_HFLAG_BR;
1074              MIPS_DEBUG("jr %s", regnames[rs]);              MIPS_DEBUG("jr %s", regnames[rs]);
1075              break;              break;
1076          case OPC_JALR:          case OPC_JALR:
1077              blink = rt;              blink = rt;
1078              ctx->hflags |= MIPS_HFLAG_DS | MIPS_HFLAG_BR;              ctx->hflags |= MIPS_HFLAG_BR;
1079              MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);              MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1080              break;              break;
1081          default:          default:
# Line 1144  static void gen_compute_branch (DisasCon Line 1152  static void gen_compute_branch (DisasCon
1152              blink = 31;              blink = 31;
1153              MIPS_DEBUG("bltzal %s, %08x", regnames[rs], btarget);              MIPS_DEBUG("bltzal %s, %08x", regnames[rs], btarget);
1154          not_likely:          not_likely:
1155              ctx->hflags |= MIPS_HFLAG_DS | MIPS_HFLAG_BC;              ctx->hflags |= MIPS_HFLAG_BC;
1156              break;              break;
1157          case OPC_BLTZALL:          case OPC_BLTZALL:
1158              gen_op_ltz();              gen_op_ltz();
1159              blink = 31;              blink = 31;
1160              MIPS_DEBUG("bltzall %s, %08x", regnames[rs], btarget);              MIPS_DEBUG("bltzall %s, %08x", regnames[rs], btarget);
1161          likely:          likely:
1162              ctx->hflags |= MIPS_HFLAG_DS | MIPS_HFLAG_BL;              ctx->hflags |= MIPS_HFLAG_BL;
1163              break;              break;
1164          }          }
1165          gen_op_set_bcond();          gen_op_set_bcond();
# Line 1178  static void gen_cp0 (DisasContext *ctx, Line 1186  static void gen_cp0 (DisasContext *ctx,
1186          if (loglevel & CPU_LOG_TB_IN_ASM) {          if (loglevel & CPU_LOG_TB_IN_ASM) {
1187              fprintf(logfile, "CP0 is not usable\n");              fprintf(logfile, "CP0 is not usable\n");
1188          }          }
1189          gen_op_raise_exception_err(EXCP_CpU, 0);          generate_exception_err (ctx, EXCP_CpU, 0);
1190          return;          return;
1191      }      }
1192      switch (opc) {      switch (opc) {
# Line 1236  static void gen_cp0 (DisasContext *ctx, Line 1244  static void gen_cp0 (DisasContext *ctx,
1244              ctx->bstate = BS_EXCP;              ctx->bstate = BS_EXCP;
1245          }          }
1246          break;          break;
1247      /* XXX: TODO: WAIT */      case OPC_WAIT:
1248            opn = "wait";
1249            /* If we get an exception, we want to restart at next instruction */
1250            ctx->pc += 4;
1251            save_cpu_state(ctx, 1);
1252            ctx->pc -= 4;
1253            gen_op_wait();
1254            ctx->bstate = BS_EXCP;
1255            break;
1256      default:      default:
1257          if (loglevel & CPU_LOG_TB_IN_ASM) {          if (loglevel & CPU_LOG_TB_IN_ASM) {
1258              fprintf(logfile, "Invalid CP0 opcode: %08x %03x %03x %03x\n",              fprintf(logfile, "Invalid CP0 opcode: %08x %03x %03x %03x\n",
# Line 1292  static void gen_blikely(DisasContext *ct Line 1308  static void gen_blikely(DisasContext *ct
1308      int l1;      int l1;
1309      l1 = gen_new_label();      l1 = gen_new_label();
1310      gen_op_jnz_T2(l1);      gen_op_jnz_T2(l1);
1311      gen_op_save_state(ctx->hflags & ~(MIPS_HFLAG_BMASK | MIPS_HFLAG_DS));      gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
1312      gen_goto_tb(ctx, 1, ctx->pc + 4);      gen_goto_tb(ctx, 1, ctx->pc + 4);
1313      gen_set_label(l1);      gen_set_label(l1);
1314  }  }
# Line 1304  static void decode_opc (DisasContext *ct Line 1320  static void decode_opc (DisasContext *ct
1320      uint16_t op, op1;      uint16_t op, op1;
1321      int16_t imm;      int16_t imm;
1322    
1323      if ((ctx->hflags & MIPS_HFLAG_DS) &&      if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
         (ctx->hflags & MIPS_HFLAG_BL)) {  
1324          /* Handle blikely not taken case */          /* Handle blikely not taken case */
1325          MIPS_DEBUG("blikely condition (%08x)", ctx->pc + 4);          MIPS_DEBUG("blikely condition (%08x)", ctx->pc + 4);
1326          gen_blikely(ctx);          gen_blikely(ctx);
# Line 1361  static void decode_opc (DisasContext *ct Line 1376  static void decode_opc (DisasContext *ct
1376          case 0x05:          /* Pmon entry point */          case 0x05:          /* Pmon entry point */
1377              gen_op_pmon((ctx->opcode >> 6) & 0x1F);              gen_op_pmon((ctx->opcode >> 6) & 0x1F);
1378              break;              break;
1379  #if defined (MIPS_HAS_MOVCI)  
1380          case 0x01:          /* MOVCI */          case 0x01:          /* MOVCI */
1381    #if defined (MIPS_HAS_MOVCI)
1382                /* XXX */
1383    #else
1384                /* Not implemented */
1385                generate_exception_err (ctx, EXCP_CpU, 1);
1386  #endif  #endif
1387                break;
1388    
1389  #if defined (TARGET_MIPS64)  #if defined (TARGET_MIPS64)
1390          case 0x14: /* MIPS64 specific opcodes */          case 0x14: /* MIPS64 specific opcodes */
1391          case 0x16:          case 0x16:
# Line 1438  static void decode_opc (DisasContext *ct Line 1460  static void decode_opc (DisasContext *ct
1460              gen_cp0(ctx, op1 | EXT_CP0, rt, rd);              gen_cp0(ctx, op1 | EXT_CP0, rt, rd);
1461              break;              break;
1462          default:          default:
1463              gen_cp0(ctx, (ctx->opcode & 0x1F) | EXT_CP0, rt, rd);              gen_cp0(ctx, (ctx->opcode & 0x3F) | EXT_CP0, rt, rd);
1464              break;              break;
1465          }          }
1466          break;          break;
# Line 1467  static void decode_opc (DisasContext *ct Line 1489  static void decode_opc (DisasContext *ct
1489          break;          break;
1490      case 0x3F: /* HACK */      case 0x3F: /* HACK */
1491          break;          break;
1492    
1493        /* Floating point.  */
1494        case 0x31: /* LWC1 */
1495        case 0x35: /* LDC1 */
1496        case 0x39: /* SWC1 */
1497        case 0x3D: /* SDC1 */
1498        case 0x11:          /* CP1 opcode */
1499  #if defined(MIPS_USES_FPU)  #if defined(MIPS_USES_FPU)
     case 0x31 ... 0x32: /* Floating point load/store */  
     case 0x35 ... 0x36:  
     case 0x3A ... 0x3B:  
     case 0x3D ... 0x3E:  
         /* Not implemented */  
1500          /* XXX: not correct */          /* XXX: not correct */
1501    #else
1502            generate_exception_err(ctx, EXCP_CpU, 1);
1503  #endif  #endif
1504      case 0x11:          /* CP1 opcode */          break;
1505          /* Not implemented */  
1506          /* XXX: not correct */      /* COP2.  */
1507        case 0x32: /* LWC2 */
1508        case 0x36: /* LDC2 */
1509        case 0x3A: /* SWC2 */
1510        case 0x3E: /* SDC2 */
1511      case 0x12:          /* CP2 opcode */      case 0x12:          /* CP2 opcode */
1512          /* Not implemented */          /* Not implemented */
1513          /* XXX: not correct */          generate_exception_err(ctx, EXCP_CpU, 2);
1514            break;
1515    
1516      case 0x13:          /* CP3 opcode */      case 0x13:          /* CP3 opcode */
1517          /* Not implemented */          /* Not implemented */
1518          /* XXX: not correct */          generate_exception_err(ctx, EXCP_CpU, 3);
1519            break;
1520    
1521  #if defined (TARGET_MIPS64)  #if defined (TARGET_MIPS64)
1522      case 0x18 ... 0x1B:      case 0x18 ... 0x1B:
1523      case 0x27:      case 0x27:
# Line 1497  static void decode_opc (DisasContext *ct Line 1531  static void decode_opc (DisasContext *ct
1531  #endif  #endif
1532      case 0x1E:      case 0x1E:
1533          /* ASE specific */          /* ASE specific */
 #if defined (MIPS_HAS_LSC)  
     case 0x31: /* LWC1 */  
     case 0x32: /* LWC2 */  
     case 0x35: /* SDC1 */  
     case 0x36: /* SDC2 */  
 #endif  
1534      default:            /* Invalid */      default:            /* Invalid */
1535          MIPS_INVAL("");          MIPS_INVAL("");
1536          generate_exception(ctx, EXCP_RI);          generate_exception(ctx, EXCP_RI);
1537          break;          break;
1538      }      }
1539      if (ctx->hflags & MIPS_HFLAG_DS) {      if (ctx->hflags & MIPS_HFLAG_BMASK) {
1540          int hflags = ctx->hflags;          int hflags = ctx->hflags;
1541          /* Branches completion */          /* Branches completion */
1542          ctx->hflags &= ~(MIPS_HFLAG_BMASK | MIPS_HFLAG_DS);          ctx->hflags &= ~MIPS_HFLAG_BMASK;
1543          ctx->bstate = BS_BRANCH;          ctx->bstate = BS_BRANCH;
1544          save_cpu_state(ctx, 0);          save_cpu_state(ctx, 0);
1545          switch (hflags & MIPS_HFLAG_BMASK) {          switch (hflags & MIPS_HFLAG_BMASK) {
# Line 1557  int gen_intermediate_code_internal (CPUS Line 1585  int gen_intermediate_code_internal (CPUS
1585      uint16_t *gen_opc_end;      uint16_t *gen_opc_end;
1586      int j, lj = -1;      int j, lj = -1;
1587    
1588        if (search_pc && loglevel)
1589            fprintf (logfile, "search pc %d\n", search_pc);
1590    
1591      pc_start = tb->pc;      pc_start = tb->pc;
1592      gen_opc_ptr = gen_opc_buf;      gen_opc_ptr = gen_opc_buf;
1593      gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;      gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1594      gen_opparam_ptr = gen_opparam_buf;      gen_opparam_ptr = gen_opparam_buf;
1595      nb_gen_labels = 0;      nb_gen_labels = 0;
1596      ctx.pc = pc_start;      ctx.pc = pc_start;
1597        ctx.saved_pc = -1;
1598      ctx.tb = tb;      ctx.tb = tb;
1599      ctx.bstate = BS_NONE;      ctx.bstate = BS_NONE;
1600      /* Restore delay slot state */      /* Restore delay slot state from the tb context.  */
1601      ctx.hflags = env->hflags;      ctx.hflags = tb->flags;
1602      ctx.saved_hflags = ctx.hflags;      ctx.saved_hflags = ctx.hflags;
1603      if (ctx.hflags & MIPS_HFLAG_BR) {      if (ctx.hflags & MIPS_HFLAG_BR) {
1604          gen_op_restore_breg_target();          gen_op_restore_breg_target();
# Line 1588  int gen_intermediate_code_internal (CPUS Line 1620  int gen_intermediate_code_internal (CPUS
1620  #ifdef DEBUG_DISAS  #ifdef DEBUG_DISAS
1621      if (loglevel & CPU_LOG_TB_CPU) {      if (loglevel & CPU_LOG_TB_CPU) {
1622          fprintf(logfile, "------------------------------------------------\n");          fprintf(logfile, "------------------------------------------------\n");
1623            /* FIXME: This may print out stale hflags from env... */
1624          cpu_dump_state(env, logfile, fprintf, 0);          cpu_dump_state(env, logfile, fprintf, 0);
1625      }      }
1626  #endif  #endif
1627  #if defined MIPS_DEBUG_DISAS  #if defined MIPS_DEBUG_DISAS
1628      if (loglevel & CPU_LOG_TB_IN_ASM)      if (loglevel & CPU_LOG_TB_IN_ASM)
1629          fprintf(logfile, "\ntb %p super %d cond %04x %04x\n",          fprintf(logfile, "\ntb %p super %d cond %04x\n",
1630                  tb, ctx.mem_idx, ctx.hflags, env->hflags);                  tb, ctx.mem_idx, ctx.hflags);
1631  #endif  #endif
1632      while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {      while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1633            if (env->nb_breakpoints > 0) {
1634                for(j = 0; j < env->nb_breakpoints; j++) {
1635                    if (env->breakpoints[j] == ctx.pc) {
1636                        save_cpu_state(ctxp, 1);
1637                        ctx.bstate = BS_BRANCH;
1638                        gen_op_debug();
1639                        goto done_generating;
1640                    }
1641                }
1642            }
1643    
1644          if (search_pc) {          if (search_pc) {
1645              j = gen_opc_ptr - gen_opc_buf;              j = gen_opc_ptr - gen_opc_buf;
             save_cpu_state(ctxp, 1);  
1646              if (lj < j) {              if (lj < j) {
1647                  lj++;                  lj++;
1648                  while (lj < j)                  while (lj < j)
1649                      gen_opc_instr_start[lj++] = 0;                      gen_opc_instr_start[lj++] = 0;
                 gen_opc_pc[lj] = ctx.pc;  
                 gen_opc_instr_start[lj] = 1;  
1650              }              }
1651                gen_opc_pc[lj] = ctx.pc;
1652                gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
1653                gen_opc_instr_start[lj] = 1;
1654          }          }
1655          ctx.opcode = ldl_code(ctx.pc);          ctx.opcode = ldl_code(ctx.pc);
1656          decode_opc(&ctx);          decode_opc(&ctx);
1657          ctx.pc += 4;          ctx.pc += 4;
1658    
1659            if (env->singlestep_enabled)
1660                break;
1661    
1662          if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)          if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
1663              break;              break;
1664    
1665  #if defined (MIPS_SINGLE_STEP)  #if defined (MIPS_SINGLE_STEP)
1666          break;          break;
1667  #endif  #endif
1668      }      }
1669      if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) {      if (env->singlestep_enabled) {
1670            save_cpu_state(ctxp, ctx.bstate == BS_NONE);
1671            gen_op_debug();
1672            goto done_generating;
1673        }
1674        else if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) {
1675          save_cpu_state(ctxp, 0);          save_cpu_state(ctxp, 0);
1676          gen_goto_tb(&ctx, 0, ctx.pc);          gen_goto_tb(&ctx, 0, ctx.pc);
1677      }      }
1678      gen_op_reset_T0();      gen_op_reset_T0();
1679      /* Generate the return instruction */      /* Generate the return instruction */
1680      gen_op_exit_tb();      gen_op_exit_tb();
1681    done_generating:
1682      *gen_opc_ptr = INDEX_op_end;      *gen_opc_ptr = INDEX_op_end;
1683      if (search_pc) {      if (search_pc) {
1684          j = gen_opc_ptr - gen_opc_buf;          j = gen_opc_ptr - gen_opc_buf;

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11

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