@@ -30,6 +30,15 @@
# Officially typea, but with rb==0, which is not used.
@typea0 ...... rd:5 ra:5 ................ &typea0
+# Officially typeb, but any immediate extension is unused.
+@typeb_bs ...... rd:5 ra:5 ..... ...... imm:5 &typeb
+
+# 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.
+%ieimm 6:5 0:5
+@typeb_ie ...... rd:5 ra:5 ..... ..... . ..... &typeb imm=%ieimm
+
###
add 000000 ..... ..... ..... 000 0000 0000 @typea
@@ -48,6 +57,17 @@ andi 101001 ..... ..... ................ @typeb
andn 100011 ..... ..... ..... 000 0000 0000 @typea
andni 101011 ..... ..... ................ @typeb
+bsrl 010001 ..... ..... ..... 000 0000 0000 @typea
+bsra 010001 ..... ..... ..... 010 0000 0000 @typea
+bsll 010001 ..... ..... ..... 100 0000 0000 @typea
+
+bsrli 011001 ..... ..... 00000 000000 ..... @typeb_bs
+bsrai 011001 ..... ..... 00000 010000 ..... @typeb_bs
+bslli 011001 ..... ..... 00000 100000 ..... @typeb_bs
+
+bsefi 011001 ..... ..... 01000 .....0 ..... @typeb_ie
+bsifi 011001 ..... ..... 10000 .....0 ..... @typeb_ie
+
clz 100100 ..... ..... 00000 000 1110 0000 @typea0
cmp 000101 ..... ..... ..... 000 0000 0001 @typea
@@ -368,6 +368,72 @@ DO_TYPEBI(andi, false, tcg_gen_andi_i32)
DO_TYPEA(andn, false, tcg_gen_andc_i32)
DO_TYPEBI(andni, false, gen_andni)
+static void gen_bsra(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_andi_i32(tmp, inb, 31);
+ tcg_gen_sar_i32(out, ina, tmp);
+ tcg_temp_free_i32(tmp);
+}
+
+static void gen_bsrl(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_andi_i32(tmp, inb, 31);
+ tcg_gen_shr_i32(out, ina, tmp);
+ tcg_temp_free_i32(tmp);
+}
+
+static void gen_bsll(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
+{
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_andi_i32(tmp, inb, 31);
+ tcg_gen_shl_i32(out, ina, tmp);
+ tcg_temp_free_i32(tmp);
+}
+
+static void gen_bsefi(TCGv_i32 out, TCGv_i32 ina, int32_t imm)
+{
+ /* Note that decodetree has extracted and reassembled imm_w/imm_s. */
+ int imm_w = extract32(imm, 5, 5);
+ int imm_s = extract32(imm, 0, 5);
+
+ if (imm_w + imm_s > 32 || imm_w == 0) {
+ /* These inputs have an undefined behavior. */
+ qemu_log_mask(LOG_GUEST_ERROR, "bsefi: Bad input w=%d s=%d\n",
+ imm_w, imm_s);
+ } else {
+ tcg_gen_extract_i32(out, ina, imm_s, imm_w);
+ }
+}
+
+static void gen_bsifi(TCGv_i32 out, TCGv_i32 ina, int32_t imm)
+{
+ /* Note that decodetree has extracted and reassembled imm_w/imm_s. */
+ int imm_w = extract32(imm, 5, 5);
+ int imm_s = extract32(imm, 0, 5);
+ int width = imm_w - imm_s + 1;
+
+ if (imm_w < imm_s) {
+ /* These inputs have an undefined behavior. */
+ qemu_log_mask(LOG_GUEST_ERROR, "bsifi: Bad input w=%d s=%d\n",
+ imm_w, imm_s);
+ } else {
+ tcg_gen_deposit_i32(out, out, ina, imm_s, width);
+ }
+}
+
+DO_TYPEA_CFG(bsra, use_barrel, false, gen_bsra)
+DO_TYPEA_CFG(bsrl, use_barrel, false, gen_bsrl)
+DO_TYPEA_CFG(bsll, use_barrel, false, gen_bsll)
+
+DO_TYPEBI_CFG(bsrai, use_barrel, false, tcg_gen_sari_i32)
+DO_TYPEBI_CFG(bsrli, use_barrel, false, tcg_gen_shri_i32)
+DO_TYPEBI_CFG(bslli, use_barrel, false, tcg_gen_shli_i32)
+
+DO_TYPEBI_CFG(bsefi, use_barrel, false, gen_bsefi)
+DO_TYPEBI_CFG(bsifi, use_barrel, false, gen_bsifi)
+
static void gen_clz(TCGv_i32 out, TCGv_i32 ina)
{
tcg_gen_clzi_i32(out, ina, 32);
@@ -757,64 +823,6 @@ static void dec_msr(DisasContext *dc)
}
}
-static void dec_barrel(DisasContext *dc)
-{
- TCGv_i32 t0;
- unsigned int imm_w, imm_s;
- bool s, t, e = false, i = false;
-
- if (trap_illegal(dc, !dc->cpu->cfg.use_barrel)) {
- return;
- }
-
- if (dc->type_b) {
- /* Insert and extract are only available in immediate mode. */
- i = extract32(dc->imm, 15, 1);
- e = extract32(dc->imm, 14, 1);
- }
- s = extract32(dc->imm, 10, 1);
- t = extract32(dc->imm, 9, 1);
- imm_w = extract32(dc->imm, 6, 5);
- imm_s = extract32(dc->imm, 0, 5);
-
- if (e) {
- if (imm_w + imm_s > 32 || imm_w == 0) {
- /* These inputs have an undefined behavior. */
- qemu_log_mask(LOG_GUEST_ERROR, "bsefi: Bad input w=%d s=%d\n",
- imm_w, imm_s);
- } else {
- tcg_gen_extract_i32(cpu_R[dc->rd], cpu_R[dc->ra], imm_s, imm_w);
- }
- } else if (i) {
- int width = imm_w - imm_s + 1;
-
- if (imm_w < imm_s) {
- /* These inputs have an undefined behavior. */
- qemu_log_mask(LOG_GUEST_ERROR, "bsifi: Bad input w=%d s=%d\n",
- imm_w, imm_s);
- } else {
- tcg_gen_deposit_i32(cpu_R[dc->rd], cpu_R[dc->rd], cpu_R[dc->ra],
- imm_s, width);
- }
- } else {
- t0 = tcg_temp_new_i32();
-
- tcg_gen_mov_i32(t0, *(dec_alu_op_b(dc)));
- tcg_gen_andi_i32(t0, t0, 31);
-
- if (s) {
- tcg_gen_shl_i32(cpu_R[dc->rd], cpu_R[dc->ra], t0);
- } else {
- if (t) {
- tcg_gen_sar_i32(cpu_R[dc->rd], cpu_R[dc->ra], t0);
- } else {
- tcg_gen_shr_i32(cpu_R[dc->rd], cpu_R[dc->ra], t0);
- }
- }
- tcg_temp_free_i32(t0);
- }
-}
-
static inline void sync_jmpstate(DisasContext *dc)
{
if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
@@ -1537,7 +1545,6 @@ static struct decoder_info {
};
void (*dec)(DisasContext *dc);
} decinfo[] = {
- {DEC_BARREL, dec_barrel},
{DEC_LD, dec_load},
{DEC_ST, dec_store},
{DEC_IMM, dec_imm},
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/microblaze/insns.decode | 20 ++++++ target/microblaze/translate.c | 125 +++++++++++++++++---------------- 2 files changed, 86 insertions(+), 59 deletions(-) -- 2.25.1