o Add modulo argument to sim_core_attach
[binutils-gdb.git] / sim / common / sim-n-core.h
index 1bcb7227bd682255e932eac52668ccfce50302f6..50c0e249c241ed5290de8d7ef4cfee5bb60493f1 100644 (file)
 #error "N must be #defined"
 #endif
 
+#include "sim-xcat.h"
+
 /* NOTE: see end of file for #undef of these macros */
 #define unsigned_N XCONCAT2(unsigned_,N)
 #define T2H_N XCONCAT2(T2H_,N)
 #define H2T_N XCONCAT2(H2T_,N)
 
-#define core_map_read_N XCONCAT2(core_map_read_,N)
-#define core_map_write_N XCONCAT2(core_map_write_,N)
+#define sim_core_read_aligned_N XCONCAT2(sim_core_read_aligned_,N)
+#define sim_core_write_aligned_N XCONCAT2(sim_core_write_aligned_,N)
+#define sim_core_read_unaligned_N XCONCAT2(sim_core_read_unaligned_,N)
+#define sim_core_write_unaligned_N XCONCAT2(sim_core_write_unaligned_,N)
 
+/* TAGS: sim_core_read_aligned_1 sim_core_read_aligned_2 */
+/* TAGS: sim_core_read_aligned_4 sim_core_read_aligned_8 */
+/* TAGS: sim_core_read_aligned_word */
 
 INLINE_SIM_CORE(unsigned_N)
-core_map_read_N(engine *system,
-               core_maps map,
-               unsigned_word addr)
+sim_core_read_aligned_N(sim_cpu *cpu,
+                       sim_cia cia,
+                       sim_core_maps map,
+                       unsigned_word xaddr)
 {
-  core_mapping *mapping = core_map_find_mapping(system, map,
-                                               addr,
-                                               sizeof(unsigned_N),
-                                               1); /*abort*/
+  sim_cpu_core *cpu_core = CPU_CORE (cpu);
+  sim_core_common *core = &cpu_core->common;
+  unsigned_N val;
+  sim_core_mapping *mapping;
+  address_word addr;
+  if (WITH_XOR_ENDIAN)
+    addr = xaddr ^ cpu_core->xor[(sizeof(unsigned_N) - 1) % WITH_XOR_ENDIAN];
+  else
+    addr = xaddr;
+  mapping = sim_core_find_mapping (core, map,
+                                  addr,
+                                  sizeof (unsigned_N),
+                                  read_transfer,
+                                  1 /*abort*/, cpu, cia);
 #if (WITH_DEVICES)
   if (WITH_CALLBACK_MEMORY && mapping->device != NULL) {
     unsigned_N data;
-    if (device_io_read_buffer(mapping->device,
-                             &data,
-                             mapping->space,
-                             addr,
-                             sizeof(unsigned_N)) != sizeof(unsigned_N))
-      device_error(mapping->device, "internal error - core_read_N() - io_read_buffer should not fail");
-    return T2H_N(data);
+    if (device_io_read_buffer (mapping->device,
+                              &data,
+                              mapping->space,
+                              addr,
+                              sizeof (unsigned_N)) != sizeof (unsigned_N))
+      device_error (mapping->device, "internal error - %s - io_read_buffer should not fail",
+                   XSTRING (sim_core_read_aligned_N));
+    val = T2H_N (data);
   }
   else
 #endif
-    return T2H_N(*(unsigned_N*)core_translate(mapping, addr));
+    val = T2H_N (*(unsigned_N*) sim_core_translate (mapping, addr));
+  if (TRACE_P (cpu, TRACE_CORE_IDX))
+    if (sizeof (unsigned_N) > 4)
+      trace_printf (CPU_STATE (cpu), cpu,
+                   "sim-n-core.h:%d: read-%d %s:0x%08lx -> 0x%08lx%08lx\n",
+                   __LINE__,
+                   sizeof (unsigned_N),
+                   sim_core_map_to_str (map),
+                   (unsigned long) addr,
+                   (unsigned long) (((unsigned64)(val)) >> 32),
+                   (unsigned long) val);
+    else
+      trace_printf (CPU_STATE (cpu), cpu,
+                   "sim-n-core.h:%d: read-%d %s:0x%08lx -> 0x%0*lx\n",
+                   __LINE__,
+                   sizeof (unsigned_N),
+                   sim_core_map_to_str (map),
+                   (unsigned long) addr,
+                   sizeof (unsigned_N) * 2,
+                   (unsigned long) val);
+  return val;
 }
 
