mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-21 04:42:53 +08:00
54780889e9
The h8300 sim has its own implementation for memory handling that I'd like to replace with the common sim memory code. However, it's got a weird bit of code it calls "eightbit mem" that makes this not as easy as it would otherwise be. The code has this comment: /* These define the size of main memory for the simulator. Note the size of main memory for the H8/300H is only 256k. Keeping it small makes the simulator run much faster and consume less memory. The linker knows about the limited size of the simulator's main memory on the H8/300H (via the h8300h.sc linker script). So if you change H8300H_MSIZE, be sure to fix the linker script too. Also note that there's a separate "eightbit" area aside from main memory. For simplicity, the simulator assumes any data memory reference outside of main memory refers to the eightbit area (in theory, this can only happen when simulating H8/300H programs). We make no attempt to catch overlapping addresses, wrapped addresses, etc etc. */ I've read the H8/300 Programming Manual and the H8/300H Software Manual and can't find documentation on it. The closest I can find is the bits about the exception vectors, but that sounds like a convention where the first 256 bytes of memory are used for a special purpose. The sim will actually allocate a sep memory buffer of 256 bytes and you address it by accessing anywhere outside of main memory. e.g. I would expect code to access it like: uint32_t *data = (void *)0; data[0] = reset_exception_vector; not like the sim expects like: uint8_t *data = (void *)0x1000000; data[0] = ...; The gcc manual has an "eightbit_data" attribute: Use this attribute on the H8/300, H8/300H, and H8S to indicate that the specified variable should be placed into the eight-bit data section. The compiler generates more efficient code for certain operations on data in the eight-bit data area. Note the eight-bit data area is limited to 256 bytes of data. And the gcc code implies that it's accessed via special addressing: eightbit_data: This variable lives in the 8-bit data area and can be referenced with 8-bit absolute memory addresses. I'm fairly certain these are referring to the 8-bit addressing modes that allow access to 0xff00 - 0xffff with only an 8-bit immediate. They aren't completely separate address spaces which this eightbit memory buffer occupies. But the sim doesn't access its eightbit memory based on specific insns, it does it purely on the addresses requested. Unfortunately, much of this code was authored by Michael Snyder, so I can't ask him :(. I asked Renesas support and they didn't know: https://renesasrulz.com/the_vault/f/archive-forum/6952/question-about-eightbit-memory So I've come to the conclusion that this was a little sim-specific hack done for <some convenience> and has no relation to real hardware. And as such, let's drop it until someone notices and can provide a reason for why we need to support it.
161 lines
4.3 KiB
C
161 lines
4.3 KiB
C
/* Main header for the Hitachi h8/300 architecture. */
|
|
|
|
#include "config.h"
|
|
#include "bfd.h"
|
|
|
|
#ifndef SIM_MAIN_H
|
|
#define SIM_MAIN_H
|
|
|
|
#define DEBUG
|
|
|
|
/* These define the size of main memory for the simulator.
|
|
|
|
Note the size of main memory for the H8/300H is only 256k. Keeping it
|
|
small makes the simulator run much faster and consume less memory.
|
|
|
|
The linker knows about the limited size of the simulator's main memory
|
|
on the H8/300H (via the h8300h.sc linker script). So if you change
|
|
H8300H_MSIZE, be sure to fix the linker script too.
|
|
|
|
Also note that there's a separate "eightbit" area aside from main
|
|
memory. For simplicity, the simulator assumes any data memory reference
|
|
outside of main memory refers to the eightbit area (in theory, this
|
|
can only happen when simulating H8/300H programs). We make no attempt
|
|
to catch overlapping addresses, wrapped addresses, etc etc. */
|
|
|
|
#define H8300_MSIZE (1 << 16)
|
|
|
|
/* avolkov:
|
|
Next 2 macros are ugly for any workstation, but while they're work.
|
|
Memory size MUST be configurable. */
|
|
#define H8300H_MSIZE (1 << 24)
|
|
#define H8300S_MSIZE (1 << 24)
|
|
|
|
#define CSIZE 1024
|
|
|
|
enum h8_regnum {
|
|
R0_REGNUM = 0,
|
|
R1_REGNUM = 1,
|
|
R2_REGNUM = 2,
|
|
R3_REGNUM = 3,
|
|
R4_REGNUM = 4,
|
|
R5_REGNUM = 5,
|
|
R6_REGNUM = 6,
|
|
R7_REGNUM = 7,
|
|
|
|
SP_REGNUM = R7_REGNUM, /* Contains address of top of stack */
|
|
FP_REGNUM = R6_REGNUM, /* Contains address of executing
|
|
stack frame */
|
|
CCR_REGNUM = 8, /* Contains processor status */
|
|
PC_REGNUM = 9, /* Contains program counter */
|
|
CYCLE_REGNUM = 10,
|
|
EXR_REGNUM = 11,
|
|
INST_REGNUM = 12,
|
|
TICK_REGNUM = 13,
|
|
MACH_REGNUM = 14,
|
|
MACL_REGNUM = 15,
|
|
SBR_REGNUM = 16,
|
|
VBR_REGNUM = 17,
|
|
|
|
ZERO_REGNUM = 18
|
|
};
|
|
|
|
enum h8_typecodes {
|
|
OP_NULL,
|
|
OP_REG, /* Register direct. */
|
|
OP_LOWREG, /* Special reg syntax for "bra". */
|
|
OP_DISP, /* Register indirect w/displacement. */
|
|
/* Note: h8300, h8300h, and h8300s permit only pre-decr and post-incr. */
|
|
OP_PREDEC, /* Register indirect w/pre-decrement. */
|
|
OP_POSTDEC, /* Register indirect w/post-decrement. */
|
|
OP_PREINC, /* Register indirect w/pre-increment. */
|
|
OP_POSTINC, /* Register indirect w/post-increment. */
|
|
OP_PCREL, /* PC Relative. */
|
|
OP_MEM, /* Absolute memory address. */
|
|
OP_CCR, /* Condition Code Register. */
|
|
OP_IMM, /* Immediate value. */
|
|
/*OP_ABS*/ /* Un-used (duplicates op_mem?). */
|
|
OP_EXR, /* EXtended control Register. */
|
|
OP_SBR, /* Vector Base Register. */
|
|
OP_VBR, /* Short-address Base Register. */
|
|
OP_MACH, /* Multiply Accumulator - high. */
|
|
OP_MACL, /* Multiply Accumulator - low. */
|
|
/* FIXME: memory indirect? */
|
|
OP_INDEXB, /* Byte index mode */
|
|
OP_INDEXW, /* Word index mode */
|
|
OP_INDEXL /* Long index mode */
|
|
};
|
|
|
|
#include "sim-basics.h"
|
|
#include "sim-base.h"
|
|
|
|
/* Structure used to describe addressing */
|
|
|
|
typedef struct
|
|
{
|
|
int type;
|
|
int reg;
|
|
int literal;
|
|
} ea_type;
|
|
|
|
/* Struct for instruction decoder. */
|
|
typedef struct
|
|
{
|
|
ea_type src;
|
|
ea_type dst;
|
|
ea_type op3;
|
|
int opcode;
|
|
int next_pc;
|
|
int oldpc;
|
|
int cycles;
|
|
#ifdef DEBUG
|
|
struct h8_opcode *op;
|
|
#endif
|
|
} decoded_inst;
|
|
|
|
struct _sim_cpu {
|
|
unsigned int regs[20]; /* 8 GR's plus ZERO, SBR, and VBR. */
|
|
unsigned int pc;
|
|
|
|
int macS; /* MAC Saturating mode */
|
|
int macV; /* MAC Overflow */
|
|
int macN; /* MAC Negative */
|
|
int macZ; /* MAC Zero */
|
|
|
|
int delayed_branch;
|
|
char **command_line; /* Pointer to command line arguments. */
|
|
|
|
unsigned char *memory;
|
|
int mask;
|
|
|
|
sim_cpu_base base;
|
|
};
|
|
|
|
/* The sim_state struct. */
|
|
struct sim_state {
|
|
sim_cpu *cpu[MAX_NR_PROCESSORS];
|
|
unsigned long memory_size;
|
|
#ifdef ADEBUG
|
|
int stats[O_LAST];
|
|
#endif
|
|
sim_state_base base;
|
|
};
|
|
|
|
/* The current state of the processor; registers, memory, etc. */
|
|
|
|
#define cpu_set_pc(CPU, VAL) (((CPU)->pc) = (VAL))
|
|
#define cpu_get_pc(CPU) (((CPU)->pc))
|
|
|
|
/* Magic numbers used to distinguish an exit from a breakpoint. */
|
|
#define LIBC_EXIT_MAGIC1 0xdead
|
|
#define LIBC_EXIT_MAGIC2 0xbeef
|
|
/* Local version of macros for decoding exit status.
|
|
(included here rather than try to find target version of wait.h)
|
|
*/
|
|
#define SIM_WIFEXITED(V) (((V) & 0xff) == 0)
|
|
#define SIM_WIFSTOPPED(V) (!SIM_WIFEXITED (V))
|
|
#define SIM_WEXITSTATUS(V) (((V) >> 8) & 0xff)
|
|
#define SIM_WSTOPSIG(V) ((V) & 0x7f)
|
|
|
|
#endif /* SIM_MAIN_H */
|