qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Max Filippov <jcmvbkbc@gmail.com>
To: qemu-devel@nongnu.org
Cc: Blue Swirl <blauwirbel@gmail.com>, Max Filippov <jcmvbkbc@gmail.com>
Subject: [Qemu-devel] [PATCH 9/9] target-xtensa: implement coprocessor context option
Date: Sun,  9 Sep 2012 05:29:58 +0400	[thread overview]
Message-ID: <1347154198-8629-10-git-send-email-jcmvbkbc@gmail.com> (raw)
In-Reply-To: <1347154198-8629-1-git-send-email-jcmvbkbc@gmail.com>

In case Coprocessor Context option is enabled CPENABLE SR bits control
whether access to coprocessors is allowed or would rise one of
CoprocessorXDisabled exceptions.

See ISA, 4.4.5 for more details.

FP is coprocessor 0.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
 target-xtensa/cpu.h       |    5 +++++
 target-xtensa/translate.c |   37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index b456283..7348277 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -468,6 +468,8 @@ static inline int cpu_mmu_index(CPUXtensaState *env)
 #define XTENSA_TBFLAG_LITBASE 0x8
 #define XTENSA_TBFLAG_DEBUG 0x10
 #define XTENSA_TBFLAG_ICOUNT 0x20
+#define XTENSA_TBFLAG_CPENABLE_MASK 0x3fc0
+#define XTENSA_TBFLAG_CPENABLE_SHIFT 6
 
 static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
         target_ulong *cs_base, int *flags)
@@ -491,6 +493,9 @@ static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
             *flags |= XTENSA_TBFLAG_ICOUNT;
         }
     }
+    if (xtensa_option_enabled(env->config, XTENSA_OPTION_COPROCESSOR)) {
+        *flags |= env->sregs[CPENABLE] << XTENSA_TBFLAG_CPENABLE_SHIFT;
+    }
 }
 
 #include "cpu-all.h"
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index d361f7f..5172194 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -65,6 +65,8 @@ typedef struct DisasContext {
     bool debug;
     bool icount;
     TCGv_i32 next_icount;
+
+    unsigned cpenable;
 } DisasContext;
 
 static TCGv_ptr cpu_env;
@@ -331,6 +333,15 @@ static void gen_check_privilege(DisasContext *dc)
     }
 }
 
+static void gen_check_cpenable(DisasContext *dc, unsigned cp)
+{
+    if (option_enabled(dc, XTENSA_OPTION_COPROCESSOR) &&
+            !(dc->cpenable & (1 << cp))) {
+        gen_exception_cause(dc, COPROCESSOR0_DISABLED + cp);
+        dc->is_jmp = DISAS_UPDATE;
+    }
+}
+
 static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
 {
     tcg_gen_mov_i32(cpu_pc, dest);
@@ -579,6 +590,12 @@ static void gen_wsr_dbreakc(DisasContext *dc, uint32_t sr, TCGv_i32 v)
     }
 }
 
