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