Add iWMMXt support to ARM simulator
[external/binutils.git] / sim / arm / wrapper.c
1 /* run front end support for arm
2    Copyright (C) 1995, 1996, 1997, 2000, 2001, 2002
3    Free Software Foundation, Inc.
4
5    This file is part of ARM SIM.
6
7    GCC is free software; you can redistribute it and/or modify it
8    under the terms of the GNU General Public License as published
9    by the Free Software Foundation; either version 2, or (at your
10    option) any later version.
11
12    GCC is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   See
15    the GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public
18    License along with this program; if not, write to the Free
19    Software Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 /* This file provides the interface between the simulator and
23    run.c and gdb (when the simulator is linked with gdb).
24    All simulator interaction should go through this file.  */
25
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include <string.h>
29 #include <bfd.h>
30 #include <signal.h>
31 #include "gdb/callback.h"
32 #include "gdb/remote-sim.h"
33 #include "armdefs.h"
34 #include "armemu.h"
35 #include "dbg_rdi.h"
36 #include "ansidecl.h"
37 #include "sim-utils.h"
38 #include "run-sim.h"
39 #include "gdb/sim-arm.h"
40
41 host_callback *sim_callback;
42
43 static struct ARMul_State *state;
44
45 /* Who is using the simulator.  */
46 static SIM_OPEN_KIND sim_kind;
47
48 /* argv[0] */
49 static char *myname;
50
51 /* Memory size in bytes.  */
52 static int mem_size = (1 << 21);
53
54 /* Non-zero to display start up banner, and maybe other things.  */
55 static int verbosity;
56
57 /* Non-zero to set big endian mode.  */
58 static int big_endian;
59
60 int stop_simulator;
61
62 /* Cirrus DSP registers.
63
64    We need to define these registers outside of maverick.c because
65    maverick.c might not be linked in unless --target=arm9e-* in which
66    case wrapper.c will not compile because it tries to access Cirrus
67    registers.  This should all go away once we get the Cirrus and ARM
68    Coprocessor to coexist in armcopro.c-- aldyh.  */
69
70 struct maverick_regs
71 {
72   union
73   {
74     int i;
75     float f;
76   } upper;
77   
78   union
79   {
80     int i;
81     float f;
82   } lower;
83 };
84
85 union maverick_acc_regs
86 {
87   long double ld;               /* Acc registers are 72-bits.  */
88 };
89
90 struct maverick_regs     DSPregs[16];
91 union maverick_acc_regs  DSPacc[4];
92 ARMword DSPsc;
93
94 static void
95 init ()
96 {
97   static int done;
98
99   if (!done)
100     {
101       ARMul_EmulateInit ();
102       state = ARMul_NewState ();
103       state->bigendSig = (big_endian ? HIGH : LOW);
104       ARMul_MemoryInit (state, mem_size);
105       ARMul_OSInit (state);
106       state->verbose = verbosity;
107       done = 1;
108     }
109 }
110
111 /* Set verbosity level of simulator.
112    This is not intended to produce detailed tracing or debugging information.
113    Just summaries.  */
114 /* FIXME: common/run.c doesn't do this yet.  */
115
116 void
117 sim_set_verbose (v)
118      int v;
119 {
120   verbosity = v;
121 }
122
123 /* Set the memory size to SIZE bytes.
124    Must be called before initializing simulator.  */
125 /* FIXME: Rename to sim_set_mem_size.  */
126
127 void
128 sim_size (size)
129      int size;
130 {
131   mem_size = size;
132 }
133
134 void
135 ARMul_ConsolePrint VPARAMS ((ARMul_State * state,
136                              const char * format,
137                              ...))
138 {
139   va_list ap;
140
141   if (state->verbose)
142     {
143       va_start (ap, format);
144       vprintf (format, ap);
145       va_end (ap);
146     }
147 }
148
149 ARMword
150 ARMul_Debug (state, pc, instr)
151      ARMul_State * state ATTRIBUTE_UNUSED;
152      ARMword       pc    ATTRIBUTE_UNUSED;
153      ARMword       instr ATTRIBUTE_UNUSED;
154 {
155   return 0;
156 }
157
158 int
159 sim_write (sd, addr, buffer, size)
160      SIM_DESC sd ATTRIBUTE_UNUSED;
161      SIM_ADDR addr;
162      unsigned char * buffer;
163      int size;
164 {
165   int i;
166
167   init ();
168
169   for (i = 0; i < size; i++)
170     ARMul_SafeWriteByte (state, addr + i, buffer[i]);
171
172   return size;
173 }
174
175 int
176 sim_read (sd, addr, buffer, size)
177      SIM_DESC sd ATTRIBUTE_UNUSED;
178      SIM_ADDR addr;
179      unsigned char * buffer;
180      int size;
181 {
182   int i;
183
184   init ();
185
186   for (i = 0; i < size; i++)
187     buffer[i] = ARMul_SafeReadByte (state, addr + i);
188
189   return size;
190 }
191
192 int
193 sim_trace (sd)
194      SIM_DESC sd ATTRIBUTE_UNUSED;
195 {  
196   (*sim_callback->printf_filtered)
197     (sim_callback,
198      "This simulator does not support tracing\n");
199   return 1;
200 }
201
202 int
203 sim_stop (sd)
204      SIM_DESC sd ATTRIBUTE_UNUSED;
205 {
206   state->Emulate = STOP;
207   stop_simulator = 1;
208   return 1;
209 }
210
211 void
212 sim_resume (sd, step, siggnal)
213      SIM_DESC sd ATTRIBUTE_UNUSED;
214      int step;
215      int siggnal ATTRIBUTE_UNUSED;
216 {
217   state->EndCondition = 0;
218   stop_simulator = 0;
219
220   if (step)
221     {
222       state->Reg[15] = ARMul_DoInstr (state);
223       if (state->EndCondition == 0)
224         state->EndCondition = RDIError_BreakpointReached;
225     }
226   else
227     {
228       state->NextInstr = RESUME;        /* treat as PC change */
229       state->Reg[15] = ARMul_DoProg (state);
230     }
231
232   FLUSHPIPE;
233 }
234
235 SIM_RC
236 sim_create_inferior (sd, abfd, argv, env)
237      SIM_DESC sd ATTRIBUTE_UNUSED;
238      struct bfd * abfd;
239      char ** argv;
240      char ** env;
241 {
242   int argvlen = 0;
243   int mach;
244   char **arg;
245
246   if (abfd != NULL)
247     ARMul_SetPC (state, bfd_get_start_address (abfd));
248   else
249     ARMul_SetPC (state, 0);     /* ??? */
250
251   mach = bfd_get_mach (abfd);
252
253   switch (mach)
254     {
255     default:
256       (*sim_callback->printf_filtered)
257         (sim_callback,
258          "Unknown machine type '%d'; please update sim_create_inferior.\n",
259          mach);
260       /* fall through */
261
262     case 0:
263       /* We wouldn't set the machine type with earlier toolchains, so we
264          explicitly select a processor capable of supporting all ARMs in
265          32bit mode.  */
266       /* We choose the XScale rather than the iWMMXt, because the iWMMXt
267          removes the FPE emulator, since it conflicts with its coprocessors.
268          For the most generic ARM support, we want the FPE emulator in place.  */
269     case bfd_mach_arm_XScale:
270       ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
271       break;
272
273     case bfd_mach_arm_iWMMXt:
274       {
275         extern int SWI_vector_installed;
276         ARMword i;
277
278         if (! SWI_vector_installed)
279           {
280             /* Intialise the hardware vectors to zero.  */
281             if (! SWI_vector_installed)
282               for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
283                 ARMul_WriteWord (state, i, 0);
284
285             /* ARM_WriteWord will have detected the write to the SWI vector,
286                but we want SWI_vector_installed to remain at 0 so that thumb
287                mode breakpoints will work.  */
288             SWI_vector_installed = 0;
289           }
290       }
291       ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_iWMMXt_Prop);
292       break;
293
294     case bfd_mach_arm_ep9312:
295       ARMul_SelectProcessor (state, ARM_v4_Prop | ARM_ep9312_Prop);
296       break;
297
298     case bfd_mach_arm_5:
299       if (bfd_family_coff (abfd))
300         {
301           /* This is a special case in order to support COFF based ARM toolchains.
302              The COFF header does not have enough room to store all the different
303              kinds of ARM cpu, so the XScale, v5T and v5TE architectures all default
304              to v5.  (See coff_set_flags() in bdf/coffcode.h).  So if we see a v5
305              machine type here, we assume it could be any of the above architectures
306              and so select the most feature-full.  */
307           ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
308           break;
309         }
310       /* Otherwise drop through.  */
311
312     case bfd_mach_arm_5T:
313       ARMul_SelectProcessor (state, ARM_v5_Prop);
314       break;
315
316     case bfd_mach_arm_5TE:
317       ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop);
318       break;
319
320     case bfd_mach_arm_4:
321     case bfd_mach_arm_4T:
322       ARMul_SelectProcessor (state, ARM_v4_Prop);
323       break;
324
325     case bfd_mach_arm_3:
326     case bfd_mach_arm_3M:
327       ARMul_SelectProcessor (state, ARM_Lock_Prop);
328       break;
329
330     case bfd_mach_arm_2:
331     case bfd_mach_arm_2a:
332       ARMul_SelectProcessor (state, ARM_Fix26_Prop);
333       break;
334     }
335
336   if (   mach != bfd_mach_arm_3
337       && mach != bfd_mach_arm_3M
338       && mach != bfd_mach_arm_2
339       && mach != bfd_mach_arm_2a)
340     {
341       /* Reset mode to ARM.  A gdb user may rerun a program that had entered
342          THUMB mode from the start and cause the ARM-mode startup code to be
343          executed in THUMB mode.  */
344       ARMul_SetCPSR (state, SVC32MODE);
345     }
346   
347   if (argv != NULL)
348     {
349       /* Set up the command line by laboriously stringing together
350          the environment carefully picked apart by our caller.  */
351
352       /* Free any old stuff.  */
353       if (state->CommandLine != NULL)
354         {
355           free (state->CommandLine);
356           state->CommandLine = NULL;
357         }
358
359       /* See how much we need.  */
360       for (arg = argv; *arg != NULL; arg++)
361         argvlen += strlen (*arg) + 1;
362
363       /* Allocate it.  */
364       state->CommandLine = malloc (argvlen + 1);
365       if (state->CommandLine != NULL)
366         {
367           arg = argv;
368           state->CommandLine[0] = '\0';
369
370           for (arg = argv; *arg != NULL; arg++)
371             {
372               strcat (state->CommandLine, *arg);
373               strcat (state->CommandLine, " ");
374             }
375         }
376     }
377
378   if (env != NULL)
379     {
380       /* Now see if there's a MEMSIZE spec in the environment.  */
381       while (*env)
382         {
383           if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
384             {
385               char *end_of_num;
386
387               /* Set up memory limit.  */
388               state->MemSize =
389                 strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0);
390             }
391           env++;
392         }
393     }
394
395   return SIM_RC_OK;
396 }
397
398 void
399 sim_info (sd, verbose)
400      SIM_DESC sd ATTRIBUTE_UNUSED;
401      int verbose ATTRIBUTE_UNUSED;
402 {
403 }
404
405 static int
406 frommem (state, memory)
407      struct ARMul_State *state;
408      unsigned char *memory;
409 {
410   if (state->bigendSig == HIGH)
411     return (memory[0] << 24) | (memory[1] << 16)
412       | (memory[2] << 8) | (memory[3] << 0);
413   else
414     return (memory[3] << 24) | (memory[2] << 16)
415       | (memory[1] << 8) | (memory[0] << 0);
416 }
417
418 static void
419 tomem (state, memory, val)
420      struct ARMul_State *state;
421      unsigned char *memory;
422      int val;
423 {
424   if (state->bigendSig == HIGH)
425     {
426       memory[0] = val >> 24;
427       memory[1] = val >> 16;
428       memory[2] = val >> 8;
429       memory[3] = val >> 0;
430     }
431   else
432     {
433       memory[3] = val >> 24;
434       memory[2] = val >> 16;
435       memory[1] = val >> 8;
436       memory[0] = val >> 0;
437     }
438 }
439
440 int
441 sim_store_register (sd, rn, memory, length)
442      SIM_DESC sd ATTRIBUTE_UNUSED;
443      int rn;
444      unsigned char *memory;
445      int length ATTRIBUTE_UNUSED;
446 {
447   init ();
448
449   switch ((enum sim_arm_regs) rn)
450     {
451     case SIM_ARM_R0_REGNUM:
452     case SIM_ARM_R1_REGNUM:
453     case SIM_ARM_R2_REGNUM:
454     case SIM_ARM_R3_REGNUM:
455     case SIM_ARM_R4_REGNUM:
456     case SIM_ARM_R5_REGNUM:
457     case SIM_ARM_R6_REGNUM:
458     case SIM_ARM_R7_REGNUM:
459     case SIM_ARM_R8_REGNUM:
460     case SIM_ARM_R9_REGNUM:
461     case SIM_ARM_R10_REGNUM:
462     case SIM_ARM_R11_REGNUM:
463     case SIM_ARM_R12_REGNUM:
464     case SIM_ARM_R13_REGNUM:
465     case SIM_ARM_R14_REGNUM:
466     case SIM_ARM_R15_REGNUM: /* PC */
467     case SIM_ARM_FP0_REGNUM:
468     case SIM_ARM_FP1_REGNUM:
469     case SIM_ARM_FP2_REGNUM:
470     case SIM_ARM_FP3_REGNUM:
471     case SIM_ARM_FP4_REGNUM:
472     case SIM_ARM_FP5_REGNUM:
473     case SIM_ARM_FP6_REGNUM:
474     case SIM_ARM_FP7_REGNUM:
475     case SIM_ARM_FPS_REGNUM:
476       ARMul_SetReg (state, state->Mode, rn, frommem (state, memory));
477       break;
478
479     case SIM_ARM_PS_REGNUM:
480       state->Cpsr = frommem (state, memory);
481       ARMul_CPSRAltered (state);
482       break;
483
484     case SIM_ARM_MAVERIC_COP0R0_REGNUM:
485     case SIM_ARM_MAVERIC_COP0R1_REGNUM:
486     case SIM_ARM_MAVERIC_COP0R2_REGNUM:
487     case SIM_ARM_MAVERIC_COP0R3_REGNUM:
488     case SIM_ARM_MAVERIC_COP0R4_REGNUM:
489     case SIM_ARM_MAVERIC_COP0R5_REGNUM:
490     case SIM_ARM_MAVERIC_COP0R6_REGNUM:
491     case SIM_ARM_MAVERIC_COP0R7_REGNUM:
492     case SIM_ARM_MAVERIC_COP0R8_REGNUM:
493     case SIM_ARM_MAVERIC_COP0R9_REGNUM:
494     case SIM_ARM_MAVERIC_COP0R10_REGNUM:
495     case SIM_ARM_MAVERIC_COP0R11_REGNUM:
496     case SIM_ARM_MAVERIC_COP0R12_REGNUM:
497     case SIM_ARM_MAVERIC_COP0R13_REGNUM:
498     case SIM_ARM_MAVERIC_COP0R14_REGNUM:
499     case SIM_ARM_MAVERIC_COP0R15_REGNUM:
500       memcpy (& DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
501               memory, sizeof (struct maverick_regs));
502       return sizeof (struct maverick_regs);
503
504     case SIM_ARM_MAVERIC_DSPSC_REGNUM:
505       memcpy (&DSPsc, memory, sizeof DSPsc);
506       return sizeof DSPsc;
507
508 #ifdef __IWMMXT__
509     case SIM_ARM_IWMMXT_COP0R0_REGNUM:
510     case SIM_ARM_IWMMXT_COP0R1_REGNUM:
511     case SIM_ARM_IWMMXT_COP0R2_REGNUM:
512     case SIM_ARM_IWMMXT_COP0R3_REGNUM:
513     case SIM_ARM_IWMMXT_COP0R4_REGNUM:
514     case SIM_ARM_IWMMXT_COP0R5_REGNUM:
515     case SIM_ARM_IWMMXT_COP0R6_REGNUM:
516     case SIM_ARM_IWMMXT_COP0R7_REGNUM:
517     case SIM_ARM_IWMMXT_COP0R8_REGNUM:
518     case SIM_ARM_IWMMXT_COP0R9_REGNUM:
519     case SIM_ARM_IWMMXT_COP0R10_REGNUM:
520     case SIM_ARM_IWMMXT_COP0R11_REGNUM:
521     case SIM_ARM_IWMMXT_COP0R12_REGNUM:
522     case SIM_ARM_IWMMXT_COP0R13_REGNUM:
523     case SIM_ARM_IWMMXT_COP0R14_REGNUM:
524     case SIM_ARM_IWMMXT_COP0R15_REGNUM:
525     case SIM_ARM_IWMMXT_COP1R0_REGNUM:
526     case SIM_ARM_IWMMXT_COP1R1_REGNUM:
527     case SIM_ARM_IWMMXT_COP1R2_REGNUM:
528     case SIM_ARM_IWMMXT_COP1R3_REGNUM:
529     case SIM_ARM_IWMMXT_COP1R4_REGNUM:
530     case SIM_ARM_IWMMXT_COP1R5_REGNUM:
531     case SIM_ARM_IWMMXT_COP1R6_REGNUM:
532     case SIM_ARM_IWMMXT_COP1R7_REGNUM:
533     case SIM_ARM_IWMMXT_COP1R8_REGNUM:
534     case SIM_ARM_IWMMXT_COP1R9_REGNUM:
535     case SIM_ARM_IWMMXT_COP1R10_REGNUM:
536     case SIM_ARM_IWMMXT_COP1R11_REGNUM:
537     case SIM_ARM_IWMMXT_COP1R12_REGNUM:
538     case SIM_ARM_IWMMXT_COP1R13_REGNUM:
539     case SIM_ARM_IWMMXT_COP1R14_REGNUM:
540     case SIM_ARM_IWMMXT_COP1R15_REGNUM:
541       return Store_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
542 #endif
543     default:
544       return 0;
545     }
546
547   return -1;
548 }
549
550 int
551 sim_fetch_register (sd, rn, memory, length)
552      SIM_DESC sd ATTRIBUTE_UNUSED;
553      int rn;
554      unsigned char *memory;
555      int length ATTRIBUTE_UNUSED;
556 {
557   ARMword regval;
558
559   init ();
560
561   switch ((enum sim_arm_regs) rn)
562     {
563     case SIM_ARM_R0_REGNUM:
564     case SIM_ARM_R1_REGNUM:
565     case SIM_ARM_R2_REGNUM:
566     case SIM_ARM_R3_REGNUM:
567     case SIM_ARM_R4_REGNUM:
568     case SIM_ARM_R5_REGNUM:
569     case SIM_ARM_R6_REGNUM:
570     case SIM_ARM_R7_REGNUM:
571     case SIM_ARM_R8_REGNUM:
572     case SIM_ARM_R9_REGNUM:
573     case SIM_ARM_R10_REGNUM:
574     case SIM_ARM_R11_REGNUM:
575     case SIM_ARM_R12_REGNUM:
576     case SIM_ARM_R13_REGNUM:
577     case SIM_ARM_R14_REGNUM:
578     case SIM_ARM_R15_REGNUM: /* PC */
579       regval = ARMul_GetReg (state, state->Mode, rn);
580       break;
581
582     case SIM_ARM_FP0_REGNUM:
583     case SIM_ARM_FP1_REGNUM:
584     case SIM_ARM_FP2_REGNUM:
585     case SIM_ARM_FP3_REGNUM:
586     case SIM_ARM_FP4_REGNUM:
587     case SIM_ARM_FP5_REGNUM:
588     case SIM_ARM_FP6_REGNUM:
589     case SIM_ARM_FP7_REGNUM:
590     case SIM_ARM_FPS_REGNUM:
591       memset (memory, 0, length);
592       return 0;
593
594     case SIM_ARM_PS_REGNUM:
595       regval = ARMul_GetCPSR (state);
596       break;
597
598     case SIM_ARM_MAVERIC_COP0R0_REGNUM:
599     case SIM_ARM_MAVERIC_COP0R1_REGNUM:
600     case SIM_ARM_MAVERIC_COP0R2_REGNUM:
601     case SIM_ARM_MAVERIC_COP0R3_REGNUM:
602     case SIM_ARM_MAVERIC_COP0R4_REGNUM:
603     case SIM_ARM_MAVERIC_COP0R5_REGNUM:
604     case SIM_ARM_MAVERIC_COP0R6_REGNUM:
605     case SIM_ARM_MAVERIC_COP0R7_REGNUM:
606     case SIM_ARM_MAVERIC_COP0R8_REGNUM:
607     case SIM_ARM_MAVERIC_COP0R9_REGNUM:
608     case SIM_ARM_MAVERIC_COP0R10_REGNUM:
609     case SIM_ARM_MAVERIC_COP0R11_REGNUM:
610     case SIM_ARM_MAVERIC_COP0R12_REGNUM:
611     case SIM_ARM_MAVERIC_COP0R13_REGNUM:
612     case SIM_ARM_MAVERIC_COP0R14_REGNUM:
613     case SIM_ARM_MAVERIC_COP0R15_REGNUM:
614       memcpy (memory, & DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
615               sizeof (struct maverick_regs));
616       return sizeof (struct maverick_regs);
617
618     case SIM_ARM_MAVERIC_DSPSC_REGNUM:
619       memcpy (memory, & DSPsc, sizeof DSPsc);
620       return sizeof DSPsc;
621
622 #ifdef __IWMMXT__
623     case SIM_ARM_IWMMXT_COP0R0_REGNUM:
624     case SIM_ARM_IWMMXT_COP0R1_REGNUM:
625     case SIM_ARM_IWMMXT_COP0R2_REGNUM:
626     case SIM_ARM_IWMMXT_COP0R3_REGNUM:
627     case SIM_ARM_IWMMXT_COP0R4_REGNUM:
628     case SIM_ARM_IWMMXT_COP0R5_REGNUM:
629     case SIM_ARM_IWMMXT_COP0R6_REGNUM:
630     case SIM_ARM_IWMMXT_COP0R7_REGNUM:
631     case SIM_ARM_IWMMXT_COP0R8_REGNUM:
632     case SIM_ARM_IWMMXT_COP0R9_REGNUM:
633     case SIM_ARM_IWMMXT_COP0R10_REGNUM:
634     case SIM_ARM_IWMMXT_COP0R11_REGNUM:
635     case SIM_ARM_IWMMXT_COP0R12_REGNUM:
636     case SIM_ARM_IWMMXT_COP0R13_REGNUM:
637     case SIM_ARM_IWMMXT_COP0R14_REGNUM:
638     case SIM_ARM_IWMMXT_COP0R15_REGNUM:
639     case SIM_ARM_IWMMXT_COP1R0_REGNUM:
640     case SIM_ARM_IWMMXT_COP1R1_REGNUM:
641     case SIM_ARM_IWMMXT_COP1R2_REGNUM:
642     case SIM_ARM_IWMMXT_COP1R3_REGNUM:
643     case SIM_ARM_IWMMXT_COP1R4_REGNUM:
644     case SIM_ARM_IWMMXT_COP1R5_REGNUM:
645     case SIM_ARM_IWMMXT_COP1R6_REGNUM:
646     case SIM_ARM_IWMMXT_COP1R7_REGNUM:
647     case SIM_ARM_IWMMXT_COP1R8_REGNUM:
648     case SIM_ARM_IWMMXT_COP1R9_REGNUM:
649     case SIM_ARM_IWMMXT_COP1R10_REGNUM:
650     case SIM_ARM_IWMMXT_COP1R11_REGNUM:
651     case SIM_ARM_IWMMXT_COP1R12_REGNUM:
652     case SIM_ARM_IWMMXT_COP1R13_REGNUM:
653     case SIM_ARM_IWMMXT_COP1R14_REGNUM:
654     case SIM_ARM_IWMMXT_COP1R15_REGNUM:
655       return Fetch_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
656 #endif
657     default:
658       return 0;
659     }
660
661   while (length)
662     {
663       tomem (state, memory, regval);
664
665       length -= 4;
666       memory += 4;
667       regval = 0;
668     }  
669
670   return -1;
671 }
672
673 #ifdef SIM_TARGET_SWITCHES
674
675 static void sim_target_parse_arg_array PARAMS ((char **));
676
677 typedef struct
678 {
679   char *        swi_option;
680   unsigned int  swi_mask;
681 } swi_options;
682
683 #define SWI_SWITCH      "--swi-support"
684
685 static swi_options options[] =
686   {
687     { "none",    0 },
688     { "demon",   SWI_MASK_DEMON },
689     { "angel",   SWI_MASK_ANGEL },
690     { "redboot", SWI_MASK_REDBOOT },
691     { "all",     -1 },
692     { "NONE",    0 },
693     { "DEMON",   SWI_MASK_DEMON },
694     { "ANGEL",   SWI_MASK_ANGEL },
695     { "REDBOOT", SWI_MASK_REDBOOT },
696     { "ALL",     -1 }
697   };
698
699
700 int
701 sim_target_parse_command_line (argc, argv)
702      int argc;
703      char ** argv;
704 {
705   int i;
706
707   for (i = 1; i < argc; i++)
708     {
709       char * ptr = argv[i];
710       int arg;
711
712       if ((ptr == NULL) || (* ptr != '-'))
713         break;
714
715       if (strncmp (ptr, SWI_SWITCH, sizeof SWI_SWITCH - 1) != 0)
716         continue;
717
718       if (ptr[sizeof SWI_SWITCH - 1] == 0)
719         {
720           /* Remove this option from the argv array.  */
721           for (arg = i; arg < argc; arg ++)
722             argv[arg] = argv[arg + 1];
723           argc --;
724           
725           ptr = argv[i];
726         }
727       else
728         ptr += sizeof SWI_SWITCH;
729
730       swi_mask = 0;
731       
732       while (* ptr)
733         {
734           int i;
735
736           for (i = sizeof options / sizeof options[0]; i--;)
737             if (strncmp (ptr, options[i].swi_option,
738                          strlen (options[i].swi_option)) == 0)
739               {
740                 swi_mask |= options[i].swi_mask;
741                 ptr += strlen (options[i].swi_option);
742
743                 if (* ptr == ',')
744                   ++ ptr;
745
746                 break;
747               }
748
749           if (i < 0)
750             break;
751         }
752
753       if (* ptr != 0)
754         fprintf (stderr, "Ignoring swi options: %s\n", ptr);
755       
756       /* Remove this option from the argv array.  */
757       for (arg = i; arg < argc; arg ++)
758         argv[arg] = argv[arg + 1];
759       argc --;
760       i --;
761     }
762   return argc;
763 }
764
765 static void
766 sim_target_parse_arg_array (argv)
767      char ** argv;
768 {
769   int i;
770
771   for (i = 0; argv[i]; i++)
772     ;
773
774   return (void) sim_target_parse_command_line (i, argv);
775 }
776
777 void
778 sim_target_display_usage ()
779 {
780   fprintf (stderr, "%s=<list>  Comma seperated list of SWI protocols to supoport.\n\
781                 This list can contain: NONE, DEMON, ANGEL, REDBOOT and/or ALL.\n",
782            SWI_SWITCH);
783 }
784 #endif
785
786 SIM_DESC
787 sim_open (kind, ptr, abfd, argv)
788      SIM_OPEN_KIND kind;
789      host_callback *ptr;
790      struct bfd *abfd;
791      char **argv;
792 {
793   sim_kind = kind;
794   if (myname) free (myname);
795   myname = (char *) xstrdup (argv[0]);
796   sim_callback = ptr;
797
798 #ifdef SIM_TARGET_SWITCHES
799   sim_target_parse_arg_array (argv);
800 #endif
801   
802   /* Decide upon the endian-ness of the processor.
803      If we can, get the information from the bfd itself.
804      Otherwise look to see if we have been given a command
805      line switch that tells us.  Otherwise default to little endian.  */
806   if (abfd != NULL)
807     big_endian = bfd_big_endian (abfd);
808   else if (argv[1] != NULL)
809     {
810       int i;
811
812       /* Scan for endian-ness and memory-size switches.  */
813       for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++)
814         if (argv[i][0] == '-' && argv[i][1] == 'E')
815           {
816             char c;
817
818             if ((c = argv[i][2]) == 0)
819               {
820                 ++i;
821                 c = argv[i][0];
822               }
823
824             switch (c)
825               {
826               case 0:
827                 sim_callback->printf_filtered
828                   (sim_callback, "No argument to -E option provided\n");
829                 break;
830
831               case 'b':
832               case 'B':
833                 big_endian = 1;
834                 break;
835
836               case 'l':
837               case 'L':
838                 big_endian = 0;
839                 break;
840
841               default:
842                 sim_callback->printf_filtered
843                   (sim_callback, "Unrecognised argument to -E option\n");
844                 break;
845               }
846           }
847         else if (argv[i][0] == '-' && argv[i][1] == 'm')
848           {
849             if (argv[i][2] != '\0')
850               sim_size (atoi (&argv[i][2]));
851             else if (argv[i + 1] != NULL)
852               {
853                 sim_size (atoi (argv[i + 1]));
854                 i++;
855               }
856             else
857               {
858                 sim_callback->printf_filtered (sim_callback,
859                                                "Missing argument to -m option\n");
860                 return NULL;
861               }
862               
863           }
864     }
865
866   return (SIM_DESC) 1;
867 }
868
869 void
870 sim_close (sd, quitting)
871      SIM_DESC sd ATTRIBUTE_UNUSED;
872      int quitting ATTRIBUTE_UNUSED;
873 {
874   if (myname)
875     free (myname);
876   myname = NULL;
877 }
878
879 SIM_RC
880 sim_load (sd, prog, abfd, from_tty)
881      SIM_DESC sd;
882      char *prog;
883      bfd *abfd;
884      int from_tty ATTRIBUTE_UNUSED;
885 {
886   bfd *prog_bfd;
887
888   prog_bfd = sim_load_file (sd, myname, sim_callback, prog, abfd,
889                             sim_kind == SIM_OPEN_DEBUG, 0, sim_write);
890   if (prog_bfd == NULL)
891     return SIM_RC_FAIL;
892   ARMul_SetPC (state, bfd_get_start_address (prog_bfd));
893   if (abfd == NULL)
894     bfd_close (prog_bfd);
895   return SIM_RC_OK;
896 }
897
898 void
899 sim_stop_reason (sd, reason, sigrc)
900      SIM_DESC sd ATTRIBUTE_UNUSED;
901      enum sim_stop *reason;
902      int *sigrc;
903 {
904   if (stop_simulator)
905     {
906       *reason = sim_stopped;
907       *sigrc = SIGINT;
908     }
909   else if (state->EndCondition == 0)
910     {
911       *reason = sim_exited;
912       *sigrc = state->Reg[0] & 255;
913     }
914   else
915     {
916       *reason = sim_stopped;
917       if (state->EndCondition == RDIError_BreakpointReached)
918         *sigrc = SIGTRAP;
919       else if (   state->EndCondition == RDIError_DataAbort
920                || state->EndCondition == RDIError_AddressException)
921         *sigrc = SIGBUS;
922       else
923         *sigrc = 0;
924     }
925 }
926
927 void
928 sim_do_command (sd, cmd)
929      SIM_DESC sd ATTRIBUTE_UNUSED;
930      char *cmd ATTRIBUTE_UNUSED;
931 {  
932   (*sim_callback->printf_filtered)
933     (sim_callback,
934      "This simulator does not accept any commands.\n");
935 }
936
937 void
938 sim_set_callbacks (ptr)
939      host_callback *ptr;
940 {
941   sim_callback = ptr;
942 }