diff options
Diffstat (limited to 'target-microblaze/translate.c')
-rw-r--r-- | target-microblaze/translate.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index 6f4eef1a69..bff3a11bc8 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -1476,6 +1476,42 @@ static void dec_null(DisasContext *dc) dc->abort_at_next_insn = 1; } +/* Insns connected to FSL or AXI stream attached devices. */ +static void dec_stream(DisasContext *dc) +{ + int mem_index = cpu_mmu_index(dc->env); + TCGv_i32 t_id, t_ctrl; + int ctrl; + + LOG_DIS("%s%s imm=%x\n", dc->rd ? "get" : "put", + dc->type_b ? "" : "d", dc->imm); + + if ((dc->tb_flags & MSR_EE_FLAG) && (mem_index == MMU_USER_IDX)) { + tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN); + t_gen_raise_exception(dc, EXCP_HW_EXCP); + return; + } + + t_id = tcg_temp_new(); + if (dc->type_b) { + tcg_gen_movi_tl(t_id, dc->imm & 0xf); + ctrl = dc->imm >> 10; + } else { + tcg_gen_andi_tl(t_id, cpu_R[dc->rb], 0xf); + ctrl = dc->imm >> 5; + } + + t_ctrl = tcg_const_tl(ctrl); + + if (dc->rd == 0) { + gen_helper_put(t_id, t_ctrl, cpu_R[dc->ra]); + } else { + gen_helper_get(cpu_R[dc->rd], t_id, t_ctrl); + } + tcg_temp_free(t_id); + tcg_temp_free(t_ctrl); +} + static struct decoder_info { struct { uint32_t bits; @@ -1500,6 +1536,7 @@ static struct decoder_info { {DEC_MUL, dec_mul}, {DEC_DIV, dec_div}, {DEC_MSR, dec_msr}, + {DEC_STREAM, dec_stream}, {{0, 0}, dec_null} }; |