* wrapper.c (op_print): New function.
(sim_dis_read): New function.
(print_insn): New function - disassembles the given instruction.
(sim_trace): Note that tracing is now allowed.
(sim_create_inferior): Default to emulating v6.
Initialise the disassembler machinery.
(sim_target_parse_command_line): Add support for -t -d and -z
options.
(sim_target_display_usage): Note existence of -d and -z options.
(sim_open): Parse -t -d and -z options.
* armemu.h: Add exports of trace, disas and trace_funcs.
Add prototype for print_insn.
* armemu.c (ARMul_Emulate26): Add tracing code.
Delete unused variables.
* thumbemu (handle_v6_thumb_insn): Delete unused variable Rd.
Move Rm variable into switch cases.
Add tracing code.
* armcopro.c (XScale_cp15_init): Add a return value.
(XScale_cp13_init): Likewise.
(XScale_cp14_init): Likewise.
(XScale_cp15_LDC): Delete unused function.
(XScale_cp15_STC): Likewise.
* maverick.c: Delete comment inside comment.
(DSPInit): Delete unused function.
(DSPMCR4): Fix compile time warning about missing parenthesis.
(DSPMCR5): Likewise.
(DSPCDP6): Delete unused variable opcode2.
+2014-03-14 Nick Clifton <nickc@redhat.com>
+
+ * wrapper.c (op_print): New function.
+ (sim_dis_read): New function.
+ (print_insn): New function - disassembles the given instruction.
+ (sim_trace): Note that tracing is now allowed.
+ (sim_create_inferior): Default to emulating v6.
+ Initialise the disassembler machinery.
+ (sim_target_parse_command_line): Add support for -t -d and -z
+ options.
+ (sim_target_display_usage): Note existence of -d and -z options.
+ (sim_open): Parse -t -d and -z options.
+ * armemu.h: Add exports of trace, disas and trace_funcs.
+ Add prototype for print_insn.
+ * armemu.c (ARMul_Emulate26): Add tracing code.
+ Delete unused variables.
+ * thumbemu (handle_v6_thumb_insn): Delete unused variable Rd.
+ Move Rm variable into switch cases.
+ Add tracing code.
+
+ * armcopro.c (XScale_cp15_init): Add a return value.
+ (XScale_cp13_init): Likewise.
+ (XScale_cp14_init): Likewise.
+ (XScale_cp15_LDC): Delete unused function.
+ (XScale_cp15_STC): Likewise.
+ * maverick.c: Delete comment inside comment.
+ (DSPInit): Delete unused function.
+ (DSPMCR4): Fix compile time warning about missing parenthesis.
+ (DSPMCR5): Likewise.
+ (DSPCDP6): Delete unused variable opcode2.
+
2014-03-14 David McQuillan <dmcq@tao-group.com>
PR sim/8388
/* Initialise the ARM Control Register. */
XScale_cp15_opcode_2_is_0_Regs[1] = 0x00000078;
+
+ return TRUE;
}
/* Check an access to a register. */
return 0;
}
-static unsigned
-XScale_cp15_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data)
-{
- unsigned reg = BITS (12, 15);
- unsigned result;
-
- result = check_cp15_access (state, reg, 0, 0, 0);
-
- if (result == ARMul_DONE && type == ARMul_DATA)
- write_cp15_reg (state, reg, 0, 0, data);
-
- return result;
-}
-
-static unsigned
-XScale_cp15_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data)
-{
- unsigned reg = BITS (12, 15);
- unsigned result;
-
- result = check_cp15_access (state, reg, 0, 0, 0);
-
- if (result == ARMul_DONE && type == ARMul_DATA)
- * data = read_cp15_reg (reg, 0, 0);
-
- return result;
-}
-
static unsigned
XScale_cp15_MRC (ARMul_State * state,
unsigned type ATTRIBUTE_UNUSED,
XScale_cp13_CR0_Regs[i] = 0;
XScale_cp13_CR1_Regs[i] = 0;
}
+
+ return TRUE;
}
/* Check an access to a register. */
for (i = 16; i--;)
XScale_cp14_Regs[i] = 0;
+
+ return TRUE;
}
/* Check an access to a register. */
/* armemu.c -- Main instruction emulation: ARM7 Instruction Emulator.
Copyright (C) 1994 Advanced RISC Machines Ltd.
Modifications to add arch. v4 support by <jsmith@cygnus.com>.
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
{
ARMword Rm;
int ror = -1;
-
+
switch (BITS (4, 11))
{
case 0x07: ror = 0; break;
if (state->EventSet)
ARMul_EnvokeEvent (state);
-#if 0 /* Enable this for a helpful bit of debugging when tracing is needed. */
- fprintf (stderr, "pc: %x, instr: %x\n", pc & ~1, instr);
- if (instr == 0)
- abort ();
-#endif
+
+ if (! TFLAG && trace)
+ {
+ fprintf (stderr, "pc: %x, ", pc & ~1);
+ if (! disas)
+ fprintf (stderr, "instr: %x\n", instr);
+ }
+
+ if (instr == 0 || pc < 0x10)
+ {
+ ARMul_Abort (state, ARMUndefinedInstrV);
+ state->Emulate = FALSE;
+ }
+
#if 0 /* Enable this code to help track down stack alignment bugs. */
{
static ARMword old_sp = -1;
}
if (state->Debug)
{
- fprintf (stderr, "sim: At %08lx Instr %08lx Mode %02lx\n", pc, instr,
- state->Mode);
+ fprintf (stderr, "sim: At %08lx Instr %08lx Mode %02lx\n",
+ (long) pc, (long) instr, (long) state->Mode);
(void) fgetc (stdin);
}
}
case t_decoded:
/* ARM instruction available. */
+ if (disas || trace)
+ {
+ fprintf (stderr, " emulate as: ");
+ if (trace)
+ fprintf (stderr, "%08x ", new);
+ if (! disas)
+ fprintf (stderr, "\n");
+ }
instr = new;
/* So continue instruction decoding. */
break;
}
}
#endif
+ if (disas)
+ print_insn (instr);
/* Check the condition codes. */
if ((temp = TOPBITS (28)) == AL)
{
if (BITS (4, 7) == 0x7)
{
- ARMword value;
extern int SWI_vector_installed;
/* Hardware is allowed to optionally override this
ARMdword op1 = state->Reg[BITS (0, 3)];
ARMdword op2 = state->Reg[BITS (8, 11)];
ARMdword dest;
- ARMdword result;
if (BIT (5))
op1 >>= 16;
/* ElSegundo SMULxy insn. */
ARMword op1 = state->Reg[BITS (0, 3)];
ARMword op2 = state->Reg[BITS (8, 11)];
- ARMword Rn = state->Reg[BITS (12, 15)];
if (BIT (5))
op1 >>= 16;
FLUSHPIPE;
break;
-
/* Branch and Link forward. */
case 0xb0:
case 0xb1:
#endif
state->Reg[15] = pc + 8 + POSBRANCH;
FLUSHPIPE;
+ if (trace_funcs)
+ fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
break;
-
/* Branch and Link backward. */
case 0xb8:
case 0xb9:
#endif
state->Reg[15] = pc + 8 + NEGBRANCH;
FLUSHPIPE;
+ if (trace_funcs)
+ fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
break;
-
/* Co-Processor Data Transfers. */
case 0xc4:
if (state->is_v5)
#endif
FLUSHPIPE;
+ if (trace_funcs)
+ fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
}
/* This routine handles writes to register 15 when the S bit is set. */
ARMul_R15Altered (state);
#endif
FLUSHPIPE;
+ if (trace_funcs)
+ fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
}
/* In machines capable of running in Thumb mode, BX, BLX, LDR and LDM
state->Reg[15] = src & 0xfffffffc;
}
FLUSHPIPE;
+ if (trace_funcs)
+ fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
#else
WriteR15 (state, src);
#endif
along with this program; if not, see <http://www.gnu.org/licenses/>. */
extern ARMword isize;
+extern int trace;
+extern int disas;
+extern int trace_funcs;
+extern void print_insn (ARMword);
/* Condition code values. */
#define EQ 0
#define CBIT (1L << 29)
#define VBIT (1L << 28)
#define SBIT (1L << 27)
+#define GE0 (1L << 16)
+#define GE1 (1L << 17)
+#define GE2 (1L << 18)
+#define GE3 (1L << 19)
#define IBIT (1L << 7)
#define FBIT (1L << 6)
#define IFBITS (3L << 6)
#include "ansidecl.h"
#include "armemu.h"
-/*#define CIRRUS_DEBUG 1 /**/
+/*#define CIRRUS_DEBUG 1 */
#if CIRRUS_DEBUG
# define printfdbg printf
#else
exit (1);
}
-static unsigned
-DSPInit (ARMul_State * state)
-{
- ARMul_ConsolePrint (state, ", DSP present");
- return TRUE;
-}
-
unsigned
DSPMRC4 (ARMul_State * state ATTRIBUTE_UNUSED,
unsigned type ATTRIBUTE_UNUSED,
v = SubOverflow (DSPregs[SRC1_REG].lower.i, DSPregs[SRC2_REG].lower.i,
res);
/* carry */
- c = (NEG (a) && POS (b) ||
- (NEG (a) && POS (res)) || (POS (b) && POS (res)));
+ c = (NEG (a) && POS (b))
+ || (NEG (a) && POS (res))
+ || (POS (b) && POS (res));
*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
break;
v = ((NEG64 (a) && POS64 (b) && POS64 (res))
|| (POS64 (a) && NEG64 (b) && NEG64 (res)));
/* carry */
- c = (NEG64 (a) && POS64 (b) ||
- (NEG64 (a) && POS64 (res)) || (POS64 (b) && POS64 (res)));
+ c = (NEG64 (a) && POS64 (b))
+ || (NEG64 (a) && POS64 (res))
+ || (POS64 (b) && POS64 (res));
*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
break;
unsigned type,
ARMword instr)
{
- int opcode2;
-
- opcode2 = BITS (5,7);
-
switch (BITS (20,21))
{
case 0:
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, see <http://www.gnu.org/licenses/>. */
ARMword tinstr,
tdstate * pvalid)
{
- ARMword Rd;
- ARMword Rm;
-
if (! state->is_v6)
{
* pvalid = t_undefined;
case 0xba40: /* rev16 */
case 0xbac0: /* revsh */
case 0xb650: /* setend */
- default:
+ default:
printf ("Unhandled v6 thumb insn: %04x\n", tinstr);
* pvalid = t_undefined;
return;
case 0xb200: /* sxth */
- Rm = state->Reg [(tinstr & 0x38) >> 3];
- if (Rm & 0x8000)
- state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000;
- else
- state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
- break;
+ {
+ ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
+
+ if (Rm & 0x8000)
+ state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000;
+ else
+ state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
+ break;
+ }
+
case 0xb240: /* sxtb */
- Rm = state->Reg [(tinstr & 0x38) >> 3];
- if (Rm & 0x80)
- state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00;
- else
- state->Reg [(tinstr & 0x7)] = Rm & 0xff;
- break;
+ {
+ ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
+
+ if (Rm & 0x80)
+ state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00;
+ else
+ state->Reg [(tinstr & 0x7)] = Rm & 0xff;
+ break;
+ }
+
case 0xb280: /* uxth */
- Rm = state->Reg [(tinstr & 0x38) >> 3];
- state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
- break;
+ {
+ ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
+
+ state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
+ break;
+ }
+
case 0xb2c0: /* uxtb */
- Rm = state->Reg [(tinstr & 0x38) >> 3];
- state->Reg [(tinstr & 0x7)] = Rm & 0xff;
- break;
+ {
+ ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
+
+ state->Reg [(tinstr & 0x7)] = Rm & 0xff;
+ break;
+ }
}
/* Indicate that the instruction has been processed. */
* pvalid = t_branch;
tinstr &= 0xFFFF;
}
+ if (trace)
+ fprintf (stderr, "pc: %x, Thumb instr: %x", pc & ~1, tinstr);
+
#if 1 /* debugging to catch non updates */
*ainstr = 0xDEADC0DE;
#endif
case 0x0e00:
if (state->is_v5)
{
- /* This is normally an undefined instruction. The v5t architecture
+ /* This is normally an undefined instruction. The v5t architecture
defines this particular pattern as a BKPT instruction, for
hardware assisted debugging. We map onto the arm BKPT
instruction. */
state->Reg[14] = (tmp | 1);
valid = t_branch;
FLUSHPIPE;
+ if (trace_funcs)
+ fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
break;
}
}
break;
}
+ if (trace && valid != t_decoded)
+ fprintf (stderr, "\n");
+
return valid;
}
#include "gdb/sim-arm.h"
#include "gdb/signals.h"
#include "libiberty.h"
+#include "iwmmxt.h"
host_callback *sim_callback;
int stop_simulator;
+#include "dis-asm.h"
+
+int trace = 0;
+int disas = 0;
+int trace_funcs = 0;
+
+static struct disassemble_info info;
+static char opbuf[1000];
+
+static int
+op_printf (char *buf, char *fmt, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start (ap, fmt);
+ ret = vsprintf (opbuf + strlen (opbuf), fmt, ap);
+ va_end (ap);
+ return ret;
+}
+
+static int
+sim_dis_read (bfd_vma memaddr ATTRIBUTE_UNUSED,
+ bfd_byte * ptr,
+ unsigned int length,
+ struct disassemble_info * info)
+{
+ ARMword val = (ARMword) *((ARMword *) info->application_data);
+
+ while (length--)
+ {
+ * ptr ++ = val & 0xFF;
+ val >>= 8;
+ }
+ return 0;
+}
+
+void
+print_insn (ARMword instr)
+{
+ int size;
+
+ opbuf[0] = 0;
+ info.application_data = & instr;
+ size = print_insn_little_arm (0, & info);
+ fprintf (stderr, " %*s\n", size, opbuf);
+}
+
/* Cirrus DSP registers.
We need to define these registers outside of maverick.c because
int
sim_trace (sd)
SIM_DESC sd ATTRIBUTE_UNUSED;
-{
- (*sim_callback->printf_filtered)
- (sim_callback,
- "This simulator does not support tracing\n");
+{
+ trace = 1;
+ sim_resume (sd, 0, 0);
return 1;
}
/* We wouldn't set the machine type with earlier toolchains, so we
explicitly select a processor capable of supporting all ARMs in
32bit mode. */
- /* We choose the XScale rather than the iWMMXt, because the iWMMXt
- removes the FPE emulator, since it conflicts with its coprocessors.
- For the most generic ARM support, we want the FPE emulator in place. */
+ ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_v6_Prop);
+ break;
+
case bfd_mach_arm_XScale:
ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_v6_Prop);
break;
ARMul_SetCPSR (state, SVC32MODE);
}
+ memset (& info, 0, sizeof (info));
+ INIT_DISASSEMBLE_INFO (info, stdout, op_printf);
+ info.read_memory_func = sim_dis_read;
+ info.arch = bfd_get_arch (abfd);
+ info.mach = bfd_get_mach (abfd);
+ info.endian_code = BFD_ENDIAN_LITTLE;
+ if (info.mach == 0)
+ info.arch = bfd_arch_arm;
+ disassemble_init_for_target (& info);
+
if (argv != NULL)
{
/* Set up the command line by laboriously stringing together
return length;
}
-#ifdef SIM_TARGET_SWITCHES
-
static void sim_target_parse_arg_array (char **);
typedef struct
if ((ptr == NULL) || (* ptr != '-'))
break;
+ if (strcmp (ptr, "-t") == 0)
+ {
+ trace = 1;
+ continue;
+ }
+
+ if (strcmp (ptr, "-z") == 0)
+ {
+ /* Remove this option from the argv array. */
+ for (arg = i; arg < argc; arg ++)
+ argv[arg] = argv[arg + 1];
+ argc --;
+ i --;
+ trace_funcs = 1;
+ continue;
+ }
+
+ if (strcmp (ptr, "-d") == 0)
+ {
+ /* Remove this option from the argv array. */
+ for (arg = i; arg < argc; arg ++)
+ argv[arg] = argv[arg + 1];
+ argc --;
+ i --;
+ disas = 1;
+ continue;
+ }
+
if (strncmp (ptr, SWI_SWITCH, sizeof SWI_SWITCH - 1) != 0)
continue;
fprintf (stream, "%s=<list> Comma seperated list of SWI protocols to supoport.\n\
This list can contain: NONE, DEMON, ANGEL, REDBOOT and/or ALL.\n",
SWI_SWITCH);
+ fprintf (stream, "-d\t\tEnable disassembly of instructions during tracing.\n");
+ fprintf (stream, "-z\t\tTrace entering and leaving functions.\n\n");
}
-#endif
SIM_DESC
sim_open (kind, ptr, abfd, argv)
break;
}
}
+ else if (argv[i][0] == '-' && argv[i][1] == 't')
+ {
+ trace = 1;
+ break;
+ }
+ else if (argv[i][0] == '-' && argv[i][1] == 'z')
+ {
+ trace_funcs = 1;
+ break;
+ }
+ else if (argv[i][0] == '-' && argv[i][1] == 'd')
+ {
+ disas = 1;
+ break;
+ }
else if (argv[i][0] == '-' && argv[i][1] == 'm')
{
if (argv[i][2] != '\0')