Skip to content

Commit

Permalink
target/sparc: Move SLL, SRL, SRA to decodetree
Browse files Browse the repository at this point in the history
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed Oct 25, 2023
1 parent a9aba13 commit 5fc546e
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 104 deletions.
14 changes: 14 additions & 0 deletions target/sparc/insns.decode
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,20 @@ TSUBcc 10 ..... 100001 ..... . ............. @r_r_ri_cc1
TADDccTV 10 ..... 100010 ..... . ............. @r_r_ri_cc1
TSUBccTV 10 ..... 100011 ..... . ............. @r_r_ri_cc1

&shiftr rd rs1 rs2 x:bool
@shiftr .. rd:5 ...... rs1:5 . x:1 ....... rs2:5 &shiftr

SLL_r 10 ..... 100101 ..... 0 . 0000000 ..... @shiftr
SRL_r 10 ..... 100110 ..... 0 . 0000000 ..... @shiftr
SRA_r 10 ..... 100111 ..... 0 . 0000000 ..... @shiftr

&shifti rd rs1 i x:bool
@shifti .. rd:5 ...... rs1:5 . x:1 ...... i:6 &shifti

SLL_i 10 ..... 100101 ..... 1 . 000000 ...... @shifti
SRL_i 10 ..... 100110 ..... 1 . 000000 ...... @shifti
SRA_i 10 ..... 100111 ..... 1 . 000000 ...... @shifti

Tcc_r 10 0 cond:4 111010 rs1:5 0 cc:1 0000000 rs2:5
{
# For v7, the entire simm13 field is present, but masked to 7 bits.
Expand Down
182 changes: 78 additions & 104 deletions target/sparc/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -4247,6 +4247,83 @@ static bool trans_MULScc(DisasContext *dc, arg_r_r_ri_cc *a)
return do_arith(dc, a, CC_OP_ADD, NULL, NULL, gen_op_mulscc);
}

static bool do_shift_r(DisasContext *dc, arg_shiftr *a, bool l, bool u)
{
TCGv dst, src1, src2;

/* Reject 64-bit shifts for sparc32. */
if (avail_32(dc) && a->x) {
return false;
}

src2 = tcg_temp_new();
tcg_gen_andi_tl(src2, gen_load_gpr(dc, a->rs2), a->x ? 63 : 31);
src1 = gen_load_gpr(dc, a->rs1);
dst = gen_dest_gpr(dc, a->rd);

if (l) {
tcg_gen_shl_tl(dst, src1, src2);
if (!a->x) {
tcg_gen_ext32u_tl(dst, dst);
}
} else if (u) {
if (!a->x) {
tcg_gen_ext32u_tl(dst, src1);
src1 = dst;
}
tcg_gen_shr_tl(dst, src1, src2);
} else {
if (!a->x) {
tcg_gen_ext32s_tl(dst, src1);
src1 = dst;
}
tcg_gen_sar_tl(dst, src1, src2);
}
gen_store_gpr(dc, a->rd, dst);
return advance_pc(dc);
}

TRANS(SLL_r, ALL, do_shift_r, a, true, true)
TRANS(SRL_r, ALL, do_shift_r, a, false, true)
TRANS(SRA_r, ALL, do_shift_r, a, false, false)

static bool do_shift_i(DisasContext *dc, arg_shifti *a, bool l, bool u)
{
TCGv dst, src1;

/* Reject 64-bit shifts for sparc32. */
if (avail_32(dc) && (a->x || a->i >= 32)) {
return false;
}

src1 = gen_load_gpr(dc, a->rs1);
dst = gen_dest_gpr(dc, a->rd);

if (avail_32(dc) || a->x) {
if (l) {
tcg_gen_shli_tl(dst, src1, a->i);
} else if (u) {
tcg_gen_shri_tl(dst, src1, a->i);
} else {
tcg_gen_sari_tl(dst, src1, a->i);
}
} else {
if (l) {
tcg_gen_deposit_z_tl(dst, src1, a->i, 32 - a->i);
} else if (u) {
tcg_gen_extract_tl(dst, src1, a->i, 32 - a->i);
} else {
tcg_gen_sextract_tl(dst, src1, a->i, 32 - a->i);
}
}
gen_store_gpr(dc, a->rd, dst);
return advance_pc(dc);
}

