aboutsummaryrefslogtreecommitdiff
path: root/target/openrisc/translate.c
diff options
context:
space:
mode:
authorStafford Horne <shorne@gmail.com>2023-02-12 18:08:13 +0900
committerStafford Horne <shorne@gmail.com>2023-05-11 15:40:03 +0100
commit08f021de3af599b8ca4c745f324a3559dc2990d3 (patch)
tree3c1f6ddc6ff00d55512747a2ccd0313010bbbca9 /target/openrisc/translate.c
parentc1eb2ddf0f8075faddc5f7c3d39feae3e8e9d6b4 (diff)
target/openrisc: Allow fpcsr access in user mode
As per OpenRISC spec 1.4 FPCSR can be read and written in user mode. Update mtspr and mfspr helpers to support this by moving the is_user check into the helper. Link: https://raw.githubusercontent.com/openrisc/doc/master/openrisc-arch-1.4-rev0.pdf Signed-off-by: Stafford Horne <shorne@gmail.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/openrisc/translate.c')
-rw-r--r--target/openrisc/translate.c72
1 files changed, 32 insertions, 40 deletions
diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c
index 76e53c78d4..43ba0cc1ad 100644
--- a/target/openrisc/translate.c
+++ b/target/openrisc/translate.c
@@ -819,45 +819,12 @@ static bool trans_l_xori(DisasContext *dc, arg_rri *a)
static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a)
{
- check_r0_write(dc, a->d);
-
- if (is_user(dc)) {
- gen_illegal_exception(dc);
- } else {
- TCGv spr = tcg_temp_new();
-
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
- gen_io_start();
- if (dc->delayed_branch) {
- tcg_gen_mov_tl(cpu_pc, jmp_pc);
- tcg_gen_discard_tl(jmp_pc);
- } else {
- tcg_gen_movi_tl(cpu_pc, dc->base.pc_next + 4);
- }
- dc->base.is_jmp = DISAS_EXIT;
- }
+ TCGv spr = tcg_temp_new();
- tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
- gen_helper_mfspr(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->d), spr);
- }
- return true;
-}
-
-static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a)
-{
- if (is_user(dc)) {
- gen_illegal_exception(dc);
- } else {
- TCGv spr;
+ check_r0_write(dc, a->d);
- if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
- gen_io_start();
- }
- /* For SR, we will need to exit the TB to recognize the new
- * exception state. For NPC, in theory this counts as a branch
- * (although the SPR only exists for use by an ICE). Save all
- * of the cpu state first, allowing it to be overwritten.
- */
+ if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
+ gen_io_start();
if (dc->delayed_branch) {
tcg_gen_mov_tl(cpu_pc, jmp_pc);
tcg_gen_discard_tl(jmp_pc);
@@ -865,11 +832,36 @@ static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a)
tcg_gen_movi_tl(cpu_pc, dc->base.pc_next + 4);
}
dc->base.is_jmp = DISAS_EXIT;
+ }
+
+ tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
+ gen_helper_mfspr(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->d), spr);
+ return true;
+}
+
+static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a)
+{
+ TCGv spr = tcg_temp_new();
- spr = tcg_temp_new();
- tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
- gen_helper_mtspr(cpu_env, spr, cpu_R(dc, a->b));
+ if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
+ gen_io_start();
}
+ /*
+ * For SR, we will need to exit the TB to recognize the new
+ * exception state. For NPC, in theory this counts as a branch
+ * (although the SPR only exists for use by an ICE). Save all
+ * of the cpu state first, allowing it to be overwritten.
+ */
+ if (dc->delayed_branch) {
+ tcg_gen_mov_tl(cpu_pc, jmp_pc);
+ tcg_gen_discard_tl(jmp_pc);
+ } else {
+ tcg_gen_movi_tl(cpu_pc, dc->base.pc_next + 4);
+ }
+ dc->base.is_jmp = DISAS_EXIT;
+
+ tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
+ gen_helper_mtspr(cpu_env, spr, cpu_R(dc, a->b));
return true;
}