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