OSDN Git Service

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