xref: /netbsd-src/external/gpl3/gdb/dist/sim/arm/wrapper.c (revision c38e7cc395b1472a774ff828e46123de44c628e9)
1 /* run front end support for arm
2    Copyright (C) 1995-2017 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 == BFD_ENDIAN_BIG ? 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 * const *argv,
233 		     char * const *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 static int
435 arm_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
436 {
437   init ();
438 
439   switch ((enum sim_arm_regs) rn)
440     {
441     case SIM_ARM_R0_REGNUM:
442     case SIM_ARM_R1_REGNUM:
443     case SIM_ARM_R2_REGNUM:
444     case SIM_ARM_R3_REGNUM:
445     case SIM_ARM_R4_REGNUM:
446     case SIM_ARM_R5_REGNUM:
447     case SIM_ARM_R6_REGNUM:
448     case SIM_ARM_R7_REGNUM:
449     case SIM_ARM_R8_REGNUM:
450     case SIM_ARM_R9_REGNUM:
451     case SIM_ARM_R10_REGNUM:
452     case SIM_ARM_R11_REGNUM:
453     case SIM_ARM_R12_REGNUM:
454     case SIM_ARM_R13_REGNUM:
455     case SIM_ARM_R14_REGNUM:
456     case SIM_ARM_R15_REGNUM: /* PC */
457     case SIM_ARM_FP0_REGNUM:
458     case SIM_ARM_FP1_REGNUM:
459     case SIM_ARM_FP2_REGNUM:
460     case SIM_ARM_FP3_REGNUM:
461     case SIM_ARM_FP4_REGNUM:
462     case SIM_ARM_FP5_REGNUM:
463     case SIM_ARM_FP6_REGNUM:
464     case SIM_ARM_FP7_REGNUM:
465     case SIM_ARM_FPS_REGNUM:
466       ARMul_SetReg (state, state->Mode, rn, frommem (state, memory));
467       break;
468 
469     case SIM_ARM_PS_REGNUM:
470       state->Cpsr = frommem (state, memory);
471       ARMul_CPSRAltered (state);
472       break;
473 
474     case SIM_ARM_MAVERIC_COP0R0_REGNUM:
475     case SIM_ARM_MAVERIC_COP0R1_REGNUM:
476     case SIM_ARM_MAVERIC_COP0R2_REGNUM:
477     case SIM_ARM_MAVERIC_COP0R3_REGNUM:
478     case SIM_ARM_MAVERIC_COP0R4_REGNUM:
479     case SIM_ARM_MAVERIC_COP0R5_REGNUM:
480     case SIM_ARM_MAVERIC_COP0R6_REGNUM:
481     case SIM_ARM_MAVERIC_COP0R7_REGNUM:
482     case SIM_ARM_MAVERIC_COP0R8_REGNUM:
483     case SIM_ARM_MAVERIC_COP0R9_REGNUM:
484     case SIM_ARM_MAVERIC_COP0R10_REGNUM:
485     case SIM_ARM_MAVERIC_COP0R11_REGNUM:
486     case SIM_ARM_MAVERIC_COP0R12_REGNUM:
487     case SIM_ARM_MAVERIC_COP0R13_REGNUM:
488     case SIM_ARM_MAVERIC_COP0R14_REGNUM:
489     case SIM_ARM_MAVERIC_COP0R15_REGNUM:
490       memcpy (& DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
491 	      memory, sizeof (struct maverick_regs));
492       return sizeof (struct maverick_regs);
493 
494     case SIM_ARM_MAVERIC_DSPSC_REGNUM:
495       memcpy (&DSPsc, memory, sizeof DSPsc);
496       return sizeof DSPsc;
497 
498     case SIM_ARM_IWMMXT_COP0R0_REGNUM:
499     case SIM_ARM_IWMMXT_COP0R1_REGNUM:
500     case SIM_ARM_IWMMXT_COP0R2_REGNUM:
501     case SIM_ARM_IWMMXT_COP0R3_REGNUM:
502     case SIM_ARM_IWMMXT_COP0R4_REGNUM:
503     case SIM_ARM_IWMMXT_COP0R5_REGNUM:
504     case SIM_ARM_IWMMXT_COP0R6_REGNUM:
505     case SIM_ARM_IWMMXT_COP0R7_REGNUM:
506     case SIM_ARM_IWMMXT_COP0R8_REGNUM:
507     case SIM_ARM_IWMMXT_COP0R9_REGNUM:
508     case SIM_ARM_IWMMXT_COP0R10_REGNUM:
509     case SIM_ARM_IWMMXT_COP0R11_REGNUM:
510     case SIM_ARM_IWMMXT_COP0R12_REGNUM:
511     case SIM_ARM_IWMMXT_COP0R13_REGNUM:
512     case SIM_ARM_IWMMXT_COP0R14_REGNUM:
513     case SIM_ARM_IWMMXT_COP0R15_REGNUM:
514     case SIM_ARM_IWMMXT_COP1R0_REGNUM:
515     case SIM_ARM_IWMMXT_COP1R1_REGNUM:
516     case SIM_ARM_IWMMXT_COP1R2_REGNUM:
517     case SIM_ARM_IWMMXT_COP1R3_REGNUM:
518     case SIM_ARM_IWMMXT_COP1R4_REGNUM:
519     case SIM_ARM_IWMMXT_COP1R5_REGNUM:
520     case SIM_ARM_IWMMXT_COP1R6_REGNUM:
521     case SIM_ARM_IWMMXT_COP1R7_REGNUM:
522     case SIM_ARM_IWMMXT_COP1R8_REGNUM:
523     case SIM_ARM_IWMMXT_COP1R9_REGNUM:
524     case SIM_ARM_IWMMXT_COP1R10_REGNUM:
525     case SIM_ARM_IWMMXT_COP1R11_REGNUM:
526     case SIM_ARM_IWMMXT_COP1R12_REGNUM:
527     case SIM_ARM_IWMMXT_COP1R13_REGNUM:
528     case SIM_ARM_IWMMXT_COP1R14_REGNUM:
529     case SIM_ARM_IWMMXT_COP1R15_REGNUM:
530       return Store_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
531 
532     default:
533       return 0;
534     }
535 
536   return length;
537 }
538 
539 static int
540 arm_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
541 {
542   ARMword regval;
543   int len = length;
544 
545   init ();
546 
547   switch ((enum sim_arm_regs) rn)
548     {
549     case SIM_ARM_R0_REGNUM:
550     case SIM_ARM_R1_REGNUM:
551     case SIM_ARM_R2_REGNUM:
552     case SIM_ARM_R3_REGNUM:
553     case SIM_ARM_R4_REGNUM:
554     case SIM_ARM_R5_REGNUM:
555     case SIM_ARM_R6_REGNUM:
556     case SIM_ARM_R7_REGNUM:
557     case SIM_ARM_R8_REGNUM:
558     case SIM_ARM_R9_REGNUM:
559     case SIM_ARM_R10_REGNUM:
560     case SIM_ARM_R11_REGNUM:
561     case SIM_ARM_R12_REGNUM:
562     case SIM_ARM_R13_REGNUM:
563     case SIM_ARM_R14_REGNUM:
564     case SIM_ARM_R15_REGNUM: /* PC */
565       regval = ARMul_GetReg (state, state->Mode, rn);
566       break;
567 
568     case SIM_ARM_FP0_REGNUM:
569     case SIM_ARM_FP1_REGNUM:
570     case SIM_ARM_FP2_REGNUM:
571     case SIM_ARM_FP3_REGNUM:
572     case SIM_ARM_FP4_REGNUM:
573     case SIM_ARM_FP5_REGNUM:
574     case SIM_ARM_FP6_REGNUM:
575     case SIM_ARM_FP7_REGNUM:
576     case SIM_ARM_FPS_REGNUM:
577       memset (memory, 0, length);
578       return 0;
579 
580     case SIM_ARM_PS_REGNUM:
581       regval = ARMul_GetCPSR (state);
582       break;
583 
584     case SIM_ARM_MAVERIC_COP0R0_REGNUM:
585     case SIM_ARM_MAVERIC_COP0R1_REGNUM:
586     case SIM_ARM_MAVERIC_COP0R2_REGNUM:
587     case SIM_ARM_MAVERIC_COP0R3_REGNUM:
588     case SIM_ARM_MAVERIC_COP0R4_REGNUM:
589     case SIM_ARM_MAVERIC_COP0R5_REGNUM:
590     case SIM_ARM_MAVERIC_COP0R6_REGNUM:
591     case SIM_ARM_MAVERIC_COP0R7_REGNUM:
592     case SIM_ARM_MAVERIC_COP0R8_REGNUM:
593     case SIM_ARM_MAVERIC_COP0R9_REGNUM:
594     case SIM_ARM_MAVERIC_COP0R10_REGNUM:
595     case SIM_ARM_MAVERIC_COP0R11_REGNUM:
596     case SIM_ARM_MAVERIC_COP0R12_REGNUM:
597     case SIM_ARM_MAVERIC_COP0R13_REGNUM:
598     case SIM_ARM_MAVERIC_COP0R14_REGNUM:
599     case SIM_ARM_MAVERIC_COP0R15_REGNUM:
600       memcpy (memory, & DSPregs [rn - SIM_ARM_MAVERIC_COP0R0_REGNUM],
601 	      sizeof (struct maverick_regs));
602       return sizeof (struct maverick_regs);
603 
604     case SIM_ARM_MAVERIC_DSPSC_REGNUM:
605       memcpy (memory, & DSPsc, sizeof DSPsc);
606       return sizeof DSPsc;
607 
608     case SIM_ARM_IWMMXT_COP0R0_REGNUM:
609     case SIM_ARM_IWMMXT_COP0R1_REGNUM:
610     case SIM_ARM_IWMMXT_COP0R2_REGNUM:
611     case SIM_ARM_IWMMXT_COP0R3_REGNUM:
612     case SIM_ARM_IWMMXT_COP0R4_REGNUM:
613     case SIM_ARM_IWMMXT_COP0R5_REGNUM:
614     case SIM_ARM_IWMMXT_COP0R6_REGNUM:
615     case SIM_ARM_IWMMXT_COP0R7_REGNUM:
616     case SIM_ARM_IWMMXT_COP0R8_REGNUM:
617     case SIM_ARM_IWMMXT_COP0R9_REGNUM:
618     case SIM_ARM_IWMMXT_COP0R10_REGNUM:
619     case SIM_ARM_IWMMXT_COP0R11_REGNUM:
620     case SIM_ARM_IWMMXT_COP0R12_REGNUM:
621     case SIM_ARM_IWMMXT_COP0R13_REGNUM:
622     case SIM_ARM_IWMMXT_COP0R14_REGNUM:
623     case SIM_ARM_IWMMXT_COP0R15_REGNUM:
624     case SIM_ARM_IWMMXT_COP1R0_REGNUM:
625     case SIM_ARM_IWMMXT_COP1R1_REGNUM:
626     case SIM_ARM_IWMMXT_COP1R2_REGNUM:
627     case SIM_ARM_IWMMXT_COP1R3_REGNUM:
628     case SIM_ARM_IWMMXT_COP1R4_REGNUM:
629     case SIM_ARM_IWMMXT_COP1R5_REGNUM:
630     case SIM_ARM_IWMMXT_COP1R6_REGNUM:
631     case SIM_ARM_IWMMXT_COP1R7_REGNUM:
632     case SIM_ARM_IWMMXT_COP1R8_REGNUM:
633     case SIM_ARM_IWMMXT_COP1R9_REGNUM:
634     case SIM_ARM_IWMMXT_COP1R10_REGNUM:
635     case SIM_ARM_IWMMXT_COP1R11_REGNUM:
636     case SIM_ARM_IWMMXT_COP1R12_REGNUM:
637     case SIM_ARM_IWMMXT_COP1R13_REGNUM:
638     case SIM_ARM_IWMMXT_COP1R14_REGNUM:
639     case SIM_ARM_IWMMXT_COP1R15_REGNUM:
640       return Fetch_Iwmmxt_Register (rn - SIM_ARM_IWMMXT_COP0R0_REGNUM, memory);
641 
642     default:
643       return 0;
644     }
645 
646   while (len)
647     {
648       tomem (state, memory, regval);
649 
650       len -= 4;
651       memory += 4;
652       regval = 0;
653     }
654 
655   return length;
656 }
657 
658 typedef struct
659 {
660   char * 	swi_option;
661   unsigned int	swi_mask;
662 } swi_options;
663 
664 #define SWI_SWITCH	"--swi-support"
665 
666 static swi_options options[] =
667   {
668     { "none",    0 },
669     { "demon",   SWI_MASK_DEMON },
670     { "angel",   SWI_MASK_ANGEL },
671     { "redboot", SWI_MASK_REDBOOT },
672     { "all",     -1 },
673     { "NONE",    0 },
674     { "DEMON",   SWI_MASK_DEMON },
675     { "ANGEL",   SWI_MASK_ANGEL },
676     { "REDBOOT", SWI_MASK_REDBOOT },
677     { "ALL",     -1 }
678   };
679 
680 
681 static int
682 sim_target_parse_command_line (int argc, char ** argv)
683 {
684   int i;
685 
686   for (i = 1; i < argc; i++)
687     {
688       char * ptr = argv[i];
689       int arg;
690 
691       if ((ptr == NULL) || (* ptr != '-'))
692 	break;
693 
694       if (strcmp (ptr, "-t") == 0)
695 	{
696 	  trace = 1;
697 	  continue;
698 	}
699 
700       if (strcmp (ptr, "-z") == 0)
701 	{
702 	  /* Remove this option from the argv array.  */
703 	  for (arg = i; arg < argc; arg ++)
704 	    argv[arg] = argv[arg + 1];
705 	  argc --;
706 	  i --;
707 	  trace_funcs = 1;
708 	  continue;
709 	}
710 
711       if (strcmp (ptr, "-d") == 0)
712 	{
713 	  /* Remove this option from the argv array.  */
714 	  for (arg = i; arg < argc; arg ++)
715 	    argv[arg] = argv[arg + 1];
716 	  argc --;
717 	  i --;
718 	  disas = 1;
719 	  continue;
720 	}
721 
722       if (strncmp (ptr, SWI_SWITCH, sizeof SWI_SWITCH - 1) != 0)
723 	continue;
724 
725       if (ptr[sizeof SWI_SWITCH - 1] == 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 
732 	  ptr = argv[i];
733 	}
734       else
735 	ptr += sizeof SWI_SWITCH;
736 
737       swi_mask = 0;
738 
739       while (* ptr)
740 	{
741 	  int i;
742 
743 	  for (i = ARRAY_SIZE (options); i--;)
744 	    if (strncmp (ptr, options[i].swi_option,
745 			 strlen (options[i].swi_option)) == 0)
746 	      {
747 		swi_mask |= options[i].swi_mask;
748 		ptr += strlen (options[i].swi_option);
749 
750 		if (* ptr == ',')
751 		  ++ ptr;
752 
753 		break;
754 	      }
755 
756 	  if (i < 0)
757 	    break;
758 	}
759 
760       if (* ptr != 0)
761 	fprintf (stderr, "Ignoring swi options: %s\n", ptr);
762 
763       /* Remove this option from the argv array.  */
764       for (arg = i; arg < argc; arg ++)
765 	argv[arg] = argv[arg + 1];
766       argc --;
767       i --;
768     }
769   return argc;
770 }
771 
772 static void
773 sim_target_parse_arg_array (char ** argv)
774 {
775   sim_target_parse_command_line (countargv (argv), argv);
776 }
777 
778 static sim_cia
779 arm_pc_get (sim_cpu *cpu)
780 {
781   return PC;
782 }
783 
784 static void
785 arm_pc_set (sim_cpu *cpu, sim_cia pc)
786 {
787   ARMul_SetPC (state, pc);
788 }
789 
790 static void
791 free_state (SIM_DESC sd)
792 {
793   if (STATE_MODULES (sd) != NULL)
794     sim_module_uninstall (sd);
795   sim_cpu_free_all (sd);
796   sim_state_free (sd);
797 }
798 
799 SIM_DESC
800 sim_open (SIM_OPEN_KIND kind,
801 	  host_callback *cb,
802 	  struct bfd *abfd,
803 	  char * const *argv)
804 {
805   int i;
806   SIM_DESC sd = sim_state_alloc (kind, cb);
807   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
808 
809   /* The cpu data is kept in a separately allocated chunk of memory.  */
810   if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
811     {
812       free_state (sd);
813       return 0;
814     }
815 
816   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
817     {
818       free_state (sd);
819       return 0;
820     }
821 
822   /* The parser will print an error message for us, so we silently return.  */
823   if (sim_parse_args (sd, argv) != SIM_RC_OK)
824     {
825       free_state (sd);
826       return 0;
827     }
828 
829   /* Check for/establish the a reference program image.  */
830   if (sim_analyze_program (sd,
831 			   (STATE_PROG_ARGV (sd) != NULL
832 			    ? *STATE_PROG_ARGV (sd)
833 			    : NULL), abfd) != SIM_RC_OK)
834     {
835       free_state (sd);
836       return 0;
837     }
838 
839   /* Configure/verify the target byte order and other runtime
840      configuration options.  */
841   if (sim_config (sd) != SIM_RC_OK)
842     {
843       sim_module_uninstall (sd);
844       return 0;
845     }
846 
847   if (sim_post_argv_init (sd) != SIM_RC_OK)
848     {
849       /* Uninstall the modules to avoid memory leaks,
850 	 file descriptor leaks, etc.  */
851       sim_module_uninstall (sd);
852       return 0;
853     }
854 
855   /* CPU specific initialization.  */
856   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
857     {
858       SIM_CPU *cpu = STATE_CPU (sd, i);
859 
860       CPU_REG_FETCH (cpu) = arm_reg_fetch;
861       CPU_REG_STORE (cpu) = arm_reg_store;
862       CPU_PC_FETCH (cpu) = arm_pc_get;
863       CPU_PC_STORE (cpu) = arm_pc_set;
864     }
865 
866   sim_callback = cb;
867 
868   sim_target_parse_arg_array (argv);
869 
870   if (argv[1] != NULL)
871     {
872       int i;
873 
874       /* Scan for memory-size switches.  */
875       for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++)
876 	if (argv[i][0] == '-' && argv[i][1] == 'm')
877 	  {
878 	    if (argv[i][2] != '\0')
879 	      mem_size = atoi (&argv[i][2]);
880 	    else if (argv[i + 1] != NULL)
881 	      {
882 		mem_size = atoi (argv[i + 1]);
883 		i++;
884 	      }
885 	    else
886 	      {
887 		sim_callback->printf_filtered (sim_callback,
888 					       "Missing argument to -m option\n");
889 		return NULL;
890 	      }
891 	  }
892     }
893 
894   return sd;
895 }
896 
897 void
898 sim_stop_reason (SIM_DESC sd ATTRIBUTE_UNUSED,
899 		 enum sim_stop *reason,
900 		 int *sigrc)
901 {
902   if (stop_simulator)
903     {
904       *reason = sim_stopped;
905       *sigrc = GDB_SIGNAL_INT;
906     }
907   else if (state->EndCondition == 0)
908     {
909       *reason = sim_exited;
910       *sigrc = state->Reg[0] & 255;
911     }
912   else
913     {
914       *reason = sim_stopped;
915       if (state->EndCondition == RDIError_BreakpointReached)
916 	*sigrc = GDB_SIGNAL_TRAP;
917       else if (   state->EndCondition == RDIError_DataAbort
918 	       || state->EndCondition == RDIError_AddressException)
919 	*sigrc = GDB_SIGNAL_BUS;
920       else
921 	*sigrc = 0;
922     }
923 }
924