db96cca0e2694f709ffd1eccdd78a08a0767c26f
[external/binutils.git] / sim / arm / wrapper.c
1 /* run front end support for arm
2    Copyright (C) 1995-2015 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 "sim-main.h"
32 #include "sim-options.h"
33 #include "armemu.h"
34 #include "dbg_rdi.h"
35 #include "ansidecl.h"
36 #include "gdb/sim-arm.h"
37 #include "gdb/signals.h"
38 #include "libiberty.h"
39 #include "iwmmxt.h"
40
41 /* TODO: This should get pulled from the SIM_DESC.  */
42 host_callback *sim_callback;
43
44 /* TODO: This should get merged into sim_cpu.  */
45 struct ARMul_State *state;
46
47 /* Memory size in bytes.  */
48 /* TODO: Memory should be converted to the common memory module.  */
49 static int mem_size = (1 << 21);
50
51 int stop_simulator;
52
53 #include "dis-asm.h"
54
55 /* TODO: Tracing should be converted to common tracing module.  */
56 int trace = 0;
57 int disas = 0;
58 int trace_funcs = 0;
59
60 static struct disassemble_info  info;
61 static char opbuf[1000];
62
63 static int
64 op_printf (char *buf, char *fmt, ...)
65 {
66   int ret;
67   va_list ap;
68
69   va_start (ap, fmt);
70   ret = vsprintf (opbuf + strlen (opbuf), fmt, ap);
71   va_end (ap);
72   return ret;
73 }
74
75 static int
76 sim_dis_read (bfd_vma                     memaddr ATTRIBUTE_UNUSED,
77               bfd_byte *                  ptr,
78               unsigned int                length,
79               struct disassemble_info *   info)
80 {
81   ARMword val = (ARMword) *((ARMword *) info->application_data);
82
83   while (length--)
84     {
85       * ptr ++ = val & 0xFF;
86       val >>= 8;
87     }
88   return 0;
89 }
90
91 void
92 print_insn (ARMword instr)
93 {
94   int size;
95
96   opbuf[0] = 0;
97   info.application_data = & instr;
98   size = print_insn_little_arm (0, & info);
99   fprintf (stderr, " %*s\n", size, opbuf);
100 }
101
102 /* Cirrus DSP registers.
103
104    We need to define these registers outside of maverick.c because
105    maverick.c might not be linked in unless --target=arm9e-* in which
106    case wrapper.c will not compile because it tries to access Cirrus
107    registers.  This should all go away once we get the Cirrus and ARM
108    Coprocessor to coexist in armcopro.c-- aldyh.  */
109
110 struct maverick_regs
111 {
112   union
113   {
114     int i;
115     float f;
116   } upper;
117
118   union
119   {
120     int i;
121     float f;
122   } lower;
123 };
124
125 union maverick_acc_regs
126 {
127   long double ld;               /* Acc registers are 72-bits.  */
128 };
129
130 struct maverick_regs     DSPregs[16];
131 union maverick_acc_regs  DSPacc[4];
132 ARMword DSPsc;
133
134 static void
135 init (void)
136 {
137   static int done;
138
139   if (!done)
140     {
141       ARMul_EmulateInit ();
142       state = ARMul_NewState ();
143       state->bigendSig = (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN ? HIGH : LOW);
144       ARMul_MemoryInit (state, mem_size);
145       ARMul_OSInit (state);
146       state->verbose = 0;
147       done = 1;
148     }
149 }
150
151 void
152 ARMul_ConsolePrint (ARMul_State * state,
153                     const char * format,
154                     ...)
155 {
156   va_list ap;
157
158   if (state->verbose)
159     {
160       va_start (ap, format);
161       vprintf (format, ap);
162       va_end (ap);
163     }
164 }
165
166 int
167 sim_write (SIM_DESC sd ATTRIBUTE_UNUSED,
168            SIM_ADDR addr,
169            const unsigned char * buffer,
170            int size)
171 {
172   int i;
173
174   init ();
175
176   for (i = 0; i < size; i++)
177     ARMul_SafeWriteByte (state, addr + i, buffer[i]);
178
179   return size;
180 }
181
182 int
183 sim_read (SIM_DESC sd ATTRIBUTE_UNUSED,
184           SIM_ADDR addr,
185           unsigned char * buffer,
186           int size)
187 {
188   int i;
189
190   init ();
191
192   for (i = 0; i < size; i++)
193     buffer[i] = ARMul_SafeReadByte (state, addr + i);
194
195   return size;
196 }
197
198 int
199 sim_stop (SIM_DESC sd ATTRIBUTE_UNUSED)
200 {
201   state->Emulate = STOP;
202   stop_simulator = 1;
203   return 1;
204 }
205
206 void
207 sim_resume (SIM_DESC sd ATTRIBUTE_UNUSED,
208             int step,
209             int siggnal ATTRIBUTE_UNUSED)
210 {
211   state->EndCondition = 0;
212   stop_simulator = 0;
213
214   if (step)
215     {
216       state->Reg[15] = ARMul_DoInstr (state);
217       if (state->EndCondition == 0)
218         state->EndCondition = RDIError_BreakpointReached;
219     }
220   else
221     {
222       state->NextInstr = RESUME;        /* treat as PC change */
223       state->Reg[15] = ARMul_DoProg (state);
224     }
225
226   FLUSHPIPE;
227 }
228
229 SIM_RC
230 sim_create_inferior (SIM_DESC sd ATTRIBUTE_UNUSED,
231                      struct bfd * abfd,
232                      char ** argv,
233                      char ** env)
234 {
235   int argvlen = 0;
236   int mach;
237   char **arg;
238
239   init ();
240
241   if (abfd != NULL)
242     {
243       ARMul_SetPC (state, bfd_get_start_address (abfd));
244       mach = bfd_get_mach (abfd);
245     }
246   else
247     {
248       ARMul_SetPC (state, 0);   /* ??? */
249       mach = 0;
250     }
251
252 #ifdef MODET
253   if (abfd != NULL && (bfd_get_start_address (abfd) & 1))
254     SETT;
255 #endif
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       ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_v6_Prop);
271       break;
272
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   memset (& info, 0, sizeof (info));
342   INIT_DISASSEMBLE_INFO (info, stdout, op_printf);
343   info.read_memory_func = sim_dis_read;
344   info.arch = bfd_get_arch (abfd);
345   info.mach = bfd_get_mach (abfd);
346   info.endian_code = BFD_ENDIAN_LITTLE;
347   if (info.mach == 0)
348     info.arch = bfd_arch_arm;
349   disassemble_init_for_target (& info);
350
351   if (argv != NULL)
352     {
353       /* Set up the command line by laboriously stringing together
354          the environment carefully picked apart by our caller.  */
355
356       /* Free any old stuff.  */
357       if (state->CommandLine != NULL)
358         {
359           free (state->CommandLine);
360           state->CommandLine = NULL;
361         }
362
363       /* See how much we need.  */
364       for (arg = argv; *arg != NULL; arg++)
365         argvlen += strlen (*arg) + 1;
366
367       /* Allocate it.  */
368       state->CommandLine = malloc (argvlen + 1);
369       if (state->CommandLine != NULL)
370         {
371           arg = argv;
372           state->CommandLine[0] = '\0';
373
374           for (arg = argv; *arg != NULL; arg++)
375             {
376               strcat (state->CommandLine, *arg);
377               strcat (state->CommandLine, " ");
378             }
379         }
380     }
381
382   if (env != NULL)
383     {
384       /* Now see if there's a MEMSIZE spec in the environment.  */
385       while (*env)
386         {
387           if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
388             {
389               char *end_of_num;
390
391               /* Set up memory limit.  */
392               state->MemSize =
393                 strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0);
394             }
395           env++;
396         }
397     }
398
399   return SIM_RC_OK;
400 }
401
402 static int
403 frommem (struct ARMul_State *state, unsigned char *memory)
404 {
405   if (state->bigendSig == HIGH)
406     return (memory[0] << 24) | (memory[1] << 16)
407       | (memory[2] << 8) | (memory[3] << 0);
408   else
409     return (memory[3] << 24) | (memory[2] << 16)
410       | (memory[1] << 8) | (memory[0] << 0);
411 }
412
413 static void
414 tomem (struct ARMul_State *state,
415        unsigned char *memory,
416        int val)
417 {
418   if (state->bigendSig == HIGH)
419     {
420       memory[0] = val >> 24;
421       memory[1] = val >> 16;
422       memory[2] = val >> 8;
423       memory[3] = val >> 0;
424     }
425   else
426     {
427       memory[3] = val >> 24;
428       memory[2] = val >> 16;
429       memory[1] = val >> 8;
430       memory[0] = val >> 0;
431     }
432 }
433
434 int
435 sim_store_register (SIM_DESC sd ATTRIBUTE_UNUSED,
436                     int rn,
437                     unsigned char *memory,
438                     int length)
439 {
440   init ();
441
442   switch ((enum sim_arm_regs) rn)
443     {
444     case SIM_ARM_R0_REGNUM:
445     case SIM_ARM_R1_REGNUM:
446     case SIM_ARM_R2_REGNUM:
447     case SIM_ARM_R3_REGNUM:
448     case SIM_ARM_R4_REGNUM:
449     case SIM_ARM_R5_REGNUM:
450     case SIM_ARM_R6_REGNUM:
451     case SIM_ARM_R7_REGNUM:
452     case SIM_ARM_R8_REGNUM:
453     case SIM_ARM_R9_REGNUM:
454     case SIM_ARM_R10_REGNUM:
455     case SIM_ARM_R11_REGNUM:
456     case SIM_ARM_R12_REGNUM:
457     case SIM_ARM_R13_REGNUM:
458     case SIM_ARM_R14_REGNUM:
459     case SIM_ARM_R15_REGNUM: /* PC */
460     case SIM_ARM_FP0_REGNUM:
461     case SIM_ARM_FP1_REGNUM:
462     case SIM_ARM_FP2_REGNUM:
463     case SIM_ARM_FP3_REGNUM:
464     case SIM_ARM_FP4_REGNUM:
465     case SIM_ARM_FP5_REGNUM:
466     case SIM_ARM_FP6_REGNUM:
467     case SIM_ARM_FP7_REGNUM:
468     case SIM_ARM_FPS_REGNUM:
469       ARMul_SetReg (state, state->Mode, rn, frommem (state, memory));
470       break;
471
472     case SIM_ARM_PS_REGNUM:
473       state->Cpsr = frommem (state, memory);
474       ARMul_CPSRAltered (state);
475       break;
476
477     case SIM_ARM_MAVERIC_COP0R0_REGNUM:
478     case SIM_ARM_MAVERIC_COP0R1_REGNUM:
479     case SIM_ARM_MAVERIC_COP0R2_REGNUM:
480     case SIM_ARM_MAVERIC_COP0R3_REGNUM:
481     case SIM_ARM_MAVERIC_COP0R4_REGNUM:
482     case SIM_ARM_MAVERIC_COP0R5_REGNUM:
483     case SIM_ARM_MAVERIC_COP0R6_REGNUM:
484     case SIM_ARM_MAVERIC_COP0R7_REGNUM:
485     case SIM_ARM_MAVERIC_COP0R8_REGNUM:
486     case SIM_ARM_MAVERIC_COP0R9_REGNUM:
487     case SIM_ARM_MAVERIC_COP0R10_REGNUM:
488     case SIM_ARM_MAVERIC_COP0R11_REGNUM:
489     case SIM_ARM_MAVERIC_COP0R12_REGNUM:
490     case SIM_ARM_MAVERIC_COP0R13_REGNUM:
491     case SIM_ARM_MAVERIC_COP0R14_REGNUM:
492     case SIM_ARM_MAVERIC_COP0R15_REGNUM:
493       memcpy (& DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
494               memory, sizeof (struct maverick_regs));
495       return sizeof (struct maverick_regs);
496
497     case SIM_ARM_MAVERIC_DSPSC_REGNUM:
498       memcpy (&DSPsc, memory, sizeof DSPsc);
499       return sizeof DSPsc;
500
501     case SIM_ARM_IWMMXT_COP0R0_REGNUM:
502     case SIM_ARM_IWMMXT_COP0R1_REGNUM:
503     case SIM_ARM_IWMMXT_COP0R2_REGNUM:
504     case SIM_ARM_IWMMXT_COP0R3_REGNUM:
505     case SIM_ARM_IWMMXT_COP0R4_REGNUM:
506     case SIM_ARM_IWMMXT_COP0R5_REGNUM:
507     case SIM_ARM_IWMMXT_COP0R6_REGNUM:
508     case SIM_ARM_IWMMXT_COP0R7_REGNUM:
509     case SIM_ARM_IWMMXT_COP0R8_REGNUM:
510     case SIM_ARM_IWMMXT_COP0R9_REGNUM:
511     case SIM_ARM_IWMMXT_COP0R10_REGNUM:
512     case SIM_ARM_IWMMXT_COP0R11_REGNUM:
513     case SIM_ARM_IWMMXT_COP0R12_REGNUM:
514     case SIM_ARM_IWMMXT_COP0R13_REGNUM:
515     case SIM_ARM_IWMMXT_COP0R14_REGNUM:
516     case SIM_ARM_IWMMXT_COP0R15_REGNUM:
517     case SIM_ARM_IWMMXT_COP1R0_REGNUM:
518     case SIM_ARM_IWMMXT_COP1R1_REGNUM:
519     case SIM_ARM_IWMMXT_COP1R2_REGNUM:
520     case SIM_ARM_IWMMXT_COP1R3_REGNUM:
521     case SIM_ARM_IWMMXT_COP1R4_REGNUM:
522     case SIM_ARM_IWMMXT_COP1R5_REGNUM:
523     case SIM_ARM_IWMMXT_COP1R6_REGNUM:
524     case SIM_ARM_IWMMXT_COP1R7_REGNUM:
525     case SIM_ARM_IWMMXT_COP1R8_REGNUM:
526     case SIM_ARM_IWMMXT_COP1R9_REGNUM:
527     case SIM_ARM_IWMMXT_COP1R10_REGNUM:
528     case SIM_ARM_IWMMXT_COP1R11_REGNUM:
529     case SIM_ARM_IWMMXT_COP1R12_REGNUM:
530     case SIM_ARM_IWMMXT_COP1R13_REGNUM:
531     case SIM_ARM_IWMMXT_COP1R14_REGNUM:
532     case SIM_ARM_IWMMXT_COP1R15_REGNUM:
533       return Store_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
534
535     default:
536       return 0;
537     }
538
539   return length;
540 }
541
542 int
543 sim_fetch_register (SIM_DESC sd ATTRIBUTE_UNUSED,
544                     int rn,
545                     unsigned char *memory,
546                     int length)
547 {
548   ARMword regval;
549   int len = length;
550
551   init ();
552
553   switch ((enum sim_arm_regs) rn)
554     {
555     case SIM_ARM_R0_REGNUM:
556     case SIM_ARM_R1_REGNUM:
557     case SIM_ARM_R2_REGNUM:
558     case SIM_ARM_R3_REGNUM:
559     case SIM_ARM_R4_REGNUM:
560     case SIM_ARM_R5_REGNUM:
561     case SIM_ARM_R6_REGNUM:
562     case SIM_ARM_R7_REGNUM:
563     case SIM_ARM_R8_REGNUM:
564     case SIM_ARM_R9_REGNUM:
565     case SIM_ARM_R10_REGNUM:
566     case SIM_ARM_R11_REGNUM:
567     case SIM_ARM_R12_REGNUM:
568     case SIM_ARM_R13_REGNUM:
569     case SIM_ARM_R14_REGNUM:
570     case SIM_ARM_R15_REGNUM: /* PC */
571       regval = ARMul_GetReg (state, state->Mode, rn);
572       break;
573
574     case SIM_ARM_FP0_REGNUM:
575     case SIM_ARM_FP1_REGNUM:
576     case SIM_ARM_FP2_REGNUM:
577     case SIM_ARM_FP3_REGNUM:
578     case SIM_ARM_FP4_REGNUM:
579     case SIM_ARM_FP5_REGNUM:
580     case SIM_ARM_FP6_REGNUM:
581     case SIM_ARM_FP7_REGNUM:
582     case SIM_ARM_FPS_REGNUM:
583       memset (memory, 0, length);
584       return 0;
585
586     case SIM_ARM_PS_REGNUM:
587       regval = ARMul_GetCPSR (state);
588       break;
589
590     case SIM_ARM_MAVERIC_COP0R0_REGNUM:
591     case SIM_ARM_MAVERIC_COP0R1_REGNUM:
592     case SIM_ARM_MAVERIC_COP0R2_REGNUM:
593     case SIM_ARM_MAVERIC_COP0R3_REGNUM:
594     case SIM_ARM_MAVERIC_COP0R4_REGNUM:
595     case SIM_ARM_MAVERIC_COP0R5_REGNUM:
596     case SIM_ARM_MAVERIC_COP0R6_REGNUM:
597     case SIM_ARM_MAVERIC_COP0R7_REGNUM:
598     case SIM_ARM_MAVERIC_COP0R8_REGNUM:
599     case SIM_ARM_MAVERIC_COP0R9_REGNUM:
600     case SIM_ARM_MAVERIC_COP0R10_REGNUM:
601     case SIM_ARM_MAVERIC_COP0R11_REGNUM:
602     case SIM_ARM_MAVERIC_COP0R12_REGNUM:
603     case SIM_ARM_MAVERIC_COP0R13_REGNUM:
604     case SIM_ARM_MAVERIC_COP0R14_REGNUM:
605     case SIM_ARM_MAVERIC_COP0R15_REGNUM:
606       memcpy (memory, & DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
607               sizeof (struct maverick_regs));
608       return sizeof (struct maverick_regs);
609
610     case SIM_ARM_MAVERIC_DSPSC_REGNUM:
611       memcpy (memory, & DSPsc, sizeof DSPsc);
612       return sizeof DSPsc;
613
614     case SIM_ARM_IWMMXT_COP0R0_REGNUM:
615     case SIM_ARM_IWMMXT_COP0R1_REGNUM:
616     case SIM_ARM_IWMMXT_COP0R2_REGNUM:
617     case SIM_ARM_IWMMXT_COP0R3_REGNUM:
618     case SIM_ARM_IWMMXT_COP0R4_REGNUM:
619     case SIM_ARM_IWMMXT_COP0R5_REGNUM:
620     case SIM_ARM_IWMMXT_COP0R6_REGNUM:
621     case SIM_ARM_IWMMXT_COP0R7_REGNUM:
622     case SIM_ARM_IWMMXT_COP0R8_REGNUM:
623     case SIM_ARM_IWMMXT_COP0R9_REGNUM:
624     case SIM_ARM_IWMMXT_COP0R10_REGNUM:
625     case SIM_ARM_IWMMXT_COP0R11_REGNUM:
626     case SIM_ARM_IWMMXT_COP0R12_REGNUM:
627     case SIM_ARM_IWMMXT_COP0R13_REGNUM:
628     case SIM_ARM_IWMMXT_COP0R14_REGNUM:
629     case SIM_ARM_IWMMXT_COP0R15_REGNUM:
630     case SIM_ARM_IWMMXT_COP1R0_REGNUM:
631     case SIM_ARM_IWMMXT_COP1R1_REGNUM:
632     case SIM_ARM_IWMMXT_COP1R2_REGNUM:
633     case SIM_ARM_IWMMXT_COP1R3_REGNUM:
634     case SIM_ARM_IWMMXT_COP1R4_REGNUM:
635     case SIM_ARM_IWMMXT_COP1R5_REGNUM:
636     case SIM_ARM_IWMMXT_COP1R6_REGNUM:
637     case SIM_ARM_IWMMXT_COP1R7_REGNUM:
638     case SIM_ARM_IWMMXT_COP1R8_REGNUM:
639     case SIM_ARM_IWMMXT_COP1R9_REGNUM:
640     case SIM_ARM_IWMMXT_COP1R10_REGNUM:
641     case SIM_ARM_IWMMXT_COP1R11_REGNUM:
642     case SIM_ARM_IWMMXT_COP1R12_REGNUM:
643     case SIM_ARM_IWMMXT_COP1R13_REGNUM:
644     case SIM_ARM_IWMMXT_COP1R14_REGNUM:
645     case SIM_ARM_IWMMXT_COP1R15_REGNUM:
646       return Fetch_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
647
648     default:
649       return 0;
650     }
651
652   while (len)
653     {
654       tomem (state, memory, regval);
655
656       len -= 4;
657       memory += 4;
658       regval = 0;
659     }
660
661   return length;
662 }
663
664 typedef struct
665 {
666   char *        swi_option;
667   unsigned int  swi_mask;
668 } swi_options;
669
670 #define SWI_SWITCH      "--swi-support"
671
672 static swi_options options[] =
673   {
674     { "none",    0 },
675     { "demon",   SWI_MASK_DEMON },
676     { "angel",   SWI_MASK_ANGEL },
677     { "redboot", SWI_MASK_REDBOOT },
678     { "all",     -1 },
679     { "NONE",    0 },
680     { "DEMON",   SWI_MASK_DEMON },
681     { "ANGEL",   SWI_MASK_ANGEL },
682     { "REDBOOT", SWI_MASK_REDBOOT },
683     { "ALL",     -1 }
684   };
685
686
687 static int
688 sim_target_parse_command_line (int argc, char ** argv)
689 {
690   int i;
691
692   for (i = 1; i < argc; i++)
693     {
694       char * ptr = argv[i];
695       int arg;
696
697       if ((ptr == NULL) || (* ptr != '-'))
698         break;
699
700       if (strcmp (ptr, "-t") == 0)
701         {
702           trace = 1;
703           continue;
704         }
705
706       if (strcmp (ptr, "-z") == 0)
707         {
708           /* Remove this option from the argv array.  */
709           for (arg = i; arg < argc; arg ++)
710             argv[arg] = argv[arg + 1];
711           argc --;
712           i --;
713           trace_funcs = 1;
714           continue;
715         }
716
717       if (strcmp (ptr, "-d") == 0)
718         {
719           /* Remove this option from the argv array.  */
720           for (arg = i; arg < argc; arg ++)
721             argv[arg] = argv[arg + 1];
722           argc --;
723           i --;
724           disas = 1;
725           continue;
726         }
727
728       if (strncmp (ptr, SWI_SWITCH, sizeof SWI_SWITCH - 1) != 0)
729         continue;
730
731       if (ptr[sizeof SWI_SWITCH - 1] == 0)
732         {
733           /* Remove this option from the argv array.  */
734           for (arg = i; arg < argc; arg ++)
735             argv[arg] = argv[arg + 1];
736           argc --;
737
738           ptr = argv[i];
739         }
740       else
741         ptr += sizeof SWI_SWITCH;
742
743       swi_mask = 0;
744
745       while (* ptr)
746         {
747           int i;
748
749           for (i = sizeof options / sizeof options[0]; i--;)
750             if (strncmp (ptr, options[i].swi_option,
751                          strlen (options[i].swi_option)) == 0)
752               {
753                 swi_mask |= options[i].swi_mask;
754                 ptr += strlen (options[i].swi_option);
755
756                 if (* ptr == ',')
757                   ++ ptr;
758
759                 break;
760               }
761
762           if (i < 0)
763             break;
764         }
765
766       if (* ptr != 0)
767         fprintf (stderr, "Ignoring swi options: %s\n", ptr);
768
769       /* Remove this option from the argv array.  */
770       for (arg = i; arg < argc; arg ++)
771         argv[arg] = argv[arg + 1];
772       argc --;
773       i --;
774     }
775   return argc;
776 }
777
778 static void
779 sim_target_parse_arg_array (char ** argv)
780 {
781   int i;
782
783   for (i = 0; argv[i]; i++)
784     ;
785
786   sim_target_parse_command_line (i, argv);
787 }
788
789 static sim_cia
790 arm_pc_get (sim_cpu *cpu)
791 {
792   return PC;
793 }
794
795 static void
796 arm_pc_set (sim_cpu *cpu, sim_cia pc)
797 {
798   ARMul_SetPC (state, pc);
799 }
800
801 static void
802 free_state (SIM_DESC sd)
803 {
804   if (STATE_MODULES (sd) != NULL)
805     sim_module_uninstall (sd);
806   sim_cpu_free_all (sd);
807   sim_state_free (sd);
808 }
809
810 SIM_DESC
811 sim_open (SIM_OPEN_KIND kind,
812           host_callback *cb,
813           struct bfd *abfd,
814           char **argv)
815 {
816   int i;
817   SIM_DESC sd = sim_state_alloc (kind, cb);
818   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
819
820   /* The cpu data is kept in a separately allocated chunk of memory.  */
821   if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
822     {
823       free_state (sd);
824       return 0;
825     }
826
827   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
828     {
829       free_state (sd);
830       return 0;
831     }
832
833   /* getopt will print the error message so we just have to exit if this fails.
834      FIXME: Hmmm...  in the case of gdb we need getopt to call
835      print_filtered.  */
836   if (sim_parse_args (sd, argv) != SIM_RC_OK)
837     {
838       free_state (sd);
839       return 0;
840     }
841
842   /* Check for/establish the a reference program image.  */
843   if (sim_analyze_program (sd,
844                            (STATE_PROG_ARGV (sd) != NULL
845                             ? *STATE_PROG_ARGV (sd)
846                             : NULL), abfd) != SIM_RC_OK)
847     {
848       free_state (sd);
849       return 0;
850     }
851
852   /* Configure/verify the target byte order and other runtime
853      configuration options.  */
854   if (sim_config (sd) != SIM_RC_OK)
855     {
856       sim_module_uninstall (sd);
857       return 0;
858     }
859
860   if (sim_post_argv_init (sd) != SIM_RC_OK)
861     {
862       /* Uninstall the modules to avoid memory leaks,
863          file descriptor leaks, etc.  */
864       sim_module_uninstall (sd);
865       return 0;
866     }
867
868   /* CPU specific initialization.  */
869   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
870     {
871       SIM_CPU *cpu = STATE_CPU (sd, i);
872
873       CPU_PC_FETCH (cpu) = arm_pc_get;
874       CPU_PC_STORE (cpu) = arm_pc_set;
875     }
876
877   sim_callback = cb;
878
879   sim_target_parse_arg_array (argv);
880
881   if (argv[1] != NULL)
882     {
883       int i;
884
885       /* Scan for memory-size switches.  */
886       for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++)
887         if (argv[i][0] == '-' && argv[i][1] == 'm')
888           {
889             if (argv[i][2] != '\0')
890               mem_size = atoi (&argv[i][2]);
891             else if (argv[i + 1] != NULL)
892               {
893                 mem_size = atoi (argv[i + 1]);
894                 i++;
895               }
896             else
897               {
898                 sim_callback->printf_filtered (sim_callback,
899                                                "Missing argument to -m option\n");
900                 return NULL;
901               }
902           }
903     }
904
905   return sd;
906 }
907
908 void
909 sim_stop_reason (SIM_DESC sd ATTRIBUTE_UNUSED,
910                  enum sim_stop *reason,
911                  int *sigrc)
912 {
913   if (stop_simulator)
914     {
915       *reason = sim_stopped;
916       *sigrc = GDB_SIGNAL_INT;
917     }
918   else if (state->EndCondition == 0)
919     {
920       *reason = sim_exited;
921       *sigrc = state->Reg[0] & 255;
922     }
923   else
924     {
925       *reason = sim_stopped;
926       if (state->EndCondition == RDIError_BreakpointReached)
927         *sigrc = GDB_SIGNAL_TRAP;
928       else if (   state->EndCondition == RDIError_DataAbort
929                || state->EndCondition == RDIError_AddressException)
930         *sigrc = GDB_SIGNAL_BUS;
931       else
932         *sigrc = 0;
933     }
934 }