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