mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-09-06 18:05:37 +00:00
target/microblaze: Convert dec_bcc to decodetree
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
16bbbbc91a
commit
fd77911304
|
@ -20,8 +20,10 @@
|
|||
&typea0 rd ra
|
||||
&typea rd ra rb
|
||||
&typea_br rd rb
|
||||
&typea_bc ra rb
|
||||
&typeb rd ra imm
|
||||
&typeb_br rd imm
|
||||
&typeb_bc ra imm
|
||||
|
||||
# Include any IMM prefix in the value reported.
|
||||
%extimm 0:s16 !function=typeb_imm
|
||||
|
@ -35,12 +37,18 @@
|
|||
# Officially typea, but with ra as opcode.
|
||||
@typea_br ...... rd:5 ..... rb:5 ........... &typea_br
|
||||
|
||||
# Officially typea, but with rd as opcode.
|
||||
@typea_bc ...... ..... ra:5 rb:5 ........... &typea_bc
|
||||
|
||||
# Officially typeb, but any immediate extension is unused.
|
||||
@typeb_bs ...... rd:5 ra:5 ..... ...... imm:5 &typeb
|
||||
|
||||
# Officially typeb, but with ra as opcode.
|
||||
@typeb_br ...... rd:5 ..... ................ &typeb_br imm=%extimm
|
||||
|
||||
# Officially typeb, but with rd as opcode.
|
||||
@typeb_bc ...... ..... ra:5 ................ &typeb_bc imm=%extimm
|
||||
|
||||
# For convenience, extract the two imm_w/imm_s fields, then pack
|
||||
# them back together as "imm". Doing this makes it easiest to
|
||||
# match the required zero at bit 5.
|
||||
|
@ -68,6 +76,34 @@ andi 101001 ..... ..... ................ @typeb
|
|||
andn 100011 ..... ..... ..... 000 0000 0000 @typea
|
||||
andni 101011 ..... ..... ................ @typeb
|
||||
|
||||
beq 100111 00000 ..... ..... 000 0000 0000 @typea_bc
|
||||
bge 100111 00101 ..... ..... 000 0000 0000 @typea_bc
|
||||
bgt 100111 00100 ..... ..... 000 0000 0000 @typea_bc
|
||||
ble 100111 00011 ..... ..... 000 0000 0000 @typea_bc
|
||||
blt 100111 00010 ..... ..... 000 0000 0000 @typea_bc
|
||||
bne 100111 00001 ..... ..... 000 0000 0000 @typea_bc
|
||||
|
||||
beqd 100111 10000 ..... ..... 000 0000 0000 @typea_bc
|
||||
bged 100111 10101 ..... ..... 000 0000 0000 @typea_bc
|
||||
bgtd 100111 10100 ..... ..... 000 0000 0000 @typea_bc
|
||||
bled 100111 10011 ..... ..... 000 0000 0000 @typea_bc
|
||||
bltd 100111 10010 ..... ..... 000 0000 0000 @typea_bc
|
||||
bned 100111 10001 ..... ..... 000 0000 0000 @typea_bc
|
||||
|
||||
beqi 101111 00000 ..... ................ @typeb_bc
|
||||
bgei 101111 00101 ..... ................ @typeb_bc
|
||||
bgti 101111 00100 ..... ................ @typeb_bc
|
||||
blei 101111 00011 ..... ................ @typeb_bc
|
||||
blti 101111 00010 ..... ................ @typeb_bc
|
||||
bnei 101111 00001 ..... ................ @typeb_bc
|
||||
|
||||
beqid 101111 10000 ..... ................ @typeb_bc
|
||||
bgeid 101111 10101 ..... ................ @typeb_bc
|
||||
bgtid 101111 10100 ..... ................ @typeb_bc
|
||||
bleid 101111 10011 ..... ................ @typeb_bc
|
||||
bltid 101111 10010 ..... ................ @typeb_bc
|
||||
bneid 101111 10001 ..... ................ @typeb_bc
|
||||
|
||||
br 100110 ..... 00000 ..... 000 0000 0000 @typea_br
|
||||
bra 100110 ..... 01000 ..... 000 0000 0000 @typea_br
|
||||
brd 100110 ..... 10000 ..... 000 0000 0000 @typea_br
|
||||
|
|
|
@ -1095,6 +1095,58 @@ DO_BR(brad, braid, true, true, false)
|
|||
DO_BR(brld, brlid, true, false, true)
|
||||
DO_BR(brald, bralid, true, true, true)
|
||||
|
||||
static bool do_bcc(DisasContext *dc, int dest_rb, int dest_imm,
|
||||
TCGCond cond, int ra, bool delay)
|
||||
{
|
||||
TCGv_i32 zero, next;
|
||||
|
||||
if (delay) {
|
||||
setup_dslot(dc, dest_rb < 0);
|
||||
}
|
||||
|
||||
dc->jmp_cond = cond;
|
||||
|
||||
/* Cache the condition register in cpu_bvalue across any delay slot. */
|
||||
tcg_gen_mov_i32(cpu_bvalue, reg_for_read(dc, ra));
|
||||
|
||||
/* Store the branch taken destination into btarget. */
|
||||
if (dest_rb > 0) {
|
||||
dc->jmp_dest = -1;
|
||||
tcg_gen_addi_i32(cpu_btarget, cpu_R[dest_rb], dc->base.pc_next);
|
||||
} else {
|
||||
dc->jmp_dest = dc->base.pc_next + dest_imm;
|
||||
tcg_gen_movi_i32(cpu_btarget, dc->jmp_dest);
|
||||
}
|
||||
|
||||
/* Compute the final destination into btarget. */
|
||||
zero = tcg_const_i32(0);
|
||||
next = tcg_const_i32(dc->base.pc_next + (delay + 1) * 4);
|
||||
tcg_gen_movcond_i32(dc->jmp_cond, cpu_btarget,
|
||||
reg_for_read(dc, ra), zero,
|
||||
cpu_btarget, next);
|
||||
tcg_temp_free_i32(zero);
|
||||
tcg_temp_free_i32(next);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define DO_BCC(NAME, COND) \
|
||||
static bool trans_##NAME(DisasContext *dc, arg_typea_bc *arg) \
|
||||
{ return do_bcc(dc, arg->rb, 0, COND, arg->ra, false); } \
|
||||
static bool trans_##NAME##d(DisasContext *dc, arg_typea_bc *arg) \
|
||||
{ return do_bcc(dc, arg->rb, 0, COND, arg->ra, true); } \
|
||||
static bool trans_##NAME##i(DisasContext *dc, arg_typeb_bc *arg) \
|
||||
{ return do_bcc(dc, -1, arg->imm, COND, arg->ra, false); } \
|
||||
static bool trans_##NAME##id(DisasContext *dc, arg_typeb_bc *arg) \
|
||||
{ return do_bcc(dc, -1, arg->imm, COND, arg->ra, true); }
|
||||
|
||||
DO_BCC(beq, TCG_COND_EQ)
|
||||
DO_BCC(bge, TCG_COND_GE)
|
||||
DO_BCC(bgt, TCG_COND_GT)
|
||||
DO_BCC(ble, TCG_COND_LE)
|
||||
DO_BCC(blt, TCG_COND_LT)
|
||||
DO_BCC(bne, TCG_COND_NE)
|
||||
|
||||
static bool trans_brk(DisasContext *dc, arg_typea_br *arg)
|
||||
{
|
||||
if (trap_userspace(dc, true)) {
|
||||
|
@ -1419,52 +1471,6 @@ static void dec_msr(DisasContext *dc)
|
|||
}
|
||||
}
|
||||
|
||||
static void dec_bcc(DisasContext *dc)
|
||||
{
|
||||
static const TCGCond mb_to_tcg_cc[] = {
|
||||
[CC_EQ] = TCG_COND_EQ,
|
||||
[CC_NE] = TCG_COND_NE,
|
||||
[CC_LT] = TCG_COND_LT,
|
||||
[CC_LE] = TCG_COND_LE,
|
||||
[CC_GE] = TCG_COND_GE,
|
||||
[CC_GT] = TCG_COND_GT,
|
||||
};
|
||||
unsigned int cc;
|
||||
unsigned int dslot;
|
||||
TCGv_i32 zero, next;
|
||||
|
||||
cc = EXTRACT_FIELD(dc->ir, 21, 23);
|
||||
dslot = dc->ir & (1 << 25);
|
||||
|
||||
if (dslot) {
|
||||
setup_dslot(dc, dc->type_b);
|
||||
}
|
||||
|
||||
dc->jmp_cond = mb_to_tcg_cc[cc];
|
||||
|
||||
/* Cache the condition register in cpu_bvalue across any delay slot. */
|
||||
tcg_gen_mov_i32(cpu_bvalue, cpu_R[dc->ra]);
|
||||
|
||||
/* Store the branch taken destination into btarget. */
|
||||
if (dc->type_b) {
|
||||
dc->jmp_dest = dc->base.pc_next + dec_alu_typeb_imm(dc);
|
||||
tcg_gen_movi_i32(cpu_btarget, dc->jmp_dest);
|
||||
} else {
|
||||
dc->jmp_dest = -1;
|
||||
tcg_gen_addi_i32(cpu_btarget, reg_for_read(dc, dc->rb),
|
||||
dc->base.pc_next);
|
||||
}
|
||||
|
||||
/* Compute the final destination into btarget. */
|
||||
zero = tcg_const_i32(0);
|
||||
next = tcg_const_i32(dc->base.pc_next + (dslot + 1) * 4);
|
||||
tcg_gen_movcond_i32(dc->jmp_cond, cpu_btarget,
|
||||
reg_for_read(dc, dc->ra), zero,
|
||||
cpu_btarget, next);
|
||||
tcg_temp_free_i32(zero);
|
||||
tcg_temp_free_i32(next);
|
||||
}
|
||||
|
||||
static inline void do_rti(DisasContext *dc)
|
||||
{
|
||||
TCGv_i32 t0, t1;
|
||||
|
@ -1595,7 +1601,6 @@ static struct decoder_info {
|
|||
};
|
||||
void (*dec)(DisasContext *dc);
|
||||
} decinfo[] = {
|
||||
{DEC_BCC, dec_bcc},
|
||||
{DEC_RTS, dec_rts},
|
||||
{DEC_MSR, dec_msr},
|
||||
{DEC_STREAM, dec_stream},
|
||||
|
|
Loading…
Reference in a new issue