]> Git Repo - qemu.git/blobdiff - target-sparc/ldst_helper.c
target-sparc64: implement Short Floating-Point Store Instructions
[qemu.git] / target-sparc / ldst_helper.c
index 1f6df49e8816c65898f9af5be4a3f9472c559959..1a62e193bdb06444e008a12e179fdd9c89172a34 100644 (file)
@@ -18,7 +18,8 @@
  */
 
 #include "cpu.h"
-#include "helper.h"
+#include "exec/helper-proto.h"
+#include "exec/cpu_ldst.h"
 
 //#define DEBUG_MMU
 //#define DEBUG_MXCC
 #define QT0 (env->qt0)
 #define QT1 (env->qt1)
 
-#if !defined(CONFIG_USER_ONLY)
-static void QEMU_NORETURN do_unaligned_access(CPUSPARCState *env,
-                                              target_ulong addr, int is_write,
-                                              int is_user, uintptr_t retaddr);
-#include "exec/softmmu_exec.h"
-#define MMUSUFFIX _mmu
-#define ALIGNED_ONLY
-
-#define SHIFT 0
-#include "exec/softmmu_template.h"
-
-#define SHIFT 1
-#include "exec/softmmu_template.h"
-
-#define SHIFT 2
-#include "exec/softmmu_template.h"
-
-#define SHIFT 3
-#include "exec/softmmu_template.h"
-#endif
-
 #if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
 /* Calculates TSB pointer value for fault page size 8k or 64k */
 static uint64_t ultrasparc_tsb_pointer(uint64_t tsb_register,
@@ -141,6 +121,7 @@ static void replace_tlb_entry(SparcTLBEntry *tlb,
 
     /* flush page range if translation is valid */
     if (TTE_IS_VALID(tlb->tte)) {
+        CPUState *cs = CPU(sparc_env_get_cpu(env1));
 
         mask = 0xffffffffffffe000ULL;
         mask <<= 3 * ((tlb->tte >> 61) & 3);
@@ -149,7 +130,7 @@ static void replace_tlb_entry(SparcTLBEntry *tlb,
         va = tlb->tag & mask;
 
         for (offset = 0; offset < size; offset += TARGET_PAGE_SIZE) {
-            tlb_flush_page(env1, va + offset);
+            tlb_flush_page(cs, va + offset);
         }
     }
 
@@ -716,7 +697,9 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
 void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val, int asi,
                    int size)
 {
-    CPUState *cs = CPU(sparc_env_get_cpu(env));
+    SPARCCPU *cpu = sparc_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
+
     helper_check_align(env, addr, size - 1);
     switch (asi) {
     case 2: /* SuperSparc MXCC registers and Leon3 cache control */
@@ -862,13 +845,13 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val, int asi,
             DPRINTF_MMU("mmu flush level %d\n", mmulev);
             switch (mmulev) {
             case 0: /* flush page */
-                tlb_flush_page(env, addr & 0xfffff000);
+                tlb_flush_page(CPU(cpu), addr & 0xfffff000);
                 break;
             case 1: /* flush segment (256k) */
             case 2: /* flush region (16M) */
             case 3: /* flush context (4G) */
             case 4: /* flush entire */
-                tlb_flush(env, 1);
+                tlb_flush(CPU(cpu), 1);
                 break;
             default:
                 break;
@@ -893,7 +876,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val, int asi,
                    disabled mode are invalid in normal mode */
                 if ((oldreg & (MMU_E | MMU_NF | env->def->mmu_bm)) !=
                     (env->mmuregs[reg] & (MMU_E | MMU_NF | env->def->mmu_bm))) {
-                    tlb_flush(env, 1);
+                    tlb_flush(CPU(cpu), 1);
                 }
                 break;
             case 1: /* Context Table Pointer Register */
@@ -904,7 +887,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val, int asi,
                 if (oldreg != env->mmuregs[reg]) {
                     /* we flush when the MMU context changes because
                        QEMU has no MMU context support */
-                    tlb_flush(env, 1);
+                    tlb_flush(CPU(cpu), 1);
                 }
                 break;
             case 3: /* Synchronous Fault Status Register with Clear */
@@ -1660,7 +1643,9 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
 void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
                    int asi, int size)
 {
-    CPUState *cs = CPU(sparc_env_get_cpu(env));
+    SPARCCPU *cpu = sparc_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
+
 #ifdef DEBUG_ASI
     dump_asi("write", addr, asi, size, val);
 #endif
@@ -1869,7 +1854,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
 #ifdef DEBUG_MMU
                 dump_mmu(stdout, fprintf, env);
 #endif
-                tlb_flush(env, 1);
+                tlb_flush(CPU(cpu), 1);
             }
             return;
         }
@@ -1958,13 +1943,13 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
                 env->dmmu.mmu_primary_context = val;
                 /* can be optimized to only flush MMU_USER_IDX
                    and MMU_KERNEL_IDX entries */
-                tlb_flush(env, 1);
+                tlb_flush(CPU(cpu), 1);
                 break;
             case 2: /* Secondary context */
                 env->dmmu.mmu_secondary_context = val;
                 /* can be optimized to only flush MMU_USER_SECONDARY_IDX
                    and MMU_KERNEL_SECONDARY_IDX entries */
-                tlb_flush(env, 1);
+                tlb_flush(CPU(cpu), 1);
                 break;
             case 5: /* TSB access */
                 DPRINTF_MMU("dmmu TSB write: 0x%016" PRIx64 " -> 0x%016"
@@ -2169,7 +2154,6 @@ void helper_stf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
     unsigned int i;
     target_ulong val;
 
-    helper_check_align(env, addr, 3);
     addr = asi_address_mask(env, asi, addr);
 
     switch (asi) {
@@ -2206,8 +2190,22 @@ void helper_stf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
             helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi & 0x19, 8);
         }
 
+        return;
+    case 0xd2: /* 16-bit floating point load primary */
+    case 0xd3: /* 16-bit floating point load secondary */
+    case 0xda: /* 16-bit floating point load primary, LE */
+    case 0xdb: /* 16-bit floating point load secondary, LE */
+        helper_check_align(env, addr, 1);
+        /* Fall through */
+    case 0xd0: /* 8-bit floating point load primary */
+    case 0xd1: /* 8-bit floating point load secondary */
+    case 0xd8: /* 8-bit floating point load primary, LE */
+    case 0xd9: /* 8-bit floating point load secondary, LE */
+        val = env->fpr[rd / 2].l.lower;
+        helper_st_asi(env, addr, val, asi & 0x8d, ((asi & 2) >> 1) + 1);
         return;
     default:
+        helper_check_align(env, addr, 3);
         break;
     }
 
@@ -2394,7 +2392,7 @@ void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr,
     /* flush neverland mappings created during no-fault mode,
        so the sequential MMU faults report proper fault types */
     if (env->mmuregs[0] & MMU_NF) {
-        tlb_flush(env, 1);
+        tlb_flush(cs, 1);
     }
 }
 #else
@@ -2420,11 +2418,13 @@ void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr,
 #endif
 
 #if !defined(CONFIG_USER_ONLY)
-static void QEMU_NORETURN do_unaligned_access(CPUSPARCState *env,
-                                              target_ulong addr, int is_write,
-                                              int is_user, uintptr_t retaddr)
+void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cs,
+                                                 vaddr addr, int is_write,
+                                                 int is_user, uintptr_t retaddr)
 {
-    SPARCCPU *cpu = sparc_env_get_cpu(env);
+    SPARCCPU *cpu = SPARC_CPU(cs);
+    CPUSPARCState *env = &cpu->env;
+
 #ifdef DEBUG_UNALIGNED
     printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
            "\n", addr, env->pc);
This page took 0.04365 seconds and 4 git commands to generate.