CRIS: Avoid more cpu_T usage.

* Explicit operand passing to prep_alu_r.
* Avoid some more cpu_T[] usage.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5550 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
edgar_igl 2008-10-27 16:46:29 +00:00
parent 8137cde8f9
commit fb48f71b3d

View File

@ -1342,14 +1342,14 @@ static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
s_ext decides if the operand1 should be sign-extended or zero-extended when s_ext decides if the operand1 should be sign-extended or zero-extended when
needed. */ needed. */
static void dec_prep_alu_r(DisasContext *dc, int rs, int rd, static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
int size, int s_ext) int size, int s_ext, TCGv dst, TCGv src)
{ {
dec_prep_move_r(dc, rs, rd, size, s_ext, cpu_T[1]); dec_prep_move_r(dc, rs, rd, size, s_ext, src);
if (s_ext) if (s_ext)
t_gen_sext(cpu_T[0], cpu_R[rd], size); t_gen_sext(dst, cpu_R[rd], size);
else else
t_gen_zext(cpu_T[0], cpu_R[rd], size); t_gen_zext(dst, cpu_R[rd], size);
} }
static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize, static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize,
@ -1459,6 +1459,7 @@ static unsigned int dec_addoq(DisasContext *dc)
cris_cc_mask(dc, 0); cris_cc_mask(dc, 0);
/* Fetch register operand, */ /* Fetch register operand, */
tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm); tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
return 2; return 2;
} }
static unsigned int dec_addq(DisasContext *dc) static unsigned int dec_addq(DisasContext *dc)
@ -1639,102 +1640,135 @@ static unsigned int dec_scc_r(DisasContext *dc)
return 2; return 2;
} }
static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
{
if (size == 4) {
t[0] = cpu_R[dc->op2];
t[1] = cpu_R[dc->op1];
} else {
t[0] = tcg_temp_new(TCG_TYPE_TL);
t[1] = tcg_temp_new(TCG_TYPE_TL);
}
}
static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
{
if (size != 4) {
tcg_temp_free(t[0]);
tcg_temp_free(t[1]);
}
}
static unsigned int dec_and_r(DisasContext *dc) static unsigned int dec_and_r(DisasContext *dc)
{ {
TCGv t[2];
int size = memsize_zz(dc); int size = memsize_zz(dc);
DIS(fprintf (logfile, "and.%c $r%u, $r%u\n", DIS(fprintf (logfile, "and.%c $r%u, $r%u\n",
memsize_char(size), dc->op1, dc->op2)); memsize_char(size), dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZ);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
cris_alu(dc, CC_OP_AND, cris_cc_mask(dc, CC_MASK_NZ);
cpu_R[dc->op2],
cpu_R[dc->op2], cpu_T[1], size); cris_alu_alloc_temps(dc, size, t);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
cris_alu_free_temps(dc, size, t);
return 2; return 2;
} }
static unsigned int dec_lz_r(DisasContext *dc) static unsigned int dec_lz_r(DisasContext *dc)
{ {
TCGv t0;
DIS(fprintf (logfile, "lz $r%u, $r%u\n", DIS(fprintf (logfile, "lz $r%u, $r%u\n",
dc->op1, dc->op2)); dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZ); cris_cc_mask(dc, CC_MASK_NZ);
dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0); t0 = tcg_temp_new(TCG_TYPE_TL);
cris_alu(dc, CC_OP_LZ, dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
tcg_temp_free(t0);
return 2; return 2;
} }
static unsigned int dec_lsl_r(DisasContext *dc) static unsigned int dec_lsl_r(DisasContext *dc)
{ {
TCGv t[2];
int size = memsize_zz(dc); int size = memsize_zz(dc);
DIS(fprintf (logfile, "lsl.%c $r%u, $r%u\n", DIS(fprintf (logfile, "lsl.%c $r%u, $r%u\n",
memsize_char(size), dc->op1, dc->op2)); memsize_char(size), dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZ);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
cris_alu(dc, CC_OP_LSL, cris_cc_mask(dc, CC_MASK_NZ);
cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); cris_alu_alloc_temps(dc, size, t);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
tcg_gen_andi_tl(t[1], t[1], 63);
cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
cris_alu_alloc_temps(dc, size, t);
return 2; return 2;
} }
static unsigned int dec_lsr_r(DisasContext *dc) static unsigned int dec_lsr_r(DisasContext *dc)
{ {
TCGv t[2];
int size = memsize_zz(dc); int size = memsize_zz(dc);
DIS(fprintf (logfile, "lsr.%c $r%u, $r%u\n", DIS(fprintf (logfile, "lsr.%c $r%u, $r%u\n",
memsize_char(size), dc->op1, dc->op2)); memsize_char(size), dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZ);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
cris_alu(dc, CC_OP_LSR, cris_cc_mask(dc, CC_MASK_NZ);
cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); cris_alu_alloc_temps(dc, size, t);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
tcg_gen_andi_tl(t[1], t[1], 63);
cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
cris_alu_free_temps(dc, size, t);
return 2; return 2;
} }
static unsigned int dec_asr_r(DisasContext *dc) static unsigned int dec_asr_r(DisasContext *dc)
{ {
TCGv t[2];
int size = memsize_zz(dc); int size = memsize_zz(dc);
DIS(fprintf (logfile, "asr.%c $r%u, $r%u\n", DIS(fprintf (logfile, "asr.%c $r%u, $r%u\n",
memsize_char(size), dc->op1, dc->op2)); memsize_char(size), dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZ);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1);
tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 63);
cris_alu(dc, CC_OP_ASR, cris_cc_mask(dc, CC_MASK_NZ);
cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); cris_alu_alloc_temps(dc, size, t);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
tcg_gen_andi_tl(t[1], t[1], 63);
cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
cris_alu_free_temps(dc, size, t);
return 2; return 2;
} }
static unsigned int dec_muls_r(DisasContext *dc) static unsigned int dec_muls_r(DisasContext *dc)
{ {
TCGv t[2];
int size = memsize_zz(dc); int size = memsize_zz(dc);
DIS(fprintf (logfile, "muls.%c $r%u, $r%u\n", DIS(fprintf (logfile, "muls.%c $r%u, $r%u\n",
memsize_char(size), dc->op1, dc->op2)); memsize_char(size), dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZV); cris_cc_mask(dc, CC_MASK_NZV);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1); cris_alu_alloc_temps(dc, size, t);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
cris_alu(dc, CC_OP_MULS, cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4); cris_alu_free_temps(dc, size, t);
return 2; return 2;
} }
static unsigned int dec_mulu_r(DisasContext *dc) static unsigned int dec_mulu_r(DisasContext *dc)
{ {
TCGv t[2];
int size = memsize_zz(dc); int size = memsize_zz(dc);
DIS(fprintf (logfile, "mulu.%c $r%u, $r%u\n", DIS(fprintf (logfile, "mulu.%c $r%u, $r%u\n",
memsize_char(size), dc->op1, dc->op2)); memsize_char(size), dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZV); cris_cc_mask(dc, CC_MASK_NZV);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); cris_alu_alloc_temps(dc, size, t);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
cris_alu(dc, CC_OP_MULU, cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4); cris_alu_alloc_temps(dc, size, t);
return 2; return 2;
} }
@ -1750,40 +1784,46 @@ static unsigned int dec_dstep_r(DisasContext *dc)
static unsigned int dec_xor_r(DisasContext *dc) static unsigned int dec_xor_r(DisasContext *dc)
{ {
TCGv t[2];
int size = memsize_zz(dc); int size = memsize_zz(dc);
DIS(fprintf (logfile, "xor.%c $r%u, $r%u\n", DIS(fprintf (logfile, "xor.%c $r%u, $r%u\n",
memsize_char(size), dc->op1, dc->op2)); memsize_char(size), dc->op1, dc->op2));
BUG_ON(size != 4); /* xor is dword. */ BUG_ON(size != 4); /* xor is dword. */
cris_cc_mask(dc, CC_MASK_NZ); cris_cc_mask(dc, CC_MASK_NZ);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); cris_alu_alloc_temps(dc, size, t);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
cris_alu(dc, CC_OP_XOR, cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4); cris_alu_free_temps(dc, size, t);
return 2; return 2;
} }
static unsigned int dec_bound_r(DisasContext *dc) static unsigned int dec_bound_r(DisasContext *dc)
{ {
TCGv l0;
int size = memsize_zz(dc); int size = memsize_zz(dc);
DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n", DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n",
memsize_char(size), dc->op1, dc->op2)); memsize_char(size), dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZ); cris_cc_mask(dc, CC_MASK_NZ);
dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_T[1]); l0 = tcg_temp_local_new(TCG_TYPE_TL);
dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
cris_alu(dc, CC_OP_BOUND, cris_alu(dc, CC_OP_BOUND,
cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
return 2; return 2;
} }
static unsigned int dec_cmp_r(DisasContext *dc) static unsigned int dec_cmp_r(DisasContext *dc)
{ {
TCGv t[2];
int size = memsize_zz(dc); int size = memsize_zz(dc);
DIS(fprintf (logfile, "cmp.%c $r%u, $r%u\n", DIS(fprintf (logfile, "cmp.%c $r%u, $r%u\n",
memsize_char(size), dc->op1, dc->op2)); memsize_char(size), dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZVC); cris_cc_mask(dc, CC_MASK_NZVC);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); cris_alu_alloc_temps(dc, size, t);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
cris_alu(dc, CC_OP_CMP, cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); cris_alu_free_temps(dc, size, t);
return 2; return 2;
} }
@ -1808,14 +1848,16 @@ static unsigned int dec_abs_r(DisasContext *dc)
static unsigned int dec_add_r(DisasContext *dc) static unsigned int dec_add_r(DisasContext *dc)
{ {
TCGv t[2];
int size = memsize_zz(dc); int size = memsize_zz(dc);
DIS(fprintf (logfile, "add.%c $r%u, $r%u\n", DIS(fprintf (logfile, "add.%c $r%u, $r%u\n",
memsize_char(size), dc->op1, dc->op2)); memsize_char(size), dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZVC); cris_cc_mask(dc, CC_MASK_NZVC);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); cris_alu_alloc_temps(dc, size, t);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
cris_alu(dc, CC_OP_ADD, cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); cris_alu_free_temps(dc, size, t);
return 2; return 2;
} }
@ -1825,9 +1867,8 @@ static unsigned int dec_addc_r(DisasContext *dc)
dc->op1, dc->op2)); dc->op1, dc->op2));
cris_evaluate_flags(dc); cris_evaluate_flags(dc);
cris_cc_mask(dc, CC_MASK_NZVC); cris_cc_mask(dc, CC_MASK_NZVC);
dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
cris_alu(dc, CC_OP_ADDC, cris_alu(dc, CC_OP_ADDC,
cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4); cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
return 2; return 2;
} }
@ -1860,6 +1901,7 @@ static char * swapmode_name(int mode, char *modename) {
static unsigned int dec_swap_r(DisasContext *dc) static unsigned int dec_swap_r(DisasContext *dc)
{ {
TCGv t0;
#if DISAS_CRIS #if DISAS_CRIS
char modename[4]; char modename[4];
#endif #endif
@ -1867,64 +1909,72 @@ static unsigned int dec_swap_r(DisasContext *dc)
swapmode_name(dc->op2, modename), dc->op1)); swapmode_name(dc->op2, modename), dc->op1));
cris_cc_mask(dc, CC_MASK_NZ); cris_cc_mask(dc, CC_MASK_NZ);
t_gen_mov_TN_reg(cpu_T[0], dc->op1); t0 = tcg_temp_new(TCG_TYPE_TL);
t_gen_mov_TN_reg(t0, dc->op1);
if (dc->op2 & 8) if (dc->op2 & 8)
tcg_gen_not_tl(cpu_T[0], cpu_T[0]); tcg_gen_not_tl(t0, t0);
if (dc->op2 & 4) if (dc->op2 & 4)
t_gen_swapw(cpu_T[0], cpu_T[0]); t_gen_swapw(t0, t0);
if (dc->op2 & 2) if (dc->op2 & 2)
t_gen_swapb(cpu_T[0], cpu_T[0]); t_gen_swapb(t0, t0);
if (dc->op2 & 1) if (dc->op2 & 1)
t_gen_swapr(cpu_T[0], cpu_T[0]); t_gen_swapr(t0, t0);
cris_alu(dc, CC_OP_MOVE, cris_alu(dc, CC_OP_MOVE,
cpu_R[dc->op1], cpu_R[dc->op1], cpu_T[0], 4); cpu_R[dc->op1], cpu_R[dc->op1], t0, 4);
return 2; return 2;
} }
static unsigned int dec_or_r(DisasContext *dc) static unsigned int dec_or_r(DisasContext *dc)
{ {
TCGv t[2];
int size = memsize_zz(dc); int size = memsize_zz(dc);
DIS(fprintf (logfile, "or.%c $r%u, $r%u\n", DIS(fprintf (logfile, "or.%c $r%u, $r%u\n",
memsize_char(size), dc->op1, dc->op2)); memsize_char(size), dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZ); cris_cc_mask(dc, CC_MASK_NZ);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); cris_alu_alloc_temps(dc, size, t);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
cris_alu(dc, CC_OP_OR, cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); cris_alu_free_temps(dc, size, t);
return 2; return 2;
} }
static unsigned int dec_addi_r(DisasContext *dc) static unsigned int dec_addi_r(DisasContext *dc)
{ {
TCGv t0;
DIS(fprintf (logfile, "addi.%c $r%u, $r%u\n", DIS(fprintf (logfile, "addi.%c $r%u, $r%u\n",
memsize_char(memsize_zz(dc)), dc->op2, dc->op1)); memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
cris_cc_mask(dc, 0); cris_cc_mask(dc, 0);
tcg_gen_shl_tl(cpu_T[0], cpu_R[dc->op2], tcg_const_tl(dc->zzsize)); t0 = tcg_temp_new(TCG_TYPE_TL);
tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], cpu_T[0]); tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
return 2; return 2;
} }
static unsigned int dec_addi_acr(DisasContext *dc) static unsigned int dec_addi_acr(DisasContext *dc)
{ {
TCGv t0;
DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n", DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n",
memsize_char(memsize_zz(dc)), dc->op2, dc->op1)); memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
cris_cc_mask(dc, 0); cris_cc_mask(dc, 0);
tcg_gen_shl_tl(cpu_T[0], cpu_R[dc->op2], tcg_const_tl(dc->zzsize)); t0 = tcg_temp_new(TCG_TYPE_TL);
tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], cpu_T[0]); tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
return 2; return 2;
} }
static unsigned int dec_neg_r(DisasContext *dc) static unsigned int dec_neg_r(DisasContext *dc)
{ {
TCGv t[2];
int size = memsize_zz(dc); int size = memsize_zz(dc);
DIS(fprintf (logfile, "neg.%c $r%u, $r%u\n", DIS(fprintf (logfile, "neg.%c $r%u, $r%u\n",
memsize_char(size), dc->op1, dc->op2)); memsize_char(size), dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZVC); cris_cc_mask(dc, CC_MASK_NZVC);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); cris_alu_alloc_temps(dc, size, t);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
cris_alu(dc, CC_OP_NEG, cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); cris_alu_free_temps(dc, size, t);
return 2; return 2;
} }
@ -1933,7 +1983,7 @@ static unsigned int dec_btst_r(DisasContext *dc)
DIS(fprintf (logfile, "btst $r%u, $r%u\n", DIS(fprintf (logfile, "btst $r%u, $r%u\n",
dc->op1, dc->op2)); dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZ); cris_cc_mask(dc, CC_MASK_NZ);
dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0); dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_T[0], cpu_T[1]);
cris_alu(dc, CC_OP_BTST, cris_alu(dc, CC_OP_BTST,
cpu_T[0], cpu_T[0], cpu_T[1], 4); cpu_T[0], cpu_T[0], cpu_T[1], 4);
@ -1945,108 +1995,127 @@ static unsigned int dec_btst_r(DisasContext *dc)
static unsigned int dec_sub_r(DisasContext *dc) static unsigned int dec_sub_r(DisasContext *dc)
{ {
TCGv t[2];
int size = memsize_zz(dc); int size = memsize_zz(dc);
DIS(fprintf (logfile, "sub.%c $r%u, $r%u\n", DIS(fprintf (logfile, "sub.%c $r%u, $r%u\n",
memsize_char(size), dc->op1, dc->op2)); memsize_char(size), dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZVC); cris_cc_mask(dc, CC_MASK_NZVC);
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0); cris_alu_alloc_temps(dc, size, t);
cris_alu(dc, CC_OP_SUB, dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
cpu_R[dc->op2], cpu_T[0], cpu_T[1], size); cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
cris_alu_free_temps(dc, size, t);
return 2; return 2;
} }
/* Zero extension. From size to dword. */ /* Zero extension. From size to dword. */
static unsigned int dec_movu_r(DisasContext *dc) static unsigned int dec_movu_r(DisasContext *dc)
{ {
TCGv t0;
int size = memsize_z(dc); int size = memsize_z(dc);
DIS(fprintf (logfile, "movu.%c $r%u, $r%u\n", DIS(fprintf (logfile, "movu.%c $r%u, $r%u\n",
memsize_char(size), memsize_char(size),
dc->op1, dc->op2)); dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZ); cris_cc_mask(dc, CC_MASK_NZ);
dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_T[1]); t0 = tcg_temp_new(TCG_TYPE_TL);
cris_alu(dc, CC_OP_MOVE, dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4); cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
tcg_temp_free(t0);
return 2; return 2;
} }
/* Sign extension. From size to dword. */ /* Sign extension. From size to dword. */
static unsigned int dec_movs_r(DisasContext *dc) static unsigned int dec_movs_r(DisasContext *dc)
{ {
TCGv t0;
int size = memsize_z(dc); int size = memsize_z(dc);
DIS(fprintf (logfile, "movs.%c $r%u, $r%u\n", DIS(fprintf (logfile, "movs.%c $r%u, $r%u\n",
memsize_char(size), memsize_char(size),
dc->op1, dc->op2)); dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZ); cris_cc_mask(dc, CC_MASK_NZ);
t0 = tcg_temp_new(TCG_TYPE_TL);
/* Size can only be qi or hi. */ /* Size can only be qi or hi. */
t_gen_sext(cpu_T[1], cpu_R[dc->op1], size); t_gen_sext(t0, cpu_R[dc->op1], size);
cris_alu(dc, CC_OP_MOVE, cris_alu(dc, CC_OP_MOVE,
cpu_R[dc->op2], cpu_R[dc->op1], cpu_T[1], 4); cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
tcg_temp_free(t0);
return 2; return 2;
} }
/* zero extension. From size to dword. */ /* zero extension. From size to dword. */
static unsigned int dec_addu_r(DisasContext *dc) static unsigned int dec_addu_r(DisasContext *dc)
{ {
TCGv t0;
int size = memsize_z(dc); int size = memsize_z(dc);
DIS(fprintf (logfile, "addu.%c $r%u, $r%u\n", DIS(fprintf (logfile, "addu.%c $r%u, $r%u\n",
memsize_char(size), memsize_char(size),
dc->op1, dc->op2)); dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZVC); cris_cc_mask(dc, CC_MASK_NZVC);
t0 = tcg_temp_new(TCG_TYPE_TL);
/* Size can only be qi or hi. */ /* Size can only be qi or hi. */
t_gen_zext(cpu_T[1], cpu_R[dc->op1], size); t_gen_zext(t0, cpu_R[dc->op1], size);
cris_alu(dc, CC_OP_ADD, cris_alu(dc, CC_OP_ADD,
cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
tcg_temp_free(t0);
return 2; return 2;
} }
/* Sign extension. From size to dword. */ /* Sign extension. From size to dword. */
static unsigned int dec_adds_r(DisasContext *dc) static unsigned int dec_adds_r(DisasContext *dc)
{ {
TCGv t0;
int size = memsize_z(dc); int size = memsize_z(dc);
DIS(fprintf (logfile, "adds.%c $r%u, $r%u\n", DIS(fprintf (logfile, "adds.%c $r%u, $r%u\n",
memsize_char(size), memsize_char(size),
dc->op1, dc->op2)); dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZVC); cris_cc_mask(dc, CC_MASK_NZVC);
t0 = tcg_temp_new(TCG_TYPE_TL);
/* Size can only be qi or hi. */ /* Size can only be qi or hi. */
t_gen_sext(cpu_T[1], cpu_R[dc->op1], size); t_gen_sext(t0, cpu_R[dc->op1], size);
cris_alu(dc, CC_OP_ADD, cris_alu(dc, CC_OP_ADD,
cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
tcg_temp_free(t0);
return 2; return 2;
} }
/* Zero extension. From size to dword. */ /* Zero extension. From size to dword. */
static unsigned int dec_subu_r(DisasContext *dc) static unsigned int dec_subu_r(DisasContext *dc)
{ {
TCGv t0;
int size = memsize_z(dc); int size = memsize_z(dc);
DIS(fprintf (logfile, "subu.%c $r%u, $r%u\n", DIS(fprintf (logfile, "subu.%c $r%u, $r%u\n",
memsize_char(size), memsize_char(size),
dc->op1, dc->op2)); dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZVC); cris_cc_mask(dc, CC_MASK_NZVC);
t0 = tcg_temp_new(TCG_TYPE_TL);
/* Size can only be qi or hi. */ /* Size can only be qi or hi. */
t_gen_zext(cpu_T[1], cpu_R[dc->op1], size); t_gen_zext(t0, cpu_R[dc->op1], size);
cris_alu(dc, CC_OP_SUB, cris_alu(dc, CC_OP_SUB,
cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
tcg_temp_free(t0);
return 2; return 2;
} }
/* Sign extension. From size to dword. */ /* Sign extension. From size to dword. */
static unsigned int dec_subs_r(DisasContext *dc) static unsigned int dec_subs_r(DisasContext *dc)
{ {
TCGv t0;
int size = memsize_z(dc); int size = memsize_z(dc);
DIS(fprintf (logfile, "subs.%c $r%u, $r%u\n", DIS(fprintf (logfile, "subs.%c $r%u, $r%u\n",
memsize_char(size), memsize_char(size),
dc->op1, dc->op2)); dc->op1, dc->op2));
cris_cc_mask(dc, CC_MASK_NZVC); cris_cc_mask(dc, CC_MASK_NZVC);
t0 = tcg_temp_new(TCG_TYPE_TL);
/* Size can only be qi or hi. */ /* Size can only be qi or hi. */
t_gen_sext(cpu_T[1], cpu_R[dc->op1], size); t_gen_sext(t0, cpu_R[dc->op1], size);
cris_alu(dc, CC_OP_SUB, cris_alu(dc, CC_OP_SUB,
cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4); cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
tcg_temp_free(t0);
return 2; return 2;
} }
@ -2055,6 +2124,7 @@ static unsigned int dec_setclrf(DisasContext *dc)
uint32_t flags; uint32_t flags;
int set = (~dc->opcode >> 2) & 1; int set = (~dc->opcode >> 2) & 1;
flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4) flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
| EXTRACT_FIELD(dc->ir, 0, 3); | EXTRACT_FIELD(dc->ir, 0, 3);
if (set && flags == 0) { if (set && flags == 0) {
@ -2069,7 +2139,7 @@ static unsigned int dec_setclrf(DisasContext *dc)
flags)); flags));
} }
/* User space is not allowed to touch these. Silently ignore. */ /* User space is not allowed to touch these. Silently ignore. */
if (dc->tb_flags & U_FLAG) { if (dc->tb_flags & U_FLAG) {
flags &= ~(S_FLAG | I_FLAG | U_FLAG); flags &= ~(S_FLAG | I_FLAG | U_FLAG);
} }
@ -2138,41 +2208,48 @@ static unsigned int dec_move_sr(DisasContext *dc)
static unsigned int dec_move_rp(DisasContext *dc) static unsigned int dec_move_rp(DisasContext *dc)
{ {
TCGv t[2];
DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2)); DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2));
cris_cc_mask(dc, 0); cris_cc_mask(dc, 0);
t[0] = tcg_temp_new(TCG_TYPE_TL);
if (dc->op2 == PR_CCS) { if (dc->op2 == PR_CCS) {
cris_evaluate_flags(dc); cris_evaluate_flags(dc);
t_gen_mov_TN_reg(cpu_T[0], dc->op1); t_gen_mov_TN_reg(t[0], dc->op1);
if (dc->tb_flags & U_FLAG) { if (dc->tb_flags & U_FLAG) {
t[1] = tcg_temp_new(TCG_TYPE_TL);
/* User space is not allowed to touch all flags. */ /* User space is not allowed to touch all flags. */
tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x39f); tcg_gen_andi_tl(t[0], t[0], 0x39f);
tcg_gen_andi_tl(cpu_T[1], cpu_PR[PR_CCS], ~0x39f); tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
tcg_gen_or_tl(cpu_T[0], cpu_T[1], cpu_T[0]); tcg_gen_or_tl(t[0], t[1], t[0]);
tcg_temp_free(t[1]);
} }
} }
else else
t_gen_mov_TN_reg(cpu_T[0], dc->op1); t_gen_mov_TN_reg(t[0], dc->op1);
t_gen_mov_preg_TN(dc, dc->op2, cpu_T[0]); t_gen_mov_preg_TN(dc, dc->op2, t[0]);
if (dc->op2 == PR_CCS) { if (dc->op2 == PR_CCS) {
cris_update_cc_op(dc, CC_OP_FLAGS, 4); cris_update_cc_op(dc, CC_OP_FLAGS, 4);
dc->flags_uptodate = 1; dc->flags_uptodate = 1;
} }
tcg_temp_free(t[0]);
return 2; return 2;
} }
static unsigned int dec_move_pr(DisasContext *dc) static unsigned int dec_move_pr(DisasContext *dc)
{ {
TCGv t0;
DIS(fprintf (logfile, "move $p%u, $r%u\n", dc->op1, dc->op2)); DIS(fprintf (logfile, "move $p%u, $r%u\n", dc->op1, dc->op2));
cris_cc_mask(dc, 0); cris_cc_mask(dc, 0);
if (dc->op2 == PR_CCS) if (dc->op2 == PR_CCS)
cris_evaluate_flags(dc); cris_evaluate_flags(dc);
t_gen_mov_TN_preg(cpu_T[1], dc->op2); t0 = tcg_temp_new(TCG_TYPE_TL);
t_gen_mov_TN_preg(t0, dc->op2);
cris_alu(dc, CC_OP_MOVE, cris_alu(dc, CC_OP_MOVE,
cpu_R[dc->op1], cpu_R[dc->op1], cpu_T[1], cpu_R[dc->op1], cpu_R[dc->op1], t0, preg_sizes[dc->op2]);
preg_sizes[dc->op2]); tcg_temp_free(t0);
return 2; return 2;
} }
@ -2193,10 +2270,14 @@ static unsigned int dec_move_mr(DisasContext *dc)
cris_update_result(dc, cpu_R[dc->op2]); cris_update_result(dc, cpu_R[dc->op2]);
} }
else { else {
insn_len = dec_prep_move_m(dc, 0, memsize, cpu_T[1]); TCGv t0;
t0 = tcg_temp_new(TCG_TYPE_TL);
insn_len = dec_prep_move_m(dc, 0, memsize, t0);
cris_cc_mask(dc, CC_MASK_NZ); cris_cc_mask(dc, CC_MASK_NZ);
cris_alu(dc, CC_OP_MOVE, cris_alu(dc, CC_OP_MOVE,
cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], memsize); cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
tcg_temp_free(t0);
} }
do_postinc(dc, memsize); do_postinc(dc, memsize);
return insn_len; return insn_len;
@ -2838,13 +2919,11 @@ static unsigned int dec_rfe_etc(DisasContext *dc)
static unsigned int dec_ftag_fidx_d_m(DisasContext *dc) static unsigned int dec_ftag_fidx_d_m(DisasContext *dc)
{ {
/* Ignore D-cache flushes. */
return 2; return 2;
} }
static unsigned int dec_ftag_fidx_i_m(DisasContext *dc) static unsigned int dec_ftag_fidx_i_m(DisasContext *dc)
{ {
/* Ignore I-cache flushes. */
return 2; return 2;
} }
@ -3207,7 +3286,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
delay slots dont break. */ delay slots dont break. */
if (!(tb->pc & 1) && env->singlestep_enabled) if (!(tb->pc & 1) && env->singlestep_enabled)
break; break;
} while (!dc->is_jmp && gen_opc_ptr < gen_opc_end } while (!dc->is_jmp && !dc->cpustate_changed
&& gen_opc_ptr < gen_opc_end
&& (dc->pc < next_page_start) && (dc->pc < next_page_start)
&& num_insns < max_insns); && num_insns < max_insns);