sim/arm: Prevent NULL pointer dereference in sim_create_inferior.
[external/binutils.git] / sim / arm / wrapper.c
1 /* run front end support for arm
2    Copyright (C) 1995-2013 Free Software Foundation, Inc.
3
4    This file is part of ARM SIM.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19 /* This file provides the interface between the simulator and
20    run.c and gdb (when the simulator is linked with gdb).
21    All simulator interaction should go through this file.  */
22
23 #include "config.h"
24 #include <stdio.h>
25 #include <stdarg.h>
26 #include <string.h>
27 #include <bfd.h>
28 #include <signal.h>
29 #include "gdb/callback.h"
30 #include "gdb/remote-sim.h"
31 #include "armdefs.h"
32 #include "armemu.h"
33 #include "dbg_rdi.h"
34 #include "ansidecl.h"
35 #include "sim-utils.h"
36 #include "run-sim.h"
37 #include "gdb/sim-arm.h"
38 #include "gdb/signals.h"
39 #include "libiberty.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      const 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     {
248       ARMul_SetPC (state, bfd_get_start_address (abfd));
249       mach = bfd_get_mach (abfd);
250     }
251   else
252     {
253       ARMul_SetPC (state, 0);   /* ??? */
254       mach = 0;
255     }
256
257   switch (mach)
258     {
259     default:
260       (*sim_callback->printf_filtered)
261         (sim_callback,
262          "Unknown machine type '%d'; please update sim_create_inferior.\n",
263          mach);
264       /* fall through */
265
266     case 0:
267       /* We wouldn't set the machine type with earlier toolchains, so we
268          explicitly select a processor capable of supporting all ARMs in
269          32bit mode.  */
270       /* We choose the XScale rather than the iWMMXt, because the iWMMXt
271          removes the FPE emulator, since it conflicts with its coprocessors.
272          For the most generic ARM support, we want the FPE emulator in place.  */
273     case bfd_mach_arm_XScale:
274       ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_v6_Prop);
275       break;
276
277     case bfd_mach_arm_iWMMXt2:
278     case bfd_mach_arm_iWMMXt:
279       {
280         extern int SWI_vector_installed;
281         ARMword i;
282
283         if (! SWI_vector_installed)
284           {
285             /* Intialise the hardware vectors to zero.  */
286             if (! SWI_vector_installed)
287               for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
288                 ARMul_WriteWord (state, i, 0);
289
290             /* ARM_WriteWord will have detected the write to the SWI vector,
291                but we want SWI_vector_installed to remain at 0 so that thumb
292                mode breakpoints will work.  */
293             SWI_vector_installed = 0;
294           }
295       }
296       ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_iWMMXt_Prop);
297       break;
298
299     case bfd_mach_arm_ep9312:
300       ARMul_SelectProcessor (state, ARM_v4_Prop | ARM_ep9312_Prop);
301       break;
302
303     case bfd_mach_arm_5:
304       if (bfd_family_coff (abfd))
305         {
306           /* This is a special case in order to support COFF based ARM toolchains.
307              The COFF header does not have enough room to store all the different
308              kinds of ARM cpu, so the XScale, v5T and v5TE architectures all default
309              to v5.  (See coff_set_flags() in bdf/coffcode.h).  So if we see a v5
310              machine type here, we assume it could be any of the above architectures
311              and so select the most feature-full.  */
312           ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
313           break;
314         }
315       /* Otherwise drop through.  */
316
317     case bfd_mach_arm_5T:
318       ARMul_SelectProcessor (state, ARM_v5_Prop);
319       break;
320
321     case bfd_mach_arm_5TE:
322       ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop);
323       break;
324
325     case bfd_mach_arm_4:
326     case bfd_mach_arm_4T:
327       ARMul_SelectProcessor (state, ARM_v4_Prop);
328       break;
329
330     case bfd_mach_arm_3:
331     case bfd_mach_arm_3M:
332       ARMul_SelectProcessor (state, ARM_Lock_Prop);
333       break;
334
335     case bfd_mach_arm_2:
336     case bfd_mach_arm_2a:
337       ARMul_SelectProcessor (state, ARM_Fix26_Prop);
338       break;
339     }
340
341   if (   mach != bfd_mach_arm_3
342       && mach != bfd_mach_arm_3M
343       && mach != bfd_mach_arm_2
344       && mach != bfd_mach_arm_2a)
345     {
346       /* Reset mode to ARM.  A gdb user may rerun a program that had entered
347          THUMB mode from the start and cause the ARM-mode startup code to be
348          executed in THUMB mode.  */
349       ARMul_SetCPSR (state, SVC32MODE);
350     }
351   
352   if (argv != NULL)
353     {
354       /* Set up the command line by laboriously stringing together
355          the environment carefully picked apart by our caller.  */
356
357       /* Free any old stuff.  */
358       if (state->CommandLine != NULL)
359         {
360           free (state->CommandLine);
361           state->CommandLine = NULL;
362         }
363
364       /* See how much we need.  */
365       for (arg = argv; *arg != NULL; arg++)
366         argvlen += strlen (*arg) + 1;
367
368       /* Allocate it.  */
369       state->CommandLine = malloc (argvlen + 1);
370       if (state->CommandLine != NULL)
371         {
372           arg = argv;
373           state->CommandLine[0] = '\0';
374
375           for (arg = argv; *arg != NULL; arg++)
376             {
377               strcat (state->CommandLine, *arg);
378               strcat (state->CommandLine, " ");
379             }
380         }
381     }
382
383   if (env != NULL)
384     {
385       /* Now see if there's a MEMSIZE spec in the environment.  */
386       while (*env)
387         {
388           if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
389             {
390               char *end_of_num;
391
392               /* Set up memory limit.  */
393               state->MemSize =
394                 strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0);
395             }
396           env++;
397         }
398     }
399
400   return SIM_RC_OK;
401 }
402
403 void
404 sim_info (sd, verbose)
405      SIM_DESC sd ATTRIBUTE_UNUSED;
406      int verbose ATTRIBUTE_UNUSED;
407 {
408 }
409
410 static int
411 frommem (state, memory)
412      struct ARMul_State *state;
413      unsigned char *memory;
414 {
415   if (state->bigendSig == HIGH)
416     return (memory[0] << 24) | (memory[1] << 16)
417       | (memory[2] << 8) | (memory[3] << 0);
418   else
419     return (memory[3] << 24) | (memory[2] << 16)
420       | (memory[1] << 8) | (memory[0] << 0);
421 }
422
423 static void
424 tomem (state, memory, val)
425      struct ARMul_State *state;
426      unsigned char *memory;
427      int val;
428 {
429   if (state->bigendSig == HIGH)
430     {
431       memory[0] = val >> 24;
432       memory[1] = val >> 16;
433       memory[2] = val >> 8;
434       memory[3] = val >> 0;
435     }
436   else
437     {
438       memory[3] = val >> 24;
439       memory[2] = val >> 16;
440       memory[1] = val >> 8;
441       memory[0] = val >> 0;
442     }
443 }
444
445 int
446 sim_store_register (sd, rn, memory, length)
447      SIM_DESC sd ATTRIBUTE_UNUSED;
448      int rn;
449      unsigned char *memory;
450      int length;
451 {
452   init ();
453
454   switch ((enum sim_arm_regs) rn)
455     {
456     case SIM_ARM_R0_REGNUM:
457     case SIM_ARM_R1_REGNUM:
458     case SIM_ARM_R2_REGNUM:
459     case SIM_ARM_R3_REGNUM:
460     case SIM_ARM_R4_REGNUM:
461     case SIM_ARM_R5_REGNUM:
462     case SIM_ARM_R6_REGNUM:
463     case SIM_ARM_R7_REGNUM:
464     case SIM_ARM_R8_REGNUM:
465     case SIM_ARM_R9_REGNUM:
466     case SIM_ARM_R10_REGNUM:
467     case SIM_ARM_R11_REGNUM:
468     case SIM_ARM_R12_REGNUM:
469     case SIM_ARM_R13_REGNUM:
470     case SIM_ARM_R14_REGNUM:
471     case SIM_ARM_R15_REGNUM: /* PC */
472     case SIM_ARM_FP0_REGNUM:
473     case SIM_ARM_FP1_REGNUM:
474     case SIM_ARM_FP2_REGNUM:
475     case SIM_ARM_FP3_REGNUM:
476     case SIM_ARM_FP4_REGNUM:
477     case SIM_ARM_FP5_REGNUM:
478     case SIM_ARM_FP6_REGNUM:
479     case SIM_ARM_FP7_REGNUM:
480     case SIM_ARM_FPS_REGNUM:
481       ARMul_SetReg (state, state->Mode, rn, frommem (state, memory));
482       break;
483
484     case SIM_ARM_PS_REGNUM:
485       state->Cpsr = frommem (state, memory);
486       ARMul_CPSRAltered (state);
487       break;
488
489     case SIM_ARM_MAVERIC_COP0R0_REGNUM:
490     case SIM_ARM_MAVERIC_COP0R1_REGNUM:
491     case SIM_ARM_MAVERIC_COP0R2_REGNUM:
492     case SIM_ARM_MAVERIC_COP0R3_REGNUM:
493     case SIM_ARM_MAVERIC_COP0R4_REGNUM:
494     case SIM_ARM_MAVERIC_COP0R5_REGNUM:
495     case SIM_ARM_MAVERIC_COP0R6_REGNUM:
496     case SIM_ARM_MAVERIC_COP0R7_REGNUM:
497     case SIM_ARM_MAVERIC_COP0R8_REGNUM:
498     case SIM_ARM_MAVERIC_COP0R9_REGNUM:
499     case SIM_ARM_MAVERIC_COP0R10_REGNUM:
500     case SIM_ARM_MAVERIC_COP0R11_REGNUM:
501     case SIM_ARM_MAVERIC_COP0R12_REGNUM:
502     case SIM_ARM_MAVERIC_COP0R13_REGNUM:
503     case SIM_ARM_MAVERIC_COP0R14_REGNUM:
504     case SIM_ARM_MAVERIC_COP0R15_REGNUM:
505       memcpy (& DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
506               memory, sizeof (struct maverick_regs));
507       return sizeof (struct maverick_regs);
508
509     case SIM_ARM_MAVERIC_DSPSC_REGNUM:
510       memcpy (&DSPsc, memory, sizeof DSPsc);
511       return sizeof DSPsc;
512
513     case SIM_ARM_IWMMXT_COP0R0_REGNUM:
514     case SIM_ARM_IWMMXT_COP0R1_REGNUM:
515     case SIM_ARM_IWMMXT_COP0R2_REGNUM:
516     case SIM_ARM_IWMMXT_COP0R3_REGNUM:
517     case SIM_ARM_IWMMXT_COP0R4_REGNUM:
518     case SIM_ARM_IWMMXT_COP0R5_REGNUM:
519     case SIM_ARM_IWMMXT_COP0R6_REGNUM:
520     case SIM_ARM_IWMMXT_COP0R7_REGNUM:
521     case SIM_ARM_IWMMXT_COP0R8_REGNUM:
522     case SIM_ARM_IWMMXT_COP0R9_REGNUM:
523     case SIM_ARM_IWMMXT_COP0R10_REGNUM:
524     case SIM_ARM_IWMMXT_COP0R11_REGNUM:
525     case SIM_ARM_IWMMXT_COP0R12_REGNUM:
526     case SIM_ARM_IWMMXT_COP0R13_REGNUM:
527     case SIM_ARM_IWMMXT_COP0R14_REGNUM:
528     case SIM_ARM_IWMMXT_COP0R15_REGNUM:
529     case SIM_ARM_IWMMXT_COP1R0_REGNUM:
530     case SIM_ARM_IWMMXT_COP1R1_REGNUM:
531     case SIM_ARM_IWMMXT_COP1R2_REGNUM:
532     case SIM_ARM_IWMMXT_COP1R3_REGNUM:
533     case SIM_ARM_IWMMXT_COP1R4_REGNUM:
534     case SIM_ARM_IWMMXT_COP1R5_REGNUM:
535     case SIM_ARM_IWMMXT_COP1R6_REGNUM:
536     case SIM_ARM_IWMMXT_COP1R7_REGNUM:
537     case SIM_ARM_IWMMXT_COP1R8_REGNUM:
538     case SIM_ARM_IWMMXT_COP1R9_REGNUM:
539     case SIM_ARM_IWMMXT_COP1R10_REGNUM:
540     case SIM_ARM_IWMMXT_COP1R11_REGNUM:
541     case SIM_ARM_IWMMXT_COP1R12_REGNUM:
542     case SIM_ARM_IWMMXT_COP1R13_REGNUM:
543     case SIM_ARM_IWMMXT_COP1R14_REGNUM:
544     case SIM_ARM_IWMMXT_COP1R15_REGNUM:
545       return Store_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
546
547     default:
548       return 0;
549     }
550
551   return length;
552 }
553
554 int
555 sim_fetch_register (sd, rn, memory, length)
556      SIM_DESC sd ATTRIBUTE_UNUSED;
557      int rn;
558      unsigned char *memory;
559      int length;
560 {
561   ARMword regval;
562   int len = length;
563
564   init ();
565
566   switch ((enum sim_arm_regs) rn)
567     {
568     case SIM_ARM_R0_REGNUM:
569     case SIM_ARM_R1_REGNUM:
570     case SIM_ARM_R2_REGNUM:
571     case SIM_ARM_R3_REGNUM:
572     case SIM_ARM_R4_REGNUM:
573     case SIM_ARM_R5_REGNUM:
574     case SIM_ARM_R6_REGNUM:
575     case SIM_ARM_R7_REGNUM:
576     case SIM_ARM_R8_REGNUM:
577     case SIM_ARM_R9_REGNUM:
578     case SIM_ARM_R10_REGNUM:
579     case SIM_ARM_R11_REGNUM:
580     case SIM_ARM_R12_REGNUM:
581     case SIM_ARM_R13_REGNUM:
582     case SIM_ARM_R14_REGNUM:
583     case SIM_ARM_R15_REGNUM: /* PC */
584       regval = ARMul_GetReg (state, state->Mode, rn);
585       break;
586
587     case SIM_ARM_FP0_REGNUM:
588     case SIM_ARM_FP1_REGNUM:
589     case SIM_ARM_FP2_REGNUM:
590     case SIM_ARM_FP3_REGNUM:
591     case SIM_ARM_FP4_REGNUM:
592     case SIM_ARM_FP5_REGNUM:
593     case SIM_ARM_FP6_REGNUM:
594     case SIM_ARM_FP7_REGNUM:
595     case SIM_ARM_FPS_REGNUM:
596       memset (memory, 0, length);
597       return 0;
598
599     case SIM_ARM_PS_REGNUM:
600       regval = ARMul_GetCPSR (state);
601       break;
602
603     case SIM_ARM_MAVERIC_COP0R0_REGNUM:
604     case SIM_ARM_MAVERIC_COP0R1_REGNUM:
605     case SIM_ARM_MAVERIC_COP0R2_REGNUM:
606     case SIM_ARM_MAVERIC_COP0R3_REGNUM:
607     case SIM_ARM_MAVERIC_COP0R4_REGNUM:
608     case SIM_ARM_MAVERIC_COP0R5_REGNUM:
609     case SIM_ARM_MAVERIC_COP0R6_REGNUM:
610     case SIM_ARM_MAVERIC_COP0R7_REGNUM:
611     case SIM_ARM_MAVERIC_COP0R8_REGNUM:
612     case SIM_ARM_MAVERIC_COP0R9_REGNUM:
613     case SIM_ARM_MAVERIC_COP0R10_REGNUM:
614     case SIM_ARM_MAVERIC_COP0R11_REGNUM:
615     case SIM_ARM_MAVERIC_COP0R12_REGNUM:
616     case SIM_ARM_MAVERIC_COP0R13_REGNUM:
617     case SIM_ARM_MAVERIC_COP0R14_REGNUM:
618     case SIM_ARM_MAVERIC_COP0R15_REGNUM:
619       memcpy (memory, & DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
620               sizeof (struct maverick_regs));
621       return sizeof (struct maverick_regs);
622
623     case SIM_ARM_MAVERIC_DSPSC_REGNUM:
624       memcpy (memory, & DSPsc, sizeof DSPsc);
625       return sizeof DSPsc;
626
627     case SIM_ARM_IWMMXT_COP0R0_REGNUM:
628     case SIM_ARM_IWMMXT_COP0R1_REGNUM:
629     case SIM_ARM_IWMMXT_COP0R2_REGNUM:
630     case SIM_ARM_IWMMXT_COP0R3_REGNUM:
631     case SIM_ARM_IWMMXT_COP0R4_REGNUM:
632     case SIM_ARM_IWMMXT_COP0R5_REGNUM:
633     case SIM_ARM_IWMMXT_COP0R6_REGNUM:
634     case SIM_ARM_IWMMXT_COP0R7_REGNUM:
635     case SIM_ARM_IWMMXT_COP0R8_REGNUM:
636     case SIM_ARM_IWMMXT_COP0R9_REGNUM:
637     case SIM_ARM_IWMMXT_COP0R10_REGNUM:
638     case SIM_ARM_IWMMXT_COP0R11_REGNUM:
639     case SIM_ARM_IWMMXT_COP0R12_REGNUM:
640     case SIM_ARM_IWMMXT_COP0R13_REGNUM:
641     case SIM_ARM_IWMMXT_COP0R14_REGNUM:
642     case SIM_ARM_IWMMXT_COP0R15_REGNUM:
643     case SIM_ARM_IWMMXT_COP1R0_REGNUM:
644     case SIM_ARM_IWMMXT_COP1R1_REGNUM:
645     case SIM_ARM_IWMMXT_COP1R2_REGNUM:
646     case SIM_ARM_IWMMXT_COP1R3_REGNUM:
647     case SIM_ARM_IWMMXT_COP1R4_REGNUM:
648     case SIM_ARM_IWMMXT_COP1R5_REGNUM:
649     case SIM_ARM_IWMMXT_COP1R6_REGNUM:
650     case SIM_ARM_IWMMXT_COP1R7_REGNUM:
651     case SIM_ARM_IWMMXT_COP1R8_REGNUM:
652     case SIM_ARM_IWMMXT_COP1R9_REGNUM:
653     case SIM_ARM_IWMMXT_COP1R10_REGNUM:
654     case SIM_ARM_IWMMXT_COP1R11_REGNUM:
655     case SIM_ARM_IWMMXT_COP1R12_REGNUM:
656     case SIM_ARM_IWMMXT_COP1R13_REGNUM:
657     case SIM_ARM_IWMMXT_COP1R14_REGNUM:
658     case SIM_ARM_IWMMXT_COP1R15_REGNUM:
659       return Fetch_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
660
661     default:
662       return 0;
663     }
664
665   while (len)
666     {
667       tomem (state, memory, regval);
668
669       len -= 4;
670       memory += 4;
671       regval = 0;
672     }  
673
674   return length;
675 }
676
677 #ifdef SIM_TARGET_SWITCHES
678
679 static void sim_target_parse_arg_array PARAMS ((char **));
680
681 typedef struct
682 {
683   char *        swi_option;
684   unsigned int  swi_mask;
685 } swi_options;
686
687 #define SWI_SWITCH      "--swi-support"
688
689 static swi_options options[] =
690   {
691     { "none",    0 },
692     { "demon",   SWI_MASK_DEMON },
693     { "angel",   SWI_MASK_ANGEL },
694     { "redboot", SWI_MASK_REDBOOT },
695     { "all",     -1 },
696     { "NONE",    0 },
697     { "DEMON",   SWI_MASK_DEMON },
698     { "ANGEL",   SWI_MASK_ANGEL },
699     { "REDBOOT", SWI_MASK_REDBOOT },
700     { "ALL",     -1 }
701   };
702
703
704 int
705 sim_target_parse_command_line (argc, argv)
706      int argc;
707      char ** argv;
708 {
709   int i;
710
711   for (i = 1; i < argc; i++)
712     {
713       char * ptr = argv[i];
714       int arg;
715
716       if ((ptr == NULL) || (* ptr != '-'))
717         break;
718
719       if (strncmp (ptr, SWI_SWITCH, sizeof SWI_SWITCH - 1) != 0)
720         continue;
721
722       if (ptr[sizeof SWI_SWITCH - 1] == 0)
723         {
724           /* Remove this option from the argv array.  */
725           for (arg = i; arg < argc; arg ++)
726             argv[arg] = argv[arg + 1];
727           argc --;
728           
729           ptr = argv[i];
730         }
731       else
732         ptr += sizeof SWI_SWITCH;
733
734       swi_mask = 0;
735       
736       while (* ptr)
737         {
738           int i;
739
740           for (i = sizeof options / sizeof options[0]; i--;)
741             if (strncmp (ptr, options[i].swi_option,
742                          strlen (options[i].swi_option)) == 0)
743               {
744                 swi_mask |= options[i].swi_mask;
745                 ptr += strlen (options[i].swi_option);
746
747                 if (* ptr == ',')
748                   ++ ptr;
749
750                 break;
751               }
752
753           if (i < 0)
754             break;
755         }
756
757       if (* ptr != 0)
758         fprintf (stderr, "Ignoring swi options: %s\n", ptr);
759       
760       /* Remove this option from the argv array.  */
761       for (arg = i; arg < argc; arg ++)
762         argv[arg] = argv[arg + 1];
763       argc --;
764       i --;
765     }
766   return argc;
767 }
768
769 static void
770 sim_target_parse_arg_array (argv)
771      char ** argv;
772 {
773   int i;
774
775   for (i = 0; argv[i]; i++)
776     ;
777
778   sim_target_parse_command_line (i, argv);
779 }
780
781 void
782 sim_target_display_usage (help)
783      int help;
784 {
785   FILE *stream = help ? stdout : stderr;
786
787   fprintf (stream, "%s=<list>  Comma seperated list of SWI protocols to supoport.\n\
788                 This list can contain: NONE, DEMON, ANGEL, REDBOOT and/or ALL.\n",
789            SWI_SWITCH);
790 }
791 #endif
792
793 SIM_DESC
794 sim_open (kind, ptr, abfd, argv)
795      SIM_OPEN_KIND kind;
796      host_callback *ptr;
797      struct bfd *abfd;
798      char **argv;
799 {
800   sim_kind = kind;
801   if (myname) free (myname);
802   myname = (char *) xstrdup (argv[0]);
803   sim_callback = ptr;
804
805 #ifdef SIM_TARGET_SWITCHES
806   sim_target_parse_arg_array (argv);
807 #endif
808   
809   /* Decide upon the endian-ness of the processor.
810      If we can, get the information from the bfd itself.
811      Otherwise look to see if we have been given a command
812      line switch that tells us.  Otherwise default to little endian.  */
813   if (abfd != NULL)
814     big_endian = bfd_big_endian (abfd);
815   else if (argv[1] != NULL)
816     {
817       int i;
818
819       /* Scan for endian-ness and memory-size switches.  */
820       for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++)
821         if (argv[i][0] == '-' && argv[i][1] == 'E')
822           {
823             char c;
824
825             if ((c = argv[i][2]) == 0)
826               {
827                 ++i;
828                 c = argv[i][0];
829               }
830
831             switch (c)
832               {
833               case 0:
834                 sim_callback->printf_filtered
835                   (sim_callback, "No argument to -E option provided\n");
836                 break;
837
838               case 'b':
839               case 'B':
840                 big_endian = 1;
841                 break;
842
843               case 'l':
844               case 'L':
845                 big_endian = 0;
846                 break;
847
848               default:
849                 sim_callback->printf_filtered
850                   (sim_callback, "Unrecognised argument to -E option\n");
851                 break;
852               }
853           }
854         else if (argv[i][0] == '-' && argv[i][1] == 'm')
855           {
856             if (argv[i][2] != '\0')
857               sim_size (atoi (&argv[i][2]));
858             else if (argv[i + 1] != NULL)
859               {
860                 sim_size (atoi (argv[i + 1]));
861                 i++;
862               }
863             else
864               {
865                 sim_callback->printf_filtered (sim_callback,
866                                                "Missing argument to -m option\n");
867                 return NULL;
868               }
869               
870           }
871     }
872
873   return (SIM_DESC) 1;
874 }
875
876 void
877 sim_close (sd, quitting)
878      SIM_DESC sd ATTRIBUTE_UNUSED;
879      int quitting ATTRIBUTE_UNUSED;
880 {
881   if (myname)
882     free (myname);
883   myname = NULL;
884 }
885
886 SIM_RC
887 sim_load (sd, prog, abfd, from_tty)
888      SIM_DESC sd;
889      char *prog;
890      bfd *abfd;
891      int from_tty ATTRIBUTE_UNUSED;
892 {
893   bfd *prog_bfd;
894
895   prog_bfd = sim_load_file (sd, myname, sim_callback, prog, abfd,
896                             sim_kind == SIM_OPEN_DEBUG, 0, sim_write);
897   if (prog_bfd == NULL)
898     return SIM_RC_FAIL;
899   ARMul_SetPC (state, bfd_get_start_address (prog_bfd));
900   if (abfd == NULL)
901     bfd_close (prog_bfd);
902   return SIM_RC_OK;
903 }
904
905 void
906 sim_stop_reason (sd, reason, sigrc)
907      SIM_DESC sd ATTRIBUTE_UNUSED;
908      enum sim_stop *reason;
909      int *sigrc;
910 {
911   if (stop_simulator)
912     {
913       *reason = sim_stopped;
914       *sigrc = GDB_SIGNAL_INT;
915     }
916   else if (state->EndCondition == 0)
917     {
918       *reason = sim_exited;
919       *sigrc = state->Reg[0] & 255;
920     }
921   else
922     {
923       *reason = sim_stopped;
924       if (state->EndCondition == RDIError_BreakpointReached)
925         *sigrc = GDB_SIGNAL_TRAP;
926       else if (   state->EndCondition == RDIError_DataAbort
927                || state->EndCondition == RDIError_AddressException)
928         *sigrc = GDB_SIGNAL_BUS;
929       else
930         *sigrc = 0;
931     }
932 }
933
934 void
935 sim_do_command (sd, cmd)
936      SIM_DESC sd ATTRIBUTE_UNUSED;
937      char *cmd ATTRIBUTE_UNUSED;
938 {  
939   (*sim_callback->printf_filtered)
940     (sim_callback,
941      "This simulator does not accept any commands.\n");
942 }
943
944 void
945 sim_set_callbacks (ptr)
946      host_callback *ptr;
947 {
948   sim_callback = ptr;
949 }
950
951 char **
952 sim_complete_command (SIM_DESC sd, const char *text, const char *word)
953 {
954   return NULL;
955 }