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