+static void gen_wsr_cpenable(DisasContext *dc, uint32_t sr, TCGv_i32 v)
+{
+    tcg_gen_andi_i32(cpu_SR[sr], v, 0xff);
+    gen_jumpi_check_loop_end(dc, 0);
+}
+
 static void gen_wsr_intset(DisasContext *dc, uint32_t sr, TCGv_i32 v)
 {
     tcg_gen_andi_i32(cpu_SR[sr], v,
@@ -681,6 +698,7 @@ static void gen_wsr(DisasContext *dc, uint32_t sr, TCGv_i32 s)
         [DBREAKA + 1] = gen_wsr_dbreaka,
         [DBREAKC] = gen_wsr_dbreakc,
         [DBREAKC + 1] = gen_wsr_dbreakc,
+        [CPENABLE] = gen_wsr_cpenable,
         [INTSET] = gen_wsr_intset,
         [INTCLEAR] = gen_wsr_intclear,
         [INTENABLE] = gen_wsr_intenable,
@@ -1832,6 +1850,7 @@ static void disas_xtensa_insn(DisasContext *dc)
             case 5: /*SSXUf*/
                 HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
                 gen_window_check2(dc, RRR_S, RRR_T);
+                gen_check_cpenable(dc, 0);
                 {
                     TCGv_i32 addr = tcg_temp_new_i32();
                     tcg_gen_add_i32(addr, cpu_R[RRR_S], cpu_R[RRR_T]);
@@ -1891,26 +1910,31 @@ static void disas_xtensa_insn(DisasContext *dc)
             HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
             switch (OP2) {
             case 0: /*ADD.S*/
+                gen_check_cpenable(dc, 0);
                 gen_helper_add_s(cpu_FR[RRR_R], cpu_env,
                         cpu_FR[RRR_S], cpu_FR[RRR_T]);
                 break;
 
             case 1: /*SUB.S*/
+                gen_check_cpenable(dc, 0);
                 gen_helper_sub_s(cpu_FR[RRR_R], cpu_env,
                         cpu_FR[RRR_S], cpu_FR[RRR_T]);
                 break;
 
             case 2: /*MUL.S*/
+                gen_check_cpenable(dc, 0);
                 gen_helper_mul_s(cpu_FR[RRR_R], cpu_env,
                         cpu_FR[RRR_S], cpu_FR[RRR_T]);
                 break;
 
             case 4: /*MADD.S*/
+                gen_check_cpenable(dc, 0);
                 gen_helper_madd_s(cpu_FR[RRR_R], cpu_env,
                         cpu_FR[RRR_R], cpu_FR[RRR_S], cpu_FR[RRR_T]);
                 break;
 
             case 5: /*MSUB.S*/
+                gen_check_cpenable(dc, 0);
                 gen_helper_msub_s(cpu_FR[RRR_R], cpu_env,
                         cpu_FR[RRR_R], cpu_FR[RRR_S], cpu_FR[RRR_T]);
                 break;
@@ -1921,6 +1945,7 @@ static void disas_xtensa_insn(DisasContext *dc)
             case 11: /*CEIL.Sf*/
             case 14: /*UTRUNC.Sf*/
                 gen_window_check1(dc, RRR_R);
+                gen_check_cpenable(dc, 0);
                 {
                     static const unsigned rounding_mode_const[] = {
                         float_round_nearest_even,
@@ -1949,6 +1974,7 @@ static void disas_xtensa_insn(DisasContext *dc)
             case 12: /*FLOAT.Sf*/
             case 13: /*UFLOAT.Sf*/
                 gen_window_check1(dc, RRR_S);
+                gen_check_cpenable(dc, 0);
                 {
                     TCGv_i32 scale = tcg_const_i32(1 << RRR_T);
 
@@ -1966,24 +1992,29 @@ static void disas_xtensa_insn(DisasContext *dc)
             case 15: /*FP1OP*/
                 switch (RRR_T) {
                 case 0: /*MOV.Sf*/
+                    gen_check_cpenable(dc, 0);
                     tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_FR[RRR_S]);
                     break;
 
                 case 1: /*ABS.Sf*/
+                    gen_check_cpenable(dc, 0);
                     gen_helper_abs_s(cpu_FR[RRR_R], cpu_FR[RRR_S]);
                     break;
 
                 case 4: /*RFRf*/
                     gen_window_check1(dc, RRR_R);
+                    gen_check_cpenable(dc, 0);
                     tcg_gen_mov_i32(cpu_R[RRR_R], cpu_FR[RRR_S]);
                     break;
 
                 case 5: /*WFRf*/
                     gen_window_check1(dc, RRR_S);
+                    gen_check_cpenable(dc, 0);
                     tcg_gen_mov_i32(cpu_FR[RRR_R], cpu_R[RRR_S]);
                     break;
 
                 case 6: /*NEG.Sf*/
+                    gen_check_cpenable(dc, 0);
                     gen_helper_neg_s(cpu_FR[RRR_R], cpu_FR[RRR_S]);
                     break;
 
@@ -2006,6 +2037,7 @@ static void disas_xtensa_insn(DisasContext *dc)
     do { \
         TCGv_i32 bit = tcg_const_i32(1 << br); \
         \
+        gen_check_cpenable(dc, 0); \
         gen_helper_##rel(cpu_env, bit, cpu_FR[a], cpu_FR[b]); \
         tcg_temp_free(bit); \
     } while (0)
@@ -2046,6 +2078,7 @@ static void disas_xtensa_insn(DisasContext *dc)
             case 10: /*MOVLTZ.Sf*/
             case 11: /*MOVGEZ.Sf*/
                 gen_window_check1(dc, RRR_T);
+                gen_check_cpenable(dc, 0);
                 {
                     static const TCGCond cond[] = {
                         TCG_COND_NE,
@@ -2063,6 +2096,7 @@ static void disas_xtensa_insn(DisasContext *dc)
             case 12: /*MOVF.Sf*/
             case 13: /*MOVT.Sf*/
                 HAS_OPTION(XTENSA_OPTION_BOOLEAN);
+                gen_check_cpenable(dc, 0);
                 {
                     int label = gen_new_label();
                     TCGv_i32 tmp = tcg_temp_new_i32();
@@ -2318,6 +2352,7 @@ static void disas_xtensa_insn(DisasContext *dc)
         case 12: /*SSIUf*/
             HAS_OPTION(XTENSA_OPTION_FP_COPROCESSOR);
             gen_window_check1(dc, RRI8_S);
+            gen_check_cpenable(dc, 0);
             {
                 TCGv_i32 addr = tcg_temp_new_i32();
                 tcg_gen_addi_i32(addr, cpu_R[RRI8_S], RRI8_IMM8 << 2);
@@ -2833,6 +2868,8 @@ static void gen_intermediate_code_internal(
     dc.ccount_delta = 0;
     dc.debug = tb->flags & XTENSA_TBFLAG_DEBUG;
     dc.icount = tb->flags & XTENSA_TBFLAG_ICOUNT;
+    dc.cpenable = (tb->flags & XTENSA_TBFLAG_CPENABLE_MASK) >>
+        XTENSA_TBFLAG_CPENABLE_SHIFT;
 
     init_litbase(&dc);
     init_sar_tracker(&dc);
-- 
1.7.7.6

      parent reply	other threads:[~2012-09-09  1:32 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-09  1:29 [Qemu-devel] [PATCH 0/9] target-xtensa: implement FP coprocessor option Max Filippov
2012-09-09  1:29 ` [Qemu-devel] [PATCH 1/9] softfloat: make float_muladd_negate_* flags independent Max Filippov
2012-09-09  9:24   ` Aurelien Jarno
2012-09-09  1:29 ` [Qemu-devel] [PATCH 2/9] target-xtensa: handle boolean option in overlays Max Filippov
2012-09-09  1:29 ` [Qemu-devel] [PATCH 3/9] target-xtensa: specialize softfloat NaN rules Max Filippov
2012-09-09  9:31   ` Peter Maydell
2012-09-09 12:13     ` Max Filippov
2012-09-09 15:14       ` Max Filippov
2012-09-09 15:44         ` Peter Maydell
2012-09-09  1:29 ` [Qemu-devel] [PATCH 4/9] target-xtensa: add FP registers Max Filippov
2012-09-09  1:29 ` [Qemu-devel] [PATCH 5/9] target-xtensa: implement LSCX and LSCI groups Max Filippov
2012-09-09  1:29 ` [Qemu-devel] [PATCH 6/9] target-xtensa: implement FP0 arithmetic Max Filippov
2012-09-09 10:05   ` Peter Maydell
2012-09-09 12:25     ` Max Filippov
2012-09-09 12:56       ` Peter Maydell
2012-09-09  1:29 ` [Qemu-devel] [PATCH 7/9] target-xtensa: implement FP0 conversions Max Filippov
2012-09-09 11:06   ` Peter Maydell
2012-09-09 12:41     ` Max Filippov
2012-09-09  1:29 ` [Qemu-devel] [PATCH 8/9] target-xtensa: implement FP1 group Max Filippov
2012-09-09  1:29 ` Max Filippov [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1347154198-8629-10-git-send-email-jcmvbkbc@gmail.com \
    --to=jcmvbkbc@gmail.com \
    --cc=blauwirbel@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).