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