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