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