]> git.proxmox.com Git - mirror_qemu.git/blobdiff - target-cris/op_helper.c
virtio-9p: handle handle_9p_output() error
[mirror_qemu.git] / target-cris / op_helper.c
index 1eacc5fd7f91a44ff310ed11e7d5b9010486061e..504303913c6c044fade39f33e9264a698b5c7274 100644 (file)
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "qemu/osdep.h"
 #include "cpu.h"
-#include "dyngen-exec.h"
 #include "mmu.h"
-#include "helper.h"
-#include "host-utils.h"
+#include "exec/helper-proto.h"
+#include "qemu/host-utils.h"
+#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
 
 //#define CRIS_OP_HELPER_DEBUG
 
 
 #ifdef CRIS_OP_HELPER_DEBUG
 #define D(x) x
-#define D_LOG(...) qemu_log(__VA__ARGS__)
+#define D_LOG(...) qemu_log(__VA_ARGS__)
 #else
 #define D(x)
 #define D_LOG(...) do { } while (0)
 #endif
 
 #if !defined(CONFIG_USER_ONLY)
-#include "softmmu_exec.h"
-
-#define MMUSUFFIX _mmu
-
-#define SHIFT 0
-#include "softmmu_template.h"
-
-#define SHIFT 1
-#include "softmmu_template.h"
-
-#define SHIFT 2
-#include "softmmu_template.h"
-
-#define SHIFT 3
-#include "softmmu_template.h"
-
 /* Try to fill the TLB and return an exception if error. If retaddr is
    NULL, it means that the function was called in C code (i.e. not
    from generated code or from helper.c) */
-/* XXX: fix it to restore all registers */
-void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx,
-              void *retaddr)
+void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
+              int mmu_idx, uintptr_t retaddr)
 {
-    TranslationBlock *tb;
-    CPUState *saved_env;
-    unsigned long pc;
+    CRISCPU *cpu = CRIS_CPU(cs);
+    CPUCRISState *env = &cpu->env;
     int ret;
 
-    saved_env = env;
-    env = env1;
-
-    D_LOG("%s pc=%x tpc=%x ra=%x\n", __func__, 
-            env->pc, env->debug1, retaddr);
-    ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx);
+    D_LOG("%s pc=%x tpc=%x ra=%p\n", __func__,
+          env->pc, env->pregs[PR_EDA], (void *)retaddr);
+    ret = cris_cpu_handle_mmu_fault(cs, addr, access_type, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
-            pc = (unsigned long)retaddr;
-            tb = tb_find_pc(pc);
-            if (tb) {
-                /* the PC is inside the translated code. It means that we have
-                   a virtual CPU fault */
-                cpu_restore_state(tb, env, pc);
-
+            if (cpu_restore_state(cs, retaddr)) {
                /* Evaluate flags after retranslation.  */
-                helper_top_evaluate_flags();
+                helper_top_evaluate_flags(env);
             }
         }
-        cpu_loop_exit(env);
+        cpu_loop_exit(cs);
     }
-    env = saved_env;
 }
 
 #endif
 
-void helper_raise_exception(uint32_t index)
+void helper_raise_exception(CPUCRISState *env, uint32_t index)
 {
-       env->exception_index = index;
-        cpu_loop_exit(env);
+    CPUState *cs = CPU(cris_env_get_cpu(env));
+
+    cs->exception_index = index;
+    cpu_loop_exit(cs);
 }
 
-void helper_tlb_flush_pid(uint32_t pid)
+void helper_tlb_flush_pid(CPUCRISState *env, uint32_t pid)
 {
 #if !defined(CONFIG_USER_ONLY)
        pid &= 0xff;
@@ -106,25 +82,26 @@ void helper_tlb_flush_pid(uint32_t pid)
 #endif
 }
 
-void helper_spc_write(uint32_t new_spc)
+void helper_spc_write(CPUCRISState *env, uint32_t new_spc)
 {
 #if !defined(CONFIG_USER_ONLY)
-       tlb_flush_page(env, env->pregs[PR_SPC]);
-       tlb_flush_page(env, new_spc);
-#endif
-}
+    CRISCPU *cpu = cris_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
 
