xref: /netbsd-src/external/gpl3/gdb/dist/sim/arm/wrapper.c (revision a24efa7dea9f1f56c3bdb15a927d3516792ace1c)
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 ARMword
167 ARMul_Debug (ARMul_State * state ATTRIBUTE_UNUSED,
168 	     ARMword       pc    ATTRIBUTE_UNUSED,
169 	     ARMword       instr ATTRIBUTE_UNUSED)
170 {
171   return 0;
172 }
173 
174 int
175 sim_write (SIM_DESC sd ATTRIBUTE_UNUSED,
176 	   SIM_ADDR addr,
177 	   const unsigned char * buffer,
178 	   int size)
179 {
180   int i;
181 
182   init ();
183 
184   for (i = 0; i < size; i++)
185     ARMul_SafeWriteByte (state, addr + i, buffer[i]);
186 
187   return size;
188 }
189 
190 int
191 sim_read (SIM_DESC sd ATTRIBUTE_UNUSED,
192 	  SIM_ADDR addr,
193 	  unsigned char * buffer,
194 	  int size)
195 {
196   int i;
197 
198   init ();
199 
200   for (i = 0; i < size; i++)
201     buffer[i] = ARMul_SafeReadByte (state, addr + i);
202 
203   return size;
204 }
205 
206 int
207 sim_stop (SIM_DESC sd ATTRIBUTE_UNUSED)
208 {
209   state->Emulate = STOP;
210   stop_simulator = 1;
211   return 1;
212 }
213 
214 void
215 sim_resume (SIM_DESC sd ATTRIBUTE_UNUSED,
216 	    int step,
217 	    int siggnal ATTRIBUTE_UNUSED)
218 {
219   state->EndCondition = 0;
220   stop_simulator = 0;
221 
222   if (step)
223     {
224       state->Reg[15] = ARMul_DoInstr (state);
225       if (state->EndCondition == 0)
226 	state->EndCondition = RDIError_BreakpointReached;
227     }
228   else
229     {
230       state->NextInstr = RESUME;	/* treat as PC change */
231       state->Reg[15] = ARMul_DoProg (state);
232     }
233 
234   FLUSHPIPE;
235 }
236 
237 SIM_RC
238 sim_create_inferior (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   init ();
248 
249   if (abfd != NULL)
250     {
251       ARMul_SetPC (state, bfd_get_start_address (abfd));
252       mach = bfd_get_mach (abfd);
253     }
254   else
255     {
256       ARMul_SetPC (state, 0);	/* ??? */
257       mach = 0;
258     }
259 
260 #ifdef MODET
261   if (abfd != NULL && (bfd_get_start_address (abfd) & 1))
262     SETT;
263 #endif
264 
265   switch (mach)
266     {
267     default:
268       (*sim_callback->printf_filtered)
269 	(sim_callback,
270 	 "Unknown machine type '%d'; please update sim_create_inferior.\n",
271 	 mach);
272       /* fall through */
273 
274     case 0:
275       /* We wouldn't set the machine type with earlier toolchains, so we
276 	 explicitly select a processor capable of supporting all ARMs in
277 	 32bit mode.  */
278       ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_v6_Prop);
279       break;
280 
281     case bfd_mach_arm_XScale:
282       ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_v6_Prop);
283       break;
284 
285     case bfd_mach_arm_iWMMXt2:
286     case bfd_mach_arm_iWMMXt:
287       {
288 	extern int SWI_vector_installed;
289 	ARMword i;
290 
291 	if (! SWI_vector_installed)
292 	  {
293 	    /* Intialise the hardware vectors to zero.  */
294 	    if (! SWI_vector_installed)
295 	      for (i = ARMul_ResetV; i <= ARMFIQV; i += 4)
296 		ARMul_WriteWord (state, i, 0);
297 
298 	    /* ARM_WriteWord will have detected the write to the SWI vector,
299 	       but we want SWI_vector_installed to remain at 0 so that thumb
300 	       mode breakpoints will work.  */
301 	    SWI_vector_installed = 0;
302 	  }
303       }
304       ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_iWMMXt_Prop);
305       break;
306 
307     case bfd_mach_arm_ep9312:
308       ARMul_SelectProcessor (state, ARM_v4_Prop | ARM_ep9312_Prop);
309       break;
310 
311     case bfd_mach_arm_5:
312       if (bfd_family_coff (abfd))
313 	{
314 	  /* This is a special case in order to support COFF based ARM toolchains.
315 	     The COFF header does not have enough room to store all the different
316 	     kinds of ARM cpu, so the XScale, v5T and v5TE architectures all default
317 	     to v5.  (See coff_set_flags() in bdf/coffcode.h).  So if we see a v5
318 	     machine type here, we assume it could be any of the above architectures
319 	     and so select the most feature-full.  */
320 	  ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
321 	  break;
322 	}
323       /* Otherwise drop through.  */
324 
325     case bfd_mach_arm_5T:
326       ARMul_SelectProcessor (state, ARM_v5_Prop);
327       break;
328 
329     case bfd_mach_arm_5TE:
330       ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop);
331       break;
332 
333     case bfd_mach_arm_4:
334     case bfd_mach_arm_4T:
335       ARMul_SelectProcessor (state, ARM_v4_Prop);
336       break;
337 
338     case bfd_mach_arm_3:
339     case bfd_mach_arm_3M:
340       ARMul_SelectProcessor (state, ARM_Lock_Prop);
341       break;
342 
343     case bfd_mach_arm_2:
344     case bfd_mach_arm_2a:
345       ARMul_SelectProcessor (state, ARM_Fix26_Prop);
346       break;
347     }
348 
349   memset (& info, 0, sizeof (info));
350   INIT_DISASSEMBLE_INFO (info, stdout, op_printf);
351   info.read_memory_func = sim_dis_read;
352   info.arch = bfd_get_arch (abfd);
353   info.mach = bfd_get_mach (abfd);
354   info.endian_code = BFD_ENDIAN_LITTLE;
355   if (info.mach == 0)
356     info.arch = bfd_arch_arm;
357   disassemble_init_for_target (& info);
358 
359   if (argv != NULL)
360     {
361       /* Set up the command line by laboriously stringing together
362 	 the environment carefully picked apart by our caller.  */
363 
364       /* Free any old stuff.  */
365       if (state->CommandLine != NULL)
366 	{
367 	  free (state->CommandLine);
368 	  state->CommandLine = NULL;
369 	}
370 
371       /* See how much we need.  */
372       for (arg = argv; *arg != NULL; arg++)
373 	argvlen += strlen (*arg) + 1;
374 
375       /* Allocate it.  */
376       state->CommandLine = malloc (argvlen + 1);
377       if (state->CommandLine != NULL)
378 	{
379 	  arg = argv;
380 	  state->CommandLine[0] = '\0';
381 
382 	  for (arg = argv; *arg != NULL; arg++)
383 	    {
384 	      strcat (state->CommandLine, *arg);
385 	      strcat (state->CommandLine, " ");
386 	    }
387 	}
388     }
389 
390   if (env != NULL)
391     {
392       /* Now see if there's a MEMSIZE spec in the environment.  */
393       while (*env)
394 	{
395 	  if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
396 	    {
397 	      char *end_of_num;
398 
399 	      /* Set up memory limit.  */
400 	      state->MemSize =
401 		strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0);
402 	    }
403 	  env++;
404 	}
405     }
406 
407   return SIM_RC_OK;
408 }
409 
410 static int
411 frommem (struct ARMul_State *state, unsigned char *memory)
412 {
413   if (state->bigendSig == HIGH)
414     return (memory[0] << 24) | (memory[1] << 16)
415       | (memory[2] << 8) | (memory[3] << 0);
416   else
417     return (memory[3] << 24) | (memory[2] << 16)
418       | (memory[1] << 8) | (memory[0] << 0);
419 }
420 
421 static void
422 tomem (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 (SIM_DESC sd ATTRIBUTE_UNUSED,
444 		    int rn,
445 		    unsigned char *memory,
446 		    int length)
447 {
448   init ();
449 
450   switch ((enum sim_arm_regs) rn)
451     {
452     case SIM_ARM_R0_REGNUM:
453     case SIM_ARM_R1_REGNUM:
454     case SIM_ARM_R2_REGNUM:
455     case SIM_ARM_R3_REGNUM:
456     case SIM_ARM_R4_REGNUM:
457     case SIM_ARM_R5_REGNUM:
458     case SIM_ARM_R6_REGNUM:
459     case SIM_ARM_R7_REGNUM:
460     case SIM_ARM_R8_REGNUM:
461     case SIM_ARM_R9_REGNUM:
462     case SIM_ARM_R10_REGNUM:
463     case SIM_ARM_R11_REGNUM:
464     case SIM_ARM_R12_REGNUM:
465     case SIM_ARM_R13_REGNUM:
466     case SIM_ARM_R14_REGNUM:
467     case SIM_ARM_R15_REGNUM: /* PC */
468     case SIM_ARM_FP0_REGNUM:
469     case SIM_ARM_FP1_REGNUM:
470     case SIM_ARM_FP2_REGNUM:
471     case SIM_ARM_FP3_REGNUM:
472     case SIM_ARM_FP4_REGNUM:
473     case SIM_ARM_FP5_REGNUM:
474     case SIM_ARM_FP6_REGNUM:
475     case SIM_ARM_FP7_REGNUM:
476     case SIM_ARM_FPS_REGNUM:
477       ARMul_SetReg (state, state->Mode, rn, frommem (state, memory));
478       break;
479 
480     case SIM_ARM_PS_REGNUM:
481       state->Cpsr = frommem (state, memory);
482       ARMul_CPSRAltered (state);
483       break;
484 
485     case SIM_ARM_MAVERIC_COP0R0_REGNUM:
486     case SIM_ARM_MAVERIC_COP0R1_REGNUM:
487     case SIM_ARM_MAVERIC_COP0R2_REGNUM:
488     case SIM_ARM_MAVERIC_COP0R3_REGNUM:
489     case SIM_ARM_MAVERIC_COP0R4_REGNUM:
490     case SIM_ARM_MAVERIC_COP0R5_REGNUM:
491     case SIM_ARM_MAVERIC_COP0R6_REGNUM:
492     case SIM_ARM_MAVERIC_COP0R7_REGNUM:
493     case SIM_ARM_MAVERIC_COP0R8_REGNUM:
494     case SIM_ARM_MAVERIC_COP0R9_REGNUM:
495     case SIM_ARM_MAVERIC_COP0R10_REGNUM:
496     case SIM_ARM_MAVERIC_COP0R11_REGNUM:
497     case SIM_ARM_MAVERIC_COP0R12_REGNUM:
498     case SIM_ARM_MAVERIC_COP0R13_REGNUM:
499     case SIM_ARM_MAVERIC_COP0R14_REGNUM:
500     case SIM_ARM_MAVERIC_COP0R15_REGNUM:
501       memcpy (& DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
502 	      memory, sizeof (struct maverick_regs));
503       return sizeof (struct maverick_regs);
504 
505     case SIM_ARM_MAVERIC_DSPSC_REGNUM:
506       memcpy (&DSPsc, memory, sizeof DSPsc);
507       return sizeof DSPsc;
508 
509     case SIM_ARM_IWMMXT_COP0R0_REGNUM:
510     case SIM_ARM_IWMMXT_COP0R1_REGNUM:
511     case SIM_ARM_IWMMXT_COP0R2_REGNUM:
512     case SIM_ARM_IWMMXT_COP0R3_REGNUM:
513     case SIM_ARM_IWMMXT_COP0R4_REGNUM:
514     case SIM_ARM_IWMMXT_COP0R5_REGNUM:
515     case SIM_ARM_IWMMXT_COP0R6_REGNUM:
516     case SIM_ARM_IWMMXT_COP0R7_REGNUM:
517     case SIM_ARM_IWMMXT_COP0R8_REGNUM:
518     case SIM_ARM_IWMMXT_COP0R9_REGNUM:
519     case SIM_ARM_IWMMXT_COP0R10_REGNUM:
520     case SIM_ARM_IWMMXT_COP0R11_REGNUM:
521     case SIM_ARM_IWMMXT_COP0R12_REGNUM:
522     case SIM_ARM_IWMMXT_COP0R13_REGNUM:
523     case SIM_ARM_IWMMXT_COP0R14_REGNUM:
524     case SIM_ARM_IWMMXT_COP0R15_REGNUM:
525     case SIM_ARM_IWMMXT_COP1R0_REGNUM:
526     case SIM_ARM_IWMMXT_COP1R1_REGNUM:
527     case SIM_ARM_IWMMXT_COP1R2_REGNUM:
528     case SIM_ARM_IWMMXT_COP1R3_REGNUM:
529     case SIM_ARM_IWMMXT_COP1R4_REGNUM:
530     case SIM_ARM_IWMMXT_COP1R5_REGNUM:
531     case SIM_ARM_IWMMXT_COP1R6_REGNUM:
532     case SIM_ARM_IWMMXT_COP1R7_REGNUM:
533     case SIM_ARM_IWMMXT_COP1R8_REGNUM:
534     case SIM_ARM_IWMMXT_COP1R9_REGNUM:
535     case SIM_ARM_IWMMXT_COP1R10_REGNUM:
536     case SIM_ARM_IWMMXT_COP1R11_REGNUM:
537     case SIM_ARM_IWMMXT_COP1R12_REGNUM:
538     case SIM_ARM_IWMMXT_COP1R13_REGNUM:
539     case SIM_ARM_IWMMXT_COP1R14_REGNUM:
540     case SIM_ARM_IWMMXT_COP1R15_REGNUM:
541       return Store_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
542 
543     default:
544       return 0;
545     }
546 
547   return length;
548 }
549 
550 int
551 sim_fetch_register (SIM_DESC sd ATTRIBUTE_UNUSED,
552 		    int rn,
553 		    unsigned char *memory,
554 		    int length)
555 {
556   ARMword regval;
557   int len = length;
558 
559   init ();
560 
561   switch ((enum sim_arm_regs) rn)
562     {
563     case SIM_ARM_R0_REGNUM:
564     case SIM_ARM_R1_REGNUM:
565     case SIM_ARM_R2_REGNUM:
566     case SIM_ARM_R3_REGNUM:
567     case SIM_ARM_R4_REGNUM:
568     case SIM_ARM_R5_REGNUM:
569     case SIM_ARM_R6_REGNUM:
570     case SIM_ARM_R7_REGNUM:
571     case SIM_ARM_R8_REGNUM:
572     case SIM_ARM_R9_REGNUM:
573     case SIM_ARM_R10_REGNUM:
574     case SIM_ARM_R11_REGNUM:
575     case SIM_ARM_R12_REGNUM:
576     case SIM_ARM_R13_REGNUM:
577     case SIM_ARM_R14_REGNUM:
578     case SIM_ARM_R15_REGNUM: /* PC */
579       regval = ARMul_GetReg (state, state->Mode, rn);
580       break;
581 
582     case SIM_ARM_FP0_REGNUM:
583     case SIM_ARM_FP1_REGNUM:
584     case SIM_ARM_FP2_REGNUM:
585     case SIM_ARM_FP3_REGNUM:
586     case SIM_ARM_FP4_REGNUM:
587     case SIM_ARM_FP5_REGNUM:
588     case SIM_ARM_FP6_REGNUM:
589     case SIM_ARM_FP7_REGNUM:
590     case SIM_ARM_FPS_REGNUM:
591       memset (memory, 0, length);
592       return 0;
593 
594     case SIM_ARM_PS_REGNUM:
595       regval = ARMul_GetCPSR (state);
596       break;
597 
598     case SIM_ARM_MAVERIC_COP0R0_REGNUM:
599     case SIM_ARM_MAVERIC_COP0R1_REGNUM:
600     case SIM_ARM_MAVERIC_COP0R2_REGNUM:
601     case SIM_ARM_MAVERIC_COP0R3_REGNUM:
602     case SIM_ARM_MAVERIC_COP0R4_REGNUM:
603     case SIM_ARM_MAVERIC_COP0R5_REGNUM:
604     case SIM_ARM_MAVERIC_COP0R6_REGNUM:
605     case SIM_ARM_MAVERIC_COP0R7_REGNUM:
606     case SIM_ARM_MAVERIC_COP0R8_REGNUM:
607     case SIM_ARM_MAVERIC_COP0R9_REGNUM:
608     case SIM_ARM_MAVERIC_COP0R10_REGNUM:
609     case SIM_ARM_MAVERIC_COP0R11_REGNUM:
610     case SIM_ARM_MAVERIC_COP0R12_REGNUM:
611     case SIM_ARM_MAVERIC_COP0R13_REGNUM:
612     case SIM_ARM_MAVERIC_COP0R14_REGNUM:
613     case SIM_ARM_MAVERIC_COP0R15_REGNUM:
614       memcpy (memory, & DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
615 	      sizeof (struct maverick_regs));
616       return sizeof (struct maverick_regs);
617 
618     case SIM_ARM_MAVERIC_DSPSC_REGNUM:
619       memcpy (memory, & DSPsc, sizeof DSPsc);
620       return sizeof DSPsc;
621 
622     case SIM_ARM_IWMMXT_COP0R0_REGNUM:
623     case SIM_ARM_IWMMXT_COP0R1_REGNUM:
624     case SIM_ARM_IWMMXT_COP0R2_REGNUM:
625     case SIM_ARM_IWMMXT_COP0R3_REGNUM:
626     case SIM_ARM_IWMMXT_COP0R4_REGNUM:
627     case SIM_ARM_IWMMXT_COP0R5_REGNUM:
628     case SIM_ARM_IWMMXT_COP0R6_REGNUM:
629     case SIM_ARM_IWMMXT_COP0R7_REGNUM:
630     case SIM_ARM_IWMMXT_COP0R8_REGNUM:
631     case SIM_ARM_IWMMXT_COP0R9_REGNUM:
632     case SIM_ARM_IWMMXT_COP0R10_REGNUM:
633     case SIM_ARM_IWMMXT_COP0R11_REGNUM:
634     case SIM_ARM_IWMMXT_COP0R12_REGNUM:
635     case SIM_ARM_IWMMXT_COP0R13_REGNUM:
636     case SIM_ARM_IWMMXT_COP0R14_REGNUM:
637     case SIM_ARM_IWMMXT_COP0R15_REGNUM:
638     case SIM_ARM_IWMMXT_COP1R0_REGNUM:
639     case SIM_ARM_IWMMXT_COP1R1_REGNUM:
640     case SIM_ARM_IWMMXT_COP1R2_REGNUM:
641     case SIM_ARM_IWMMXT_COP1R3_REGNUM:
642     case SIM_ARM_IWMMXT_COP1R4_REGNUM:
643     case SIM_ARM_IWMMXT_COP1R5_REGNUM:
644     case SIM_ARM_IWMMXT_COP1R6_REGNUM:
645     case SIM_ARM_IWMMXT_COP1R7_REGNUM:
646     case SIM_ARM_IWMMXT_COP1R8_REGNUM:
647     case SIM_ARM_IWMMXT_COP1R9_REGNUM:
648     case SIM_ARM_IWMMXT_COP1R10_REGNUM:
649     case SIM_ARM_IWMMXT_COP1R11_REGNUM:
650     case SIM_ARM_IWMMXT_COP1R12_REGNUM:
651     case SIM_ARM_IWMMXT_COP1R13_REGNUM:
652     case SIM_ARM_IWMMXT_COP1R14_REGNUM:
653     case SIM_ARM_IWMMXT_COP1R15_REGNUM:
654       return Fetch_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
655 
656     default:
657       return 0;
658     }
659 
660   while (len)
661     {
662       tomem (state, memory, regval);
663 
664       len -= 4;
665       memory += 4;
666       regval = 0;
667     }
668 
669   return length;
670 }
671 
672 typedef struct
673 {
674   char * 	swi_option;
675   unsigned int	swi_mask;
676 } swi_options;
677 
678 #define SWI_SWITCH	"--swi-support"
679 
680 static swi_options options[] =
681   {
682     { "none",    0 },
683     { "demon",   SWI_MASK_DEMON },
684     { "angel",   SWI_MASK_ANGEL },
685     { "redboot", SWI_MASK_REDBOOT },
686     { "all",     -1 },
687     { "NONE",    0 },
688     { "DEMON",   SWI_MASK_DEMON },
689     { "ANGEL",   SWI_MASK_ANGEL },
690     { "REDBOOT", SWI_MASK_REDBOOT },
691     { "ALL",     -1 }
692   };
693 
694 
695 static int
696 sim_target_parse_command_line (int argc, char ** argv)
697 {
698   int i;
699 
700   for (i = 1; i < argc; i++)
701     {
702       char * ptr = argv[i];
703       int arg;
704 
705       if ((ptr == NULL) || (* ptr != '-'))
706 	break;
707 
708       if (strcmp (ptr, "-t") == 0)
709 	{
710 	  trace = 1;
711 	  continue;
712 	}
713 
714       if (strcmp (ptr, "-z") == 0)
715 	{
716 	  /* Remove this option from the argv array.  */
717 	  for (arg = i; arg < argc; arg ++)
718 	    argv[arg] = argv[arg + 1];
719 	  argc --;
720 	  i --;
721 	  trace_funcs = 1;
722 	  continue;
723 	}
724 
725       if (strcmp (ptr, "-d") == 0)
726 	{
727 	  /* Remove this option from the argv array.  */
728 	  for (arg = i; arg < argc; arg ++)
729 	    argv[arg] = argv[arg + 1];
730 	  argc --;
731 	  i --;
732 	  disas = 1;
733 	  continue;
734 	}
735 
736       if (strncmp (ptr, SWI_SWITCH, sizeof SWI_SWITCH - 1) != 0)
737 	continue;
738 
739       if (ptr[sizeof SWI_SWITCH - 1] == 0)
740 	{
741 	  /* Remove this option from the argv array.  */
742 	  for (arg = i; arg < argc; arg ++)
743 	    argv[arg] = argv[arg + 1];
744 	  argc --;
745 
746 	  ptr = argv[i];
747 	}
748       else
749 	ptr += sizeof SWI_SWITCH;
750 
751       swi_mask = 0;
752 
753       while (* ptr)
754 	{
755 	  int i;
756 
757 	  for (i = sizeof options / sizeof options[0]; i--;)
758 	    if (strncmp (ptr, options[i].swi_option,
759 			 strlen (options[i].swi_option)) == 0)
760 	      {
761 		swi_mask |= options[i].swi_mask;
762 		ptr += strlen (options[i].swi_option);
763 
764 		if (* ptr == ',')
765 		  ++ ptr;
766 
767 		break;
768 	      }
769 
770 	  if (i < 0)
771 	    break;
772 	}
773 
774       if (* ptr != 0)
775 	fprintf (stderr, "Ignoring swi options: %s\n", ptr);
776 
777       /* Remove this option from the argv array.  */
778       for (arg = i; arg < argc; arg ++)
779 	argv[arg] = argv[arg + 1];
780       argc --;
781       i --;
782     }
783   return argc;
784 }
785 
786 static void
787 sim_target_parse_arg_array (char ** argv)
788 {
789   int i;
790 
791   for (i = 0; argv[i]; i++)
792     ;
793 
794   sim_target_parse_command_line (i, argv);
795 }
796 
797 static sim_cia
798 arm_pc_get (sim_cpu *cpu)
799 {
800   return PC;
801 }
802 
803 static void
804 arm_pc_set (sim_cpu *cpu, sim_cia pc)
805 {
806   ARMul_SetPC (state, pc);
807 }
808 
809 static void
810 free_state (SIM_DESC sd)
811 {
812   if (STATE_MODULES (sd) != NULL)
813     sim_module_uninstall (sd);
814   sim_cpu_free_all (sd);
815   sim_state_free (sd);
816 }
817 
818 SIM_DESC
819 sim_open (SIM_OPEN_KIND kind,
820 	  host_callback *cb,
821 	  struct bfd *abfd,
822 	  char **argv)
823 {
824   int i;
825   SIM_DESC sd = sim_state_alloc (kind, cb);
826   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
827 
828   /* The cpu data is kept in a separately allocated chunk of memory.  */
829   if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
830     {
831       free_state (sd);
832       return 0;
833     }
834 
835   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
836     {
837       free_state (sd);
838       return 0;
839     }
840 
841   /* getopt will print the error message so we just have to exit if this fails.
842      FIXME: Hmmm...  in the case of gdb we need getopt to call
843      print_filtered.  */
844   if (sim_parse_args (sd, argv) != SIM_RC_OK)
845     {
846       free_state (sd);
847       return 0;
848     }
849 
850   /* Check for/establish the a reference program image.  */
851   if (sim_analyze_program (sd,
852 			   (STATE_PROG_ARGV (sd) != NULL
853 			    ? *STATE_PROG_ARGV (sd)
854 			    : NULL), abfd) != SIM_RC_OK)
855     {
856       free_state (sd);
857       return 0;
858     }
859 
860   /* Configure/verify the target byte order and other runtime
861      configuration options.  */
862   if (sim_config (sd) != SIM_RC_OK)
863     {
864       sim_module_uninstall (sd);
865       return 0;
866     }
867 
868   if (sim_post_argv_init (sd) != SIM_RC_OK)
869     {
870       /* Uninstall the modules to avoid memory leaks,
871 	 file descriptor leaks, etc.  */
872       sim_module_uninstall (sd);
873       return 0;
874     }
875 
876   /* CPU specific initialization.  */
877   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
878     {
879       SIM_CPU *cpu = STATE_CPU (sd, i);
880 
881       CPU_PC_FETCH (cpu) = arm_pc_get;
882       CPU_PC_STORE (cpu) = arm_pc_set;
883     }
884 
885   sim_callback = cb;
886 
887   sim_target_parse_arg_array (argv);
888 
889   if (argv[1] != NULL)
890     {
891       int i;
892 
893       /* Scan for memory-size switches.  */
894       for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++)
895 	if (argv[i][0] == '-' && argv[i][1] == 'm')
896 	  {
897 	    if (argv[i][2] != '\0')
898 	      mem_size = atoi (&argv[i][2]);
899 	    else if (argv[i + 1] != NULL)
900 	      {
901 		mem_size = atoi (argv[i + 1]);
902 		i++;
903 	      }
904 	    else
905 	      {
906 		sim_callback->printf_filtered (sim_callback,
907 					       "Missing argument to -m option\n");
908 		return NULL;
909 	      }
910 
911 	  }
912     }
913 
914   return sd;
915 }
916 
917 void
918 sim_close (SIM_DESC sd ATTRIBUTE_UNUSED,
919 	   int quitting ATTRIBUTE_UNUSED)
920 {
921   /* Nothing to do.  */
922 }
923 
924 void
925 sim_stop_reason (SIM_DESC sd ATTRIBUTE_UNUSED,
926 		 enum sim_stop *reason,
927 		 int *sigrc)
928 {
929   if (stop_simulator)
930     {
931       *reason = sim_stopped;
932       *sigrc = GDB_SIGNAL_INT;
933     }
934   else if (state->EndCondition == 0)
935     {
936       *reason = sim_exited;
937       *sigrc = state->Reg[0] & 255;
938     }
939   else
940     {
941       *reason = sim_stopped;
942       if (state->EndCondition == RDIError_BreakpointReached)
943 	*sigrc = GDB_SIGNAL_TRAP;
944       else if (   state->EndCondition == RDIError_DataAbort
945 	       || state->EndCondition == RDIError_AddressException)
946 	*sigrc = GDB_SIGNAL_BUS;
947       else
948 	*sigrc = 0;
949     }
950 }
951