X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=sim%2Fh8300%2Fcompile.c;h=0e4b6d2b2912e952771c75a601b391b1ccddb36c;hb=b7f97e9cb4aed394c2f903434801c84b73336cdf;hp=b4989682359e7bd02dc5fd29b29110c52d9bdf0b;hpb=247fccdeb54a09a14287b2e829511803ad9d7cc1;p=binutils-gdb.git diff --git a/sim/h8300/compile.c b/sim/h8300/compile.c index b4989682359..0e4b6d2b291 100644 --- a/sim/h8300/compile.c +++ b/sim/h8300/compile.c @@ -19,6 +19,7 @@ #include "config.h" +#include #include #ifdef HAVE_TIME_H #include @@ -26,12 +27,20 @@ #ifdef HAVE_STDLIB_H #include #endif +#ifdef HAVE_SYS_PARAM_H #include -#include "wait.h" +#endif #include "ansidecl.h" #include "bfd.h" -#include "callback.h" -#include "remote-sim.h" +#include "gdb/callback.h" +#include "gdb/remote-sim.h" +#include "gdb/sim-h8300.h" +#include "sys/stat.h" +#include "sys/types.h" + +#ifndef SIGTRAP +# define SIGTRAP 5 +#endif int debug; @@ -46,9 +55,9 @@ static char *myname; by gdb. */ void sim_set_simcache_size PARAMS ((int)); -#define X(op, size) op*4+size +#define X(op, size) op * 4 + size -#define SP (h8300hmode ? SL:SW) +#define SP (h8300hmode ? SL : SW) #define SB 0 #define SW 1 #define SL 2 @@ -61,35 +70,56 @@ void sim_set_simcache_size PARAMS ((int)); #define OP_CCR 7 #define OP_IMM 8 #define OP_ABS 10 +#define OP_EXR 11 #define h8_opcodes ops #define DEFINE_TABLE #include "opcode/h8300.h" #include "inst.h" +/* The rate at which to call the host's poll_quit callback. */ + +#define POLL_QUIT_INTERVAL 0x80000 + #define LOW_BYTE(x) ((x) & 0xff) -#define HIGH_BYTE(x) (((x)>>8) & 0xff) -#define P(X,Y) ((X<<8) | Y) +#define HIGH_BYTE(x) (((x) >> 8) & 0xff) +#define P(X,Y) ((X << 8) | Y) + +#define BUILDSR() \ + cpu.ccr = ((I << 7) | (UI << 6) | (H << 5) | (U << 4) \ + | (N << 3) | (Z << 2) | (V << 1) | C); -#define BUILDSR() cpu.ccr = (N << 3) | (Z << 2) | (V<<1) | C; +#define BUILDEXR() \ + if (h8300smode) cpu.exr = (trace<<7) | intMask; #define GETSR() \ c = (cpu.ccr >> 0) & 1;\ v = (cpu.ccr >> 1) & 1;\ nz = !((cpu.ccr >> 2) & 1);\ - n = (cpu.ccr >> 3) & 1; + n = (cpu.ccr >> 3) & 1;\ + u = (cpu.ccr >> 4) & 1;\ + h = (cpu.ccr >> 5) & 1;\ + ui = ((cpu.ccr >> 6) & 1);\ + intMaskBit = (cpu.ccr >> 7) & 1; + +#define GETEXR() \ + if (h8300smode) \ + { \ + trace = (cpu.exr >> 7) & 1; \ + intMask = cpu.exr & 7; \ + } #ifdef __CHAR_IS_SIGNED__ -#define SEXTCHAR(x) ((char)(x)) +#define SEXTCHAR(x) ((char) (x)) #endif #ifndef SEXTCHAR -#define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff): x & 0xff) +#define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff) : x & 0xff) #endif #define UEXTCHAR(x) ((x) & 0xff) #define UEXTSHORT(x) ((x) & 0xffff) -#define SEXTSHORT(x) ((short)(x)) +#define SEXTSHORT(x) ((short) (x)) static cpu_state_type cpu; @@ -98,25 +128,20 @@ int h8300smode = 0; static int memory_size; - static int -get_now () +get_now (void) { -#ifndef WIN32 - return time (0); -#endif - return 0; + return time (0); /* WinXX HAS UNIX like 'time', so why not using it? */ } static int -now_persec () +now_persec (void) { return 1; } - static int -bitfrom (x) +bitfrom (int x) { switch (x & SIZE) { @@ -131,9 +156,8 @@ bitfrom (x) } } -static -unsigned int -lvalue (x, rn) +static unsigned int +lvalue (int x, int rn) { switch (x / 4) { @@ -145,39 +169,45 @@ lvalue (x, rn) return X (OP_REG, SP); case OP_MEM: - return X (OP_MEM, SP); + default: - abort (); + abort (); /* ?? May be something more usefull? */ } } -static unsigned int -decode (addr, data, dst) - int addr; - unsigned char *data; - decoded_inst *dst; +static int +cmdline_location() +{ + if (h8300smode) + return 0xffff00L; + else if (h8300hmode) + return 0x2ff00L; + else + return 0xff00L; +} +static unsigned int +decode (int addr, unsigned char *data, decoded_inst *dst) { int rs = 0; int rd = 0; int rdisp = 0; int abs = 0; - int plen = 0; int bit = 0; - - struct h8_opcode *q = h8_opcodes; + int plen = 0; + struct h8_opcode *q; int size = 0; + dst->dst.type = -1; dst->src.type = -1; - /* Find the exact opcode/arg combo */ - while (q->name) + + /* Find the exact opcode/arg combo. */ + for (q = h8_opcodes; q->name; q++) { - op_type *nib; + op_type *nib = q->data.nib; unsigned int len = 0; - nib = q->data.nib; - while (1) { op_type looking_for = *nib; @@ -196,40 +226,40 @@ decode (addr, data, dst) { if (!(((int) thisnib & 0x8) != 0)) goto fail; - looking_for = (op_type) ((int) looking_for & ~(int) - B31); + + looking_for = (op_type) ((int) looking_for & ~(int) B31); thisnib &= 0x7; } + if ((int) looking_for & (int) B30) { if (!(((int) thisnib & 0x8) == 0)) goto fail; + looking_for = (op_type) ((int) looking_for & ~(int) B30); } + if (looking_for & DBIT) { - if ((looking_for & 5) != (thisnib & 5)) + /* Exclude adds/subs by looking at bit 0 and 2, and + make sure the operand size, either w or l, + matches by looking at bit 1. */ + if ((looking_for & 7) != (thisnib & 7)) goto fail; + abs = (thisnib & 0x8) ? 2 : 1; } else if (looking_for & (REG | IND | INC | DEC)) { if (looking_for & REG) { - /* - * Can work out size from the - * register - */ + /* Can work out size from the register. */ size = bitfrom (looking_for); } if (looking_for & SRC) - { - rs = thisnib; - } + rs = thisnib; else - { - rd = thisnib; - } + rd = thisnib; } else if (looking_for & L_16) { @@ -242,10 +272,7 @@ decode (addr, data, dst) } else if (looking_for & ABSJMP) { - abs = - (data[1] << 16) - | (data[2] << 8) - | (data[3]); + abs = (data[1] << 16) | (data[2] << 8) | (data[3]); } else if (looking_for & MEMIND) { @@ -254,6 +281,7 @@ decode (addr, data, dst) else if (looking_for & L_32) { int i = len >> 1; + abs = (data[i] << 24) | (data[i + 1] << 16) | (data[i + 2] << 8) @@ -264,12 +292,13 @@ decode (addr, data, dst) else if (looking_for & L_24) { int i = len >> 1; + abs = (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]); plen = 24; } else if (looking_for & IGNORE) { - /* nothing to do */ + ; } else if (looking_for & DISPREG) { @@ -288,6 +317,8 @@ decode (addr, data, dst) case 0: abs = 1; break; + default: + goto fail; } } else if (looking_for & L_8) @@ -302,9 +333,9 @@ decode (addr, data, dst) { plen = 8; abs = h8300hmode ? ~0xff0000ff : ~0xffff00ff; - abs |= data[len >> 1] & 0xff ; + abs |= data[len >> 1] & 0xff; } - else + else { abs = data[len >> 1] & 0xff; } @@ -319,7 +350,7 @@ decode (addr, data, dst) { dst->op = q; - /* Fill in the args */ + /* Fill in the args. */ { op_type *args = q->args.nib; int hadone = 0; @@ -331,15 +362,11 @@ decode (addr, data, dst) ea_type *p; if (x & DST) - { - p = &(dst->dst); - } + p = &(dst->dst); else - { - p = &(dst->src); - } + p = &(dst->src); - if (x & (L_3)) + if (x & L_3) { p->type = X (OP_IMM, size); p->literal = bit; @@ -351,8 +378,8 @@ decode (addr, data, dst) } else if (x & REG) { - /* Reset the size, some - ops (like mul) have two sizes */ + /* Reset the size. + Some ops (like mul) have two sizes. */ size = bitfrom (x); p->type = X (OP_REG, size); @@ -407,6 +434,10 @@ decode (addr, data, dst) { p->type = OP_CCR; } + else if (x & EXR) + { + p->type = OP_EXR; + } else printf ("Hmmmm %x", x); @@ -414,12 +445,9 @@ decode (addr, data, dst) } } - /* - * But a jmp or a jsr gets - * automagically lvalued, since we - * branch to their address not their - * contents - */ + /* But a jmp or a jsr gets automagically lvalued, + since we branch to their address not their + contents. */ if (q->how == O (O_JSR, SB) || q->how == O (O_JMP, SB)) { @@ -432,23 +460,46 @@ decode (addr, data, dst) dst->opcode = q->how; dst->cycles = q->time; - /* And a jsr to 0xc4 is turned into a magic trap */ + /* And a jsr to these locations are turned into magic + traps. */ if (dst->opcode == O (O_JSR, SB)) { - if (dst->src.literal == 0xc4) + switch (dst->src.literal) { - dst->opcode = O (O_SYSCALL, SB); + case 0xc5: + dst->opcode = O (O_SYS_OPEN, SB); + break; + case 0xc6: + dst->opcode = O (O_SYS_READ, SB); + break; + case 0xc7: + dst->opcode = O (O_SYS_WRITE, SB); + break; + case 0xc8: + dst->opcode = O (O_SYS_LSEEK, SB); + break; + case 0xc9: + dst->opcode = O (O_SYS_CLOSE, SB); + break; + case 0xca: + dst->opcode = O (O_SYS_STAT, SB); + break; + case 0xcb: + dst->opcode = O (O_SYS_FSTAT, SB); + break; + case 0xcc: + dst->opcode = O (O_SYS_CMDLINE, SB); + break; } + /* End of Processing for system calls. */ } dst->next_pc = addr + len / 2; return; } else - { - printf ("Dont understand %x \n", looking_for); - } + printf ("Don't understand %x \n", looking_for); } len++; @@ -456,20 +507,19 @@ decode (addr, data, dst) } fail: - q++; + ; } + /* Fell off the end. */ dst->opcode = O (O_ILL, SB); } - static void -compile (pc) +compile (int pc) { int idx; - /* find the next cache entry to use */ - + /* Find the next cache entry to use. */ idx = cpu.cache_top + 1; cpu.compiles++; if (idx >= cpu.csize) @@ -478,16 +528,16 @@ compile (pc) } cpu.cache_top = idx; - /* Throw away its old meaning */ + /* Throw away its old meaning. */ cpu.cache_idx[cpu.cache[idx].oldpc] = 0; - /* set to new address */ + /* Set to new address. */ cpu.cache[idx].oldpc = pc; - /* fill in instruction info */ + /* Fill in instruction info. */ decode (pc, cpu.memory + pc, cpu.cache + idx); - /* point to new cache entry */ + /* Point to new cache entry. */ cpu.cache_idx[pc] = idx; } @@ -534,9 +584,8 @@ static unsigned int *lreg[18]; #define SET_MEMORY_B(x,y) \ (x < memory_size ? (cpu.memory[(x)] = y) : (cpu.eightbit[x & 0xff] = y)) -int -fetch (arg, n) - ea_type *arg; +static int +fetch (ea_type *arg) { int rn = arg->reg; int abs = arg->literal; @@ -611,17 +660,14 @@ fetch (arg, n) return t; default: - abort (); + abort (); /* ?? May be something more usefull? */ } } -static -void -store (arg, n) - ea_type *arg; - int n; +static void +store (ea_type *arg, int n) { int rn = arg->reg; int abs = arg->literal; @@ -694,9 +740,8 @@ static union littleendian; -static -void -init_pointers () +static void +init_pointers (void) { static int init; @@ -707,7 +752,9 @@ init_pointers () init = 1; littleendian.i = 1; - if (h8300hmode) + if (h8300smode) + memory_size = H8300S_MSIZE; + else if (h8300hmode) memory_size = H8300H_MSIZE; else memory_size = H8300_MSIZE; @@ -715,7 +762,7 @@ init_pointers () cpu.cache_idx = (unsigned short *) calloc (sizeof (short), memory_size); cpu.eightbit = (unsigned char *) calloc (sizeof (char), 256); - /* `msize' must be a power of two */ + /* `msize' must be a power of two. */ if ((memory_size & (memory_size - 1)) != 0) abort (); cpu.mask = memory_size - 1; @@ -744,6 +791,7 @@ init_pointers () } p++; } + wreg[i] = wreg[i + 8] = 0; while (q < u) { if (*q == 0x2233) @@ -756,24 +804,22 @@ init_pointers () } q++; } + if (wreg[i] == 0 || wreg[i + 8] == 0) + abort (); cpu.regs[i] = 0; lreg[i] = &cpu.regs[i]; } lreg[8] = &cpu.regs[8]; - /* initialize the seg registers */ + /* Initialize the seg registers. */ if (!cpu.cache) sim_set_simcache_size (CSIZE); } } static void -control_c (sig, code, scp, addr) - int sig; - int code; - char *scp; - char *addr; +control_c (int sig) { cpu.state = SIM_STATE_STOPPED; cpu.exception = SIGINT; @@ -783,12 +829,13 @@ control_c (sig, code, scp, addr) #define Z (nz == 0) #define V (v != 0) #define N (n != 0) +#define U (u != 0) +#define H (h != 0) +#define UI (ui != 0) +#define I (intMaskBit != 0) static int -mop (code, bsize, sign) - decoded_inst *code; - int bsize; - int sign; +mop (decoded_inst *code, int bsize, int sign) { int multiplier; int multiplicand; @@ -828,12 +875,13 @@ mop (code, bsize, sign) { SET_L_REG (code->dst.reg, result); } -/* return ((n==1) << 1) | (nz==1); */ - +#if 0 + return ((n == 1) << 1) | (nz == 1); +#endif } #define ONOT(name, how) \ -case O(name, SB): \ +case O (name, SB): \ { \ int t; \ int hm = 0x80; \ @@ -841,7 +889,7 @@ case O(name, SB): \ how; \ goto shift8; \ } \ -case O(name, SW): \ +case O (name, SW): \ { \ int t; \ int hm = 0x8000; \ @@ -849,7 +897,7 @@ case O(name, SW): \ how; \ goto shift16; \ } \ -case O(name, SL): \ +case O (name, SL): \ { \ int t; \ int hm = 0x80000000; \ @@ -859,7 +907,7 @@ case O(name, SL): \ } #define OSHIFTS(name, how1, how2) \ -case O(name, SB): \ +case O (name, SB): \ { \ int t; \ int hm = 0x80; \ @@ -874,7 +922,7 @@ case O(name, SB): \ } \ goto shift8; \ } \ -case O(name, SW): \ +case O (name, SW): \ { \ int t; \ int hm = 0x8000; \ @@ -889,7 +937,7 @@ case O(name, SW): \ } \ goto shift16; \ } \ -case O(name, SL): \ +case O (name, SL): \ { \ int t; \ int hm = 0x80000000; \ @@ -906,28 +954,48 @@ case O(name, SL): \ } #define OBITOP(name,f, s, op) \ -case O(name, SB): \ +case O (name, SB): \ { \ int m; \ int b; \ if (f) ea = fetch (&code->dst); \ - m=1<< fetch(&code->src); \ + m=1<< fetch (&code->src); \ op; \ - if(s) store (&code->dst,ea); goto next; \ + if (s) store (&code->dst,ea); goto next; \ } int -sim_stop (sd) - SIM_DESC sd; +sim_stop (SIM_DESC sd) { cpu.state = SIM_STATE_STOPPED; cpu.exception = SIGINT; return 1; } +#define R0_REGNUM 0 +#define R1_REGNUM 1 +#define R2_REGNUM 2 +#define R3_REGNUM 3 +#define R4_REGNUM 4 +#define R5_REGNUM 5 +#define R6_REGNUM 6 +#define R7_REGNUM 7 + +#define SP_REGNUM R7_REGNUM /* Contains address of top of stack */ +#define FP_REGNUM R6_REGNUM /* Contains address of executing + * stack frame */ + +#define CCR_REGNUM 8 /* Contains processor status */ +#define PC_REGNUM 9 /* Contains program counter */ + +#define CYCLE_REGNUM 10 + +#define EXR_REGNUM 11 +#define INST_REGNUM 12 +#define TICK_REGNUM 13 + void -sim_resume (sd, step, siggnal) - SIM_DESC sd; +sim_resume (SIM_DESC sd, int step, int siggnal) { static int init1; int cycles = 0; @@ -941,7 +1009,8 @@ sim_resume (sd, step, siggnal) int ea; int bit; int pc; - int c, nz, v, n; + int c, nz, v, n, u, h, ui, intMaskBit; + int trace, intMask; int oldmask; init_pointers (); @@ -965,6 +1034,8 @@ sim_resume (sd, step, siggnal) abort (); GETSR (); + GETEXR (); + oldmask = cpu.mask; if (!h8300hmode) cpu.mask = 0xffff; @@ -979,15 +1050,15 @@ sim_resume (sd, step, siggnal) #define ALUOP(STORE, NAME, HOW) \ - case O(NAME,SB): HOW; if(STORE)goto alu8;else goto just_flags_alu8; \ - case O(NAME, SW): HOW; if(STORE)goto alu16;else goto just_flags_alu16; \ - case O(NAME,SL): HOW; if(STORE)goto alu32;else goto just_flags_alu32; + case O (NAME, SB): HOW; if (STORE) goto alu8; else goto just_flags_alu8; \ + case O (NAME, SW): HOW; if (STORE) goto alu16; else goto just_flags_alu16; \ + case O (NAME, SL): HOW; if (STORE) goto alu32; else goto just_flags_alu32; -#define LOGOP(NAME, HOW) \ - case O(NAME,SB): HOW; goto log8;\ - case O(NAME, SW): HOW; goto log16;\ - case O(NAME,SL): HOW; goto log32; +#define LOGOP(NAME, HOW) \ + case O (NAME, SB): HOW; goto log8; \ + case O (NAME, SW): HOW; goto log16; \ + case O (NAME, SL): HOW; goto log32; @@ -1001,8 +1072,12 @@ sim_resume (sd, step, siggnal) #endif - cycles += code->cycles; - insts++; + if (code->opcode) + { + cycles += code->cycles; + insts++; + } + switch (code->opcode) { case 0: @@ -1029,8 +1104,8 @@ sim_resume (sd, step, siggnal) res = rd + ea; goto alu8; -#define EA ea = fetch(&code->src); -#define RD_EA ea = fetch(&code->src); rd = fetch(&code->dst); +#define EA ea = fetch (&code->src); +#define RD_EA ea = fetch (&code->src); rd = fetch (&code->dst); ALUOP (1, O_SUB, RD_EA; ea = -ea; @@ -1091,6 +1166,41 @@ sim_resume (sd, step, siggnal) SET_L_REG (code->dst.reg, res); goto just_flags_log32; + case O (O_EEPMOV, SB): + case O (O_EEPMOV, SW): + if (h8300hmode || h8300smode) + { + register unsigned char *_src, *_dst; + unsigned int count = ((code->opcode == O (O_EEPMOV, SW)) + ? cpu.regs[R4_REGNUM] & 0xffff + : cpu.regs[R4_REGNUM] & 0xff); + + _src = (cpu.regs[R5_REGNUM] < memory_size + ? cpu.memory + cpu.regs[R5_REGNUM] + : cpu.eightbit + (cpu.regs[R5_REGNUM] & 0xff)); + if ((_src + count) >= (cpu.memory + memory_size)) + { + if ((_src + count) >= (cpu.eightbit + 0x100)) + goto illegal; + } + _dst = (cpu.regs[R6_REGNUM] < memory_size + ? cpu.memory + cpu.regs[R6_REGNUM] + : cpu.eightbit + (cpu.regs[R6_REGNUM] & 0xff)); + if ((_dst + count) >= (cpu.memory + memory_size)) + { + if ((_dst + count) >= (cpu.eightbit + 0x100)) + goto illegal; + } + memcpy (_dst, _src, count); + + cpu.regs[R5_REGNUM] += count; + cpu.regs[R6_REGNUM] += count; + cpu.regs[R4_REGNUM] &= ((code->opcode == O (O_EEPMOV, SW)) + ? (~0xffff) : (~0xff)); + cycles += 2 * count; + goto next; + } + goto illegal; case O (O_ADDS, SL): SET_L_REG (code->dst.reg, @@ -1170,23 +1280,69 @@ sim_resume (sd, step, siggnal) SET_L_REG (code->dst.reg, res); goto just_flags_inc32; - #define GET_CCR(x) BUILDSR();x = cpu.ccr +#define GET_EXR(x) BUILDEXR ();x = cpu.exr + + case O (O_LDC, SB): + case O (O_LDC, SW): + res = fetch (&code->src); + goto setc; + case O (O_STC, SB): + case O (O_STC, SW): + if (code->src.type == OP_CCR) + { + GET_CCR (res); + } + else if (code->src.type == OP_EXR && h8300smode) + { + GET_EXR (res); + } + else + goto illegal; + store (&code->dst, res); + goto next; case O (O_ANDC, SB): - GET_CCR (rd); + if (code->dst.type == OP_CCR) + { + GET_CCR (rd); + } + else if (code->dst.type == OP_EXR && h8300smode) + { + GET_EXR (rd); + } + else + goto illegal; ea = code->src.literal; res = rd & ea; goto setc; case O (O_ORC, SB): - GET_CCR (rd); + if (code->dst.type == OP_CCR) + { + GET_CCR (rd); + } + else if (code->dst.type == OP_EXR && h8300smode) + { + GET_EXR (rd); + } + else + goto illegal; ea = code->src.literal; res = rd | ea; goto setc; case O (O_XORC, SB): - GET_CCR (rd); + if (code->dst.type == OP_CCR) + { + GET_CCR (rd); + } + else if (code->dst.type == OP_EXR && h8300smode) + { + GET_EXR (rd); + } + else + goto illegal; ea = code->src.literal; res = rd ^ ea; goto setc; @@ -1268,10 +1424,447 @@ sim_resume (sd, step, siggnal) goto condtrue; goto next; - case O (O_SYSCALL, SB): - printf ("%c", cpu.regs[2]); + /* Trap for Command Line setup. */ + case O (O_SYS_CMDLINE, SB): + { + int i = 0; /* Loop counter. */ + int j = 0; /* Loop counter. */ + int ind_arg_len = 0; /* Length of each argument. */ + int no_of_args = 0; /* The no. or cmdline args. */ + int current_location = 0; /* Location of string. */ + int old_sp = 0; /* The Initial Stack Pointer. */ + int no_of_slots = 0; /* No. of slots required on the stack + for storing cmdline args. */ + int sp_move = 0; /* No. of locations by which the stack needs + to grow. */ + int new_sp = 0; /* The final stack pointer location passed + back. */ + int *argv_ptrs; /* Pointers of argv strings to be stored. */ + int argv_ptrs_location = 0; /* Location of pointers to cmdline + args on the stack. */ + int char_ptr_size = 0; /* Size of a character pointer on + target machine. */ + int addr_cmdline = 0; /* Memory location where cmdline has + to be stored. */ + int size_cmdline = 0; /* Size of cmdline. */ + + /* Set the address of 256 free locations where command line is + stored. */ + addr_cmdline = cmdline_location(); + cpu.regs[0] = addr_cmdline; + + /* Counting the no. of commandline arguments. */ + for (i = 0; ptr_command_line[i] != NULL; i++) + continue; + + /* No. of arguments in the command line. */ + no_of_args = i; + + /* Current location is just a temporary variable,which we are + setting to the point to the start of our commandline string. */ + current_location = addr_cmdline; + + /* Allocating space for storing pointers of the command line + arguments. */ + argv_ptrs = (int *) malloc (sizeof (int) * no_of_args); + + /* Setting char_ptr_size to the sizeof (char *) on the different + architectures. */ + if (h8300hmode || h8300smode) + { + char_ptr_size = 4; + } + else + { + char_ptr_size = 2; + } + + for (i = 0; i < no_of_args; i++) + { + ind_arg_len = 0; + + /* The size of the commandline argument. */ + ind_arg_len = (strlen (ptr_command_line[i]) + 1); + + /* The total size of the command line string. */ + size_cmdline += ind_arg_len; + + /* As we have only 256 bytes, we need to provide a graceful + exit. Anyways, a program using command line arguments + where we cannot store all the command line arguments + given may behave unpredictably. */ + if (size_cmdline >= 256) + { + cpu.regs[0] = 0; + goto next; + } + else + { + /* current_location points to the memory where the next + commandline argument is stored. */ + argv_ptrs[i] = current_location; + for (j = 0; j < ind_arg_len; j++) + { + SET_MEMORY_B ((current_location + + (sizeof (char) * j)), + *(ptr_command_line[i] + + sizeof (char) * j)); + } + + /* Setting current_location to the starting of next + argument. */ + current_location += ind_arg_len; + } + } + + /* This is the original position of the stack pointer. */ + old_sp = cpu.regs[7]; + + /* We need space from the stack to store the pointers to argvs. */ + /* As we will infringe on the stack, we need to shift the stack + pointer so that the data is not overwritten. We calculate how + much space is required. */ + sp_move = (no_of_args) * (char_ptr_size); + + /* The final position of stack pointer, we have thus taken some + space from the stack. */ + new_sp = old_sp - sp_move; + + /* Temporary variable holding value where the argv pointers need + to be stored. */ + argv_ptrs_location = new_sp; + + /* The argv pointers are stored at sequential locations. As per + the H8300 ABI. */ + for (i = 0; i < no_of_args; i++) + { + /* Saving the argv pointer. */ + if (h8300hmode || h8300smode) + { + SET_MEMORY_L (argv_ptrs_location, argv_ptrs[i]); + } + else + { + SET_MEMORY_W (argv_ptrs_location, argv_ptrs[i]); + } + + /* The next location where the pointer to the next argv + string has to be stored. */ + argv_ptrs_location += char_ptr_size; + } + + /* Required by POSIX, Setting 0x0 at the end of the list of argv + pointers. */ + if (h8300hmode || h8300smode) + { + SET_MEMORY_L (old_sp, 0x0); + } + else + { + SET_MEMORY_W (old_sp, 0x0); + } + + /* Freeing allocated memory. */ + free (argv_ptrs); + for (i = 0; i <= no_of_args; i++) + { + free (ptr_command_line[i]); + } + free (ptr_command_line); + + /* The no. of argv arguments are returned in Reg 0. */ + cpu.regs[0] = no_of_args; + /* The Pointer to argv in Register 1. */ + cpu.regs[1] = new_sp; + /* Setting the stack pointer to the new value. */ + cpu.regs[7] = new_sp; + } + goto next; + + /* System call processing starts. */ + case O (O_SYS_OPEN, SB): + { + int len = 0; /* Length of filename. */ + char *filename; /* Filename would go here. */ + char temp_char; /* Temporary character */ + int mode = 0; /* Mode bits for the file. */ + int open_return; /* Return value of open, file descriptor. */ + int i; /* Loop counter */ + int filename_ptr; /* Pointer to filename in cpu memory. */ + + /* Setting filename_ptr to first argument of open. */ + filename_ptr = h8300hmode ? GET_L_REG (0) : GET_W_REG (0); + + /* Trying to get mode. */ + if (h8300hmode || h8300smode) + { + mode = GET_MEMORY_L (cpu.regs[7] + 4); + } + else + { + mode = GET_MEMORY_W (cpu.regs[7] + 2); + } + + /* Trying to find the length of the filename. */ + temp_char = GET_MEMORY_B (cpu.regs[0]); + + len = 1; + while (temp_char != '\0') + { + temp_char = GET_MEMORY_B (filename_ptr + len); + len++; + } + + /* Allocating space for the filename. */ + filename = (char *) malloc (sizeof (char) * len); + + /* String copying the filename from memory. */ + for (i = 0; i < len; i++) + { + temp_char = GET_MEMORY_B (filename_ptr + i); + filename[i] = temp_char; + } + + /* Callback to open and return the file descriptor. */ + open_return = sim_callback->open (sim_callback, filename, mode); + + /* Return value in register 0. */ + cpu.regs[0] = open_return; + + /* Freeing memory used for filename. */ + free (filename); + } goto next; + case O (O_SYS_READ, SB): + { + char *char_ptr; /* Where characters read would be stored. */ + int fd; /* File descriptor */ + int buf_size; /* BUF_SIZE parameter in read. */ + int i = 0; /* Temporary Loop counter */ + int read_return = 0; /* Return value from callback to + read. */ + + fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0); + buf_size = h8300hmode ? GET_L_REG (2) : GET_W_REG (2); + + char_ptr = (char *) malloc (sizeof (char) * buf_size); + + /* Callback to read and return the no. of characters read. */ + read_return = + sim_callback->read (sim_callback, fd, char_ptr, buf_size); + + /* The characters read are stored in cpu memory. */ + for (i = 0; i < buf_size; i++) + { + SET_MEMORY_B ((cpu.regs[1] + (sizeof (char) * i)), + *(char_ptr + (sizeof (char) * i))); + } + + /* Return value in Register 0. */ + cpu.regs[0] = read_return; + + /* Freeing memory used as buffer. */ + free (char_ptr); + } + goto next; + + case O (O_SYS_WRITE, SB): + { + int fd; /* File descriptor */ + char temp_char; /* Temporary character */ + int len; /* Length of write, Parameter II to write. */ + int char_ptr; /* Character Pointer, Parameter I of write. */ + char *ptr; /* Where characters to be written are stored. + */ + int write_return; /* Return value from callback to write. */ + int i = 0; /* Loop counter */ + + fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0); + char_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1); + len = h8300hmode ? GET_L_REG (2) : GET_W_REG (2); + + /* Allocating space for the characters to be written. */ + ptr = (char *) malloc (sizeof (char) * len); + + /* Fetching the characters from cpu memory. */ + for (i = 0; i < len; i++) + { + temp_char = GET_MEMORY_B (char_ptr + i); + ptr[i] = temp_char; + } + + /* Callback write and return the no. of characters written. */ + write_return = sim_callback->write (sim_callback, fd, ptr, len); + + /* Return value in Register 0. */ + cpu.regs[0] = write_return; + + /* Freeing memory used as buffer. */ + free (ptr); + } + goto next; + + case O (O_SYS_LSEEK, SB): + { + int fd; /* File descriptor */ + int offset; /* Offset */ + int origin; /* Origin */ + int lseek_return; /* Return value from callback to lseek. */ + + fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0); + offset = h8300hmode ? GET_L_REG (1) : GET_W_REG (1); + origin = h8300hmode ? GET_L_REG (2) : GET_W_REG (2); + + /* Callback lseek and return offset. */ + lseek_return = + sim_callback->lseek (sim_callback, fd, offset, origin); + + /* Return value in register 0. */ + cpu.regs[0] = lseek_return; + } + goto next; + + case O (O_SYS_CLOSE, SB): + { + int fd; /* File descriptor */ + int close_return; /* Return value from callback to close. */ + + fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0); + + /* Callback close and return. */ + close_return = sim_callback->close (sim_callback, fd); + + /* Return value in register 0. */ + cpu.regs[0] = close_return; + } + goto next; + + case O (O_SYS_FSTAT, SB): + { + int fd; /* File descriptor */ + struct stat stat_rec; /* Stat record */ + int fstat_return; /* Return value from callback to stat. */ + int stat_ptr; /* Pointer to stat record. */ + char *temp_stat_ptr; /* Temporary stat_rec pointer. */ + + fd = h8300hmode ? GET_L_REG (0) : GET_W_REG (0); + + /* Setting stat_ptr to second argument of stat. */ + stat_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1); + + /* Callback stat and return. */ + fstat_return = sim_callback->fstat (sim_callback, fd, &stat_rec); + + /* Have stat_ptr point to starting of stat_rec. */ + temp_stat_ptr = (char *) (&stat_rec); + + /* Setting up the stat structure returned. */ + SET_MEMORY_W (stat_ptr, stat_rec.st_dev); + stat_ptr += 2; + SET_MEMORY_W (stat_ptr, stat_rec.st_ino); + stat_ptr += 2; + SET_MEMORY_L (stat_ptr, stat_rec.st_mode); + stat_ptr += 4; + SET_MEMORY_W (stat_ptr, stat_rec.st_nlink); + stat_ptr += 2; + SET_MEMORY_W (stat_ptr, stat_rec.st_uid); + stat_ptr += 2; + SET_MEMORY_W (stat_ptr, stat_rec.st_gid); + stat_ptr += 2; + SET_MEMORY_W (stat_ptr, stat_rec.st_rdev); + stat_ptr += 2; + SET_MEMORY_L (stat_ptr, stat_rec.st_size); + stat_ptr += 4; + SET_MEMORY_L (stat_ptr, stat_rec.st_atime); + stat_ptr += 8; + SET_MEMORY_L (stat_ptr, stat_rec.st_mtime); + stat_ptr += 8; + SET_MEMORY_L (stat_ptr, stat_rec.st_ctime); + + /* Return value in register 0. */ + cpu.regs[0] = fstat_return; + } + goto next; + + case O (O_SYS_STAT, SB): + { + int len = 0; /* Length of filename. */ + char *filename; /* Filename would go here. */ + char temp_char; /* Temporary character */ + int filename_ptr; /* Pointer to filename in cpu memory. */ + struct stat stat_rec; /* Stat record */ + int stat_return; /* Return value from callback to stat */ + int stat_ptr; /* Pointer to stat record. */ + char *temp_stat_ptr; /* Temporary stat_rec pointer. */ + int i = 0; /* Loop Counter */ + + /* Setting filename_ptr to first argument of open. */ + filename_ptr = h8300hmode ? GET_L_REG (0) : GET_W_REG (0); + + /* Trying to find the length of the filename. */ + temp_char = GET_MEMORY_B (cpu.regs[0]); + + len = 1; + while (temp_char != '\0') + { + temp_char = GET_MEMORY_B (filename_ptr + len); + len++; + } + + /* Allocating space for the filename. */ + filename = (char *) malloc (sizeof (char) * len); + + /* String copying the filename from memory. */ + for (i = 0; i < len; i++) + { + temp_char = GET_MEMORY_B (filename_ptr + i); + filename[i] = temp_char; + } + + /* Setting stat_ptr to second argument of stat. */ + /* stat_ptr = cpu.regs[1]; */ + stat_ptr = h8300hmode ? GET_L_REG (1) : GET_W_REG (1); + + /* Callback stat and return. */ + stat_return = + sim_callback->stat (sim_callback, filename, &stat_rec); + + /* Have stat_ptr point to starting of stat_rec. */ + temp_stat_ptr = (char *) (&stat_rec); + + /* Freeing memory used for filename. */ + free (filename); + + /* Setting up the stat structure returned. */ + SET_MEMORY_W (stat_ptr, stat_rec.st_dev); + stat_ptr += 2; + SET_MEMORY_W (stat_ptr, stat_rec.st_ino); + stat_ptr += 2; + SET_MEMORY_L (stat_ptr, stat_rec.st_mode); + stat_ptr += 4; + SET_MEMORY_W (stat_ptr, stat_rec.st_nlink); + stat_ptr += 2; + SET_MEMORY_W (stat_ptr, stat_rec.st_uid); + stat_ptr += 2; + SET_MEMORY_W (stat_ptr, stat_rec.st_gid); + stat_ptr += 2; + SET_MEMORY_W (stat_ptr, stat_rec.st_rdev); + stat_ptr += 2; + SET_MEMORY_L (stat_ptr, stat_rec.st_size); + stat_ptr += 4; + SET_MEMORY_L (stat_ptr, stat_rec.st_atime); + stat_ptr += 8; + SET_MEMORY_L (stat_ptr, stat_rec.st_mtime); + stat_ptr += 8; + SET_MEMORY_L (stat_ptr, stat_rec.st_ctime); + + /* Return value in register 0. */ + cpu.regs[0] = stat_return; + } + goto next; + /* End of system call processing. */ + ONOT (O_NOT, rd = ~rd; v = 0;); OSHIFTS (O_SHLL, c = rd & hm; v = 0; rd <<= 1, @@ -1284,7 +1877,7 @@ sim_resume (sd, step, siggnal) c = rd & (hm >> 1); v = (rd & (hm >> 1)) != ((rd & (hm >> 2)) << 2); rd <<= 2); OSHIFTS (O_SHAR, t = rd & hm; c = rd & 1; v = 0; rd >>= 1; rd |= t, - t = rd & hm; c = rd & 2; v = 0; rd >>= 2; rd |= t | t >> 1 ); + t = rd & hm; c = rd & 2; v = 0; rd >>= 2; rd |= t | t >> 1); OSHIFTS (O_ROTL, c = rd & hm; v = 0; rd <<= 1; rd |= C, c = rd & hm; v = 0; rd <<= 1; rd |= C; c = rd & hm; rd <<= 1; rd |= C); @@ -1356,32 +1949,17 @@ sim_resume (sd, step, siggnal) cpu.exception = SIGILL; goto end; case O (O_SLEEP, SN): - /* The format of r0 is defined by devo/include/wait.h. */ -#if 0 /* FIXME: Ugh. A breakpoint is the sleep insn. */ - if (WIFEXITED (cpu.regs[0])) - { - cpu.state = SIM_STATE_EXITED; - cpu.exception = WEXITSTATUS (cpu.regs[0]); - } - else if (WIFSTOPPED (cpu.regs[0])) - { - cpu.state = SIM_STATE_STOPPED; - cpu.exception = WSTOPSIG (cpu.regs[0]); - } - else - { - cpu.state = SIM_STATE_SIGNALLED; - cpu.exception = WTERMSIG (cpu.regs[0]); - } -#else /* FIXME: Doesn't this break for breakpoints when r0 contains just the right (er, wrong) value? */ cpu.state = SIM_STATE_STOPPED; - if (! WIFEXITED (cpu.regs[0]) && WIFSIGNALED (cpu.regs[0])) + /* The format of r0 is defined by target newlib. Expand + the macros here instead of looking for .../sys/wait.h. */ +#define SIM_WIFEXITED(v) (((v) & 0xff) == 0) +#define SIM_WIFSIGNALED(v) (((v) & 0x7f) > 0 && (((v) & 0x7f) < 0x7f)) + if (! SIM_WIFEXITED (cpu.regs[0]) && SIM_WIFSIGNALED (cpu.regs[0])) cpu.exception = SIGILL; else cpu.exception = SIGTRAP; -#endif goto end; case O (O_BPT, SN): cpu.state = SIM_STATE_STOPPED; @@ -1391,7 +1969,7 @@ sim_resume (sd, step, siggnal) OBITOP (O_BNOT, 1, 1, ea ^= m); OBITOP (O_BTST, 1, 0, nz = ea & m); OBITOP (O_BCLR, 1, 1, ea &= ~m); - OBITOP (O_BSET, 1, 1, ea |= m); + OBITOP (O_BSET, 1, 1, ea |= m); OBITOP (O_BLD, 1, 0, c = ea & m); OBITOP (O_BILD, 1, 0, c = !(ea & m)); OBITOP (O_BST, 1, 1, ea &= ~m; @@ -1402,11 +1980,12 @@ sim_resume (sd, step, siggnal) OBITOP (O_BIAND, 1, 0, c = !(ea & m) && C); OBITOP (O_BOR, 1, 0, c = (ea & m) || C); OBITOP (O_BIOR, 1, 0, c = !(ea & m) || C); - OBITOP (O_BXOR, 1, 0, c = (ea & m) != C); + OBITOP (O_BXOR, 1, 0, c = ((ea & m) != 0) != C); OBITOP (O_BIXOR, 1, 0, c = !(ea & m) != C); - -#define MOP(bsize, signed) mop(code, bsize,signed); goto next; +#define MOP(bsize, signed) \ + mop (code, bsize, signed); \ + goto next; case O (O_MULS, SB): MOP (1, 1); @@ -1421,6 +2000,22 @@ sim_resume (sd, step, siggnal) MOP (0, 0); break; + case O (O_TAS, SB): + if (!h8300smode || code->src.type != X (OP_REG, SL)) + goto illegal; + switch (code->src.reg) + { + case R0_REGNUM: + case R1_REGNUM: + case R4_REGNUM: + case R5_REGNUM: + break; + default: + goto illegal; + } + res = fetch (&code->src); + store (&code->src, res | 0x80); + goto just_flags_log8; case O (O_DIVU, SB): { @@ -1428,8 +2023,8 @@ sim_resume (sd, step, siggnal) ea = GET_B_REG (code->src.reg); if (ea) { - tmp = (unsigned)rd % ea; - rd = (unsigned)rd / ea; + tmp = (unsigned) rd % ea; + rd = (unsigned) rd / ea; } SET_W_REG (code->dst.reg, (rd & 0xff) | (tmp << 8)); n = ea & 0x80; @@ -1445,8 +2040,8 @@ sim_resume (sd, step, siggnal) nz = ea & 0xffff; if (ea) { - tmp = (unsigned)rd % ea; - rd = (unsigned)rd / ea; + tmp = (unsigned) rd % ea; + rd = (unsigned) rd / ea; } SET_L_REG (code->dst.reg, (rd & 0xffff) | (tmp << 16)); goto next; @@ -1486,7 +2081,7 @@ sim_resume (sd, step, siggnal) goto next; } case O (O_EXTS, SW): - rd = GET_B_REG (code->src.reg + 8) & 0xff; /* Yes, src, not dst. */ + rd = GET_W_REG (code->src.reg) & 0xff; /* Yes, src, not dst. */ ea = rd & 0x80 ? -256 : 0; res = rd + ea; goto log16; @@ -1496,7 +2091,7 @@ sim_resume (sd, step, siggnal) res = rd + ea; goto log32; case O (O_EXTU, SW): - rd = GET_B_REG (code->src.reg + 8) & 0xff; + rd = GET_W_REG (code->src.reg) & 0xff; ea = 0; res = rd + ea; goto log16; @@ -1543,7 +2138,59 @@ sim_resume (sd, step, siggnal) } goto next; + case O (O_DAA, SB): + /* Decimal Adjust Addition. This is for BCD arithmetic. */ + res = GET_B_REG (code->src.reg); + if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) + && !h && (0 <= (res & 0xf) && (res & 0xf) <= 9)) + res = res; /* Value added == 0. */ + else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) + && !h && (10 <= (res & 0xf) && (res & 0xf) <= 15)) + res = res + 0x6; /* Value added == 6. */ + else if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) + && h && (0 <= (res & 0xf) && (res & 0xf) <= 3)) + res = res + 0x6; /* Value added == 6. */ + else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) + && !h && (0 <= (res & 0xf) && (res & 0xf) <= 9)) + res = res + 0x60; /* Value added == 60. */ + else if (!c && (9 <= (res >> 4) && (res >> 4) <= 15) + && !h && (10 <= (res & 0xf) && (res & 0xf) <= 15)) + res = res + 0x66; /* Value added == 66. */ + else if (!c && (10 <= (res >> 4) && (res >> 4) <= 15) + && h && (0 <= (res & 0xf) && (res & 0xf) <= 3)) + res = res + 0x66; /* Value added == 66. */ + else if (c && (1 <= (res >> 4) && (res >> 4) <= 2) + && !h && (0 <= (res & 0xf) && (res & 0xf) <= 9)) + res = res + 0x160; /* Value added == 60, plus 'carry'. */ + else if (c && (1 <= (res >> 4) && (res >> 4) <= 2) + && !h && (10 <= (res & 0xf) && (res & 0xf) <= 15)) + res = res + 0x166; /* Value added == 66, plus 'carry'. */ + else if (c && (1 <= (res >> 4) && (res >> 4) <= 3) + && h && (0 <= (res & 0xf) && (res & 0xf) <= 3)) + res = res + 0x166; /* Value added == 66, plus 'carry'. */ + + goto alu8; + + case O (O_DAS, SB): + /* Decimal Adjust Subtraction. This is for BCD arithmetic. */ + res = GET_B_REG (code->src.reg); /* FIXME fetch, fetch2... */ + if (!c && (0 <= (res >> 4) && (res >> 4) <= 9) + && !h && (0 <= (res & 0xf) && (res & 0xf) <= 9)) + res = res; /* Value added == 0. */ + else if (!c && (0 <= (res >> 4) && (res >> 4) <= 8) + && h && (6 <= (res & 0xf) && (res & 0xf) <= 15)) + res = res + 0xfa; /* Value added == 0xfa. */ + else if (c && (7 <= (res >> 4) && (res >> 4) <= 15) + && !h && (0 <= (res & 0xf) && (res & 0xf) <= 9)) + res = res + 0xa0; /* Value added == 0xa0. */ + else if (c && (6 <= (res >> 4) && (res >> 4) <= 15) + && h && (6 <= (res & 0xf) && (res & 0xf) <= 15)) + res = res + 0x9a; /* Value added == 0x9a. */ + + goto alu8; + default: + illegal: cpu.state = SIM_STATE_STOPPED; cpu.exception = SIGILL; goto end; @@ -1552,8 +2199,19 @@ sim_resume (sd, step, siggnal) abort (); setc: - cpu.ccr = res; - GETSR (); + if (code->dst.type == OP_CCR) + { + cpu.ccr = res; + GETSR (); + } + else if (code->dst.type == OP_EXR && h8300smode) + { + cpu.exr = res; + GETEXR (); + } + else + goto illegal; + goto next; condtrue: @@ -1712,11 +2370,14 @@ sim_resume (sd, step, siggnal) end: ; - /* if (cpu.regs[8] ) abort(); */ +#if 0 + if (cpu.regs[8]) + abort (); +#endif - if (poll_count++ > 100) + if (--poll_count < 0) { - poll_count = 0; + poll_count = POLL_QUIT_INTERVAL; if ((*sim_callback->poll_quit) != NULL && (*sim_callback->poll_quit) (sim_callback)) sim_stop (sd); @@ -1727,27 +2388,23 @@ sim_resume (sd, step, siggnal) cpu.ticks += get_now () - tick_start; cpu.cycles += cycles; cpu.insts += insts; - + cpu.pc = pc; BUILDSR (); + BUILDEXR (); cpu.mask = oldmask; signal (SIGINT, prev); } int -sim_trace (sd) - SIM_DESC sd; +sim_trace (SIM_DESC sd) { - /* FIXME: unfinished */ + /* FIXME: Unfinished. */ abort (); } int -sim_write (sd, addr, buffer, size) - SIM_DESC sd; - SIM_ADDR addr; - unsigned char *buffer; - int size; +sim_write (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size) { int i; @@ -1768,11 +2425,7 @@ sim_write (sd, addr, buffer, size) } int -sim_read (sd, addr, buffer, size) - SIM_DESC sd; - SIM_ADDR addr; - unsigned char *buffer; - int size; +sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size) { init_pointers (); if (addr < 0) @@ -1785,32 +2438,8 @@ sim_read (sd, addr, buffer, size) } -#define R0_REGNUM 0 -#define R1_REGNUM 1 -#define R2_REGNUM 2 -#define R3_REGNUM 3 -#define R4_REGNUM 4 -#define R5_REGNUM 5 -#define R6_REGNUM 6 -#define R7_REGNUM 7 - -#define SP_REGNUM R7_REGNUM /* Contains address of top of stack */ -#define FP_REGNUM R6_REGNUM /* Contains address of executing - * stack frame */ - -#define CCR_REGNUM 8 /* Contains processor status */ -#define PC_REGNUM 9 /* Contains program counter */ - -#define CYCLE_REGNUM 10 -#define INST_REGNUM 11 -#define TICK_REGNUM 12 - - -void -sim_store_register (sd, rn, value) - SIM_DESC sd; - int rn; - unsigned char *value; +int +sim_store_register (SIM_DESC sd, int rn, unsigned char *value, int length) { int longval; int shortval; @@ -1840,6 +2469,9 @@ sim_store_register (sd, rn, value) case CCR_REGNUM: cpu.ccr = intval; break; + case EXR_REGNUM: + cpu.exr = intval; + break; case CYCLE_REGNUM: cpu.cycles = longval; break; @@ -1852,27 +2484,30 @@ sim_store_register (sd, rn, value) cpu.ticks = longval; break; } + return -1; } -void -sim_fetch_register (sd, rn, buf) - SIM_DESC sd; - int rn; - unsigned char *buf; +int +sim_fetch_register (SIM_DESC sd, int rn, unsigned char *buf, int length) { int v; int longreg = 0; init_pointers (); + if (!h8300smode && rn >= EXR_REGNUM) + rn++; switch (rn) { default: abort (); - case 8: + case CCR_REGNUM: v = cpu.ccr; break; - case 9: + case EXR_REGNUM: + v = cpu.exr; + break; + case PC_REGNUM: v = cpu.pc; break; case R0_REGNUM: @@ -1885,15 +2520,15 @@ sim_fetch_register (sd, rn, buf) case R7_REGNUM: v = cpu.regs[rn]; break; - case 10: + case CYCLE_REGNUM: v = cpu.cycles; longreg = 1; break; - case 11: + case TICK_REGNUM: v = cpu.ticks; longreg = 1; break; - case 12: + case INST_REGNUM: v = cpu.insts; longreg = 1; break; @@ -1910,13 +2545,11 @@ sim_fetch_register (sd, rn, buf) buf[0] = v >> 8; buf[1] = v; } + return -1; } void -sim_stop_reason (sd, reason, sigrc) - SIM_DESC sd; - enum sim_stop *reason; - int *sigrc; +sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc) { #if 0 /* FIXME: This should work but we can't use it. grep for SLEEP above. */ @@ -1936,14 +2569,13 @@ sim_stop_reason (sd, reason, sigrc) /* FIXME: Rename to sim_set_mem_size. */ void -sim_size (n) - int n; +sim_size (int n) { /* Memory size is fixed. */ } void -sim_set_simcache_size (n) +sim_set_simcache_size (int n) { if (cpu.cache) free (cpu.cache); @@ -1956,9 +2588,7 @@ sim_set_simcache_size (n) void -sim_info (sd, verbose) - SIM_DESC sd; - int verbose; +sim_info (SIM_DESC sd, int verbose) { double timetaken = (double) cpu.ticks / (double) now_persec (); double virttime = cpu.cycles / 10.0e6; @@ -2002,57 +2632,51 @@ sim_info (sd, verbose) #endif } -/* Indicate whether the cpu is an h8/300 or h8/300h. - FLAG is non-zero for the h8/300h. */ +/* Indicate whether the cpu is an H8/300 or H8/300H. + FLAG is non-zero for the H8/300H. */ void -set_h8300h (flag) - int flag; +set_h8300h (int h_flag, int s_flag) { - h8300hmode = flag; -} - -void -sim_kill (sd) - SIM_DESC sd; -{ - /* nothing to do */ + /* FIXME: Much of the code in sim_load can be moved to sim_open. + This function being replaced by a sim_open:ARGV configuration + option. */ + h8300hmode = h_flag; + h8300smode = s_flag; } SIM_DESC -sim_open (kind, ptr, abfd, argv) - SIM_OPEN_KIND kind; - struct host_callback_struct *ptr; - struct _bfd *abfd; - char **argv; +sim_open (SIM_OPEN_KIND kind, + struct host_callback_struct *ptr, + struct bfd *abfd, + char **argv) { + /* FIXME: Much of the code in sim_load can be moved here. */ + sim_kind = kind; myname = argv[0]; sim_callback = ptr; - /* fudge our descriptor */ + /* Fudge our descriptor. */ return (SIM_DESC) 1; } void -sim_close (sd, quitting) - SIM_DESC sd; - int quitting; +sim_close (SIM_DESC sd, int quitting) { - /* nothing to do */ + /* Nothing to do. */ } /* Called by gdb to load a program into memory. */ SIM_RC -sim_load (sd, prog, abfd, from_tty) - SIM_DESC sd; - char *prog; - bfd *abfd; - int from_tty; +sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty) { bfd *prog_bfd; - /* See if the file is for the h8/300 or h8/300h. */ + /* FIXME: The code below that sets a specific variant of the H8/300 + being simulated should be moved to sim_open(). */ + + /* See if the file is for the H8/300 or H8/300H. */ /* ??? This may not be the most efficient way. The z8k simulator does this via a different mechanism (INIT_EXTRA_SYMTAB_INFO). */ if (abfd != NULL) @@ -2063,11 +2687,11 @@ sim_load (sd, prog, abfd, from_tty) { /* Set the cpu type. We ignore failure from bfd_check_format and bfd_openr as sim_load_file checks too. */ - if (bfd_check_format (prog_bfd, bfd_object)) + if (bfd_check_format (prog_bfd, bfd_object)) { unsigned long mach = bfd_get_mach (prog_bfd); - set_h8300h (mach == bfd_mach_h8300h - || mach == bfd_mach_h8300s); + set_h8300h (mach == bfd_mach_h8300h || mach == bfd_mach_h8300s, + mach == bfd_mach_h8300s); } } @@ -2079,13 +2703,16 @@ sim_load (sd, prog, abfd, from_tty) simulator memory. The problem is when we do that, we don't know whether we're - debugging an h8/300 or h8/300h program. + debugging an H8/300 or H8/300H program. This is the first point at which we can make that determination, so we just reallocate memory now; this will also allow us to handle - switching between h8/300 and h8/300h programs without exiting + switching between H8/300 and H8/300H programs without exiting gdb. */ - if (h8300hmode) + + if (h8300smode) + memory_size = H8300S_MSIZE; + else if (h8300hmode) memory_size = H8300H_MSIZE; else memory_size = H8300_MSIZE; @@ -2101,13 +2728,14 @@ sim_load (sd, prog, abfd, from_tty) cpu.cache_idx = (unsigned short *) calloc (sizeof (short), memory_size); cpu.eightbit = (unsigned char *) calloc (sizeof (char), 256); - /* `msize' must be a power of two */ + /* `msize' must be a power of two. */ if ((memory_size & (memory_size - 1)) != 0) abort (); cpu.mask = memory_size - 1; if (sim_load_file (sd, myname, sim_callback, prog, prog_bfd, - sim_kind == SIM_OPEN_DEBUG) + sim_kind == SIM_OPEN_DEBUG, + 0, sim_write) == NULL) { /* Close the bfd if we opened it. */ @@ -2116,7 +2744,6 @@ sim_load (sd, prog, abfd, from_tty) return SIM_RC_FAIL; } - cpu.pc = bfd_get_start_address (prog_bfd); /* Close the bfd if we opened it. */ if (abfd == NULL && prog_bfd != NULL) bfd_close (prog_bfd); @@ -2124,26 +2751,51 @@ sim_load (sd, prog, abfd, from_tty) } SIM_RC -sim_create_inferior (sd, argv, env) - SIM_DESC sd; - char **argv; - char **env; +sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env) { + int i = 0; + int len_arg = 0; + int no_of_args = 0; + + if (abfd != NULL) + cpu.pc = bfd_get_start_address (abfd); + else + cpu.pc = 0; + + /* Command Line support. */ + if (argv != NULL) + { + /* Counting the no. of commandline arguments. */ + for (no_of_args = 0; argv[no_of_args] != NULL; no_of_args++) + continue; + + /* Allocating memory for the argv pointers. */ + ptr_command_line = (char **) malloc ((sizeof (char *)) + * (no_of_args + 1)); + + for (i = 0; i < no_of_args; i++) + { + /* Calculating the length of argument for allocating memory. */ + len_arg = strlen (argv[i] + 1); + ptr_command_line[i] = (char *) malloc (sizeof (char) * len_arg); + /* Copying the argument string. */ + ptr_command_line[i] = (char *) strdup (argv[i]); + } + ptr_command_line[i] = NULL; + } + return SIM_RC_OK; } void -sim_do_command (sd, cmd) - SIM_DESC sd; - char *cmd; +sim_do_command (SIM_DESC sd, char *cmd) { (*sim_callback->printf_filtered) (sim_callback, "This simulator does not accept any commands.\n"); } void -sim_set_callbacks (ptr) - struct host_callback_struct *ptr; +sim_set_callbacks (struct host_callback_struct *ptr) { sim_callback = ptr; }