mirror of
https://github.com/qemu/qemu.git
synced 2024-11-24 11:23:43 +08:00
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:
parent
8137cde8f9
commit
fb48f71b3d
@ -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
|
||||
needed. */
|
||||
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)
|
||||
t_gen_sext(cpu_T[0], cpu_R[rd], size);
|
||||
t_gen_sext(dst, cpu_R[rd], size);
|
||||
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,
|
||||
@ -1459,6 +1459,7 @@ static unsigned int dec_addoq(DisasContext *dc)
|
||||
cris_cc_mask(dc, 0);
|
||||
/* Fetch register operand, */
|
||||
tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);
|
||||
|
||||
return 2;
|
||||
}
|
||||
static unsigned int dec_addq(DisasContext *dc)
|
||||
@ -1639,102 +1640,135 @@ static unsigned int dec_scc_r(DisasContext *dc)
|
||||
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)
|
||||
{
|
||||
TCGv t[2];
|
||||
int size = memsize_zz(dc);
|
||||
|
||||
DIS(fprintf (logfile, "and.%c $r%u, $r%u\n",
|
||||
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,
|
||||
cpu_R[dc->op2],
|
||||
cpu_R[dc->op2], cpu_T[1], size);
|
||||
cris_cc_mask(dc, CC_MASK_NZ);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static unsigned int dec_lz_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t0;
|
||||
DIS(fprintf (logfile, "lz $r%u, $r%u\n",
|
||||
dc->op1, dc->op2));
|
||||
cris_cc_mask(dc, CC_MASK_NZ);
|
||||
dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
|
||||
cris_alu(dc, CC_OP_LZ,
|
||||
cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4);
|
||||
t0 = tcg_temp_new(TCG_TYPE_TL);
|
||||
dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
|
||||
cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
|
||||
tcg_temp_free(t0);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static unsigned int dec_lsl_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t[2];
|
||||
int size = memsize_zz(dc);
|
||||
|
||||
DIS(fprintf (logfile, "lsl.%c $r%u, $r%u\n",
|
||||
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,
|
||||
cpu_R[dc->op2], cpu_T[0], cpu_T[1], size);
|
||||
cris_cc_mask(dc, CC_MASK_NZ);
|
||||
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;
|
||||
}
|
||||
|
||||
static unsigned int dec_lsr_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t[2];
|
||||
int size = memsize_zz(dc);
|
||||
|
||||
DIS(fprintf (logfile, "lsr.%c $r%u, $r%u\n",
|
||||
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,
|
||||
cpu_R[dc->op2], cpu_T[0], cpu_T[1], size);
|
||||
cris_cc_mask(dc, CC_MASK_NZ);
|
||||
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;
|
||||
}
|
||||
|
||||
static unsigned int dec_asr_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t[2];
|
||||
int size = memsize_zz(dc);
|
||||
|
||||
DIS(fprintf (logfile, "asr.%c $r%u, $r%u\n",
|
||||
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,
|
||||
cpu_R[dc->op2], cpu_T[0], cpu_T[1], size);
|
||||
cris_cc_mask(dc, CC_MASK_NZ);
|
||||
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;
|
||||
}
|
||||
|
||||
static unsigned int dec_muls_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t[2];
|
||||
int size = memsize_zz(dc);
|
||||
|
||||
DIS(fprintf (logfile, "muls.%c $r%u, $r%u\n",
|
||||
memsize_char(size), dc->op1, dc->op2));
|
||||
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,
|
||||
cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4);
|
||||
cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
|
||||
cris_alu_free_temps(dc, size, t);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static unsigned int dec_mulu_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t[2];
|
||||
int size = memsize_zz(dc);
|
||||
|
||||
DIS(fprintf (logfile, "mulu.%c $r%u, $r%u\n",
|
||||
memsize_char(size), dc->op1, dc->op2));
|
||||
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,
|
||||
cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4);
|
||||
cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
|
||||
cris_alu_alloc_temps(dc, size, t);
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -1750,40 +1784,46 @@ static unsigned int dec_dstep_r(DisasContext *dc)
|
||||
|
||||
static unsigned int dec_xor_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t[2];
|
||||
int size = memsize_zz(dc);
|
||||
DIS(fprintf (logfile, "xor.%c $r%u, $r%u\n",
|
||||
memsize_char(size), dc->op1, dc->op2));
|
||||
BUG_ON(size != 4); /* xor is dword. */
|
||||
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,
|
||||
cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4);
|
||||
cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
|
||||
cris_alu_free_temps(dc, size, t);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static unsigned int dec_bound_r(DisasContext *dc)
|
||||
{
|
||||
TCGv l0;
|
||||
int size = memsize_zz(dc);
|
||||
DIS(fprintf (logfile, "bound.%c $r%u, $r%u\n",
|
||||
memsize_char(size), dc->op1, dc->op2));
|
||||
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,
|
||||
cpu_R[dc->op2], cpu_R[dc->op2], cpu_T[1], 4);
|
||||
cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static unsigned int dec_cmp_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t[2];
|
||||
int size = memsize_zz(dc);
|
||||
DIS(fprintf (logfile, "cmp.%c $r%u, $r%u\n",
|
||||
memsize_char(size), dc->op1, dc->op2));
|
||||
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,
|
||||
cpu_R[dc->op2], cpu_T[0], cpu_T[1], size);
|
||||
cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
|
||||
cris_alu_free_temps(dc, size, t);
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -1808,14 +1848,16 @@ static unsigned int dec_abs_r(DisasContext *dc)
|
||||
|
||||
static unsigned int dec_add_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t[2];
|
||||
int size = memsize_zz(dc);
|
||||
DIS(fprintf (logfile, "add.%c $r%u, $r%u\n",
|
||||
memsize_char(size), dc->op1, dc->op2));
|
||||
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,
|
||||
cpu_R[dc->op2], cpu_T[0], cpu_T[1], size);
|
||||
cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
|
||||
cris_alu_free_temps(dc, size, t);
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -1825,9 +1867,8 @@ static unsigned int dec_addc_r(DisasContext *dc)
|
||||
dc->op1, dc->op2));
|
||||
cris_evaluate_flags(dc);
|
||||
cris_cc_mask(dc, CC_MASK_NZVC);
|
||||
dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1860,6 +1901,7 @@ static char * swapmode_name(int mode, char *modename) {
|
||||
|
||||
static unsigned int dec_swap_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t0;
|
||||
#if DISAS_CRIS
|
||||
char modename[4];
|
||||
#endif
|
||||
@ -1867,64 +1909,72 @@ static unsigned int dec_swap_r(DisasContext *dc)
|
||||
swapmode_name(dc->op2, modename), dc->op1));
|
||||
|
||||
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)
|
||||
tcg_gen_not_tl(cpu_T[0], cpu_T[0]);
|
||||
tcg_gen_not_tl(t0, t0);
|
||||
if (dc->op2 & 4)
|
||||
t_gen_swapw(cpu_T[0], cpu_T[0]);
|
||||
t_gen_swapw(t0, t0);
|
||||
if (dc->op2 & 2)
|
||||
t_gen_swapb(cpu_T[0], cpu_T[0]);
|
||||
t_gen_swapb(t0, t0);
|
||||
if (dc->op2 & 1)
|
||||
t_gen_swapr(cpu_T[0], cpu_T[0]);
|
||||
t_gen_swapr(t0, t0);
|
||||
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;
|
||||
}
|
||||
|
||||
static unsigned int dec_or_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t[2];
|
||||
int size = memsize_zz(dc);
|
||||
DIS(fprintf (logfile, "or.%c $r%u, $r%u\n",
|
||||
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_OR,
|
||||
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]);
|
||||
cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
|
||||
cris_alu_free_temps(dc, size, t);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static unsigned int dec_addi_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t0;
|
||||
DIS(fprintf (logfile, "addi.%c $r%u, $r%u\n",
|
||||
memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
|
||||
cris_cc_mask(dc, 0);
|
||||
tcg_gen_shl_tl(cpu_T[0], cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
|
||||
tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], cpu_T[0]);
|
||||
t0 = tcg_temp_new(TCG_TYPE_TL);
|
||||
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;
|
||||
}
|
||||
|
||||
static unsigned int dec_addi_acr(DisasContext *dc)
|
||||
{
|
||||
TCGv t0;
|
||||
DIS(fprintf (logfile, "addi.%c $r%u, $r%u, $acr\n",
|
||||
memsize_char(memsize_zz(dc)), dc->op2, dc->op1));
|
||||
cris_cc_mask(dc, 0);
|
||||
tcg_gen_shl_tl(cpu_T[0], cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
|
||||
tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], cpu_T[0]);
|
||||
t0 = tcg_temp_new(TCG_TYPE_TL);
|
||||
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;
|
||||
}
|
||||
|
||||
static unsigned int dec_neg_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t[2];
|
||||
int size = memsize_zz(dc);
|
||||
DIS(fprintf (logfile, "neg.%c $r%u, $r%u\n",
|
||||
memsize_char(size), dc->op1, dc->op2));
|
||||
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,
|
||||
cpu_R[dc->op2], cpu_T[0], cpu_T[1], size);
|
||||
cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
|
||||
cris_alu_free_temps(dc, size, t);
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -1933,7 +1983,7 @@ static unsigned int dec_btst_r(DisasContext *dc)
|
||||
DIS(fprintf (logfile, "btst $r%u, $r%u\n",
|
||||
dc->op1, dc->op2));
|
||||
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,
|
||||
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)
|
||||
{
|
||||
TCGv t[2];
|
||||
int size = memsize_zz(dc);
|
||||
DIS(fprintf (logfile, "sub.%c $r%u, $r%u\n",
|
||||
memsize_char(size), dc->op1, dc->op2));
|
||||
cris_cc_mask(dc, CC_MASK_NZVC);
|
||||
dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0);
|
||||
cris_alu(dc, CC_OP_SUB,
|
||||
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]);
|
||||
cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
|
||||
cris_alu_free_temps(dc, size, t);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Zero extension. From size to dword. */
|
||||
static unsigned int dec_movu_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t0;
|
||||
int size = memsize_z(dc);
|
||||
DIS(fprintf (logfile, "movu.%c $r%u, $r%u\n",
|
||||
memsize_char(size),
|
||||
dc->op1, dc->op2));
|
||||
|
||||
cris_cc_mask(dc, CC_MASK_NZ);
|
||||
dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_T[1]);
|
||||
cris_alu(dc, CC_OP_MOVE,
|
||||
cpu_R[dc->op2], cpu_T[0], cpu_T[1], 4);
|
||||
t0 = tcg_temp_new(TCG_TYPE_TL);
|
||||
dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
|
||||
cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
|
||||
tcg_temp_free(t0);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Sign extension. From size to dword. */
|
||||
static unsigned int dec_movs_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t0;
|
||||
int size = memsize_z(dc);
|
||||
DIS(fprintf (logfile, "movs.%c $r%u, $r%u\n",
|
||||
memsize_char(size),
|
||||
dc->op1, dc->op2));
|
||||
|
||||
cris_cc_mask(dc, CC_MASK_NZ);
|
||||
t0 = tcg_temp_new(TCG_TYPE_TL);
|
||||
/* 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,
|
||||
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;
|
||||
}
|
||||
|
||||
/* zero extension. From size to dword. */
|
||||
static unsigned int dec_addu_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t0;
|
||||
int size = memsize_z(dc);
|
||||
DIS(fprintf (logfile, "addu.%c $r%u, $r%u\n",
|
||||
memsize_char(size),
|
||||
dc->op1, dc->op2));
|
||||
|
||||
cris_cc_mask(dc, CC_MASK_NZVC);
|
||||
t0 = tcg_temp_new(TCG_TYPE_TL);
|
||||
/* 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,
|
||||
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;
|
||||
}
|
||||
|
||||
/* Sign extension. From size to dword. */
|
||||
static unsigned int dec_adds_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t0;
|
||||
int size = memsize_z(dc);
|
||||
DIS(fprintf (logfile, "adds.%c $r%u, $r%u\n",
|
||||
memsize_char(size),
|
||||
dc->op1, dc->op2));
|
||||
|
||||
cris_cc_mask(dc, CC_MASK_NZVC);
|
||||
t0 = tcg_temp_new(TCG_TYPE_TL);
|
||||
/* 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,
|
||||
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;
|
||||
}
|
||||
|
||||
/* Zero extension. From size to dword. */
|
||||
static unsigned int dec_subu_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t0;
|
||||
int size = memsize_z(dc);
|
||||
DIS(fprintf (logfile, "subu.%c $r%u, $r%u\n",
|
||||
memsize_char(size),
|
||||
dc->op1, dc->op2));
|
||||
|
||||
cris_cc_mask(dc, CC_MASK_NZVC);
|
||||
t0 = tcg_temp_new(TCG_TYPE_TL);
|
||||
/* 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,
|
||||
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;
|
||||
}
|
||||
|
||||
/* Sign extension. From size to dword. */
|
||||
static unsigned int dec_subs_r(DisasContext *dc)
|
||||
{
|
||||
TCGv t0;
|
||||
int size = memsize_z(dc);
|
||||
DIS(fprintf (logfile, "subs.%c $r%u, $r%u\n",
|
||||
memsize_char(size),
|
||||
dc->op1, dc->op2));
|
||||
|
||||
cris_cc_mask(dc, CC_MASK_NZVC);
|
||||
t0 = tcg_temp_new(TCG_TYPE_TL);
|
||||
/* 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,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -2055,6 +2124,7 @@ static unsigned int dec_setclrf(DisasContext *dc)
|
||||
uint32_t flags;
|
||||
int set = (~dc->opcode >> 2) & 1;
|
||||
|
||||
|
||||
flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
|
||||
| EXTRACT_FIELD(dc->ir, 0, 3);
|
||||
if (set && flags == 0) {
|
||||
@ -2069,7 +2139,7 @@ static unsigned int dec_setclrf(DisasContext *dc)
|
||||
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) {
|
||||
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)
|
||||
{
|
||||
TCGv t[2];
|
||||
DIS(fprintf (logfile, "move $r%u, $p%u\n", dc->op1, dc->op2));
|
||||
cris_cc_mask(dc, 0);
|
||||
|
||||
t[0] = tcg_temp_new(TCG_TYPE_TL);
|
||||
if (dc->op2 == PR_CCS) {
|
||||
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) {
|
||||
t[1] = tcg_temp_new(TCG_TYPE_TL);
|
||||
/* User space is not allowed to touch all flags. */
|
||||
tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x39f);
|
||||
tcg_gen_andi_tl(cpu_T[1], cpu_PR[PR_CCS], ~0x39f);
|
||||
tcg_gen_or_tl(cpu_T[0], cpu_T[1], cpu_T[0]);
|
||||
tcg_gen_andi_tl(t[0], t[0], 0x39f);
|
||||
tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
|
||||
tcg_gen_or_tl(t[0], t[1], t[0]);
|
||||
tcg_temp_free(t[1]);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
cris_update_cc_op(dc, CC_OP_FLAGS, 4);
|
||||
dc->flags_uptodate = 1;
|
||||
}
|
||||
tcg_temp_free(t[0]);
|
||||
return 2;
|
||||
}
|
||||
static unsigned int dec_move_pr(DisasContext *dc)
|
||||
{
|
||||
TCGv t0;
|
||||
DIS(fprintf (logfile, "move $p%u, $r%u\n", dc->op1, dc->op2));
|
||||
cris_cc_mask(dc, 0);
|
||||
|
||||
if (dc->op2 == PR_CCS)
|
||||
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,
|
||||
cpu_R[dc->op1], cpu_R[dc->op1], cpu_T[1],
|
||||
preg_sizes[dc->op2]);
|
||||
cpu_R[dc->op1], cpu_R[dc->op1], t0, preg_sizes[dc->op2]);
|
||||
tcg_temp_free(t0);
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -2193,10 +2270,14 @@ static unsigned int dec_move_mr(DisasContext *dc)
|
||||
cris_update_result(dc, cpu_R[dc->op2]);
|
||||
}
|
||||
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_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);
|
||||
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)
|
||||
{
|
||||
/* Ignore D-cache flushes. */
|
||||
return 2;
|
||||
}
|
||||
|
||||
static unsigned int dec_ftag_fidx_i_m(DisasContext *dc)
|
||||
{
|
||||
/* Ignore I-cache flushes. */
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -3207,7 +3286,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
|
||||
delay slots dont break. */
|
||||
if (!(tb->pc & 1) && env->singlestep_enabled)
|
||||
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)
|
||||
&& num_insns < max_insns);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user