update copyright year range in GDB files
[external/binutils.git] / sim / arm / wrapper.c
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 = sizeof options / sizeof options[0]; 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 }