*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
*/
#include <stdarg.h>
static TCGv_ptr cpu_env;
static TCGv cpu_gpr[32], cpu_PC;
static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
-static TCGv cpu_dspctrl, btarget;
-static TCGv_i32 bcond;
-static TCGv_i32 fpu_fpr32[32], fpu_fpr32h[32];
-static TCGv_i64 fpu_fpr64[32];
+static TCGv cpu_dspctrl, btarget, bcond;
+static TCGv_i32 hflags;
static TCGv_i32 fpu_fcr0, fpu_fcr31;
#include "gen-icount.h"
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
-static const char *fregnames_64[] =
- { "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7",
- "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15",
- "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
- "F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31", };
-
-static const char *fregnames_h[] =
- { "h0", "h1", "h2", "h3", "h4", "h5", "h6", "h7",
- "h8", "h9", "h10", "h11", "h12", "h13", "h14", "h15",
- "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
- "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31", };
-
#ifdef MIPS_DEBUG_DISAS
-#define MIPS_DEBUG(fmt, args...) \
-do { \
- if (loglevel & CPU_LOG_TB_IN_ASM) { \
- fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n", \
- ctx->pc, ctx->opcode , ##args); \
- } \
-} while (0)
+#define MIPS_DEBUG(fmt, args...) \
+ qemu_log_mask(CPU_LOG_TB_IN_ASM, \
+ TARGET_FMT_lx ": %08x " fmt "\n", \
+ ctx->pc, ctx->opcode , ##args)
+#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
#else
#define MIPS_DEBUG(fmt, args...) do { } while(0)
+#define LOG_DISAS(...) do { } while (0)
#endif
#define MIPS_INVAL(op) \
/* Floating point register moves. */
static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
{
- tcg_gen_mov_i32(t, fpu_fpr32[reg]);
+ tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
}
static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
{
- tcg_gen_mov_i32(fpu_fpr32[reg], t);
+ tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
}
-static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
+static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
{
- if (ctx->hflags & MIPS_HFLAG_F64)
- tcg_gen_mov_i64(t, fpu_fpr64[reg]);
- else {
- tcg_gen_concat_i32_i64(t, fpu_fpr32[reg & ~1], fpu_fpr32[reg | 1]);
- }
+ tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
}
-static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
+static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
{
- if (ctx->hflags & MIPS_HFLAG_F64)
- tcg_gen_mov_i64(fpu_fpr64[reg], t);
- else {
- tcg_gen_trunc_i64_i32(fpu_fpr32[reg & ~1], t);
- tcg_gen_shri_i64(t, t, 32);
- tcg_gen_trunc_i64_i32(fpu_fpr32[reg | 1], t);
- }
+ tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
}
-static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
+static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
{
- tcg_gen_mov_i32(t, fpu_fpr32h[reg]);
+ if (ctx->hflags & MIPS_HFLAG_F64) {
+ tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
+ } else {
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i32 t1 = tcg_temp_new_i32();
+ gen_load_fpr32(t0, reg & ~1);
+ gen_load_fpr32(t1, reg | 1);
+ tcg_gen_concat_i32_i64(t, t0, t1);
+ tcg_temp_free_i32(t0);
+ tcg_temp_free_i32(t1);
+ }
}
-static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
+static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
{
- tcg_gen_mov_i32(fpu_fpr32h[reg], t);
+ if (ctx->hflags & MIPS_HFLAG_F64) {
+ tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
+ } else {
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i32 t1 = tcg_temp_new_i32();
+ tcg_gen_trunc_i64_i32(t1, t);
+ gen_store_fpr32(t1, reg & ~1);
+ tcg_gen_shri_i64(t0, t, 32);
+ tcg_gen_trunc_i64_i32(t1, t0);
+ gen_store_fpr32(t1, reg | 1);
+ tcg_temp_free_i32(t1);
+ tcg_temp_free_i64(t0);
+ }
}
-static inline void get_fp_cond (TCGv_i32 t)
+static inline int get_fp_bit (int cc)
{
- TCGv_i32 r_tmp1 = tcg_temp_new_i32();
- TCGv_i32 r_tmp2 = tcg_temp_new_i32();
-
- tcg_gen_shri_i32(r_tmp2, fpu_fcr31, 24);
- tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
- tcg_gen_shri_i32(r_tmp1, fpu_fcr31, 23);
- tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
- tcg_gen_or_i32(t, r_tmp1, r_tmp2);
- tcg_temp_free_i32(r_tmp1);
- tcg_temp_free_i32(r_tmp2);
+ if (cc)
+ return 24 + cc;
+ else
+ return 23;
}
#define FOP_CONDS(type, fmt, bits) \
#undef FOP_CONDS
/* Tests */
-#define OP_COND(name, cond) \
-static inline void glue(gen_op_, name) (TCGv t0, TCGv t1) \
-{ \
- int l1 = gen_new_label(); \
- int l2 = gen_new_label(); \
- \
- tcg_gen_brcond_tl(cond, t0, t1, l1); \
- tcg_gen_movi_tl(t0, 0); \
- tcg_gen_br(l2); \
- gen_set_label(l1); \
- tcg_gen_movi_tl(t0, 1); \
- gen_set_label(l2); \
+#define OP_COND(name, cond) \
+static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, TCGv t1) \
+{ \
+ int l1 = gen_new_label(); \
+ int l2 = gen_new_label(); \
+ \
+ tcg_gen_brcond_tl(cond, t0, t1, l1); \
+ tcg_gen_movi_tl(ret, 0); \
+ tcg_gen_br(l2); \
+ gen_set_label(l1); \
+ tcg_gen_movi_tl(ret, 1); \
+ gen_set_label(l2); \
}
OP_COND(eq, TCG_COND_EQ);
OP_COND(ne, TCG_COND_NE);
OP_COND(ltu, TCG_COND_LTU);
#undef OP_COND
-#define OP_CONDI(name, cond) \
-static inline void glue(gen_op_, name) (TCGv t, target_ulong val) \
-{ \
- int l1 = gen_new_label(); \
- int l2 = gen_new_label(); \
- \
- tcg_gen_brcondi_tl(cond, t, val, l1); \
- tcg_gen_movi_tl(t, 0); \
- tcg_gen_br(l2); \
- gen_set_label(l1); \
- tcg_gen_movi_tl(t, 1); \
- gen_set_label(l2); \
+#define OP_CONDI(name, cond) \
+static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, target_ulong val) \
+{ \
+ int l1 = gen_new_label(); \
+ int l2 = gen_new_label(); \
+ \
+ tcg_gen_brcondi_tl(cond, t0, val, l1); \
+ tcg_gen_movi_tl(ret, 0); \
+ tcg_gen_br(l2); \
+ gen_set_label(l1); \
+ tcg_gen_movi_tl(ret, 1); \
+ gen_set_label(l2); \
}
OP_CONDI(lti, TCG_COND_LT);
OP_CONDI(ltiu, TCG_COND_LTU);
#undef OP_CONDI
#define OP_CONDZ(name, cond) \
-static inline void glue(gen_op_, name) (TCGv t) \
+static inline void glue(gen_op_, name) (TCGv ret, TCGv t0) \
{ \
int l1 = gen_new_label(); \
int l2 = gen_new_label(); \
\
- tcg_gen_brcondi_tl(cond, t, 0, l1); \
- tcg_gen_movi_tl(t, 0); \
+ tcg_gen_brcondi_tl(cond, t0, 0, l1); \
+ tcg_gen_movi_tl(ret, 0); \
tcg_gen_br(l2); \
gen_set_label(l1); \
- tcg_gen_movi_tl(t, 1); \
+ tcg_gen_movi_tl(ret, 1); \
gen_set_label(l2); \
}
OP_CONDZ(gez, TCG_COND_GE);
static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
{
-#if defined MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "hflags %08x saved %08x\n",
- ctx->hflags, ctx->saved_hflags);
- }
-#endif
+ LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
if (do_save_pc && ctx->pc != ctx->saved_pc) {
gen_save_pc(ctx->pc);
ctx->saved_pc = ctx->pc;
}
if (ctx->hflags != ctx->saved_hflags) {
- TCGv_i32 r_tmp = tcg_temp_new_i32();
-
- tcg_gen_movi_i32(r_tmp, ctx->hflags);
- tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
- tcg_temp_free_i32(r_tmp);
+ tcg_gen_movi_i32(hflags, ctx->hflags);
ctx->saved_hflags = ctx->hflags;
switch (ctx->hflags & MIPS_HFLAG_BMASK) {
case MIPS_HFLAG_BR:
} else if (offset == 0) {
gen_load_gpr(t0, base);
} else {
- gen_load_gpr(t0, base);
- tcg_gen_movi_tl(t1, offset);
- gen_op_addr_add(ctx, t0, t1);
+ tcg_gen_movi_tl(t0, offset);
+ gen_op_addr_add(ctx, t0, cpu_gpr[base]);
}
/* Don't do NOP if destination is zero: we must perform the actual
memory access. */
break;
case OPC_LWL:
save_cpu_state(ctx, 1);
- gen_load_gpr(t1, rt);
+ gen_load_gpr(t1, rt);
gen_helper_3i(lwl, t1, t0, t1, ctx->mem_idx);
gen_store_gpr(t1, rt);
opn = "lwl";
break;
case OPC_LWR:
save_cpu_state(ctx, 1);
- gen_load_gpr(t1, rt);
+ gen_load_gpr(t1, rt);
gen_helper_3i(lwr, t1, t0, t1, ctx->mem_idx);
gen_store_gpr(t1, rt);
opn = "lwr";
} else if (offset == 0) {
gen_load_gpr(t0, base);
} else {
- TCGv t1 = tcg_temp_local_new();
-
- gen_load_gpr(t0, base);
- tcg_gen_movi_tl(t1, offset);
- gen_op_addr_add(ctx, t0, t1);
- tcg_temp_free(t1);
+ tcg_gen_movi_tl(t0, offset);
+ gen_op_addr_add(ctx, t0, cpu_gpr[base]);
}
/* Don't do NOP if destination is zero: we must perform the actual
memory access. */
break;
#endif
case OPC_SLTI:
- gen_op_lti(t0, uimm);
+ gen_op_lti(t0, t0, uimm);
opn = "slti";
break;
case OPC_SLTIU:
- gen_op_ltiu(t0, uimm);
+ gen_op_ltiu(t0, t0, uimm);
opn = "sltiu";
break;
case OPC_ANDI:
break;
#endif
case OPC_SLT:
- gen_op_lt(t0, t1);
+ gen_op_lt(t0, t0, t1);
opn = "slt";
break;
case OPC_SLTU:
- gen_op_ltu(t0, t1);
+ gen_op_ltu(t0, t0, t1);
opn = "sltu";
break;
case OPC_AND:
opn = "and";
break;
case OPC_NOR:
- tcg_gen_or_tl(t0, t0, t1);
- tcg_gen_not_tl(t0, t0);
+ tcg_gen_nor_tl(t0, t0, t1);
opn = "nor";
break;
case OPC_OR:
static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
{
const char *opn = "hilo";
- TCGv t0 = tcg_temp_local_new();
if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
/* Treat as NOP. */
MIPS_DEBUG("NOP");
- goto out;
+ return;
}
switch (opc) {
case OPC_MFHI:
- tcg_gen_mov_tl(t0, cpu_HI[0]);
- gen_store_gpr(t0, reg);
+ tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
opn = "mfhi";
break;
case OPC_MFLO:
- tcg_gen_mov_tl(t0, cpu_LO[0]);
- gen_store_gpr(t0, reg);
+ tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
opn = "mflo";
break;
case OPC_MTHI:
- gen_load_gpr(t0, reg);
- tcg_gen_mov_tl(cpu_HI[0], t0);
+ if (reg != 0)
+ tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
+ else
+ tcg_gen_movi_tl(cpu_HI[0], 0);
opn = "mthi";
break;
case OPC_MTLO:
- gen_load_gpr(t0, reg);
- tcg_gen_mov_tl(cpu_LO[0], t0);
+ if (reg != 0)
+ tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
+ else
+ tcg_gen_movi_tl(cpu_LO[0], 0);
opn = "mtlo";
break;
- default:
- MIPS_INVAL(opn);
- generate_exception(ctx, EXCP_RI);
- goto out;
}
MIPS_DEBUG("%s %s", opn, regnames[reg]);
- out:
- tcg_temp_free(t0);
}
static void gen_muldiv (DisasContext *ctx, uint32_t opc,
int rs, int rt)
{
const char *opn = "mul/div";
- TCGv t0 = tcg_temp_local_new();
- TCGv t1 = tcg_temp_local_new();
+ TCGv t0, t1;
+
+ switch (opc) {
+ case OPC_DIV:
+ case OPC_DIVU:
+#if defined(TARGET_MIPS64)
+ case OPC_DDIV:
+ case OPC_DDIVU:
+#endif
+ t0 = tcg_temp_local_new();
+ t1 = tcg_temp_local_new();
+ break;
+ default:
+ t0 = tcg_temp_new();
+ t1 = tcg_temp_new();
+ break;
+ }
gen_load_gpr(t0, rs);
gen_load_gpr(t1, rt);
case OPC_DIV:
{
int l1 = gen_new_label();
+ int l2 = gen_new_label();
+ tcg_gen_ext32s_tl(t0, t0);
+ tcg_gen_ext32s_tl(t1, t1);
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
- {
- int l2 = gen_new_label();
- TCGv_i32 r_tmp1 = tcg_temp_local_new_i32();
- TCGv_i32 r_tmp2 = tcg_temp_local_new_i32();
- TCGv_i32 r_tmp3 = tcg_temp_local_new_i32();
-
- tcg_gen_trunc_tl_i32(r_tmp1, t0);
- tcg_gen_trunc_tl_i32(r_tmp2, t1);
- tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp1, -1 << 31, l2);
- tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp2, -1, l2);
- tcg_gen_ext32s_tl(cpu_LO[0], t0);
- tcg_gen_movi_tl(cpu_HI[0], 0);
- tcg_gen_br(l1);
- gen_set_label(l2);
- tcg_gen_div_i32(r_tmp3, r_tmp1, r_tmp2);
- tcg_gen_rem_i32(r_tmp2, r_tmp1, r_tmp2);
- tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
- tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp2);
- tcg_temp_free_i32(r_tmp1);
- tcg_temp_free_i32(r_tmp2);
- tcg_temp_free_i32(r_tmp3);
- }
+ tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
+ tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
+
+ tcg_gen_mov_tl(cpu_LO[0], t0);
+ tcg_gen_movi_tl(cpu_HI[0], 0);
+ tcg_gen_br(l1);
+ gen_set_label(l2);
+ tcg_gen_div_tl(cpu_LO[0], t0, t1);
+ tcg_gen_rem_tl(cpu_HI[0], t0, t1);
+ tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
+ tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
gen_set_label(l1);
}
opn = "div";
{
int l1 = gen_new_label();
- tcg_gen_ext32s_tl(t1, t1);
+ tcg_gen_ext32u_tl(t0, t0);
+ tcg_gen_ext32u_tl(t1, t1);
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
- {
- TCGv_i32 r_tmp1 = tcg_temp_new_i32();
- TCGv_i32 r_tmp2 = tcg_temp_new_i32();
- TCGv_i32 r_tmp3 = tcg_temp_new_i32();
-
- tcg_gen_trunc_tl_i32(r_tmp1, t0);
- tcg_gen_trunc_tl_i32(r_tmp2, t1);
- tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
- tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
- tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
- tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp1);
- tcg_temp_free_i32(r_tmp1);
- tcg_temp_free_i32(r_tmp2);
- tcg_temp_free_i32(r_tmp3);
- }
+ tcg_gen_divu_tl(cpu_LO[0], t0, t1);
+ tcg_gen_remu_tl(cpu_HI[0], t0, t1);
+ tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
+ tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
gen_set_label(l1);
}
opn = "divu";
break;
case OPC_MULT:
{
- TCGv_i64 r_tmp1 = tcg_temp_new_i64();
- TCGv_i64 r_tmp2 = tcg_temp_new_i64();
-
- tcg_gen_ext_tl_i64(r_tmp1, t0);
- tcg_gen_ext_tl_i64(r_tmp2, t1);
- tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
- tcg_temp_free_i64(r_tmp2);
- tcg_gen_trunc_i64_tl(t0, r_tmp1);
- tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
- tcg_gen_trunc_i64_tl(t1, r_tmp1);
- tcg_temp_free_i64(r_tmp1);
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
+
+ tcg_gen_ext_tl_i64(t2, t0);
+ tcg_gen_ext_tl_i64(t3, t1);
+ tcg_gen_mul_i64(t2, t2, t3);
+ tcg_temp_free_i64(t3);
+ tcg_gen_trunc_i64_tl(t0, t2);
+ tcg_gen_shri_i64(t2, t2, 32);
+ tcg_gen_trunc_i64_tl(t1, t2);
+ tcg_temp_free_i64(t2);
tcg_gen_ext32s_tl(cpu_LO[0], t0);
tcg_gen_ext32s_tl(cpu_HI[0], t1);
}
break;
case OPC_MULTU:
{
- TCGv_i64 r_tmp1 = tcg_temp_new_i64();
- TCGv_i64 r_tmp2 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
tcg_gen_ext32u_tl(t0, t0);
tcg_gen_ext32u_tl(t1, t1);
- tcg_gen_extu_tl_i64(r_tmp1, t0);
- tcg_gen_extu_tl_i64(r_tmp2, t1);
- tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
- tcg_temp_free_i64(r_tmp2);
- tcg_gen_trunc_i64_tl(t0, r_tmp1);
- tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
- tcg_gen_trunc_i64_tl(t1, r_tmp1);
- tcg_temp_free_i64(r_tmp1);
+ tcg_gen_extu_tl_i64(t2, t0);
+ tcg_gen_extu_tl_i64(t3, t1);
+ tcg_gen_mul_i64(t2, t2, t3);
+ tcg_temp_free_i64(t3);
+ tcg_gen_trunc_i64_tl(t0, t2);
+ tcg_gen_shri_i64(t2, t2, 32);
+ tcg_gen_trunc_i64_tl(t1, t2);
+ tcg_temp_free_i64(t2);
tcg_gen_ext32s_tl(cpu_LO[0], t0);
tcg_gen_ext32s_tl(cpu_HI[0], t1);
}
case OPC_DDIV:
{
int l1 = gen_new_label();
+ int l2 = gen_new_label();
tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
- {
- int l2 = gen_new_label();
-
- tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
- tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
- tcg_gen_mov_tl(cpu_LO[0], t0);
- tcg_gen_movi_tl(cpu_HI[0], 0);
- tcg_gen_br(l1);
- gen_set_label(l2);
- tcg_gen_div_i64(cpu_LO[0], t0, t1);
- tcg_gen_rem_i64(cpu_HI[0], t0, t1);
- }
+ tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
+ tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
+ tcg_gen_mov_tl(cpu_LO[0], t0);
+ tcg_gen_movi_tl(cpu_HI[0], 0);
+ tcg_gen_br(l1);
+ gen_set_label(l2);
+ tcg_gen_div_i64(cpu_LO[0], t0, t1);
+ tcg_gen_rem_i64(cpu_HI[0], t0, t1);
gen_set_label(l1);
}
opn = "ddiv";
#endif
case OPC_MADD:
{
- TCGv_i64 r_tmp1 = tcg_temp_new_i64();
- TCGv_i64 r_tmp2 = tcg_temp_new_i64();
-
- tcg_gen_ext_tl_i64(r_tmp1, t0);
- tcg_gen_ext_tl_i64(r_tmp2, t1);
- tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
- tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
- tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
- tcg_temp_free_i64(r_tmp2);
- tcg_gen_trunc_i64_tl(t0, r_tmp1);
- tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
- tcg_gen_trunc_i64_tl(t1, r_tmp1);
- tcg_temp_free_i64(r_tmp1);
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
+
+ tcg_gen_ext_tl_i64(t2, t0);
+ tcg_gen_ext_tl_i64(t3, t1);
+ tcg_gen_mul_i64(t2, t2, t3);
+ tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
+ tcg_gen_add_i64(t2, t2, t3);
+ tcg_temp_free_i64(t3);
+ tcg_gen_trunc_i64_tl(t0, t2);
+ tcg_gen_shri_i64(t2, t2, 32);
+ tcg_gen_trunc_i64_tl(t1, t2);
+ tcg_temp_free_i64(t2);
tcg_gen_ext32s_tl(cpu_LO[0], t0);
tcg_gen_ext32s_tl(cpu_LO[1], t1);
}
break;
case OPC_MADDU:
{
- TCGv_i64 r_tmp1 = tcg_temp_new_i64();
- TCGv_i64 r_tmp2 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
tcg_gen_ext32u_tl(t0, t0);
tcg_gen_ext32u_tl(t1, t1);
- tcg_gen_extu_tl_i64(r_tmp1, t0);
- tcg_gen_extu_tl_i64(r_tmp2, t1);
- tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
- tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
- tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
- tcg_temp_free_i64(r_tmp2);
- tcg_gen_trunc_i64_tl(t0, r_tmp1);
- tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
- tcg_gen_trunc_i64_tl(t1, r_tmp1);
- tcg_temp_free_i64(r_tmp1);
+ tcg_gen_extu_tl_i64(t2, t0);
+ tcg_gen_extu_tl_i64(t3, t1);
+ tcg_gen_mul_i64(t2, t2, t3);
+ tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
+ tcg_gen_add_i64(t2, t2, t3);
+ tcg_temp_free_i64(t3);
+ tcg_gen_trunc_i64_tl(t0, t2);
+ tcg_gen_shri_i64(t2, t2, 32);
+ tcg_gen_trunc_i64_tl(t1, t2);
+ tcg_temp_free_i64(t2);
tcg_gen_ext32s_tl(cpu_LO[0], t0);
tcg_gen_ext32s_tl(cpu_HI[0], t1);
}
break;
case OPC_MSUB:
{
- TCGv_i64 r_tmp1 = tcg_temp_new_i64();
- TCGv_i64 r_tmp2 = tcg_temp_new_i64();
-
- tcg_gen_ext_tl_i64(r_tmp1, t0);
- tcg_gen_ext_tl_i64(r_tmp2, t1);
- tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
- tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
- tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
- tcg_temp_free_i64(r_tmp2);
- tcg_gen_trunc_i64_tl(t0, r_tmp1);
- tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
- tcg_gen_trunc_i64_tl(t1, r_tmp1);
- tcg_temp_free_i64(r_tmp1);
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
+
+ tcg_gen_ext_tl_i64(t2, t0);
+ tcg_gen_ext_tl_i64(t3, t1);
+ tcg_gen_mul_i64(t2, t2, t3);
+ tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
+ tcg_gen_sub_i64(t2, t2, t3);
+ tcg_temp_free_i64(t3);
+ tcg_gen_trunc_i64_tl(t0, t2);
+ tcg_gen_shri_i64(t2, t2, 32);
+ tcg_gen_trunc_i64_tl(t1, t2);
+ tcg_temp_free_i64(t2);
tcg_gen_ext32s_tl(cpu_LO[0], t0);
tcg_gen_ext32s_tl(cpu_HI[0], t1);
}
break;
case OPC_MSUBU:
{
- TCGv_i64 r_tmp1 = tcg_temp_new_i64();
- TCGv_i64 r_tmp2 = tcg_temp_new_i64();
+ TCGv_i64 t2 = tcg_temp_new_i64();
+ TCGv_i64 t3 = tcg_temp_new_i64();
tcg_gen_ext32u_tl(t0, t0);
tcg_gen_ext32u_tl(t1, t1);
- tcg_gen_extu_tl_i64(r_tmp1, t0);
- tcg_gen_extu_tl_i64(r_tmp2, t1);
- tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
- tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
- tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
- tcg_temp_free_i64(r_tmp2);
- tcg_gen_trunc_i64_tl(t0, r_tmp1);
- tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
- tcg_gen_trunc_i64_tl(t1, r_tmp1);
- tcg_temp_free_i64(r_tmp1);
+ tcg_gen_extu_tl_i64(t2, t0);
+ tcg_gen_extu_tl_i64(t3, t1);
+ tcg_gen_mul_i64(t2, t2, t3);
+ tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
+ tcg_gen_sub_i64(t2, t2, t3);
+ tcg_temp_free_i64(t3);
+ tcg_gen_trunc_i64_tl(t0, t2);
+ tcg_gen_shri_i64(t2, t2, 32);
+ tcg_gen_trunc_i64_tl(t1, t2);
+ tcg_temp_free_i64(t2);
tcg_gen_ext32s_tl(cpu_LO[0], t0);
tcg_gen_ext32s_tl(cpu_HI[0], t1);
}
int rd, int rs, int rt)
{
const char *opn = "mul vr54xx";
- TCGv t0 = tcg_temp_local_new();
- TCGv t1 = tcg_temp_local_new();
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
gen_load_gpr(t0, rs);
gen_load_gpr(t1, rt);
case OPC_VR54XX_MULS:
gen_helper_muls(t0, t0, t1);
opn = "muls";
- break;
+ break;
case OPC_VR54XX_MULSU:
gen_helper_mulsu(t0, t0, t1);
opn = "mulsu";
- break;
+ break;
case OPC_VR54XX_MACC:
gen_helper_macc(t0, t0, t1);
opn = "macc";
- break;
+ break;
case OPC_VR54XX_MACCU:
gen_helper_maccu(t0, t0, t1);
opn = "maccu";
- break;
+ break;
case OPC_VR54XX_MSAC:
gen_helper_msac(t0, t0, t1);
opn = "msac";
- break;
+ break;
case OPC_VR54XX_MSACU:
gen_helper_msacu(t0, t0, t1);
opn = "msacu";
- break;
+ break;
case OPC_VR54XX_MULHI:
gen_helper_mulhi(t0, t0, t1);
opn = "mulhi";
- break;
+ break;
case OPC_VR54XX_MULHIU:
gen_helper_mulhiu(t0, t0, t1);
opn = "mulhiu";
- break;
+ break;
case OPC_VR54XX_MULSHI:
gen_helper_mulshi(t0, t0, t1);
opn = "mulshi";
- break;
+ break;
case OPC_VR54XX_MULSHIU:
gen_helper_mulshiu(t0, t0, t1);
opn = "mulshiu";
- break;
+ break;
case OPC_VR54XX_MACCHI:
gen_helper_macchi(t0, t0, t1);
opn = "macchi";
- break;
+ break;
case OPC_VR54XX_MACCHIU:
gen_helper_macchiu(t0, t0, t1);
opn = "macchiu";
- break;
+ break;
case OPC_VR54XX_MSACHI:
gen_helper_msachi(t0, t0, t1);
opn = "msachi";
- break;
+ break;
case OPC_VR54XX_MSACHIU:
gen_helper_msachiu(t0, t0, t1);
opn = "msachiu";
- break;
+ break;
default:
MIPS_INVAL("mul vr54xx");
generate_exception(ctx, EXCP_RI);
int rd, int rs)
{
const char *opn = "CLx";
- TCGv t0 = tcg_temp_local_new();
+ TCGv t0;
if (rd == 0) {
/* Treat as NOP. */
MIPS_DEBUG("NOP");
- goto out;
+ return;
}
+ t0 = tcg_temp_new();
gen_load_gpr(t0, rs);
switch (opc) {
case OPC_CLO:
- gen_helper_clo(t0, t0);
+ gen_helper_clo(cpu_gpr[rd], t0);
opn = "clo";
break;
case OPC_CLZ:
- gen_helper_clz(t0, t0);
+ gen_helper_clz(cpu_gpr[rd], t0);
opn = "clz";
break;
#if defined(TARGET_MIPS64)
case OPC_DCLO:
- gen_helper_dclo(t0, t0);
+ gen_helper_dclo(cpu_gpr[rd], t0);
opn = "dclo";
break;
case OPC_DCLZ:
- gen_helper_dclz(t0, t0);
+ gen_helper_dclz(cpu_gpr[rd], t0);
opn = "dclz";
break;
#endif
- default:
- MIPS_INVAL(opn);
- generate_exception(ctx, EXCP_RI);
- goto out;
}
- gen_store_gpr(t0, rd);
MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
-
- out:
tcg_temp_free(t0);
}
int rs, int rt, int16_t imm)
{
int cond;
- TCGv t0 = tcg_temp_local_new();
- TCGv t1 = tcg_temp_local_new();
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
cond = 0;
/* Load needed operands */
case OPC_TGEU: /* rs >= rs unsigned */
case OPC_TGEIU: /* r0 >= 0 unsigned */
/* Always trap */
- tcg_gen_movi_tl(t0, 1);
+ generate_exception(ctx, EXCP_TRAP);
break;
case OPC_TLT: /* rs < rs */
case OPC_TLTI: /* r0 < 0 */
case OPC_TNE: /* rs != rs */
case OPC_TNEI: /* r0 != 0 */
/* Never trap: treat as NOP. */
- goto out;
- default:
- MIPS_INVAL("trap");
- generate_exception(ctx, EXCP_RI);
- goto out;
+ break;
}
} else {
+ int l1 = gen_new_label();
+
switch (opc) {
case OPC_TEQ:
case OPC_TEQI:
- gen_op_eq(t0, t1);
+ tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
break;
case OPC_TGE:
case OPC_TGEI:
- gen_op_ge(t0, t1);
+ tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
break;
case OPC_TGEU:
case OPC_TGEIU:
- gen_op_geu(t0, t1);
+ tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
break;
case OPC_TLT:
case OPC_TLTI:
- gen_op_lt(t0, t1);
+ tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
break;
case OPC_TLTU:
case OPC_TLTIU:
- gen_op_ltu(t0, t1);
+ tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
break;
case OPC_TNE:
case OPC_TNEI:
- gen_op_ne(t0, t1);
+ tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
break;
- default:
- MIPS_INVAL("trap");
- generate_exception(ctx, EXCP_RI);
- goto out;
}
- }
- save_cpu_state(ctx, 1);
- {
- int l1 = gen_new_label();
-
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
- gen_helper_0i(raise_exception, EXCP_TRAP);
+ generate_exception(ctx, EXCP_TRAP);
gen_set_label(l1);
}
- ctx->bstate = BS_STOP;
- out:
tcg_temp_free(t0);
tcg_temp_free(t1);
}
target_ulong btgt = -1;
int blink = 0;
int bcond_compute = 0;
- TCGv t0 = tcg_temp_local_new();
- TCGv t1 = tcg_temp_local_new();
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
if (ctx->hflags & MIPS_HFLAG_BMASK) {
#ifdef MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile,
- "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
- ctx->pc);
- }
+ LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
#endif
generate_exception(ctx, EXCP_RI);
goto out;
MIPS_DEBUG("bnever (NOP)");
goto out;
case OPC_BLTZAL: /* 0 < 0 */
- tcg_gen_movi_tl(t0, ctx->pc + 8);
- gen_store_gpr(t0, 31);
+ tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
MIPS_DEBUG("bnever and link");
goto out;
case OPC_BLTZALL: /* 0 < 0 likely */
- tcg_gen_movi_tl(t0, ctx->pc + 8);
- gen_store_gpr(t0, 31);
+ tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
/* Skip the instruction in the delay slot */
MIPS_DEBUG("bnever, link and skip");
ctx->pc += 4;
} else {
switch (opc) {
case OPC_BEQ:
- gen_op_eq(t0, t1);
+ gen_op_eq(bcond, t0, t1);
MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
regnames[rs], regnames[rt], btgt);
goto not_likely;
case OPC_BEQL:
- gen_op_eq(t0, t1);
+ gen_op_eq(bcond, t0, t1);
MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
regnames[rs], regnames[rt], btgt);
goto likely;
case OPC_BNE:
- gen_op_ne(t0, t1);
+ gen_op_ne(bcond, t0, t1);
MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
regnames[rs], regnames[rt], btgt);
goto not_likely;
case OPC_BNEL:
- gen_op_ne(t0, t1);
+ gen_op_ne(bcond, t0, t1);
MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
regnames[rs], regnames[rt], btgt);
goto likely;
case OPC_BGEZ:
- gen_op_gez(t0);
+ gen_op_gez(bcond, t0);
MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto not_likely;
case OPC_BGEZL:
- gen_op_gez(t0);
+ gen_op_gez(bcond, t0);
MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto likely;
case OPC_BGEZAL:
- gen_op_gez(t0);
+ gen_op_gez(bcond, t0);
MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
blink = 31;
goto not_likely;
case OPC_BGEZALL:
- gen_op_gez(t0);
+ gen_op_gez(bcond, t0);
blink = 31;
MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto likely;
case OPC_BGTZ:
- gen_op_gtz(t0);
+ gen_op_gtz(bcond, t0);
MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto not_likely;
case OPC_BGTZL:
- gen_op_gtz(t0);
+ gen_op_gtz(bcond, t0);
MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto likely;
case OPC_BLEZ:
- gen_op_lez(t0);
+ gen_op_lez(bcond, t0);
MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto not_likely;
case OPC_BLEZL:
- gen_op_lez(t0);
+ gen_op_lez(bcond, t0);
MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto likely;
case OPC_BLTZ:
- gen_op_ltz(t0);
+ gen_op_ltz(bcond, t0);
MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto not_likely;
case OPC_BLTZL:
- gen_op_ltz(t0);
+ gen_op_ltz(bcond, t0);
MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
goto likely;
case OPC_BLTZAL:
- gen_op_ltz(t0);
+ gen_op_ltz(bcond, t0);
blink = 31;
MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
not_likely:
ctx->hflags |= MIPS_HFLAG_BC;
- tcg_gen_trunc_tl_i32(bcond, t0);
break;
case OPC_BLTZALL:
- gen_op_ltz(t0);
+ gen_op_ltz(bcond, t0);
blink = 31;
MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
likely:
ctx->hflags |= MIPS_HFLAG_BL;
- tcg_gen_trunc_tl_i32(bcond, t0);
break;
default:
MIPS_INVAL("conditional branch/jump");
ctx->btarget = btgt;
if (blink > 0) {
- tcg_gen_movi_tl(t0, ctx->pc + 8);
- gen_store_gpr(t0, blink);
+ tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
}
out:
static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
{
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
+ TCGv t0;
- gen_load_gpr(t1, rt);
+ if (rd == 0) {
+ /* If no destination, treat it as a NOP. */
+ MIPS_DEBUG("NOP");
+ return;
+ }
+
+ t0 = tcg_temp_new();
+ gen_load_gpr(t0, rt);
switch (op2) {
case OPC_WSBH:
- tcg_gen_shri_tl(t0, t1, 8);
- tcg_gen_andi_tl(t0, t0, 0x00FF00FF);
- tcg_gen_shli_tl(t1, t1, 8);
- tcg_gen_andi_tl(t1, t1, ~0x00FF00FF);
- tcg_gen_or_tl(t0, t0, t1);
- tcg_gen_ext32s_tl(t0, t0);
+ {
+ TCGv t1 = tcg_temp_new();
+
+ tcg_gen_shri_tl(t1, t0, 8);
+ tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
+ tcg_gen_shli_tl(t0, t0, 8);
+ tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
+ tcg_gen_or_tl(t0, t0, t1);
+ tcg_temp_free(t1);
+ tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
+ }
break;
case OPC_SEB:
- tcg_gen_ext8s_tl(t0, t1);
+ tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
break;
case OPC_SEH:
- tcg_gen_ext16s_tl(t0, t1);
+ tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
break;
#if defined(TARGET_MIPS64)
case OPC_DSBH:
- gen_load_gpr(t1, rt);
- tcg_gen_shri_tl(t0, t1, 8);
- tcg_gen_andi_tl(t0, t0, 0x00FF00FF00FF00FFULL);
- tcg_gen_shli_tl(t1, t1, 8);
- tcg_gen_andi_tl(t1, t1, ~0x00FF00FF00FF00FFULL);
- tcg_gen_or_tl(t0, t0, t1);
+ {
+ TCGv t1 = tcg_temp_new();
+
+ tcg_gen_shri_tl(t1, t0, 8);
+ tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
+ tcg_gen_shli_tl(t0, t0, 8);
+ tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
+ tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
+ tcg_temp_free(t1);
+ }
break;
case OPC_DSHD:
- gen_load_gpr(t1, rt);
- tcg_gen_shri_tl(t0, t1, 16);
- tcg_gen_andi_tl(t0, t0, 0x0000FFFF0000FFFFULL);
- tcg_gen_shli_tl(t1, t1, 16);
- tcg_gen_andi_tl(t1, t1, ~0x0000FFFF0000FFFFULL);
- tcg_gen_or_tl(t1, t0, t1);
- tcg_gen_shri_tl(t0, t1, 32);
- tcg_gen_shli_tl(t1, t1, 32);
- tcg_gen_or_tl(t0, t0, t1);
+ {
+ TCGv t1 = tcg_temp_new();
+
+ tcg_gen_shri_tl(t1, t0, 16);
+ tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
+ tcg_gen_shli_tl(t0, t0, 16);
+ tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
+ tcg_gen_or_tl(t0, t0, t1);
+ tcg_gen_shri_tl(t1, t0, 32);
+ tcg_gen_shli_tl(t0, t0, 32);
+ tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
+ tcg_temp_free(t1);
+ }
break;
#endif
default:
MIPS_INVAL("bsfhl");
generate_exception(ctx, EXCP_RI);
tcg_temp_free(t0);
- tcg_temp_free(t1);
return;
}
- gen_store_gpr(t0, rd);
tcg_temp_free(t0);
- tcg_temp_free(t1);
}
#ifndef CONFIG_USER_ONLY
default:
goto die;
}
-#if defined MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
- rn, reg, sel);
- }
-#endif
+ LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
return;
die:
-#if defined MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
- rn, reg, sel);
- }
-#endif
+ LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
generate_exception(ctx, EXCP_RI);
}
default:
goto die;
}
-#if defined MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
- rn, reg, sel);
- }
-#endif
+ LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
/* For simplicity assume that all writes can cause interrupts. */
if (use_icount) {
gen_io_end();
return;
die:
-#if defined MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
- rn, reg, sel);
- }
-#endif
+ LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
generate_exception(ctx, EXCP_RI);
}
default:
goto die;
}
-#if defined MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
- rn, reg, sel);
- }
-#endif
+ LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
return;
die:
-#if defined MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
- rn, reg, sel);
- }
-#endif
+ LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
generate_exception(ctx, EXCP_RI);
}
default:
goto die;
}
-#if defined MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
- rn, reg, sel);
- }
-#endif
+ LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
/* For simplicity assume that all writes can cause interrupts. */
if (use_icount) {
gen_io_end();
return;
die:
-#if defined MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
- rn, reg, sel);
- }
-#endif
+ LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
generate_exception(ctx, EXCP_RI);
}
#endif /* TARGET_MIPS64 */
default:
goto die;
}
-#if defined MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
- rt, u, sel, h);
- }
-#endif
+ LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
gen_store_gpr(t0, rd);
tcg_temp_free(t0);
return;
die:
tcg_temp_free(t0);
-#if defined MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
- rt, u, sel, h);
- }
-#endif
+ LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
generate_exception(ctx, EXCP_RI);
}
default:
goto die;
}
-#if defined MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
- rd, u, sel, h);
- }
-#endif
+ LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
tcg_temp_free(t0);
return;
die:
tcg_temp_free(t0);
-#if defined MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
- rd, u, sel, h);
- }
-#endif
+ LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
generate_exception(ctx, EXCP_RI);
}
break;
case OPC_TLBWI:
opn = "tlbwi";
- if (!env->tlb->do_tlbwi)
+ if (!env->tlb->helper_tlbwi)
goto die;
gen_helper_tlbwi();
break;
case OPC_TLBWR:
opn = "tlbwr";
- if (!env->tlb->do_tlbwr)
+ if (!env->tlb->helper_tlbwr)
goto die;
gen_helper_tlbwr();
break;
case OPC_TLBP:
opn = "tlbp";
- if (!env->tlb->do_tlbp)
+ if (!env->tlb->helper_tlbp)
goto die;
gen_helper_tlbp();
break;
case OPC_TLBR:
opn = "tlbr";
- if (!env->tlb->do_tlbr)
+ if (!env->tlb->helper_tlbr)
goto die;
gen_helper_tlbr();
break;
switch (op) {
case OPC_BC1F:
- {
- int l1 = gen_new_label();
- int l2 = gen_new_label();
-
- get_fp_cond(t0);
- tcg_gen_andi_i32(t0, t0, 0x1 << cc);
- tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
- tcg_gen_movi_i32(bcond, 0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_i32(bcond, 1);
- gen_set_label(l2);
- }
+ tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
+ tcg_gen_not_i32(t0, t0);
+ tcg_gen_andi_i32(t0, t0, 1);
+ tcg_gen_extu_i32_tl(bcond, t0);
opn = "bc1f";
goto not_likely;
case OPC_BC1FL:
- {
- int l1 = gen_new_label();
- int l2 = gen_new_label();
-
- get_fp_cond(t0);
- tcg_gen_andi_i32(t0, t0, 0x1 << cc);
- tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
- tcg_gen_movi_i32(bcond, 0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_i32(bcond, 1);
- gen_set_label(l2);
- }
+ tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
+ tcg_gen_not_i32(t0, t0);
+ tcg_gen_andi_i32(t0, t0, 1);
+ tcg_gen_extu_i32_tl(bcond, t0);
opn = "bc1fl";
goto likely;
case OPC_BC1T:
- {
- int l1 = gen_new_label();
- int l2 = gen_new_label();
-
- get_fp_cond(t0);
- tcg_gen_andi_i32(t0, t0, 0x1 << cc);
- tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
- tcg_gen_movi_i32(bcond, 0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_i32(bcond, 1);
- gen_set_label(l2);
- }
+ tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
+ tcg_gen_andi_i32(t0, t0, 1);
+ tcg_gen_extu_i32_tl(bcond, t0);
opn = "bc1t";
goto not_likely;
case OPC_BC1TL:
- {
- int l1 = gen_new_label();
- int l2 = gen_new_label();
-
- get_fp_cond(t0);
- tcg_gen_andi_i32(t0, t0, 0x1 << cc);
- tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
- tcg_gen_movi_i32(bcond, 0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_i32(bcond, 1);
- gen_set_label(l2);
- }
+ tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
+ tcg_gen_andi_i32(t0, t0, 1);
+ tcg_gen_extu_i32_tl(bcond, t0);
opn = "bc1tl";
likely:
ctx->hflags |= MIPS_HFLAG_BL;
break;
case OPC_BC1FANY2:
{
- int l1 = gen_new_label();
- int l2 = gen_new_label();
-
- get_fp_cond(t0);
- tcg_gen_andi_i32(t0, t0, 0x3 << cc);
- tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
- tcg_gen_movi_i32(bcond, 0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_i32(bcond, 1);
- gen_set_label(l2);
+ TCGv_i32 t1 = tcg_temp_new_i32();
+ tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
+ tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
+ tcg_gen_or_i32(t0, t0, t1);
+ tcg_temp_free_i32(t1);
+ tcg_gen_not_i32(t0, t0);
+ tcg_gen_andi_i32(t0, t0, 1);
+ tcg_gen_extu_i32_tl(bcond, t0);
}
opn = "bc1any2f";
goto not_likely;
case OPC_BC1TANY2:
{
- int l1 = gen_new_label();
- int l2 = gen_new_label();
-
- get_fp_cond(t0);
- tcg_gen_andi_i32(t0, t0, 0x3 << cc);
- tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
- tcg_gen_movi_i32(bcond, 0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_i32(bcond, 1);
- gen_set_label(l2);
+ TCGv_i32 t1 = tcg_temp_new_i32();
+ tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
+ tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
+ tcg_gen_or_i32(t0, t0, t1);
+ tcg_temp_free_i32(t1);
+ tcg_gen_andi_i32(t0, t0, 1);
+ tcg_gen_extu_i32_tl(bcond, t0);
}
opn = "bc1any2t";
goto not_likely;
case OPC_BC1FANY4:
{
- int l1 = gen_new_label();
- int l2 = gen_new_label();
-
- get_fp_cond(t0);
- tcg_gen_andi_i32(t0, t0, 0xf << cc);
- tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
- tcg_gen_movi_i32(bcond, 0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_i32(bcond, 1);
- gen_set_label(l2);
+ TCGv_i32 t1 = tcg_temp_new_i32();
+ tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
+ tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
+ tcg_gen_or_i32(t0, t0, t1);
+ tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
+ tcg_gen_or_i32(t0, t0, t1);
+ tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
+ tcg_gen_or_i32(t0, t0, t1);
+ tcg_temp_free_i32(t1);
+ tcg_gen_not_i32(t0, t0);
+ tcg_gen_andi_i32(t0, t0, 1);
+ tcg_gen_extu_i32_tl(bcond, t0);
}
opn = "bc1any4f";
goto not_likely;
case OPC_BC1TANY4:
{
- int l1 = gen_new_label();
- int l2 = gen_new_label();
-
- get_fp_cond(t0);
- tcg_gen_andi_i32(t0, t0, 0xf << cc);
- tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
- tcg_gen_movi_i32(bcond, 0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_i32(bcond, 1);
- gen_set_label(l2);
+ TCGv_i32 t1 = tcg_temp_new_i32();
+ tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
+ tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
+ tcg_gen_or_i32(t0, t0, t1);
+ tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
+ tcg_gen_or_i32(t0, t0, t1);
+ tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
+ tcg_gen_or_i32(t0, t0, t1);
+ tcg_temp_free_i32(t1);
+ tcg_gen_andi_i32(t0, t0, 1);
+ tcg_gen_extu_i32_tl(bcond, t0);
}
opn = "bc1any4t";
not_likely:
gen_load_fpr32(fp0, fs);
tcg_gen_ext_i32_tl(t0, fp0);
tcg_temp_free_i32(fp0);
- }
+ }
gen_store_gpr(t0, rt);
opn = "mfc1";
break;
tcg_gen_trunc_tl_i32(fp0, t0);
gen_store_fpr32(fp0, fs);
tcg_temp_free_i32(fp0);
- }
+ }
opn = "mtc1";
break;
case OPC_CFC1:
gen_load_fpr64(ctx, fp0, fs);
tcg_gen_trunc_i64_tl(t0, fp0);
tcg_temp_free_i64(fp0);
- }
+ }
gen_store_gpr(t0, rt);
opn = "dmfc1";
break;
tcg_gen_extu_tl_i64(fp0, t0);
gen_store_fpr64(ctx, fp0, fs);
tcg_temp_free_i64(fp0);
- }
+ }
opn = "dmtc1";
break;
case OPC_MFHC1:
gen_load_fpr32h(fp0, fs);
tcg_gen_ext_i32_tl(t0, fp0);
tcg_temp_free_i32(fp0);
- }
+ }
gen_store_gpr(t0, rt);
opn = "mfhc1";
break;
tcg_gen_trunc_tl_i32(fp0, t0);
gen_store_fpr32h(fp0, fs);
tcg_temp_free_i32(fp0);
- }
+ }
opn = "mthc1";
break;
default:
static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
{
- int l1 = gen_new_label();
- uint32_t ccbit;
+ int l1;
TCGCond cond;
- TCGv t0 = tcg_temp_local_new();
- TCGv_i32 r_tmp = tcg_temp_new_i32();
+ TCGv_i32 t0;
+
+ if (rd == 0) {
+ /* Treat as NOP. */
+ return;
+ }
- if (cc)
- ccbit = 1 << (24 + cc);
- else
- ccbit = 1 << 23;
if (tf)
cond = TCG_COND_EQ;
else
cond = TCG_COND_NE;
- gen_load_gpr(t0, rd);
- tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit);
- tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
- tcg_temp_free_i32(r_tmp);
- gen_load_gpr(t0, rs);
+ l1 = gen_new_label();
+ t0 = tcg_temp_new_i32();
+ tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
+ tcg_gen_brcondi_i32(cond, t0, 0, l1);
+ if (rs == 0) {
+ tcg_gen_movi_tl(cpu_gpr[rd], 0);
+ } else {
+ tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
+ }
gen_set_label(l1);
- gen_store_gpr(t0, rd);
- tcg_temp_free(t0);
+ tcg_temp_free_i32(t0);
}
static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
{
- uint32_t ccbit;
int cond;
- TCGv_i32 r_tmp1 = tcg_temp_new_i32();
- TCGv_i32 fp0 = tcg_temp_local_new_i32();
+ TCGv_i32 t0 = tcg_temp_new_i32();
int l1 = gen_new_label();
- if (cc)
- ccbit = 1 << (24 + cc);
- else
- ccbit = 1 << 23;
-
if (tf)
cond = TCG_COND_EQ;
else
cond = TCG_COND_NE;
- gen_load_fpr32(fp0, fd);
- tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
- tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
- tcg_temp_free_i32(r_tmp1);
- gen_load_fpr32(fp0, fs);
+ tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
+ tcg_gen_brcondi_i32(cond, t0, 0, l1);
+ gen_load_fpr32(t0, fs);
+ gen_store_fpr32(t0, fd);
gen_set_label(l1);
- gen_store_fpr32(fp0, fd);
- tcg_temp_free_i32(fp0);
+ tcg_temp_free_i32(t0);
}
static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
{
- uint32_t ccbit;
int cond;
- TCGv_i32 r_tmp1 = tcg_temp_new_i32();
- TCGv_i64 fp0 = tcg_temp_local_new_i64();
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ TCGv_i64 fp0;
int l1 = gen_new_label();
- if (cc)
- ccbit = 1 << (24 + cc);
- else
- ccbit = 1 << 23;
-
if (tf)
cond = TCG_COND_EQ;
else
cond = TCG_COND_NE;
- gen_load_fpr64(ctx, fp0, fd);
- tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
- tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
- tcg_temp_free_i32(r_tmp1);
+ tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
+ tcg_gen_brcondi_i32(cond, t0, 0, l1);
+ fp0 = tcg_temp_local_new_i64();
gen_load_fpr64(ctx, fp0, fs);
- gen_set_label(l1);
gen_store_fpr64(ctx, fp0, fd);
tcg_temp_free_i64(fp0);
+ gen_set_label(l1);
+ tcg_temp_free_i32(t0);
}
static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
{
- uint32_t ccbit1, ccbit2;
int cond;
- TCGv_i32 r_tmp1 = tcg_temp_new_i32();
- TCGv_i32 fp0 = tcg_temp_local_new_i32();
+ TCGv_i32 t0 = tcg_temp_new_i32();
int l1 = gen_new_label();
int l2 = gen_new_label();
- if (cc) {
- ccbit1 = 1 << (24 + cc);
- ccbit2 = 1 << (25 + cc);
- } else {
- ccbit1 = 1 << 23;
- ccbit2 = 1 << 25;
- }
-
if (tf)
cond = TCG_COND_EQ;
else
cond = TCG_COND_NE;
- gen_load_fpr32(fp0, fd);
- tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit1);
- tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
- gen_load_fpr32(fp0, fs);
+ tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc));
+ tcg_gen_brcondi_i32(cond, t0, 0, l1);
+ gen_load_fpr32(t0, fs);
+ gen_store_fpr32(t0, fd);
gen_set_label(l1);
- gen_store_fpr32(fp0, fd);
- gen_load_fpr32h(fp0, fd);
- tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit2);
- tcg_gen_brcondi_i32(cond, r_tmp1, 0, l2);
- gen_load_fpr32h(fp0, fs);
+ tcg_gen_andi_i32(t0, fpu_fcr31, get_fp_bit(cc+1));
+ tcg_gen_brcondi_i32(cond, t0, 0, l2);
+ gen_load_fpr32h(t0, fs);
+ gen_store_fpr32h(t0, fd);
gen_set_label(l2);
- gen_store_fpr32h(fp0, fd);
- tcg_temp_free_i32(r_tmp1);
- tcg_temp_free_i32(fp0);
+ tcg_temp_free_i32(t0);
}
} else if (index == 0) {
gen_load_gpr(t0, base);
} else {
- gen_load_gpr(t0, base);
- gen_load_gpr(t1, index);
- gen_op_addr_add(ctx, t0, t1);
+ gen_load_gpr(t0, index);
+ gen_op_addr_add(ctx, t0, cpu_gpr[base]);
}
/* Don't do NOP if destination is zero: we must perform the actual
memory access. */
int l1 = gen_new_label();
MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
- tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
- {
- TCGv_i32 r_tmp = tcg_temp_new_i32();
-
- tcg_gen_movi_i32(r_tmp, ctx->hflags & ~MIPS_HFLAG_BMASK);
- tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
- tcg_temp_free_i32(r_tmp);
- }
+ tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
+ tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
gen_goto_tb(ctx, 1, ctx->pc + 4);
gen_set_label(l1);
}
case OPC_MUL:
gen_arith(env, ctx, op1, rd, rs, rt);
break;
- case OPC_CLZ ... OPC_CLO:
+ case OPC_CLO:
+ case OPC_CLZ:
check_insn(env, ctx, ISA_MIPS32);
gen_cl(ctx, op1, rd, rs);
break;
/* Treat as NOP. */
break;
#if defined(TARGET_MIPS64)
- case OPC_DCLZ ... OPC_DCLO:
+ case OPC_DCLO:
+ case OPC_DCLZ:
check_insn(env, ctx, ISA_MIPS64);
check_mips_64(ctx);
gen_cl(ctx, op1, rd, rs);
gen_helper_rdhwr_ccres(t0);
break;
case 29:
- if (env->user_mode_only) {
- tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
- break;
- } else {
- /* XXX: Some CPUs implement this in hardware.
- Not supported yet. */
- }
+#if defined(CONFIG_USER_ONLY)
+ tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
+ break;
+#else
+ /* XXX: Some CPUs implement this in hardware.
+ Not supported yet. */
+#endif
default: /* Invalid */
MIPS_INVAL("rdhwr");
generate_exception(ctx, EXCP_RI);
case OPC_DMTC0:
#endif
#ifndef CONFIG_USER_ONLY
- if (!env->user_mode_only)
- gen_cp0(env, ctx, op1, rt, rd);
+ gen_cp0(env, ctx, op1, rt, rd);
#endif /* !CONFIG_USER_ONLY */
break;
case OPC_C0_FIRST ... OPC_C0_LAST:
#ifndef CONFIG_USER_ONLY
- if (!env->user_mode_only)
- gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
+ gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
#endif /* !CONFIG_USER_ONLY */
break;
case OPC_MFMC0:
#ifndef CONFIG_USER_ONLY
- if (!env->user_mode_only) {
+ {
TCGv t0 = tcg_temp_local_new();
op2 = MASK_MFMC0(ctx->opcode);
{
int l1 = gen_new_label();
- tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
+ tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
gen_goto_tb(ctx, 1, ctx->pc + 4);
gen_set_label(l1);
gen_goto_tb(ctx, 0, ctx->btarget);
int num_insns;
int max_insns;
- if (search_pc && loglevel)
- fprintf (logfile, "search pc %d\n", search_pc);
+ if (search_pc)
+ qemu_log("search pc %d\n", search_pc);
pc_start = tb->pc;
/* Leave some spare opc slots for branch handling. */
/* Restore delay slot state from the tb context. */
ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
restore_cpu_state(env, &ctx);
- if (env->user_mode_only)
+#ifdef CONFIG_USER_ONLY
ctx.mem_idx = MIPS_HFLAG_UM;
- else
+#else
ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
+#endif
num_insns = 0;
max_insns = tb->cflags & CF_COUNT_MASK;
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
#ifdef DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_CPU) {
- fprintf(logfile, "------------------------------------------------\n");
- /* FIXME: This may print out stale hflags from env... */
- cpu_dump_state(env, logfile, fprintf, 0);
- }
-#endif
-#ifdef MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM)
- fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
- tb, ctx.mem_idx, ctx.hflags);
+ qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
+ /* FIXME: This may print out stale hflags from env... */
+ log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
#endif
+ LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
gen_icount_start();
while (ctx.bstate == BS_NONE) {
- if (unlikely(env->breakpoints)) {
- for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
+ if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
+ TAILQ_FOREACH(bp, &env->breakpoints, entry) {
if (bp->pc == ctx.pc) {
save_cpu_state(&ctx, 1);
ctx.bstate = BS_BRANCH;
save_cpu_state(&ctx, ctx.bstate == BS_NONE);
gen_helper_0i(raise_exception, EXCP_DEBUG);
} else {
- switch (ctx.bstate) {
+ switch (ctx.bstate) {
case BS_STOP:
gen_helper_interrupt_restart();
gen_goto_tb(&ctx, 0, ctx.pc);
case BS_BRANCH:
default:
break;
- }
+ }
}
done_generating:
gen_icount_end(tb, num_insns);
tb->icount = num_insns;
}
#ifdef DEBUG_DISAS
-#if defined MIPS_DEBUG_DISAS
- if (loglevel & CPU_LOG_TB_IN_ASM)
- fprintf(logfile, "\n");
-#endif
- if (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
- target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
- fprintf(logfile, "\n");
- }
- if (loglevel & CPU_LOG_TB_CPU) {
- fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
+ LOG_DISAS("\n");
+ if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+ qemu_log("IN: %s\n", lookup_symbol(pc_start));
+ log_target_disas(pc_start, ctx.pc - pc_start, 0);
+ qemu_log("\n");
}
+ qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
#endif
}
/* Initialize various static tables. */
if (inited)
- return;
+ return;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
for (i = 0; i < 32; i++)
cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUState, active_tc.DSPControl),
"DSPControl");
- bcond = tcg_global_mem_new_i32(TCG_AREG0,
- offsetof(CPUState, bcond), "bcond");
+ bcond = tcg_global_mem_new(TCG_AREG0,
+ offsetof(CPUState, bcond), "bcond");
btarget = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUState, btarget), "btarget");
- for (i = 0; i < 32; i++)
- fpu_fpr32[i] = tcg_global_mem_new_i32(TCG_AREG0,
- offsetof(CPUState, active_fpu.fpr[i].w[FP_ENDIAN_IDX]),
- fregnames[i]);
- for (i = 0; i < 32; i++)
- fpu_fpr64[i] = tcg_global_mem_new_i64(TCG_AREG0,
- offsetof(CPUState, active_fpu.fpr[i]),
- fregnames_64[i]);
- for (i = 0; i < 32; i++)
- fpu_fpr32h[i] = tcg_global_mem_new_i32(TCG_AREG0,
- offsetof(CPUState, active_fpu.fpr[i].w[!FP_ENDIAN_IDX]),
- fregnames_h[i]);
+ hflags = tcg_global_mem_new_i32(TCG_AREG0,
+ offsetof(CPUState, hflags), "hflags");
+
fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
offsetof(CPUState, active_fpu.fcr0),
"fcr0");
if (!def)
return NULL;
env = qemu_mallocz(sizeof(CPUMIPSState));
- if (!env)
- return NULL;
env->cpu_model = def;
cpu_exec_init(env);
void cpu_reset (CPUMIPSState *env)
{
+ if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+ qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+ log_cpu_state(env, 0);
+ }
+
memset(env, 0, offsetof(CPUMIPSState, breakpoints));
tlb_flush(env, 1);
/* Minimal init */
#if defined(CONFIG_USER_ONLY)
- env->user_mode_only = 1;
-#endif
- if (env->user_mode_only) {
- env->hflags = MIPS_HFLAG_UM;
+ env->hflags = MIPS_HFLAG_UM;
+#else
+ if (env->hflags & MIPS_HFLAG_BMASK) {
+ /* If the exception was raised from a delay slot,
+ come back to the jump. */
+ env->CP0_ErrorEPC = env->active_tc.PC - 4;
} else {
- if (env->hflags & MIPS_HFLAG_BMASK) {
- /* If the exception was raised from a delay slot,
- come back to the jump. */
- env->CP0_ErrorEPC = env->active_tc.PC - 4;
- } else {
- env->CP0_ErrorEPC = env->active_tc.PC;
- }
- env->active_tc.PC = (int32_t)0xBFC00000;
- env->CP0_Wired = 0;
- /* SMP not implemented */
- env->CP0_EBase = 0x80000000;
- env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
- /* vectored interrupts not implemented, timer on int 7,
- no performance counters. */
- env->CP0_IntCtl = 0xe0000000;
- {
- int i;
-
- for (i = 0; i < 7; i++) {
- env->CP0_WatchLo[i] = 0;
- env->CP0_WatchHi[i] = 0x80000000;
- }
- env->CP0_WatchLo[7] = 0;
- env->CP0_WatchHi[7] = 0;
+ env->CP0_ErrorEPC = env->active_tc.PC;
+ }
+ env->active_tc.PC = (int32_t)0xBFC00000;
+ env->CP0_Wired = 0;
+ /* SMP not implemented */
+ env->CP0_EBase = 0x80000000;
+ env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
+ /* vectored interrupts not implemented, timer on int 7,
+ no performance counters. */
+ env->CP0_IntCtl = 0xe0000000;
+ {
+ int i;
+
+ for (i = 0; i < 7; i++) {
+ env->CP0_WatchLo[i] = 0;
+ env->CP0_WatchHi[i] = 0x80000000;
}
- /* Count register increments in debug mode, EJTAG version 1 */
- env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
- env->hflags = MIPS_HFLAG_CP0;
+ env->CP0_WatchLo[7] = 0;
+ env->CP0_WatchHi[7] = 0;
}
+ /* Count register increments in debug mode, EJTAG version 1 */
+ env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
+ env->hflags = MIPS_HFLAG_CP0;
+#endif
env->exception_index = EXCP_NONE;
cpu_mips_register(env, env->cpu_model);
}