+/* TAGS: sim_core_read_unaligned_1 sim_core_read_unaligned_2 */
+/* TAGS: sim_core_read_unaligned_4 sim_core_read_unaligned_8 */
+/* TAGS: sim_core_read_unaligned_word */
+
+INLINE_SIM_CORE(unsigned_N)
+sim_core_read_unaligned_N(sim_cpu *cpu,
+                         sim_cia cia,
+                         sim_core_maps map,
+                         address_word addr)
+{
+  int alignment = sizeof (unsigned_N) - 1;
+  /* if hardwired to forced alignment just do it */
+  if (WITH_ALIGNMENT == FORCED_ALIGNMENT)
+    return sim_core_read_aligned_N (cpu, cia, map, addr & ~alignment);
+  else if ((addr & alignment) == 0)
+    return sim_core_read_aligned_N (cpu, cia, map, addr);
+  else
+    switch (CURRENT_ALIGNMENT)
+      {
+      case STRICT_ALIGNMENT:
+       SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map,
+                        sizeof (unsigned_N), addr,
+                        read_transfer, sim_core_unaligned_signal);
+       return -1;
+      case NONSTRICT_ALIGNMENT:
+       {
+         unsigned_N val;
+         if (sim_core_xor_read_buffer (CPU_STATE (cpu), cpu, map, &val, addr,
+                                       sizeof(unsigned_N))
+             != sizeof(unsigned_N))
+           SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map,
+                            sizeof (unsigned_N), addr,
+                            read_transfer, sim_core_unaligned_signal);
+         val = T2H_N(val);
+         return val;
+       }
+      case FORCED_ALIGNMENT:
+       return sim_core_read_aligned_N (cpu, cia, map, addr & ~alignment);
+      case MIXED_ALIGNMENT:
+       sim_engine_abort (CPU_STATE (cpu), cpu, cia,
+                         "internal error - %s - mixed alignment",
+                         XSTRING (sim_core_read_unaligned_N));
+       return 0;
+      default:
+       sim_engine_abort (CPU_STATE (cpu), cpu, cia,
+                         "internal error - %s - bad switch",
+                         XSTRING (sim_core_read_unaligned_N));
+       return 0;
+      }
+}
 
+/* TAGS: sim_core_write_aligned_1 sim_core_write_aligned_2 */
+/* TAGS: sim_core_write_aligned_4 sim_core_write_aligned_8 */
+/* TAGS: sim_core_write_aligned_word */
 
 INLINE_SIM_CORE(void)