-void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2)
-{
-       qemu_log("%s: a0=%x a1=%x\n", __func__, a0, a1);
+    tlb_flush_page(cs, env->pregs[PR_SPC]);
+    tlb_flush_page(cs, new_spc);
+#endif
 }
 
 /* Used by the tlb decoder.  */
 #define EXTRACT_FIELD(src, start, end) \
            (((src) >> start) & ((1 << (end - start + 1)) - 1))
 
-void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg)
+void helper_movl_sreg_reg(CPUCRISState *env, uint32_t sreg, uint32_t reg)
 {
+#if !defined(CONFIG_USER_ONLY)
+    CRISCPU *cpu = cris_env_get_cpu(env);
+#endif
        uint32_t srs;
        srs = env->pregs[PR_SRS];
        srs &= 3;
@@ -166,14 +143,14 @@ void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg)
                        D_LOG("tlb flush vaddr=%x v=%d pc=%x\n", 
                                  vaddr, tlb_v, env->pc);
                        if (tlb_v) {
-                               tlb_flush_page(env, vaddr);
+                tlb_flush_page(CPU(cpu), vaddr);
                        }
                }
        }
 #endif
 }
 
-void helper_movl_reg_sreg (uint32_t reg, uint32_t sreg)
+void helper_movl_reg_sreg(CPUCRISState *env, uint32_t reg, uint32_t sreg)
 {
        uint32_t srs;
        env->pregs[PR_SRS] &= 3;
@@ -201,7 +178,7 @@ void helper_movl_reg_sreg (uint32_t reg, uint32_t sreg)
        env->regs[reg] = env->sregs[srs][sreg];
 }
 
-static void cris_ccs_rshift(CPUState *env)
+static void cris_ccs_rshift(CPUCRISState *env)
 {
        uint32_t ccs;
 
@@ -218,7 +195,7 @@ static void cris_ccs_rshift(CPUState *env)
        env->pregs[PR_CCS] = ccs;
 }
 
-void helper_rfe(void)
+void helper_rfe(CPUCRISState *env)
 {
        int rflag = env->pregs[PR_CCS] & R_FLAG;
 
@@ -234,7 +211,7 @@ void helper_rfe(void)
                env->pregs[PR_CCS] |= P_FLAG;
 }
 
-void helper_rfn(void)
+void helper_rfn(CPUCRISState *env)
 {
        int rflag = env->pregs[PR_CCS] & R_FLAG;
 
@@ -249,8 +226,8 @@ void helper_rfn(void)
        if (!rflag)
                env->pregs[PR_CCS] |= P_FLAG;
 
-    /* Always set the M flag.  */
-    env->pregs[PR_CCS] |= M_FLAG;
+       /* Always set the M flag.  */
+       env->pregs[PR_CCS] |= M_FLAG_V32;
 }
 
 uint32_t helper_lz(uint32_t t0)
@@ -258,7 +235,7 @@ uint32_t helper_lz(uint32_t t0)
        return clz32(t0);
 }
 
-uint32_t helper_btst(uint32_t t0, uint32_t t1, uint32_t ccs)
+uint32_t helper_btst(CPUCRISState *env, uint32_t t0, uint32_t t1, uint32_t ccs)
 {
        /* FIXME: clean this up.  */
 
@@ -286,7 +263,8 @@ uint32_t helper_btst(uint32_t t0, uint32_t t1, uint32_t ccs)
        return ccs;
 }
 
-static inline uint32_t evaluate_flags_writeback(uint32_t flags, uint32_t ccs)
+static inline uint32_t evaluate_flags_writeback(CPUCRISState *env,
+                                                uint32_t flags, uint32_t ccs)
 {
        unsigned int x, z, mask;
 
@@ -305,7 +283,8 @@ static inline uint32_t evaluate_flags_writeback(uint32_t flags, uint32_t ccs)
        return ccs;
 }
 
