]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/arm/wrapper.c
sim: arm/d10v/h8300/m68hc11/microblaze/mips/mn10300/moxie/sh/v850: convert to common...
[thirdparty/binutils-gdb.git] / sim / arm / wrapper.c
CommitLineData
c906108c 1/* run front end support for arm
32d0add0 2 Copyright (C) 1995-2015 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>
6d358e86 26#include <string.h>
c906108c
SS
27#include <bfd.h>
28#include <signal.h>
3c25f8c7
AC
29#include "gdb/callback.h"
30#include "gdb/remote-sim.h"
49d62f89
MF
31#include "sim-main.h"
32#include "sim-options.h"
c906108c
SS
33#include "armemu.h"
34#include "dbg_rdi.h"
6d358e86 35#include "ansidecl.h"
26216b98 36#include "gdb/sim-arm.h"
aba6488e 37#include "gdb/signals.h"
9256caa6 38#include "libiberty.h"
8d052926 39#include "iwmmxt.h"
74ec5579 40
49d62f89 41/* TODO: This should get pulled from the SIM_DESC. */
c906108c
SS
42host_callback *sim_callback;
43
49d62f89
MF
44/* TODO: This should get merged into sim_cpu. */
45struct ARMul_State *state;
c906108c
SS
46
47/* Memory size in bytes. */
49d62f89 48/* TODO: Memory should be converted to the common memory module. */
058f270d 49static int mem_size = (1 << 21);
c906108c 50
7a292a7a
SS
51int stop_simulator;
52
8d052926
NC
53#include "dis-asm.h"
54
49d62f89 55/* TODO: Tracing should be converted to common tracing module. */
8d052926
NC
56int trace = 0;
57int disas = 0;
58int trace_funcs = 0;
59
60static struct disassemble_info info;
61static char opbuf[1000];
62
63static int
64op_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
75static int
76sim_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
91void
92print_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
f603c8fe
NC
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
110struct maverick_regs
111{
112 union
113 {
114 int i;
115 float f;
116 } upper;
454de2ee 117
f603c8fe
NC
118 union
119 {
120 int i;
121 float f;
122 } lower;
123};
124
125union maverick_acc_regs
126{
127 long double ld; /* Acc registers are 72-bits. */
128};
129
130struct maverick_regs DSPregs[16];
131union maverick_acc_regs DSPacc[4];
132ARMword DSPsc;
133
dfcd3bfb 134static void
d68d7e6b 135init (void)
c906108c
SS
136{
137 static int done;
138
139 if (!done)
140 {
dfcd3bfb 141 ARMul_EmulateInit ();
c906108c 142 state = ARMul_NewState ();
49d62f89 143 state->bigendSig = (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN ? HIGH : LOW);
dfcd3bfb
JM
144 ARMul_MemoryInit (state, mem_size);
145 ARMul_OSInit (state);
58b991b1 146 state->verbose = 0;
c906108c
SS
147 done = 1;
148 }
149}
150
dfcd3bfb 151void
bdca5ee4
TT
152ARMul_ConsolePrint (ARMul_State * state,
153 const char * format,
154 ...)
c906108c
SS
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
c906108c 166int
d68d7e6b
NC
167sim_write (SIM_DESC sd ATTRIBUTE_UNUSED,
168 SIM_ADDR addr,
169 const unsigned char * buffer,
170 int size)
c906108c
SS
171{
172 int i;
3943c96b 173
c906108c 174 init ();
3943c96b 175
c906108c 176 for (i = 0; i < size; i++)
917bca4f 177 ARMul_SafeWriteByte (state, addr + i, buffer[i]);
3943c96b 178
c906108c
SS
179 return size;
180}
181
182int
d68d7e6b
NC
183sim_read (SIM_DESC sd ATTRIBUTE_UNUSED,
184 SIM_ADDR addr,
185 unsigned char * buffer,
186 int size)
c906108c
SS
187{
188 int i;
917bca4f 189
c906108c 190 init ();
86c735a5 191
c906108c 192 for (i = 0; i < size; i++)
917bca4f
NC
193 buffer[i] = ARMul_SafeReadByte (state, addr + i);
194
c906108c
SS
195 return size;
196}
197
c906108c 198int
d68d7e6b 199sim_stop (SIM_DESC sd ATTRIBUTE_UNUSED)
c906108c 200{
7a292a7a
SS
201 state->Emulate = STOP;
202 stop_simulator = 1;
203 return 1;
c906108c
SS
204}
205
206void
d68d7e6b
NC
207sim_resume (SIM_DESC sd ATTRIBUTE_UNUSED,
208 int step,
209 int siggnal ATTRIBUTE_UNUSED)
c906108c
SS
210{
211 state->EndCondition = 0;
7a292a7a 212 stop_simulator = 0;
c906108c
SS
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 {
dfcd3bfb 222 state->NextInstr = RESUME; /* treat as PC change */
c906108c
SS
223 state->Reg[15] = ARMul_DoProg (state);
224 }
225
226 FLUSHPIPE;
227}
228
229SIM_RC
d68d7e6b
NC
230sim_create_inferior (SIM_DESC sd ATTRIBUTE_UNUSED,
231 struct bfd * abfd,
232 char ** argv,
233 char ** env)
c906108c 234{
dfcd3bfb 235 int argvlen = 0;
1e6b544a 236 int mach;
c906108c
SS
237 char **arg;
238
1ed6c797
WN
239 init ();
240
c906108c 241 if (abfd != NULL)
8782aa32
WN
242 {
243 ARMul_SetPC (state, bfd_get_start_address (abfd));
244 mach = bfd_get_mach (abfd);
245 }
c906108c 246 else
8782aa32
WN
247 {
248 ARMul_SetPC (state, 0); /* ??? */
249 mach = 0;
250 }
1e6b544a 251
73cb0348
NC
252#ifdef MODET
253 if (abfd != NULL && (bfd_get_start_address (abfd) & 1))
254 SETT;
255#endif
256
3943c96b
NC
257 switch (mach)
258 {
259 default:
86c735a5
NC
260 (*sim_callback->printf_filtered)
261 (sim_callback,
10b57fcb
NC
262 "Unknown machine type '%d'; please update sim_create_inferior.\n",
263 mach);
3943c96b
NC
264 /* fall through */
265
f1129fb8 266 case 0:
3943c96b 267 /* We wouldn't set the machine type with earlier toolchains, so we
f1129fb8
NC
268 explicitly select a processor capable of supporting all ARMs in
269 32bit mode. */
8d052926
NC
270 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_v6_Prop);
271 break;
272
272fcdcd 273 case bfd_mach_arm_XScale:
8207e0f2 274 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_v6_Prop);
272fcdcd
NC
275 break;
276
b0f05691 277 case bfd_mach_arm_iWMMXt2:
0f026fd0
NC
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
f603c8fe
NC
299 case bfd_mach_arm_ep9312:
300 ARMul_SelectProcessor (state, ARM_v4_Prop | ARM_ep9312_Prop);
301 break;
302
f1129fb8 303 case bfd_mach_arm_5:
c17aa318
NC
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. */
25180f8a 316
f1129fb8
NC
317 case bfd_mach_arm_5T:
318 ARMul_SelectProcessor (state, ARM_v5_Prop);
319 break;
3943c96b 320
f1129fb8
NC
321 case bfd_mach_arm_5TE:
322 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop);
323 break;
324
f1129fb8
NC
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:
3943c96b
NC
332 ARMul_SelectProcessor (state, ARM_Lock_Prop);
333 break;
334
f1129fb8
NC
335 case bfd_mach_arm_2:
336 case bfd_mach_arm_2a:
3943c96b
NC
337 ARMul_SelectProcessor (state, ARM_Fix26_Prop);
338 break;
339 }
340
8d052926
NC
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
c906108c
SS
351 if (argv != NULL)
352 {
5f7d0a33
NC
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. */
c906108c
SS
357 if (state->CommandLine != NULL)
358 {
dfcd3bfb 359 free (state->CommandLine);
c906108c
SS
360 state->CommandLine = NULL;
361 }
dfcd3bfb 362
5f7d0a33 363 /* See how much we need. */
c906108c 364 for (arg = argv; *arg != NULL; arg++)
dfcd3bfb
JM
365 argvlen += strlen (*arg) + 1;
366
5f7d0a33 367 /* Allocate it. */
dfcd3bfb 368 state->CommandLine = malloc (argvlen + 1);
c906108c
SS
369 if (state->CommandLine != NULL)
370 {
371 arg = argv;
dfcd3bfb 372 state->CommandLine[0] = '\0';
5f7d0a33 373
c906108c
SS
374 for (arg = argv; *arg != NULL; arg++)
375 {
dfcd3bfb
JM
376 strcat (state->CommandLine, *arg);
377 strcat (state->CommandLine, " ");
c906108c
SS
378 }
379 }
380 }
381
382 if (env != NULL)
383 {
5f7d0a33 384 /* Now see if there's a MEMSIZE spec in the environment. */
c906108c
SS
385 while (*env)
386 {
dfcd3bfb 387 if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
c906108c 388 {
c906108c 389 char *end_of_num;
dfcd3bfb 390
5f7d0a33 391 /* Set up memory limit. */
dfcd3bfb
JM
392 state->MemSize =
393 strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0);
c906108c
SS
394 }
395 env++;
396 }
397 }
398
399 return SIM_RC_OK;
400}
401
dfcd3bfb 402static int
d68d7e6b 403frommem (struct ARMul_State *state, unsigned char *memory)
c906108c
SS
404{
405 if (state->bigendSig == HIGH)
86c735a5
NC
406 return (memory[0] << 24) | (memory[1] << 16)
407 | (memory[2] << 8) | (memory[3] << 0);
c906108c 408 else
86c735a5
NC
409 return (memory[3] << 24) | (memory[2] << 16)
410 | (memory[1] << 8) | (memory[0] << 0);
c906108c
SS
411}
412
c906108c 413static void
d68d7e6b
NC
414tomem (struct ARMul_State *state,
415 unsigned char *memory,
416 int val)
c906108c
SS
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
e1211e55
MF
434static int
435arm_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
c906108c
SS
436{
437 init ();
f1129fb8 438
26216b98 439 switch ((enum sim_arm_regs) rn)
3463c3fb 440 {
26216b98
AC
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:
3463c3fb 470 state->Cpsr = frommem (state, memory);
10b57fcb 471 ARMul_CPSRAltered (state);
26216b98
AC
472 break;
473
f603c8fe
NC
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
0f026fd0
NC
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);
3a3d6f65 531
26216b98
AC
532 default:
533 return 0;
3463c3fb 534 }
26216b98 535
9256caa6 536 return length;
c906108c
SS
537}
538
e1211e55
MF
539static int
540arm_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
c906108c
SS
541{
542 ARMword regval;
9256caa6 543 int len = length;
c906108c
SS
544
545 init ();
f1129fb8 546
26216b98
AC
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
f603c8fe
NC
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
0f026fd0
NC
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);
3a3d6f65 641
26216b98
AC
642 default:
643 return 0;
644 }
272fcdcd 645
9256caa6 646 while (len)
272fcdcd
NC
647 {
648 tomem (state, memory, regval);
649
9256caa6 650 len -= 4;
272fcdcd
NC
651 memory += 4;
652 regval = 0;
454de2ee 653 }
272fcdcd 654
9256caa6 655 return length;
c906108c
SS
656}
657
de4112fa
NC
658typedef struct
659{
660 char * swi_option;
661 unsigned int swi_mask;
662} swi_options;
663
664#define SWI_SWITCH "--swi-support"
665
666static 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
49d62f89 681static int
d68d7e6b 682sim_target_parse_command_line (int argc, char ** argv)
de4112fa
NC
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
8d052926
NC
694 if (strcmp (ptr, "-t") == 0)
695 {
696 trace = 1;
697 continue;
698 }
454de2ee 699
8d052926
NC
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 }
454de2ee 710
8d052926
NC
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
de4112fa
NC
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 --;
454de2ee 731
de4112fa
NC
732 ptr = argv[i];
733 }
734 else
735 ptr += sizeof SWI_SWITCH;
736
737 swi_mask = 0;
454de2ee 738
de4112fa
NC
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);
454de2ee 762
de4112fa
NC
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
772static void
d68d7e6b 773sim_target_parse_arg_array (char ** argv)
de4112fa
NC
774{
775 int i;
776
777 for (i = 0; argv[i]; i++)
778 ;
779
8944021f 780 sim_target_parse_command_line (i, argv);
de4112fa
NC
781}
782
27b97b40
MF
783static sim_cia
784arm_pc_get (sim_cpu *cpu)
785{
786 return PC;
787}
788
789static void
790arm_pc_set (sim_cpu *cpu, sim_cia pc)
791{
792 ARMul_SetPC (state, pc);
793}
794
49d62f89
MF
795static void
796free_state (SIM_DESC sd)
de4112fa 797{
49d62f89
MF
798 if (STATE_MODULES (sd) != NULL)
799 sim_module_uninstall (sd);
800 sim_cpu_free_all (sd);
801 sim_state_free (sd);
de4112fa 802}
de4112fa 803
c906108c 804SIM_DESC
49d62f89
MF
805sim_open (SIM_OPEN_KIND kind,
806 host_callback *cb,
807 struct bfd *abfd,
808 char **argv)
c906108c 809{
27b97b40 810 int i;
49d62f89
MF
811 SIM_DESC sd = sim_state_alloc (kind, cb);
812 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
d68d7e6b 813
49d62f89
MF
814 /* The cpu data is kept in a separately allocated chunk of memory. */
815 if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
816 {
817 free_state (sd);
818 return 0;
819 }
d68d7e6b 820
49d62f89
MF
821 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
822 {
823 free_state (sd);
824 return 0;
825 }
dfcd3bfb 826
49d62f89
MF
827 /* getopt will print the error message so we just have to exit if this fails.
828 FIXME: Hmmm... in the case of gdb we need getopt to call
829 print_filtered. */
830 if (sim_parse_args (sd, argv) != SIM_RC_OK)
c906108c 831 {
49d62f89
MF
832 free_state (sd);
833 return 0;
834 }
dfcd3bfb 835
49d62f89
MF
836 /* Check for/establish the a reference program image. */
837 if (sim_analyze_program (sd,
838 (STATE_PROG_ARGV (sd) != NULL
839 ? *STATE_PROG_ARGV (sd)
840 : NULL), abfd) != SIM_RC_OK)
841 {
842 free_state (sd);
843 return 0;
844 }
dfcd3bfb 845
49d62f89
MF
846 /* Configure/verify the target byte order and other runtime
847 configuration options. */
848 if (sim_config (sd) != SIM_RC_OK)
849 {
850 sim_module_uninstall (sd);
851 return 0;
852 }
dfcd3bfb 853
49d62f89
MF
854 if (sim_post_argv_init (sd) != SIM_RC_OK)
855 {
856 /* Uninstall the modules to avoid memory leaks,
857 file descriptor leaks, etc. */
858 sim_module_uninstall (sd);
859 return 0;
860 }
dfcd3bfb 861
27b97b40
MF
862 /* CPU specific initialization. */
863 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
864 {
865 SIM_CPU *cpu = STATE_CPU (sd, i);
866
e1211e55
MF
867 CPU_REG_FETCH (cpu) = arm_reg_fetch;
868 CPU_REG_STORE (cpu) = arm_reg_store;
27b97b40
MF
869 CPU_PC_FETCH (cpu) = arm_pc_get;
870 CPU_PC_STORE (cpu) = arm_pc_set;
871 }
872
49d62f89 873 sim_callback = cb;
dfcd3bfb 874
49d62f89 875 sim_target_parse_arg_array (argv);
dfcd3bfb 876
49d62f89
MF
877 if (argv[1] != NULL)
878 {
879 int i;
880
881 /* Scan for memory-size switches. */
882 for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++)
883 if (argv[i][0] == '-' && argv[i][1] == 'm')
058f270d
AC
884 {
885 if (argv[i][2] != '\0')
49d62f89 886 mem_size = atoi (&argv[i][2]);
058f270d
AC
887 else if (argv[i + 1] != NULL)
888 {
49d62f89 889 mem_size = atoi (argv[i + 1]);
058f270d
AC
890 i++;
891 }
892 else
893 {
894 sim_callback->printf_filtered (sim_callback,
895 "Missing argument to -m option\n");
896 return NULL;
897 }
058f270d 898 }
c906108c
SS
899 }
900
49d62f89 901 return sd;
c906108c
SS
902}
903
c906108c 904void
d68d7e6b
NC
905sim_stop_reason (SIM_DESC sd ATTRIBUTE_UNUSED,
906 enum sim_stop *reason,
907 int *sigrc)
c906108c 908{
7a292a7a
SS
909 if (stop_simulator)
910 {
911 *reason = sim_stopped;
a493e3e2 912 *sigrc = GDB_SIGNAL_INT;
7a292a7a
SS
913 }
914 else if (state->EndCondition == 0)
c906108c
SS
915 {
916 *reason = sim_exited;
917 *sigrc = state->Reg[0] & 255;
918 }
919 else
920 {
921 *reason = sim_stopped;
922 if (state->EndCondition == RDIError_BreakpointReached)
a493e3e2 923 *sigrc = GDB_SIGNAL_TRAP;
0f026fd0
NC
924 else if ( state->EndCondition == RDIError_DataAbort
925 || state->EndCondition == RDIError_AddressException)
a493e3e2 926 *sigrc = GDB_SIGNAL_BUS;
c906108c
SS
927 else
928 *sigrc = 0;
929 }
930}