static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
{
TCGv_i32 tmp = tcg_temp_new_i32();
- tcg_gen_trunc_i64_i32(tmp, t);
+ tcg_gen_extrl_i64_i32(tmp, t);
tcg_gen_mov_i32(cpu_fregs[reg + 1], tmp);
tcg_gen_shri_i64(t, t, 32);
- tcg_gen_trunc_i64_i32(tmp, t);
+ tcg_gen_extrl_i64_i32(tmp, t);
tcg_gen_mov_i32(cpu_fregs[reg], tmp);
tcg_temp_free_i32(tmp);
}
return;
case 0x6008: /* swap.b Rm,Rn */
{
- TCGv high, low;
- high = tcg_temp_new();
- tcg_gen_andi_i32(high, REG(B7_4), 0xffff0000);
- low = tcg_temp_new();
+ TCGv low = tcg_temp_new();;
tcg_gen_ext16u_i32(low, REG(B7_4));
tcg_gen_bswap16_i32(low, low);
- tcg_gen_or_i32(REG(B11_8), high, low);
+ tcg_gen_deposit_i32(REG(B11_8), REG(B7_4), low, 0, 16);
tcg_temp_free(low);
- tcg_temp_free(high);
}
return;
case 0x6009: /* swap.w Rm,Rn */
{
TCGv cmp1 = tcg_temp_new();
TCGv cmp2 = tcg_temp_new();
- tcg_gen_xor_i32(cmp1, REG(B7_4), REG(B11_8));
- tcg_gen_andi_i32(cmp2, cmp1, 0xff000000);
- tcg_gen_setcondi_i32(TCG_COND_EQ, cpu_sr_t, cmp2, 0);
- tcg_gen_andi_i32(cmp2, cmp1, 0x00ff0000);
- tcg_gen_setcondi_i32(TCG_COND_EQ, cmp2, cmp2, 0);
- tcg_gen_or_i32(cpu_sr_t, cpu_sr_t, cmp2);
- tcg_gen_andi_i32(cmp2, cmp1, 0x0000ff00);
- tcg_gen_setcondi_i32(TCG_COND_EQ, cmp2, cmp2, 0);
- tcg_gen_or_i32(cpu_sr_t, cpu_sr_t, cmp2);
- tcg_gen_andi_i32(cmp2, cmp1, 0x000000ff);
- tcg_gen_setcondi_i32(TCG_COND_EQ, cmp2, cmp2, 0);
- tcg_gen_or_i32(cpu_sr_t, cpu_sr_t, cmp2);
+ tcg_gen_xor_i32(cmp2, REG(B7_4), REG(B11_8));
+ tcg_gen_subi_i32(cmp1, cmp2, 0x01010101);
+ tcg_gen_andc_i32(cmp1, cmp1, cmp2);
+ tcg_gen_andi_i32(cmp1, cmp1, 0x80808080);
+ tcg_gen_setcondi_i32(TCG_COND_NE, cpu_sr_t, cmp1, 0);
tcg_temp_free(cmp2);
tcg_temp_free(cmp1);
}
return;
case 0x400c: /* shad Rm,Rn */
{
- TCGLabel *label1 = gen_new_label();
- TCGLabel *label2 = gen_new_label();
- TCGLabel *label3 = gen_new_label();
- TCGLabel *label4 = gen_new_label();
- TCGv shift;
- tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);
- /* Rm positive, shift to the left */
- shift = tcg_temp_new();
- tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
- tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift);
- tcg_temp_free(shift);
- tcg_gen_br(label4);
- /* Rm negative, shift to the right */
- gen_set_label(label1);
- shift = tcg_temp_new();
- tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
- tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2);
- tcg_gen_not_i32(shift, REG(B7_4));
- tcg_gen_andi_i32(shift, shift, 0x1f);
- tcg_gen_addi_i32(shift, shift, 1);
- tcg_gen_sar_i32(REG(B11_8), REG(B11_8), shift);
- tcg_temp_free(shift);
- tcg_gen_br(label4);
- /* Rm = -32 */
- gen_set_label(label2);
- tcg_gen_brcondi_i32(TCG_COND_LT, REG(B11_8), 0, label3);
- tcg_gen_movi_i32(REG(B11_8), 0);
- tcg_gen_br(label4);
- gen_set_label(label3);
- tcg_gen_movi_i32(REG(B11_8), 0xffffffff);
- gen_set_label(label4);
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ TCGv t2 = tcg_temp_new();
+
+ tcg_gen_andi_i32(t0, REG(B7_4), 0x1f);
+
+ /* positive case: shift to the left */
+ tcg_gen_shl_i32(t1, REG(B11_8), t0);
+
+ /* negative case: shift to the right in two steps to
+ correctly handle the -32 case */
+ tcg_gen_xori_i32(t0, t0, 0x1f);
+ tcg_gen_sar_i32(t2, REG(B11_8), t0);
+ tcg_gen_sari_i32(t2, t2, 1);
+
+ /* select between the two cases */
+ tcg_gen_movi_i32(t0, 0);
+ tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2);
+
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+ tcg_temp_free(t2);
}
return;
case 0x400d: /* shld Rm,Rn */
{
- TCGLabel *label1 = gen_new_label();
- TCGLabel *label2 = gen_new_label();
- TCGLabel *label3 = gen_new_label();
- TCGv shift;
- tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);
- /* Rm positive, shift to the left */
- shift = tcg_temp_new();
- tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
- tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift);
- tcg_temp_free(shift);
- tcg_gen_br(label3);
- /* Rm negative, shift to the right */
- gen_set_label(label1);
- shift = tcg_temp_new();
- tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);
- tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2);
- tcg_gen_not_i32(shift, REG(B7_4));
- tcg_gen_andi_i32(shift, shift, 0x1f);
- tcg_gen_addi_i32(shift, shift, 1);
- tcg_gen_shr_i32(REG(B11_8), REG(B11_8), shift);
- tcg_temp_free(shift);
- tcg_gen_br(label3);
- /* Rm = -32 */
- gen_set_label(label2);
- tcg_gen_movi_i32(REG(B11_8), 0);
- gen_set_label(label3);
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ TCGv t2 = tcg_temp_new();
+
+ tcg_gen_andi_i32(t0, REG(B7_4), 0x1f);
+
+ /* positive case: shift to the left */
+ tcg_gen_shl_i32(t1, REG(B11_8), t0);
+
+ /* negative case: shift to the right in two steps to
+ correctly handle the -32 case */
+ tcg_gen_xori_i32(t0, t0, 0x1f);
+ tcg_gen_shr_i32(t2, REG(B11_8), t0);
+ tcg_gen_shri_i32(t2, t2, 1);
+
+ /* select between the two cases */
+ tcg_gen_movi_i32(t0, 0);
+ tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2);
+
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+ tcg_temp_free(t2);
}
return;
case 0x3008: /* sub Rm,Rn */
{
uint32_t old_flags = ctx->flags;
- if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
- tcg_gen_debug_insn_start(ctx->pc);
- }
-
_decode_opc(ctx);
if (old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
tcg_ctx.gen_opc_instr_start[ii] = 1;
tcg_ctx.gen_opc_icount[ii] = num_insns;
}
- if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
+ tcg_gen_insn_start(ctx.pc);
+ num_insns++;
+
+ if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
gen_io_start();
-#if 0
- fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
- fflush(stderr);
-#endif
+ }
+
ctx.opcode = cpu_lduw_code(env, ctx.pc);
decode_opc(&ctx);
- num_insns++;
ctx.pc += 2;
if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
break;
#ifdef DEBUG_DISAS
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
qemu_log("IN:\n"); /* , lookup_symbol(pc_start)); */
- log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
+ log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
qemu_log("\n");
}
#endif