-uint32_t helper_evaluate_flags_muls(uint32_t ccs, uint32_t res, uint32_t mof)
+uint32_t helper_evaluate_flags_muls(CPUCRISState *env,
+                                    uint32_t ccs, uint32_t res, uint32_t mof)
 {
        uint32_t flags = 0;
        int64_t tmp;
@@ -323,10 +302,11 @@ uint32_t helper_evaluate_flags_muls(uint32_t ccs, uint32_t res, uint32_t mof)
        if ((dneg && mof != -1)
            || (!dneg && mof != 0))
                flags |= V_FLAG;
-       return evaluate_flags_writeback(flags, ccs);
+        return evaluate_flags_writeback(env, flags, ccs);
 }
 
-uint32_t helper_evaluate_flags_mulu(uint32_t ccs, uint32_t res, uint32_t mof)
+uint32_t helper_evaluate_flags_mulu(CPUCRISState *env,
+                                    uint32_t ccs, uint32_t res, uint32_t mof)
 {
        uint32_t flags = 0;
        uint64_t tmp;
@@ -341,10 +321,10 @@ uint32_t helper_evaluate_flags_mulu(uint32_t ccs, uint32_t res, uint32_t mof)
        if (mof)
                flags |= V_FLAG;
 
-       return evaluate_flags_writeback(flags, ccs);
+        return evaluate_flags_writeback(env, flags, ccs);
 }
 