TRANS(SLL_i, ALL, do_shift_i, a, true, true)
TRANS(SRL_i, ALL, do_shift_i, a, false, true)
TRANS(SRA_i, ALL, do_shift_i, a, false, false)

#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
Expand Down Expand Up @@ -4595,77 +4672,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
default:
goto illegal_insn;
}
#ifdef TARGET_SPARC64
} else if (xop == 0x25) { /* sll, V9 sllx */
cpu_src1 = get_src1(dc, insn);
if (IS_IMM) { /* immediate */
simm = GET_FIELDs(insn, 20, 31);
if (insn & (1 << 12)) {
tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x3f);
} else {
tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x1f);
}
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
cpu_src2 = gen_load_gpr(dc, rs2);
cpu_tmp0 = tcg_temp_new();
if (insn & (1 << 12)) {
tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
} else {
tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
}
tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
}
gen_store_gpr(dc, rd, cpu_dst);
} else if (xop == 0x26) { /* srl, V9 srlx */
cpu_src1 = get_src1(dc, insn);
if (IS_IMM) { /* immediate */
simm = GET_FIELDs(insn, 20, 31);
if (insn & (1 << 12)) {
tcg_gen_shri_i64(cpu_dst, cpu_src1, simm & 0x3f);
} else {
tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
tcg_gen_shri_i64(cpu_dst, cpu_dst, simm & 0x1f);
}
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
cpu_src2 = gen_load_gpr(dc, rs2);
cpu_tmp0 = tcg_temp_new();
if (insn & (1 << 12)) {
tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
} else {
tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
}
}
gen_store_gpr(dc, rd, cpu_dst);
} else if (xop == 0x27) { /* sra, V9 srax */
cpu_src1 = get_src1(dc, insn);
if (IS_IMM) { /* immediate */
simm = GET_FIELDs(insn, 20, 31);
if (insn & (1 << 12)) {
tcg_gen_sari_i64(cpu_dst, cpu_src1, simm & 0x3f);
} else {
tcg_gen_ext32s_i64(cpu_dst, cpu_src1);
tcg_gen_sari_i64(cpu_dst, cpu_dst, simm & 0x1f);
}
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
cpu_src2 = gen_load_gpr(dc, rs2);
cpu_tmp0 = tcg_temp_new();
if (insn & (1 << 12)) {
tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
} else {
tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
tcg_gen_ext32s_i64(cpu_dst, cpu_src1);
tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
}
}
gen_store_gpr(dc, rd, cpu_dst);
#endif
} else if (xop < 0x36) {
if (xop < 0x20) {
goto illegal_insn;
Expand All @@ -4678,42 +4684,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
case 0x22: /* taddcctv */
case 0x23: /* tsubcctv */
case 0x24: /* mulscc */
goto illegal_insn; /* in decodetree */
#ifndef TARGET_SPARC64
case 0x25: /* sll */
if (IS_IMM) { /* immediate */
simm = GET_FIELDs(insn, 20, 31);
tcg_gen_shli_tl(cpu_dst, cpu_src1, simm & 0x1f);
} else { /* register */
cpu_tmp0 = tcg_temp_new();
tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
}
gen_store_gpr(dc, rd, cpu_dst);
break;
case 0x26: /* srl */
if (IS_IMM) { /* immediate */
simm = GET_FIELDs(insn, 20, 31);
tcg_gen_shri_tl(cpu_dst, cpu_src1, simm & 0x1f);
} else { /* register */
cpu_tmp0 = tcg_temp_new();
tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
}
gen_store_gpr(dc, rd, cpu_dst);
break;
case 0x27: /* sra */
if (IS_IMM) { /* immediate */
simm = GET_FIELDs(insn, 20, 31);
tcg_gen_sari_tl(cpu_dst, cpu_src1, simm & 0x1f);
} else { /* register */
cpu_tmp0 = tcg_temp_new();
tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
}
gen_store_gpr(dc, rd, cpu_dst);
break;
#endif
goto illegal_insn; /* in decodetree */
case 0x30:
goto illegal_insn; /* WRASR in decodetree */
case 0x32:
Expand Down

0 comments on commit 5fc546e

Please sign in to comment.