-core_map_write_N(engine *system,
-                core_maps map,
-                unsigned_word addr,
-                unsigned_N val)
+sim_core_write_aligned_N(sim_cpu *cpu,
+                        sim_cia cia,
+                        sim_core_maps map,
+                        unsigned_word xaddr,
+                        unsigned_N val)
 {
-  core_mapping *mapping = core_map_find_mapping(system, map,
-                                               addr,
-                                               sizeof(unsigned_N),
-                                               1); /*abort*/
+  sim_cpu_core *cpu_core = CPU_CORE (cpu);
+  sim_core_common *core = &cpu_core->common;
+  sim_core_mapping *mapping;
+  address_word addr;
+  if (WITH_XOR_ENDIAN)
+    addr = xaddr ^ cpu_core->xor[(sizeof(unsigned_N) - 1) % WITH_XOR_ENDIAN];
+  else
+    addr = xaddr;
+  mapping = sim_core_find_mapping(core, map,
+                                 addr,
+                                 sizeof (unsigned_N),
+                                 write_transfer,
+                                 1 /*abort*/, cpu, cia);
 #if (WITH_DEVICES)
   if (WITH_CALLBACK_MEMORY && mapping->device != NULL) {
-    unsigned_N data = H2T_N(val);
-    if (device_io_write_buffer(mapping->device,
-                              &data,
-                              mapping->space,
-                              addr,
-                              sizeof(unsigned_N), /* nr_bytes */
-                              processor,
-                              cia) != sizeof(unsigned_N))
-      device_error(mapping->device, "internal error - core_write_N() - io_write_buffer should not fail");
+    unsigned_N data = H2T_N (val);
+    if (device_io_write_buffer (mapping->device,
+                               &data,
+                               mapping->space,
+                               addr,
+                               sizeof (unsigned_N), /* nr_bytes */
+                               cpu,
+                               cia) != sizeof (unsigned_N))
+      device_error (mapping->device, "internal error - %s - io_write_buffer should not fail",
+                   XSTRING (sim_core_write_aligned_N));
   }
   else
 #endif
-    *(unsigned_N*)core_translate(mapping, addr) = H2T_N(val);
+    *(unsigned_N*) sim_core_translate (mapping, addr) = H2T_N (val);
+  if (TRACE_P (cpu, TRACE_CORE_IDX))
+    if (sizeof (unsigned_N) > 4)
+      trace_printf (CPU_STATE (cpu), cpu,
+                   "sim-n-core.h:%d: write-%d %s:0x%08lx <- 0x%08lx%08lx\n",
+                   __LINE__,
+                   sizeof (unsigned_N),
+                   sim_core_map_to_str (map),
+                   (unsigned long) addr,
+                   (unsigned long) (((unsigned64)(val)) >> 32),
+                   (unsigned long) val);
+    else
+      trace_printf (CPU_STATE (cpu), cpu,
+                   "sim-n-core.h:%d: write-%d %s:0x%08lx <- 0x%0*lx\n",
+                   __LINE__,
+                   sizeof (unsigned_N),
+                   sim_core_map_to_str (map),
+                   (unsigned long) addr,
+                   sizeof (unsigned_N) * 2,
+                   (unsigned long) val);
+}
+
+/* TAGS: sim_core_write_unaligned_1 sim_core_write_unaligned_2 */
+/* TAGS: sim_core_write_unaligned_4 sim_core_write_unaligned_8 */
+/* TAGS: sim_core_write_unaligned_word */
+
+INLINE_SIM_CORE(void)
+sim_core_write_unaligned_N(sim_cpu *cpu,
+                          sim_cia cia,
+                          sim_core_maps map,
+                          address_word addr,
+                          unsigned_N val)
+{
+  int alignment = sizeof (unsigned_N) - 1;
+  /* if hardwired to forced alignment just do it */
+  if (WITH_ALIGNMENT == FORCED_ALIGNMENT)
+    sim_core_write_aligned_N (cpu, cia, map, addr & ~alignment, val);
+  else if ((addr & alignment) == 0)
+    sim_core_write_aligned_N (cpu, cia, map, addr, val);
+  else
+    switch (CURRENT_ALIGNMENT)
+      {
+      case STRICT_ALIGNMENT:
+       SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map,
+                        sizeof (unsigned_N), addr,
+                        write_transfer, sim_core_unaligned_signal);
+       break;
+      case NONSTRICT_ALIGNMENT:
+       {
+         unsigned_N val = H2T_N (val);
+         if (sim_core_xor_write_buffer (CPU_STATE (cpu), cpu, map, &val, addr,
+                                        sizeof(unsigned_N))
+             != sizeof(unsigned_N))
+           SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map,
+                            sizeof (unsigned_N), addr,
+                            write_transfer, sim_core_unaligned_signal);
+         break;
+       }
+      case FORCED_ALIGNMENT:
+       sim_core_write_aligned_N (cpu, cia, map, addr & ~alignment, val);
+       break;
+      case MIXED_ALIGNMENT:
+       sim_engine_abort (CPU_STATE (cpu), cpu, cia,
+                         "internal error - %s - mixed alignment",
+                         XSTRING (sim_core_write_unaligned_N));
+       break;
+      default:
+       sim_engine_abort (CPU_STATE (cpu), cpu, cia,
+                         "internal error - %s - bad switch",
+                         XSTRING (sim_core_write_unaligned_N));
+       break;
+      }
 }
 
 
@@ -91,5 +265,7 @@ core_map_write_N(engine *system,
 #undef unsigned_N
 #undef T2H_N
 #undef H2T_N
-#undef core_map_read_N
-#undef core_map_write_N
+#undef sim_core_read_aligned_N
+#undef sim_core_write_aligned_N
+#undef sim_core_read_unaligned_N
+#undef sim_core_write_unaligned_N