-uint32_t helper_evaluate_flags_mcp(uint32_t ccs,
+uint32_t helper_evaluate_flags_mcp(CPUCRISState *env, uint32_t ccs,
                                   uint32_t src, uint32_t dst, uint32_t res)
 {
        uint32_t flags = 0;
@@ -370,10 +350,10 @@ uint32_t helper_evaluate_flags_mcp(uint32_t ccs,
                        flags |= R_FLAG;
        }
 
-       return evaluate_flags_writeback(flags, ccs);
+        return evaluate_flags_writeback(env, flags, ccs);
 }
 
-uint32_t helper_evaluate_flags_alu_4(uint32_t ccs,
+uint32_t helper_evaluate_flags_alu_4(CPUCRISState *env, uint32_t ccs,
                                     uint32_t src, uint32_t dst, uint32_t res)
 {
        uint32_t flags = 0;
@@ -399,10 +379,10 @@ uint32_t helper_evaluate_flags_alu_4(uint32_t ccs,
                        flags |= C_FLAG;
        }
 
-       return evaluate_flags_writeback(flags, ccs);
+        return evaluate_flags_writeback(env, flags, ccs);
 }
 
-uint32_t helper_evaluate_flags_sub_4(uint32_t ccs,
+uint32_t helper_evaluate_flags_sub_4(CPUCRISState *env, uint32_t ccs,
                                     uint32_t src, uint32_t dst, uint32_t res)
 {
        uint32_t flags = 0;
@@ -429,10 +409,11 @@ uint32_t helper_evaluate_flags_sub_4(uint32_t ccs,
        }
 
        flags ^= C_FLAG;
-       return evaluate_flags_writeback(flags, ccs);
+        return evaluate_flags_writeback(env, flags, ccs);
 }
 
-uint32_t helper_evaluate_flags_move_4(uint32_t ccs, uint32_t res)
+uint32_t helper_evaluate_flags_move_4(CPUCRISState *env,
+                                      uint32_t ccs, uint32_t res)
 {
        uint32_t flags = 0;
 
@@ -441,9 +422,10 @@ uint32_t helper_evaluate_flags_move_4(uint32_t ccs, uint32_t res)
        else if (res == 0L)
                flags |= Z_FLAG;
 
-       return evaluate_flags_writeback(flags, ccs);
+        return evaluate_flags_writeback(env, flags, ccs);
 }
-uint32_t helper_evaluate_flags_move_2(uint32_t ccs, uint32_t res)
+uint32_t helper_evaluate_flags_move_2(CPUCRISState *env,
+                                      uint32_t ccs, uint32_t res)
 {
        uint32_t flags = 0;
 
@@ -452,12 +434,12 @@ uint32_t helper_evaluate_flags_move_2(uint32_t ccs, uint32_t res)
        else if (res == 0)
                flags |= Z_FLAG;
 
-       return evaluate_flags_writeback(flags, ccs);
+        return evaluate_flags_writeback(env, flags, ccs);
 }
 
 /* TODO: This is expensive. We could split things up and only evaluate part of
    CCR on a need to know basis. For now, we simply re-evaluate everything.  */
-void  helper_evaluate_flags(void)
+void helper_evaluate_flags(CPUCRISState *env)
 {
        uint32_t src, dst, res;
        uint32_t flags = 0;
@@ -573,25 +555,26 @@ void  helper_evaluate_flags(void)
        if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP)
                flags ^= C_FLAG;
 
-       env->pregs[PR_CCS] = evaluate_flags_writeback(flags, env->pregs[PR_CCS]);
+        env->pregs[PR_CCS] = evaluate_flags_writeback(env, flags,
+                                                      env->pregs[PR_CCS]);
 }
 
-void helper_top_evaluate_flags(void)
+void helper_top_evaluate_flags(CPUCRISState *env)
 {
        switch (env->cc_op)
        {
                case CC_OP_MCP:
-                       env->pregs[PR_CCS] = helper_evaluate_flags_mcp(
+                        env->pregs[PR_CCS] = helper_evaluate_flags_mcp(env,
                                        env->pregs[PR_CCS], env->cc_src,
                                        env->cc_dest, env->cc_result);
                        break;
                case CC_OP_MULS:
-                       env->pregs[PR_CCS] = helper_evaluate_flags_muls(
+                        env->pregs[PR_CCS] = helper_evaluate_flags_muls(env,
                                        env->pregs[PR_CCS], env->cc_result,
                                        env->pregs[PR_MOF]);
                        break;
                case CC_OP_MULU:
-                       env->pregs[PR_CCS] = helper_evaluate_flags_mulu(
+                        env->pregs[PR_CCS] = helper_evaluate_flags_mulu(env,
                                        env->pregs[PR_CCS], env->cc_result,
                                        env->pregs[PR_MOF]);
                        break;
@@ -606,18 +589,18 @@ void helper_top_evaluate_flags(void)
                {
                        case 4:
                                env->pregs[PR_CCS] =
-                                       helper_evaluate_flags_move_4(
+                                        helper_evaluate_flags_move_4(env,
                                                        env->pregs[PR_CCS],
                                                        env->cc_result);
                                break;
                        case 2:
                                env->pregs[PR_CCS] =
-                                       helper_evaluate_flags_move_2(
+                                        helper_evaluate_flags_move_2(env,
                                                        env->pregs[PR_CCS],
                                                        env->cc_result);
                                break;
                        default:
-                               helper_evaluate_flags();
+                                helper_evaluate_flags(env);
                                break;
                }
                break;
@@ -628,12 +611,12 @@ void helper_top_evaluate_flags(void)
                case CC_OP_CMP:
                        if (env->cc_size == 4)
                                env->pregs[PR_CCS] =
-                                       helper_evaluate_flags_sub_4(
+                                        helper_evaluate_flags_sub_4(env,
                                                env->pregs[PR_CCS],
                                                env->cc_src, env->cc_dest,
                                                env->cc_result);
                        else
-                               helper_evaluate_flags();
+                                helper_evaluate_flags(env);
                        break;
                default:
                {
@@ -641,13 +624,13 @@ void helper_top_evaluate_flags(void)
                        {
                        case 4:
                                env->pregs[PR_CCS] =
-                                       helper_evaluate_flags_alu_4(
+                                        helper_evaluate_flags_alu_4(env,
                                                env->pregs[PR_CCS],
                                                env->cc_src, env->cc_dest,
                                                env->cc_result);
                                break;
                        default:
-                               helper_evaluate_flags();
+                                helper_evaluate_flags(env);
                                break;
                        }
                }