sim: device_error: punt
[external/binutils.git] / sim / common / sim-core.c
1 /* The common simulator framework for GDB, the GNU Debugger.
2
3    Copyright 2002-2015 Free Software Foundation, Inc.
4
5    Contributed by Andrew Cagney and Red Hat.
6
7    This file is part of GDB.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
22
23 #ifndef SIM_CORE_C
24 #define SIM_CORE_C
25
26 #include "sim-main.h"
27 #include "sim-assert.h"
28
29 #if (WITH_HW)
30 #include "sim-hw.h"
31 #define device_io_read_buffer(client, ...) device_io_read_buffer ((device *)(client), __VA_ARGS__)
32 #define device_io_write_buffer(client, ...) device_io_write_buffer ((device *)(client), __VA_ARGS__)
33 #endif
34
35 /* "core" module install handler.
36
37    This is called via sim_module_install to install the "core"
38    subsystem into the simulator.  */
39
40 #if EXTERN_SIM_CORE_P
41 static MODULE_INIT_FN sim_core_init;
42 static MODULE_UNINSTALL_FN sim_core_uninstall;
43 #endif
44
45 #if EXTERN_SIM_CORE_P
46 SIM_RC
47 sim_core_install (SIM_DESC sd)
48 {
49   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
50
51   /* establish the other handlers */
52   sim_module_add_uninstall_fn (sd, sim_core_uninstall);
53   sim_module_add_init_fn (sd, sim_core_init);
54
55   /* establish any initial data structures - none */
56   return SIM_RC_OK;
57 }
58 #endif
59
60
61 /* Uninstall the "core" subsystem from the simulator.  */
62
63 #if EXTERN_SIM_CORE_P
64 static void
65 sim_core_uninstall (SIM_DESC sd)
66 {
67   sim_core *core = STATE_CORE (sd);
68   unsigned map;
69   /* blow away any mappings */
70   for (map = 0; map < nr_maps; map++) {
71     sim_core_mapping *curr = core->common.map[map].first;
72     while (curr != NULL) {
73       sim_core_mapping *tbd = curr;
74       curr = curr->next;
75       if (tbd->free_buffer != NULL) {
76         SIM_ASSERT (tbd->buffer != NULL);
77         free (tbd->free_buffer);
78       }
79       free (tbd);
80     }
81     core->common.map[map].first = NULL;
82   }
83 }
84 #endif
85
86
87 #if EXTERN_SIM_CORE_P
88 static SIM_RC
89 sim_core_init (SIM_DESC sd)
90 {
91   /* Nothing to do */
92   return SIM_RC_OK;
93 }
94 #endif
95
96
97
98 #ifndef SIM_CORE_SIGNAL
99 #define SIM_CORE_SIGNAL(SD,CPU,CIA,MAP,NR_BYTES,ADDR,TRANSFER,ERROR) \
100 sim_core_signal ((SD), (CPU), (CIA), (MAP), (NR_BYTES), (ADDR), (TRANSFER), (ERROR))
101 #endif
102
103 #if EXTERN_SIM_CORE_P
104 void
105 sim_core_signal (SIM_DESC sd,
106                  sim_cpu *cpu,
107                  sim_cia cia,
108                  unsigned map,
109                  int nr_bytes,
110                  address_word addr,
111                  transfer_type transfer,
112                  sim_core_signals sig)
113 {
114   const char *copy = (transfer == read_transfer ? "read" : "write");
115   address_word ip = CIA_ADDR (cia);
116   switch (sig)
117     {
118     case sim_core_unmapped_signal:
119       sim_io_eprintf (sd, "core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
120                       nr_bytes, copy, (unsigned long) addr, (unsigned long) ip);
121       sim_engine_halt (sd, cpu, NULL, cia, sim_stopped, SIM_SIGSEGV);
122       break;
123     case sim_core_unaligned_signal:
124       sim_io_eprintf (sd, "core: %d byte misaligned %s to address 0x%lx at 0x%lx\n",
125                       nr_bytes, copy, (unsigned long) addr, (unsigned long) ip);
126       sim_engine_halt (sd, cpu, NULL, cia, sim_stopped, SIM_SIGBUS);
127       break;
128     default:
129       sim_engine_abort (sd, cpu, cia,
130                         "sim_core_signal - internal error - bad switch");
131     }
132 }
133 #endif
134
135
136 #if EXTERN_SIM_CORE_P
137 static sim_core_mapping *
138 new_sim_core_mapping (SIM_DESC sd,
139                       int level,
140                       int space,
141                       address_word addr,
142                       address_word nr_bytes,
143                       unsigned modulo,
144 #if WITH_HW
145                       struct hw *device,
146 #else
147                       device *device,
148 #endif
149                       void *buffer,
150                       void *free_buffer)
151 {
152   sim_core_mapping *new_mapping = ZALLOC (sim_core_mapping);
153   /* common */
154   new_mapping->level = level;
155   new_mapping->space = space;
156   new_mapping->base = addr;
157   new_mapping->nr_bytes = nr_bytes;
158   new_mapping->bound = addr + (nr_bytes - 1);
159   new_mapping->mask = modulo - 1;
160   new_mapping->buffer = buffer;
161   new_mapping->free_buffer = free_buffer;
162   new_mapping->device = device;
163   return new_mapping;
164 }
165 #endif
166
167
168 #if EXTERN_SIM_CORE_P
169 static void
170 sim_core_map_attach (SIM_DESC sd,
171                      sim_core_map *access_map,
172                      int level,
173                      int space,
174                      address_word addr,
175                      address_word nr_bytes,
176                      unsigned modulo,
177 #if WITH_HW
178                      struct hw *client, /*callback/default*/
179 #else
180                      device *client, /*callback/default*/
181 #endif
182                      void *buffer, /*raw_memory*/
183                      void *free_buffer) /*raw_memory*/
184 {
185   /* find the insertion point for this additional mapping and then
186      insert */
187   sim_core_mapping *next_mapping;
188   sim_core_mapping **last_mapping;
189
190   SIM_ASSERT ((client == NULL) != (buffer == NULL));
191   SIM_ASSERT ((client == NULL) >= (free_buffer != NULL));
192
193   /* actually do occasionally get a zero size map */
194   if (nr_bytes == 0)
195     {
196 #if (WITH_HW)
197       sim_hw_abort (sd, client, "called on sim_core_map_attach with size zero");
198 #endif
199       sim_io_error (sd, "called on sim_core_map_attach with size zero");
200     }
201
202   /* find the insertion point (between last/next) */
203   next_mapping = access_map->first;
204   last_mapping = &access_map->first;
205   while (next_mapping != NULL
206         && (next_mapping->level < level
207             || (next_mapping->level == level
208                 && next_mapping->bound < addr)))
209     {
210       /* provided levels are the same */
211       /* assert: next_mapping->base > all bases before next_mapping */
212       /* assert: next_mapping->bound >= all bounds before next_mapping */
213       last_mapping = &next_mapping->next;
214       next_mapping = next_mapping->next;
215     }
216
217   /* check insertion point correct */
218   SIM_ASSERT (next_mapping == NULL || next_mapping->level >= level);
219   if (next_mapping != NULL && next_mapping->level == level
220       && next_mapping->base < (addr + (nr_bytes - 1)))
221     {
222 #if WITH_HW
223       sim_hw_abort (sd, client, "memory map %d:0x%lx..0x%lx (%ld bytes) overlaps %d:0x%lx..0x%lx (%ld bytes)",
224                     space,
225                     (long) addr,
226                     (long) (addr + (nr_bytes - 1)),
227                     (long) nr_bytes,
228                     next_mapping->space,
229                     (long) next_mapping->base,
230                     (long) next_mapping->bound,
231                     (long) next_mapping->nr_bytes);
232 #endif
233       sim_io_error (sd, "memory map %d:0x%lx..0x%lx (%ld bytes) overlaps %d:0x%lx..0x%lx (%ld bytes)",
234                     space,
235                     (long) addr,
236                     (long) (addr + (nr_bytes - 1)),
237                     (long) nr_bytes,
238                     next_mapping->space,
239                     (long) next_mapping->base,
240                     (long) next_mapping->bound,
241                     (long) next_mapping->nr_bytes);
242   }
243
244   /* create/insert the new mapping */
245   *last_mapping = new_sim_core_mapping (sd,
246                                         level,
247                                         space, addr, nr_bytes, modulo,
248                                         client, buffer, free_buffer);
249   (*last_mapping)->next = next_mapping;
250 }
251 #endif
252
253
254 /* Attach memory or a memory mapped device to the simulator.
255    See sim-core.h for a full description.  */
256
257 #if EXTERN_SIM_CORE_P
258 void
259 sim_core_attach (SIM_DESC sd,
260                  sim_cpu *cpu,
261                  int level,
262                  unsigned mapmask,
263                  int space,
264                  address_word addr,
265                  address_word nr_bytes,
266                  unsigned modulo,
267 #if WITH_HW
268                  struct hw *client,
269 #else
270                  device *client,
271 #endif
272                  void *optional_buffer)
273 {
274   sim_core *memory = STATE_CORE (sd);
275   unsigned map;
276   void *buffer;
277   void *free_buffer;
278
279   /* check for for attempt to use unimplemented per-processor core map */
280   if (cpu != NULL)
281     sim_io_error (sd, "sim_core_map_attach - processor specific memory map not yet supported");
282
283   if (client != NULL && modulo != 0)
284     {
285 #if (WITH_HW)
286       sim_hw_abort (sd, client, "sim_core_attach - internal error - modulo and callback memory conflict");
287 #endif
288       sim_io_error (sd, "sim_core_attach - internal error - modulo and callback memory conflict");
289     }
290   if (modulo != 0)
291     {
292       unsigned mask = modulo - 1;
293       /* any zero bits */
294       while (mask >= sizeof (unsigned64)) /* minimum modulo */
295         {
296           if ((mask & 1) == 0)
297             mask = 0;
298           else
299             mask >>= 1;
300         }
301       if (mask != sizeof (unsigned64) - 1)
302         {
303 #if (WITH_HW)
304           sim_hw_abort (sd, client, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo);
305 #endif
306           sim_io_error (sd, "sim_core_attach - internal error - modulo %lx not power of two", (long) modulo);
307         }
308     }
309
310   /* verify consistency between device and buffer */
311   if (client != NULL && optional_buffer != NULL)
312     {
313 #if (WITH_HW)
314       sim_hw_abort (sd, client, "sim_core_attach - internal error - conflicting buffer and attach arguments");
315 #endif
316       sim_io_error (sd, "sim_core_attach - internal error - conflicting buffer and attach arguments");
317     }
318   if (client == NULL)
319     {
320       if (optional_buffer == NULL)
321         {
322           int padding = (addr % sizeof (unsigned64));
323           unsigned long bytes = (modulo == 0 ? nr_bytes : modulo) + padding;
324           free_buffer = zalloc (bytes);
325           buffer = (char*) free_buffer + padding;
326         }
327       else
328         {
329           buffer = optional_buffer;
330           free_buffer = NULL;
331         }
332     }
333   else
334     {
335       /* a device */
336       buffer = NULL;
337       free_buffer = NULL;
338     }
339
340   /* attach the region to all applicable access maps */
341   for (map = 0;
342        map < nr_maps;
343        map++)
344     {
345       if (mapmask & (1 << map))
346         {
347           sim_core_map_attach (sd, &memory->common.map[map],
348                                level, space, addr, nr_bytes, modulo,
349                                client, buffer, free_buffer);
350           free_buffer = NULL;
351         }
352     }
353
354   /* Just copy this map to each of the processor specific data structures.
355      FIXME - later this will be replaced by true processor specific
356      maps. */
357   {
358     int i;
359     for (i = 0; i < MAX_NR_PROCESSORS; i++)
360       {
361         CPU_CORE (STATE_CPU (sd, i))->common = STATE_CORE (sd)->common;
362       }
363   }
364 }
365 #endif
366
367
368 /* Remove any memory reference related to this address */
369 #if EXTERN_SIM_CORE_P
370 static void
371 sim_core_map_detach (SIM_DESC sd,
372                      sim_core_map *access_map,
373                      int level,
374                      int space,
375                      address_word addr)
376 {
377   sim_core_mapping **entry;
378   for (entry = &access_map->first;
379        (*entry) != NULL;
380        entry = &(*entry)->next)
381     {
382       if ((*entry)->base == addr
383           && (*entry)->level == level
384           && (*entry)->space == space)
385         {
386           sim_core_mapping *dead = (*entry);
387           (*entry) = dead->next;
388           if (dead->free_buffer != NULL)
389             free (dead->free_buffer);
390           free (dead);
391           return;
392         }
393     }
394 }
395 #endif
396
397 #if EXTERN_SIM_CORE_P
398 void
399 sim_core_detach (SIM_DESC sd,
400                  sim_cpu *cpu,
401                  int level,
402                  int address_space,
403                  address_word addr)
404 {
405   sim_core *memory = STATE_CORE (sd);
406   unsigned map;
407   for (map = 0; map < nr_maps; map++)
408     {
409       sim_core_map_detach (sd, &memory->common.map[map],
410                            level, address_space, addr);
411     }
412   /* Just copy this update to each of the processor specific data
413      structures.  FIXME - later this will be replaced by true
414      processor specific maps. */
415   {
416     int i;
417     for (i = 0; i < MAX_NR_PROCESSORS; i++)
418       {
419         CPU_CORE (STATE_CPU (sd, i))->common = STATE_CORE (sd)->common;
420       }
421   }
422 }
423 #endif
424
425
426 STATIC_INLINE_SIM_CORE\
427 (sim_core_mapping *)
428 sim_core_find_mapping (sim_core_common *core,
429                        unsigned map,
430                        address_word addr,
431                        unsigned nr_bytes,
432                        transfer_type transfer,
433                        int abort, /*either 0 or 1 - hint to inline/-O */
434                        sim_cpu *cpu, /* abort => cpu != NULL */
435                        sim_cia cia)
436 {
437   sim_core_mapping *mapping = core->map[map].first;
438   ASSERT ((addr & (nr_bytes - 1)) == 0); /* must be aligned */
439   ASSERT ((addr + (nr_bytes - 1)) >= addr); /* must not wrap */
440   ASSERT (!abort || cpu != NULL); /* abort needs a non null CPU */
441   while (mapping != NULL)
442     {
443       if (addr >= mapping->base
444           && (addr + (nr_bytes - 1)) <= mapping->bound)
445         return mapping;
446       mapping = mapping->next;
447     }
448   if (abort)
449     {
450       SIM_CORE_SIGNAL (CPU_STATE (cpu), cpu, cia, map, nr_bytes, addr, transfer,
451                        sim_core_unmapped_signal);
452     }
453   return NULL;
454 }
455
456
457 STATIC_INLINE_SIM_CORE\
458 (void *)
459 sim_core_translate (sim_core_mapping *mapping,
460                     address_word addr)
461 {
462   return (void *)((unsigned8 *) mapping->buffer
463                   + ((addr - mapping->base) & mapping->mask));
464 }
465
466
467 #if EXTERN_SIM_CORE_P
468 unsigned
469 sim_core_read_buffer (SIM_DESC sd,
470                       sim_cpu *cpu,
471                       unsigned map,
472                       void *buffer,
473                       address_word addr,
474                       unsigned len)
475 {
476   sim_core_common *core = (cpu == NULL ? &STATE_CORE (sd)->common : &CPU_CORE (cpu)->common);
477   unsigned count = 0;
478   while (count < len)
479  {
480     address_word raddr = addr + count;
481     sim_core_mapping *mapping =
482       sim_core_find_mapping (core, map,
483                             raddr, /*nr-bytes*/1,
484                             read_transfer,
485                             0 /*dont-abort*/, NULL, NULL_CIA);
486     if (mapping == NULL)
487       break;
488 #if (WITH_DEVICES)
489     if (mapping->device != NULL)
490       {
491         int nr_bytes = len - count;
492         sim_cia cia = cpu ? CPU_PC_GET (cpu) : NULL_CIA;
493         if (raddr + nr_bytes - 1> mapping->bound)
494           nr_bytes = mapping->bound - raddr + 1;
495         if (device_io_read_buffer (mapping->device,
496                                    (unsigned_1*)buffer + count,
497                                    mapping->space,
498                                    raddr,
499                                    nr_bytes,
500                                    sd,
501                                    cpu,
502                                    cia) != nr_bytes)
503           break;
504         count += nr_bytes;
505         continue;
506       }
507 #endif
508 #if (WITH_HW)
509     if (mapping->device != NULL)
510       {
511         int nr_bytes = len - count;
512         if (raddr + nr_bytes - 1> mapping->bound)
513           nr_bytes = mapping->bound - raddr + 1;
514         if (sim_hw_io_read_buffer (sd, mapping->device,
515                                    (unsigned_1*)buffer + count,
516                                    mapping->space,
517                                    raddr,
518                                    nr_bytes) != nr_bytes)
519           break;
520         count += nr_bytes;
521         continue;
522       }
523 #endif
524     ((unsigned_1*)buffer)[count] =
525       *(unsigned_1*)sim_core_translate (mapping, raddr);
526     count += 1;
527  }
528   return count;
529 }
530 #endif
531
532
533 #if EXTERN_SIM_CORE_P
534 unsigned
535 sim_core_write_buffer (SIM_DESC sd,
536                        sim_cpu *cpu,
537                        unsigned map,
538                        const void *buffer,
539                        address_word addr,
540                        unsigned len)
541 {
542   sim_core_common *core = (cpu == NULL ? &STATE_CORE (sd)->common : &CPU_CORE (cpu)->common);
543   unsigned count = 0;
544   while (count < len)
545     {
546       address_word raddr = addr + count;
547       sim_core_mapping *mapping =
548         sim_core_find_mapping (core, map,
549                                raddr, /*nr-bytes*/1,
550                                write_transfer,
551                                0 /*dont-abort*/, NULL, NULL_CIA);
552       if (mapping == NULL)
553         break;
554 #if (WITH_DEVICES)
555       if (mapping->device != NULL)
556         {
557           int nr_bytes = len - count;
558           sim_cia cia = cpu ? CPU_PC_GET (cpu) : NULL_CIA;
559           if (raddr + nr_bytes - 1 > mapping->bound)
560             nr_bytes = mapping->bound - raddr + 1;
561           if (device_io_write_buffer (mapping->device,
562                                       (unsigned_1*)buffer + count,
563                                       mapping->space,
564                                       raddr,
565                                       nr_bytes,
566                                       sd,
567                                       cpu,
568                                       cia) != nr_bytes)
569             break;
570           count += nr_bytes;
571           continue;
572         }
573 #endif
574 #if (WITH_HW)
575       if (mapping->device != NULL)
576         {
577           int nr_bytes = len - count;
578           if (raddr + nr_bytes - 1 > mapping->bound)
579             nr_bytes = mapping->bound - raddr + 1;
580           if (sim_hw_io_write_buffer (sd, mapping->device,
581                                       (unsigned_1*)buffer + count,
582                                       mapping->space,
583                                       raddr,
584                                       nr_bytes) != nr_bytes)
585             break;
586           count += nr_bytes;
587           continue;
588         }
589 #endif
590       *(unsigned_1*)sim_core_translate (mapping, raddr) =
591         ((unsigned_1*)buffer)[count];
592       count += 1;
593     }
594   return count;
595 }
596 #endif
597
598
599 #if EXTERN_SIM_CORE_P
600 void
601 sim_core_set_xor (SIM_DESC sd,
602                   sim_cpu *cpu,
603                   int is_xor)
604 {
605   /* set up the XOR map if required. */
606   if (WITH_XOR_ENDIAN) {
607     {
608       sim_core *core = STATE_CORE (sd);
609       sim_cpu_core *cpu_core = (cpu != NULL ? CPU_CORE (cpu) : NULL);
610       if (cpu_core != NULL)
611         {
612           int i = 1;
613           unsigned mask;
614           if (is_xor)
615             mask = WITH_XOR_ENDIAN - 1;
616           else
617             mask = 0;
618           while (i - 1 < WITH_XOR_ENDIAN)
619             {
620               cpu_core->xor[i-1] = mask;
621               mask = (mask << 1) & (WITH_XOR_ENDIAN - 1);
622               i = (i << 1);
623             }
624         }
625       else
626         {
627           if (is_xor)
628             core->byte_xor = WITH_XOR_ENDIAN - 1;
629           else
630             core->byte_xor = 0;
631         }
632     }
633   }
634   else {
635     if (is_xor)
636       sim_engine_abort (sd, NULL, NULL_CIA,
637                         "Attempted to enable xor-endian mode when permenantly disabled.");
638   }
639 }
640 #endif
641
642
643 #if EXTERN_SIM_CORE_P
644 static void
645 reverse_n (unsigned_1 *dest,
646            const unsigned_1 *src,
647            int nr_bytes)
648 {
649   int i;
650   for (i = 0; i < nr_bytes; i++)
651     {
652       dest [nr_bytes - i - 1] = src [i];
653     }
654 }
655 #endif
656
657
658 #if EXTERN_SIM_CORE_P
659 unsigned
660 sim_core_xor_read_buffer (SIM_DESC sd,
661                           sim_cpu *cpu,
662                           unsigned map,
663                           void *buffer,
664                           address_word addr,
665                           unsigned nr_bytes)
666 {
667   address_word byte_xor = (cpu == NULL ? STATE_CORE (sd)->byte_xor : CPU_CORE (cpu)->xor[0]);
668   if (!WITH_XOR_ENDIAN || !byte_xor)
669     return sim_core_read_buffer (sd, cpu, map, buffer, addr, nr_bytes);
670   else
671     /* only break up transfers when xor-endian is both selected and enabled */
672     {
673       unsigned_1 x[WITH_XOR_ENDIAN + 1]; /* +1 to avoid zero-sized array */
674       unsigned nr_transfered = 0;
675       address_word start = addr;
676       unsigned nr_this_transfer = (WITH_XOR_ENDIAN - (addr & ~(WITH_XOR_ENDIAN - 1)));
677       address_word stop;
678       /* initial and intermediate transfers are broken when they cross
679          an XOR endian boundary */
680       while (nr_transfered + nr_this_transfer < nr_bytes)
681         /* initial/intermediate transfers */
682         {
683           /* since xor-endian is enabled stop^xor defines the start
684              address of the transfer */
685           stop = start + nr_this_transfer - 1;
686           SIM_ASSERT (start <= stop);
687           SIM_ASSERT ((stop ^ byte_xor) <= (start ^ byte_xor));
688           if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
689               != nr_this_transfer)
690             return nr_transfered;
691           reverse_n (&((unsigned_1*)buffer)[nr_transfered], x, nr_this_transfer);
692           nr_transfered += nr_this_transfer;
693           nr_this_transfer = WITH_XOR_ENDIAN;
694           start = stop + 1;
695         }
696       /* final transfer */
697       nr_this_transfer = nr_bytes - nr_transfered;
698       stop = start + nr_this_transfer - 1;
699       SIM_ASSERT (stop == (addr + nr_bytes - 1));
700       if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
701           != nr_this_transfer)
702         return nr_transfered;
703       reverse_n (&((unsigned_1*)buffer)[nr_transfered], x, nr_this_transfer);
704       return nr_bytes;
705     }
706 }
707 #endif
708
709
710 #if EXTERN_SIM_CORE_P
711 unsigned
712 sim_core_xor_write_buffer (SIM_DESC sd,
713                            sim_cpu *cpu,
714                            unsigned map,
715                            const void *buffer,
716                            address_word addr,
717                            unsigned nr_bytes)
718 {
719   address_word byte_xor = (cpu == NULL ? STATE_CORE (sd)->byte_xor : CPU_CORE (cpu)->xor[0]);
720   if (!WITH_XOR_ENDIAN || !byte_xor)
721     return sim_core_write_buffer (sd, cpu, map, buffer, addr, nr_bytes);
722   else
723     /* only break up transfers when xor-endian is both selected and enabled */
724     {
725       unsigned_1 x[WITH_XOR_ENDIAN + 1]; /* +1 to avoid zero sized array */
726       unsigned nr_transfered = 0;
727       address_word start = addr;
728       unsigned nr_this_transfer = (WITH_XOR_ENDIAN - (addr & ~(WITH_XOR_ENDIAN - 1)));
729       address_word stop;
730       /* initial and intermediate transfers are broken when they cross
731          an XOR endian boundary */
732       while (nr_transfered + nr_this_transfer < nr_bytes)
733         /* initial/intermediate transfers */
734         {
735           /* since xor-endian is enabled stop^xor defines the start
736              address of the transfer */
737           stop = start + nr_this_transfer - 1;
738           SIM_ASSERT (start <= stop);
739           SIM_ASSERT ((stop ^ byte_xor) <= (start ^ byte_xor));
740           reverse_n (x, &((unsigned_1*)buffer)[nr_transfered], nr_this_transfer);
741           if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
742               != nr_this_transfer)
743             return nr_transfered;
744           nr_transfered += nr_this_transfer;
745           nr_this_transfer = WITH_XOR_ENDIAN;
746           start = stop + 1;
747         }
748       /* final transfer */
749       nr_this_transfer = nr_bytes - nr_transfered;
750       stop = start + nr_this_transfer - 1;
751       SIM_ASSERT (stop == (addr + nr_bytes - 1));
752       reverse_n (x, &((unsigned_1*)buffer)[nr_transfered], nr_this_transfer);
753       if (sim_core_read_buffer (sd, cpu, map, x, stop ^ byte_xor, nr_this_transfer)
754           != nr_this_transfer)
755         return nr_transfered;
756       return nr_bytes;
757     }
758 }
759 #endif
760
761 #if EXTERN_SIM_CORE_P
762 void *
763 sim_core_trans_addr (SIM_DESC sd,
764                      sim_cpu *cpu,
765                      unsigned map,
766                      address_word addr)
767 {
768   sim_core_common *core = (cpu == NULL ? &STATE_CORE (sd)->common : &CPU_CORE (cpu)->common);
769   sim_core_mapping *mapping =
770     sim_core_find_mapping (core, map,
771                            addr, /*nr-bytes*/1,
772                            write_transfer,
773                            0 /*dont-abort*/, NULL, NULL_CIA);
774   if (mapping == NULL)
775     return NULL;
776   return sim_core_translate (mapping, addr);
777 }
778 #endif
779
780
781
782 /* define the read/write 1/2/4/8/16/word functions */
783
784 #define N 16
785 #include "sim-n-core.h"
786
787 #define N 8
788 #include "sim-n-core.h"
789
790 #define N 7
791 #define M 8
792 #include "sim-n-core.h"
793
794 #define N 6
795 #define M 8
796 #include "sim-n-core.h"
797
798 #define N 5
799 #define M 8
800 #include "sim-n-core.h"
801
802 #define N 4
803 #include "sim-n-core.h"
804
805 #define N 3
806 #define M 4
807 #include "sim-n-core.h"
808
809 #define N 2
810 #include "sim-n-core.h"
811
812 #define N 1
813 #include "sim-n-core.h"
814
815 #endif