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