diff options
Diffstat (limited to 'sim/h8500/compile.c')
-rw-r--r-- | sim/h8500/compile.c | 2519 |
1 files changed, 0 insertions, 2519 deletions
diff --git a/sim/h8500/compile.c b/sim/h8500/compile.c deleted file mode 100644 index 1aad644fa8a..00000000000 --- a/sim/h8500/compile.c +++ /dev/null @@ -1,2519 +0,0 @@ -/* Simulator for the Hitachi H8/500 architecture. - - Written by Steve Chamberlain of Cygnus Support. - sac@cygnus.com - - This file is part of H8/500 sim - - - THIS SOFTWARE IS NOT COPYRIGHTED - - Cygnus offers the following for use in the public domain. Cygnus - makes no warranty with regard to the software or it's performance - and the user accepts the software "AS IS" with all faults. - - CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO - THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -*/ - -#include "config.h" - -#include <signal.h> -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#endif -#ifdef HAVE_TIME_H -#include <time.h> -#endif -#include <sys/param.h> -#include <setjmp.h> -#include "ansidecl.h" -#include "bfd.h" -#include "callback.h" -#include "remote-sim.h" - -#define O_RECOMPILE 85 -#define DEFINE_TABLE -#define DISASSEMBLER_TABLE - -/* FIXME: Needs to live in header file. - This header should also include the things in remote-sim.h. - One could move this to remote-sim.h but this function isn't needed - by gdb. */ -void sim_set_simcache_size PARAMS ((int)); - -int debug; - -host_callback *sim_callback; - -static SIM_OPEN_KIND sim_kind; -static char *myname; - -/* This code can be compiled with any old C compiler, in which case - four or five switch statements will be executed for each - instruction simulated. It can be compiled with GCC, then the - simulated instructions thread through the code fragments, and - everything goes much faster. - - These definitions make the code work either way -*/ -#ifdef __GNUC__ -#define DISPATCH(X) goto *(X); do -#define LABEL(X) X##_L -#define LABELN(X,N) X##_L##N -#define LABEL_REF(X) &&X##_L -#define LABEL_REFN(X,N) &&X##_L##N -#define ENDDISPATCH while (0); -#define fastref void * - -#define DEFAULT ; -#define INLINE __inline__ -#else -#define DEFAULT default : -#define DISPATCH(X) switch (X) -#define LABEL(X) case X -#define LABELN(X,N) case X -#define LABEL_REF(X) X -#define LABEL_REFN(X,N) X -#define ENDDISPATCH -#define fastref int - - - -#define INLINE -#define STORE_REG_B 1 -#define STORE_REG_W 2 -#define STORE_INC_B 3 -#define STORE_INC_W 4 -#define STORE_DEC_B 5 -#define STORE_DEC_W 6 -#define STORE_DISP_B 7 -#define STORE_DISP_W 8 -#define STORE_CRB 9 -#define STORE_CRW 10 -#define STORE_REG_L 11 -#define STORE_NOP 12 - -#define FETCH_NOP 9 -#define FETCH_REG_B 10 -#define FETCH_REG_W 11 -#define FETCH_INC_B 12 -#define FETCH_INC_W 13 -#define FETCH_DEC_B 14 -#define FETCH_DEC_W 15 -#define FETCH_DISP_B 16 -#define FETCH_DISP_W 17 -#define FETCH_IMM 18 -#define FETCH_CRB 19 -#define FETCH_CRW 20 -#define FETCH_LVAL 21 -#define FETCH_LVAL24 22 -#define FETCH_REG_L 23 - -#define FLAG_m 20 -#define FLAG_M 21 -#define FLAG_A 22 -#define FLAG_NONE 23 -#define FLAG_NOSTORE 24 -#define FLAG_CLEAR 25 -#define FLAG_a 26 -#define FLAG_BRANCH 27 -#define FLAG_special 28 - -#define FLAG_shiftword 29 -#define FLAG_shiftbyte 30 - -#define FLAG_multword 31 -#define FLAG_multbyte 32 -#endif - - -#define h8500_table h8500_compile_table -#include "../opcodes/h8500-opc.h" - -#include "inst.h" - -#define LOW_BYTE(x) ((x) & 0xff) -#define HIGH_BYTE(x) (((x)>>8) & 0xff) -#define NORMAL_CP ((cpu.regs[R_CP].c - cpu.memory)>>16) -#define NORMAL_DP ((cpu.regs[R_DP].c - cpu.memory)>>16) -#define NORMAL_EP ((cpu.regs[R_EP].c - cpu.memory)>>16) -#define NORMAL_TP ((cpu.regs[R_TP].c - cpu.memory)>>16) -#define SET_NORMREG(x,y) ((cpu.regs[x].l = (y))) -#define GET_NORMREG(x) (cpu.regs[x].l) -#define SET_SEGREG(x,y) { cpu.regs[x].c = ((y) & 0xff0000) + cpu.memory;} -#define GET_SEGREG(x) ( (cpu.regs[x].c - cpu.memory ) >> 16) -#define SET_NORMAL_CPPC(x) { pc = (x) & 0xffff; SET_SEGREG(R_CP, (x));} -#define NORMAL_SR ((N<<3)|(Z<<2)|(V<<1)|(C)) -#define P(X,Y) ((X<<8) | Y) - -#define BUILDSR() cpu.regs[R_SR].s[LOW] = (N << 3) | (Z << 2) | (V<<1) | C; - -#define GETSR() \ - C = (cpu.regs[R_SR].s[LOW] >> 0) & 1;\ - V = (cpu.regs[R_SR].s[LOW] >> 1) & 1;\ - Z = (cpu.regs[R_SR].s[LOW] >> 2) & 1;\ - N = (cpu.regs[R_SR].s[LOW] >> 3) & 1; - -#ifdef __CHAR_IS_SIGNED__ -#define SEXTCHAR(x) ((char)(x)) -#endif - -#ifndef SEXTCHAR -#define SEXTCHAR(x) ((x & 0x80) ? (x | ~0xff):x) -#endif - -#define SEXTSHORT(x) ((short)(x)) - -/* Which segment registers go with which pointer registers */ -static unsigned char **segmap[R_LAST]; -static unsigned char *(regptr[R_LAST][3]); -static unsigned char *(segregptr[R_LAST][3]); -static cpu_state_type cpu; - -static int segforreg[] = {R_DP, R_DP, R_DP, R_DP, - R_EP, R_EP, R_TP, R_TP, - R_DP, R_DP, R_DP, R_DP, - R_EP, R_EP, R_TP, R_TP}; -int LOW; -int HIGH; - -/* routines for getting and storing args */ -#define elval(struct, lit) \ - (((*(struct.reg.wptr) + lit) & 0xffff) + (*(struct.r2.segreg))) - -#define displval(s) elval((s),(s).literal) - -#define ireglval(struct) elval(struct, 0) -#define wordat(x) (((x)[0] << 8) | (x)[1]) -#define longat(x) ((wordat((x))<<16)|(wordat((x)+2))) -#define byteat(x) ((x)[0]) - -#define setwordat(x,y) {x[0] =( y)>>8; x[1] = y;} -#define setbyteat(x,y) {x[0] = y;} - -/*#define setalignedwordat(x,y) {((short *)x)[0] =y;}*/ -/* -statics -*/ - -ea_type rd; -ea_type rs; -ea_type imm; -ea_type cr; -ea_type ea; -ea_type nop; -ea_type lval; -ea_type lval24; - -ea_type eavector[2]; - -int disp; - -#define JBYTE 0 -#define JWORD 1 -#define JLONG 2 - -typedef union -{ - struct - { - fastref srcabyte; - fastref srcaword; - fastref srcalong; - - fastref srcbbyte; - fastref srcbword; - fastref srcblong; - - fastref dstbyte; - fastref dstword; - fastref dstlong; - } s; - struct - { - fastref byte; - fastref word; - fastref lon; - } a[3]; - - fastref j[9]; -} size_ptr; - -union -{ - struct ea_struct - { - size_ptr ea_nop; - size_ptr ea_reg; - size_ptr ea_inc; - size_ptr ea_dec; - size_ptr ea_disp; - - size_ptr ea_imm; - size_ptr ea_cr; - size_ptr ea_lval; - size_ptr ea_lval24; - } s; -#define N_EATYPES (sizeof(struct ea_struct) / sizeof(size_ptr)) - size_ptr a[N_EATYPES]; -} eas; - -/* This function takes an ea structure filled in for the 1st source - operand and modifies it to be for either the 1st, 2nd or dst operand */ - -static void -howto_workout (encoded, semiencoded, n) - ea_type *encoded; - ea_type *semiencoded; - int n; -{ - int i; - *encoded = *semiencoded; - - for (i = 0; i < N_EATYPES; i++) - { - if (encoded->type == eas.a[i].s.srcabyte) - { - encoded->type = eas.a[i].a[n].byte; - return; - } - else if (encoded->type == eas.a[i].s.srcaword) - { - encoded->type = eas.a[i].a[n].word; - return; - } - else if (encoded->type == eas.a[i].s.srcalong) - { - encoded->type = eas.a[i].a[n].lon; - return; - } - } - - abort (); -} - -fastref flag_shiftword; -fastref flag_shiftbyte; -fastref flag_multword; -fastref flag_multbyte; -fastref flag_mp; -fastref flag_special; -fastref flag_Mp; -fastref flag_ap; -fastref flag_Ap; -fastref flag_nonep; -fastref flag_nostorep; -fastref flag_clearp; -fastref flag_branch; -fastref exec_dispatch[100]; - -static int -get_now () -{ - return time (0); -} - -static int -now_persec () -{ - return 1; -} - -static void -gotcr (ptr, n) - ea_type *ptr; - int n; -{ - int size; - n &= 0x7; - if (n == 0) - { - abort (); - } - else - { - ptr->type = eas.s.ea_cr.j[JBYTE]; - ptr->reg.bptr = segregptr[n][JLONG]; - } -} -static void -gotreg (ptr, n, size) - ea_type *ptr; - int n; - int size; -{ - n &= 0x7; - ptr->type = eas.s.ea_reg.j[size]; - ptr->reg.bptr = regptr[n][size]; -} - -static void -gotinc (ptr, n, inc, size) - ea_type *ptr; - int n; - int size; -{ - n &= 0x7; - if (inc > 0) - { - ptr->type = eas.s.ea_inc.j[size]; - } - else - { - ptr->type = eas.s.ea_dec.j[size]; - } - ptr->reg.bptr = regptr[n][JWORD]; - ptr->r2.segreg = segmap[n]; -} - - -static void -gotabs (ptr, disp, reg, size) - ea_type *ptr; - int disp; - int reg; - int size; -{ - ptr->type = eas.s.ea_disp.j[size]; - ptr->reg.bptr = regptr[reg][JWORD]; - ptr->r2.segreg = segmap[reg]; - ptr->literal = disp; -} - -static void -gotind (ptr, disp, reg, size) - ea_type *ptr; - int disp; - int reg; - int size; -{ - gotabs (ptr, disp, reg & 0x7, size); -} - -static void -gotimm (ptr, val) - ea_type *ptr; - int val; -{ - ptr->type = eas.s.ea_imm.j[0]; - ptr->literal = val; -} - -static void -indoff (ptr) - ea_type *ptr; -{ - int i; - for (i = 0; i < 6; i++) - { - if (ptr->type == eas.s.ea_disp.j[i]) - { - ptr->type = eas.s.ea_lval.j[i]; - return; - } - } -} - -thinkabout_shifts (d, bytesized) - decoded_inst *d; - int bytesized; -{ - if (bytesized) - { - /* Got a byte shift, fake up second arg */ - d->srcb.type = eas.s.ea_imm.s.srcbword; - d->srcb.literal = 8; - } - else - { - /* got a word shift, fake up second arg */ - d->srcb.type = eas.s.ea_imm.s.srcbword; - d->srcb.literal = 16; - } -} - -/* Calculate the number of cycles required to run this - instruction -*/ -static void -compcycles (dst, opcode) - decoded_inst *dst; - h8500_opcode_info *opcode; -{ - int cycles = 0; - /* Guess for the time being - 1 cycle for the first two bytes in the - opcode - to fecth the operand, and 3 cycles for all the rest of - the bytes, since they mean that there is probably an operand to - fetch */ - - switch (opcode->length) - { - case 1: - case 2: - cycles += opcode->length; - break; - default: - cycles += opcode->length * 3; - break; - } - - dst->cycles = cycles; -} - -static void -translate (ptr, from, to) - ea_type *ptr; - fastref from; - fastref to; -{ - if (ptr->reg.wptr == &cpu.regs[7].s[LOW] - && ptr->type == from) - { - ptr->type = to; - } -} - -static -void -fix_incdecs (dst) - decoded_inst *dst; -{ - if (dst->dst.type == eas.s.ea_inc.s.dstbyte - && (dst->srca.type == eas.s.ea_inc.s.srcabyte - || dst->srcb.type == eas.s.ea_inc.s.srcbbyte)) - { - dst->dst.type = eas.s.ea_disp.s.dstbyte; - } - - if (dst->dst.type == eas.s.ea_inc.s.dstword - && (dst->srca.type == eas.s.ea_inc.s.srcaword - || dst->srcb.type == eas.s.ea_inc.s.srcbword)) - { - dst->dst.type = eas.s.ea_disp.s.dstword; - } - - if (dst->dst.type == eas.s.ea_dec.s.dstbyte - || dst->dst.type == eas.s.ea_dec.s.dstword) - { - if (dst->srca.type == eas.s.ea_dec.s.srcabyte) - { - dst->srca.type = eas.s.ea_disp.s.srcabyte; - } - else if (dst->srca.type == eas.s.ea_dec.s.srcaword) - { - dst->srca.type = eas.s.ea_disp.s.srcaword; - } - else if (dst->srcb.type == eas.s.ea_dec.s.srcbbyte) - { - dst->srcb.type = eas.s.ea_disp.s.srcbbyte; - } - else if (dst->srcb.type == eas.s.ea_dec.s.srcbword) - { - dst->srcb.type = eas.s.ea_disp.s.srcbword; - } - } - - - /* Turn a byte ops from the sp into word ops */ - translate (&dst->dst, eas.s.ea_dec.s.dstbyte, eas.s.ea_dec.s.dstword); - translate (&dst->dst, eas.s.ea_inc.s.dstbyte, eas.s.ea_inc.s.dstword); - - translate (&dst->srca, eas.s.ea_dec.s.srcabyte, eas.s.ea_dec.s.srcaword); - translate (&dst->srca, eas.s.ea_inc.s.srcabyte, eas.s.ea_inc.s.srcaword); - - translate (&dst->srcb, eas.s.ea_dec.s.srcbbyte, eas.s.ea_dec.s.srcbword); - translate (&dst->srcb, eas.s.ea_inc.s.srcbbyte, eas.s.ea_inc.s.srcbword); - - -} - - -static void -find (pc, buffer, dst) - int pc; - unsigned char *buffer; - decoded_inst *dst; -{ - h8500_opcode_info *opcode; - int i; - int idx; - int hadimm = 0; - dst->srca.reg.rptr = 0; - - /* Run down the table to find the one which matches */ - for (opcode = h8500_table; opcode->name; opcode++) - { - int byte; - int rn; - int rd; - int rs; - int disp; - int abs; - int imm; - int pcrel; - int qim; - int i; - int cr; - - - dst->opcode = exec_dispatch[opcode->flavor & 0x7f]; - - for (byte = 0; byte < opcode->length; byte++) - { - if ((buffer[byte] & opcode->bytes[byte].mask) - != (opcode->bytes[byte].contents)) - { - goto next; - } - else - { - /* extract any info parts */ - switch (opcode->bytes[byte].insert) - { - case 0: - case FP: - break; - default: - abort (); - break; - case RN: - rn = buffer[byte] & 0x7; - break; - case RS: - rs = buffer[byte] & 0x7; - break; - case CRB: - cr = buffer[byte] & 0x7; - if (cr == 0) - goto next; - break; - case CRW: - cr = buffer[byte] & 0x7; - if (cr != 0) - goto next; - break; - case DISP16: - disp = (buffer[byte] << 8) | (buffer[byte + 1]); - break; - case FPIND_D8: - case DISP8: - disp = ((char) (buffer[byte])); - break; - case RD: - case RDIND: - rd = buffer[byte] & 0x7; - break; - case ABS24: - abs = - (buffer[byte] << 16) - | (buffer[byte + 1] << 8) - | (buffer[byte + 2]); - break; - case ABS16: - abs = (buffer[byte] << 8) | (buffer[byte + 1]); - break; - case ABS8: - abs = (buffer[byte]); - break; - case IMM16: - imm = (buffer[byte] << 8) | (buffer[byte + 1]); - break; - case IMM4: - imm = (buffer[byte]) & 0xf; - break; - case IMM8: - case RLIST: - imm = SEXTCHAR (buffer[byte]); - break; - case PCREL16: - pcrel = SEXTSHORT ((buffer[byte] << 8) | (buffer[byte + 1])); - break; - case PCREL8: - pcrel = SEXTCHAR ((buffer[byte])); - break; - case QIM: - switch (buffer[byte] & 0x7) - { - case 0: - imm = 1; - break; - case 1: - imm = 2; - break; - case 4: - imm = -1; - break; - case 5: - imm = -2; - break; - } - break; - - } - } - } - if (opcode->flavor & O_BYTE) - { - idx = 0; - switch (opcode->flags) - { - case 'h': - dst->flags = flag_shiftbyte; - break; - case 'p': - dst->flags = flag_multbyte; - break; - case 'B': - dst->flags = flag_branch; - break; - case 'm': - dst->flags = flag_mp; - break; - case 'a': - dst->flags = flag_ap; - break; - case '-': - dst->flags = flag_nonep; - break; - case 0: - dst->flags = flag_nostorep; - break; - case 'c': - dst->flags = flag_clearp; - break; - case 's': - /* special */ - dst->flags = flag_special; - } - } - else - { - idx = 1; - switch (opcode->flags) - { - case 'h': - dst->flags = flag_shiftword; - break; - case 'p': - dst->flags = flag_multword; - break; - case 'B': - dst->flags = flag_branch; - break; - case 'm': - dst->flags = flag_Mp; - break; - case 'a': - dst->flags = flag_Ap; - break; - case '-': - dst->flags = flag_nonep; - break; - case 0: - dst->flags = flag_nostorep; - break; - case 'c': - dst->flags = flag_clearp; - break; - case 's': - /* special */ - dst->flags = flag_special; - break; - } - } - - for (i = 0; i < opcode->nargs; i++) - { - ea_type *p = eavector + i; - - switch (opcode->arg_type[i]) - { - default: - abort (); - - case FP: - gotreg (p, 6, idx); - break; - case RNIND: - disp = 0; - case RNIND_D16: - case RNIND_D8: - gotind (p, disp, rn, idx); - break; - break; - case RDIND: - disp = 0; - case RDIND_D16: - case RDIND_D8: - gotind (p, disp, rd, idx); - break; - case FPIND_D8: - gotind (p, disp, 6, idx); - break; - case CRB: - case CRW: - gotcr (p, cr); - break; - case RN: - gotreg (p, rn, idx); - break; - case RD: - gotreg (p, rd, idx); - break; - case RS: - gotreg (p, rs, idx); - break; - case RNDEC: - gotinc (p, rn, -1, idx); - break; - case RNINC: - gotinc (p, rn, 1, idx); - break; - case SPINC: - gotinc (p, 7, 1, idx); - break; - case SPDEC: - gotinc (p, 7, -1, idx); - break; - case ABS24: - case ABS16: - gotabs (p, abs, R_HARD_0, idx); - break; - case ABS8: - gotabs (p, abs, R_HARD8_0, idx); - break; - case IMM16: - case RLIST: - case QIM: - case IMM4: - case IMM8: - gotimm (p, imm); - break; - case PCREL16: - case PCREL8: - gotimm (p, - ((pcrel + pc + opcode->length) & 0xffff) | (pc & 0xff0000), - R_HARD_0, JLONG); - - } - } - - /* Finished and done - turn from two operand stuff into three */ - - dst->srca.type = eas.s.ea_nop.s.srcabyte; - dst->srcb.type = eas.s.ea_nop.s.srcbbyte; - dst->dst.type = eas.s.ea_nop.s.dstbyte; - - if (opcode->nargs) - { - switch (opcode->nargs) - { - case 1: - howto_workout (&dst->srca, &eavector[0], 0); - if (opcode->dst != '!') - howto_workout (&dst->dst, &eavector[0], 2); - break; - case 2: - if (opcode->src2 == '!') - { - howto_workout (&dst->srca, &eavector[0], 0); - howto_workout (&dst->dst, &eavector[1], 2); - } - else - { - howto_workout (&dst->srca, &eavector[0], 0); - howto_workout (&dst->srcb, &eavector[1], 1); - if (opcode->dst != '!') - { - howto_workout (&dst->dst, &eavector[1], 2); - } - } - break; - } - - - - /* Some extra stuff with pre inc and post dec, - make sure that if the same ea is there twice, only one of the - ops is auto inc/dec */ - - fix_incdecs (dst); - - - /* Some special cases */ - if (dst->opcode == exec_dispatch[O_PJSR] - || dst->opcode == exec_dispatch[O_PJMP]) - { - /* Both the @abs:24 and @rn turn into a disp word, - chose the right a mode since @abs:24 is 4 bytes - long */ - - if (opcode->length == 4) - { - dst->srca.type = eas.s.ea_lval24.s.srcabyte; - } - else - { - dst->srca.type = eas.s.ea_reg.s.srcalong; - } - - dst->srca.r2.rptr = &cpu.regs[R_HARD_0]; - - /* For [P]JSR, keep return address precomputed */ - dst->srcb.literal = pc + opcode->length; - dst->srcb.type = eas.s.ea_imm.s.srcbword; - } - else if (dst->opcode == exec_dispatch[O_MULXU]) - { - /* This is a multiply -fix the destination op */ - if (dst->dst.type == eas.s.ea_reg.s.dstword) - { - dst->dst.type = eas.s.ea_reg.s.dstlong; - } - else - { - dst->dst.type = eas.s.ea_reg.s.dstword; - } - dst->dst.reg.bptr = regptr[rd][JWORD]; - } - else if (dst->opcode == exec_dispatch[O_DIVXU]) - { - /* This is a wider than normal, fix the source operand */ - dst->srcb.type - = (dst->srcb.type == eas.s.ea_reg.s.srcbword) - ? eas.s.ea_reg.s.srcblong - : eas.s.ea_reg.s.srcbword; - - dst->dst.type - = (dst->dst.type == eas.s.ea_reg.s.dstword) - ? eas.s.ea_reg.s.dstlong - : eas.s.ea_reg.s.dstword; - - } - - else if (dst->opcode == exec_dispatch[O_LDM]) - { - /* Turn of the stack ref */ - dst->srca.type = eas.s.ea_nop.s.srcabyte; - } - else if (dst->opcode == exec_dispatch[O_STM]) - { - /* Turn of the stack ref */ - dst->srcb.type = eas.s.ea_nop.s.srcbbyte; - } - - - /* extends read one size and write another */ - else if (dst->opcode == exec_dispatch[O_EXTS] - || dst->opcode == exec_dispatch[O_EXTU]) - { - dst->dst.type = eas.s.ea_reg.s.dstword; - dst->dst.reg.bptr = regptr[rd][JWORD]; - dst->flags = flag_Ap; - } - - - if (opcode->flags == 'h') - thinkabout_shifts (dst, opcode->flavor & O_BYTE); - - - /* For a branch, turn off one level of indirection */ - if (opcode->src1 == 'B') - { - indoff (&dst->srca, 0); - } - - } - dst->next_pc = pc + opcode->length; - - compcycles (dst, opcode); - - return; - - - next:; - } - - /* Couldn't understand anything */ - dst->opcode = exec_dispatch[O_TRAPA]; - dst->next_pc = pc + 1; - -} - -compile (pc) -{ - int idx; - - /* find the next cache entry to use */ - - idx = cpu.cache_top + 1; - cpu.compiles++; - if (idx >= cpu.csize) - { - idx = 1; - } - cpu.cache_top = idx; - - /* Throw away its old meaning */ - cpu.cache_idx[cpu.cache[idx].oldpc] = 0; - - /* set to new address */ - cpu.cache[idx].oldpc = pc; - - /* fill in instruction info */ - find (pc, cpu.memory + pc, cpu.cache + idx); - - /* point to new cache entry */ - cpu.cache_idx[pc] = idx; -} - -baddefault (x) -{ - printf ("bad default %d\n", x); -} - -static int fetch_l (arg) - ea_type *arg; -{ - int l, r; - - int h = *(arg->reg.wptr); - r = (union rtype *) (arg->reg.wptr) - &cpu.regs[0]; - r++; - - l = cpu.regs[r].s[LOW]; - return (h << 16) | l; - -} - -#define FETCH(dst, arg, n) \ -{ \ - int r; unsigned char*lval; \ - DISPATCH((arg).type) \ - { LABELN(FETCH_NOP,n): \ - dst= 0; \ - break; \ - DEFAULT baddefault((arg).type); break; \ - LABELN(FETCH_LVAL,n): \ - dst = (*(((arg).reg.wptr)) + (arg.literal)) ; \ - break; \ - LABELN(FETCH_LVAL24,n): \ - dst = (*(((arg).reg.wptr)) + *(((arg).r2.wptr)) + (arg.literal)) &0xffffff; \ - break; \ - LABELN(FETCH_CRB,n): \ - dst = (*((arg).reg.segptr) - cpu.memory)>>16; \ - break; \ - LABELN(FETCH_CRW,n): \ - dst = BUILDSR();\ - break; \ - LABELN(FETCH_REG_B,n): \ - dst = *((arg).reg.bptr); \ - break; \ - LABELN(FETCH_REG_W,n): \ - dst = *((arg).reg.wptr); \ - break; \ - LABELN(FETCH_REG_L,n): \ - dst = fetch_l(&(arg));\ - break; \ - LABELN(FETCH_INC_B,n): \ - lval = elval ((arg), 0); \ - dst = byteat (lval); \ - (*((arg).reg.wptr))++; \ - break; \ - LABELN(FETCH_INC_W,n): \ - lval = elval ((arg), 0); \ - dst = wordat (lval); \ - (*(((arg).reg.wptr))) += 2; \ - break; \ - LABELN(FETCH_DEC_B, n): \ - (*(arg).reg.wptr)--; \ - lval = elval ((arg), 0); \ - r = byteat (lval); \ - dst = r; \ - break; \ - LABELN(FETCH_DEC_W, n): \ - (*((arg).reg.wptr)) -= 2; \ - lval = elval ((arg), 0); \ - r = wordat (lval); \ - dst = r; \ - break; \ - LABELN(FETCH_DISP_B,n): \ - lval = displval ((arg)); \ - dst = byteat (lval); \ - break; \ - LABELN(FETCH_DISP_W,n): \ - lval = displval ((arg)); \ - dst = wordat (lval); \ - break; \ - LABELN(FETCH_IMM, n): \ - dst = (arg).literal; \ - break; \ - } \ - ENDDISPATCH; \ -} - -static union -{ - short int i; - struct - { - char low; - char high; - } - u; -} - -littleendian; - -static -void -init_pointers () -{ - static int init; - - if (!init) - { - int i; - - init = 1; - littleendian.i = 1; - - for (i = 0; i < (int) R_LAST; i++) - { - if (littleendian.u.high) - { - /* big endian host */ - - - LOW = 1; - HIGH = 0; - - regptr[i][0] = ((unsigned char *) (cpu.regs + i)) + 3; - regptr[i][1] = ((unsigned char *) (cpu.regs + i)) + 2; - } - else - { - LOW = 0; - HIGH = 1; - - regptr[i][0] = (unsigned char *) &(cpu.regs[i]); - regptr[i][1] = (unsigned char *) (&(cpu.regs[i])); - } - - regptr[i][2] = (unsigned char *) &(cpu.regs[i]); - } - - memcpy (segregptr + 0, regptr + R_SR, sizeof (segregptr[0])); - memcpy (segregptr + 1, regptr + R_TP, sizeof (segregptr[1])); - memcpy (segregptr + 3, regptr + R_BR, sizeof (segregptr[3])); - memcpy (segregptr + 4, regptr + R_EP, sizeof (segregptr[4])); - memcpy (segregptr + 5, regptr + R_DP, sizeof (segregptr[5])); - memcpy (segregptr + 6, regptr + R_CP, sizeof (segregptr[6])); - memcpy (segregptr + 7, regptr + R_TP, sizeof (segregptr[7])); - - /* Pointers to into the cpu state for the seg registers */ - - segmap[R0] = &cpu.regs[R_DP].c; - segmap[R1] = &cpu.regs[R_DP].c; - segmap[R2] = &cpu.regs[R_DP].c; - segmap[R3] = &cpu.regs[R_DP].c; - segmap[R4] = &cpu.regs[R_EP].c; - segmap[R5] = &cpu.regs[R_EP].c; - segmap[R6] = &cpu.regs[R_TP].c; - segmap[R7] = &cpu.regs[R_TP].c; - segmap[R_HARD_0] = &cpu.regs[R_DP].c; - segmap[R_HARD8_0] = &cpu.regs[R_BP].c; - - cpu.memory = (unsigned char *) calloc (sizeof (char), H8500_MSIZE); - cpu.cache_idx = (unsigned short *) calloc (sizeof (short), H8500_MSIZE); - - /* initialize the seg registers */ - - cpu.regs[R_DP].c = cpu.memory; - cpu.regs[R_TP].c = cpu.memory; - cpu.regs[R_CP].c = cpu.memory; - cpu.regs[R_BP].c = cpu.memory; - cpu.regs[R_EP].c = cpu.memory; - cpu.regs[R7].s[LOW] = 0xfffe; - cpu.regs[R6].s[LOW] = 0xfffe; - if (!cpu.cache) - sim_set_simcache_size (CSIZE); - } -} - -#define PUSHWORD(x) \ -{ \ - int sp = cpu.regs[R7].s[LOW]; \ - unsigned char *p; \ - \ - sp -= 2; \ - p = (sp & 0xffff) + (cpu.regs[R_TP].c); \ - cpu.regs[R7].s[LOW] = sp; \ - setwordat (p, x); \ -} \ - -#define POPWORD(d) \ -{ \ - int spx= cpu.regs[R7].s[LOW]; \ - unsigned char *p; \ - \ - p = (spx& 0xffff) + (cpu.regs[R_TP].c); \ - spx+= 2; \ - cpu.regs[R7].s[LOW] = spx; \ - d = wordat (p); \ -} \ - -/* simulate a monitor trap */ -trap () -{ - switch (cpu.regs[R3].s[LOW] & 0xff) - { - case 33: - /* exit */ - cpu.exception = SIGQUIT; - break; - case 34: - /* abort */ - cpu.exception = SIGABRT; - break; - case 6: - /* print char in r0 */ - printf ("%c", cpu.regs[R0].s[LOW]); - break; - } -} -void -control_c (sig, code, scp, addr) - int sig; - int code; - char *scp; - char *addr; -{ - cpu.exception = SIGINT; -} - -static jmp_buf jbuf; -static void -segv () -{ - cpu.exception = SIGSEGV; - longjmp (jbuf, 1); -} - -int -sim_stop (sd) - SIM_DESC sd; -{ - cpu.exception = SIGINT; - return 1; -} - -void -sim_resume (sd, step, siggnal) - SIM_DESC sd; -{ - static int init1; - int res; - int tmp; - int arga; - int argb; - int bit; - int pc; - int C, Z, V, N; - int cycles = 0; - int insts = 0; - int tick_start = get_now (); - void (*prev) (); - void (*prev_seg) (); - - if (!init1) - { - int i; - - init1 = 1; - init_pointers (); - - for (i = 0; i < N_EATYPES; i++) - { - eas.a[i].s.srcabyte = LABEL_REFN (FETCH_NOP, 0); - eas.a[i].s.srcaword = LABEL_REFN (FETCH_NOP, 0); - eas.a[i].s.srcalong = LABEL_REFN (FETCH_NOP, 0); - - eas.a[i].s.srcbbyte = LABEL_REFN (FETCH_NOP, 1); - eas.a[i].s.srcbword = LABEL_REFN (FETCH_NOP, 1); - eas.a[i].s.srcblong = LABEL_REFN (FETCH_NOP, 1); - - eas.a[i].s.dstbyte = LABEL_REF (STORE_NOP); - eas.a[i].s.dstword = LABEL_REF (STORE_NOP); - eas.a[i].s.dstlong = LABEL_REF (STORE_NOP); - } - - eas.s.ea_lval.s.srcabyte = LABEL_REFN (FETCH_LVAL, 0); - eas.s.ea_lval.s.srcaword = LABEL_REFN (FETCH_LVAL, 0); - eas.s.ea_lval24.s.srcabyte = LABEL_REFN (FETCH_LVAL24, 0); - eas.s.ea_lval24.s.srcaword = LABEL_REFN (FETCH_LVAL24, 0); - - eas.s.ea_nop.s.srcabyte = LABEL_REFN (FETCH_NOP, 0); - eas.s.ea_nop.s.srcaword = LABEL_REFN (FETCH_NOP, 0); - eas.s.ea_nop.s.srcbbyte = LABEL_REFN (FETCH_NOP, 1); - eas.s.ea_nop.s.srcbword = LABEL_REFN (FETCH_NOP, 1); - eas.s.ea_nop.s.dstbyte = LABEL_REF (STORE_NOP); - eas.s.ea_nop.s.dstword = LABEL_REF (STORE_NOP); - - eas.s.ea_cr.s.srcabyte = LABEL_REFN (FETCH_CRB, 0); - eas.s.ea_cr.s.srcaword = LABEL_REFN (FETCH_CRW, 0); - - eas.s.ea_cr.s.srcbbyte = LABEL_REFN (FETCH_CRB, 1); - eas.s.ea_cr.s.srcbword = LABEL_REFN (FETCH_CRW, 1); - - eas.s.ea_cr.s.dstbyte = LABEL_REF (STORE_CRB); - eas.s.ea_cr.s.dstword = LABEL_REF (STORE_CRW); - - eas.s.ea_reg.s.srcabyte = LABEL_REFN (FETCH_REG_B, 0); - eas.s.ea_reg.s.srcaword = LABEL_REFN (FETCH_REG_W, 0); - eas.s.ea_reg.s.srcalong = LABEL_REFN (FETCH_REG_L, 0); - - eas.s.ea_reg.s.srcbbyte = LABEL_REFN (FETCH_REG_B, 1); - eas.s.ea_reg.s.srcbword = LABEL_REFN (FETCH_REG_W, 1); - eas.s.ea_reg.s.srcblong = LABEL_REFN (FETCH_REG_L, 1); - - eas.s.ea_reg.s.dstbyte = LABEL_REF (STORE_REG_B); - eas.s.ea_reg.s.dstword = LABEL_REF (STORE_REG_W); - eas.s.ea_reg.s.dstlong = LABEL_REF (STORE_REG_L); - - eas.s.ea_inc.s.srcabyte = LABEL_REFN (FETCH_INC_B, 0); - eas.s.ea_inc.s.srcaword = LABEL_REFN (FETCH_INC_W, 0); - eas.s.ea_inc.s.srcbbyte = LABEL_REFN (FETCH_INC_B, 1); - eas.s.ea_inc.s.srcbword = LABEL_REFN (FETCH_INC_W, 1); - eas.s.ea_inc.s.dstbyte = LABEL_REF (STORE_INC_B); - eas.s.ea_inc.s.dstword = LABEL_REF (STORE_INC_W); - - eas.s.ea_dec.s.srcabyte = LABEL_REFN (FETCH_DEC_B, 0); - eas.s.ea_dec.s.srcaword = LABEL_REFN (FETCH_DEC_W, 0); - eas.s.ea_dec.s.srcbbyte = LABEL_REFN (FETCH_DEC_B, 1); - eas.s.ea_dec.s.srcbword = LABEL_REFN (FETCH_DEC_W, 1); - eas.s.ea_dec.s.dstbyte = LABEL_REF (STORE_DEC_B); - eas.s.ea_dec.s.dstword = LABEL_REF (STORE_DEC_W); - - eas.s.ea_disp.s.srcabyte = LABEL_REFN (FETCH_DISP_B, 0); - eas.s.ea_disp.s.srcaword = LABEL_REFN (FETCH_DISP_W, 0); - eas.s.ea_disp.s.srcbbyte = LABEL_REFN (FETCH_DISP_B, 1); - eas.s.ea_disp.s.srcbword = LABEL_REFN (FETCH_DISP_W, 1); - eas.s.ea_disp.s.dstbyte = LABEL_REF (STORE_DISP_B); - eas.s.ea_disp.s.dstword = LABEL_REF (STORE_DISP_W); - - eas.s.ea_imm.s.srcabyte = LABEL_REFN (FETCH_IMM, 0); - eas.s.ea_imm.s.srcaword = LABEL_REFN (FETCH_IMM, 0); - eas.s.ea_imm.s.srcbbyte = LABEL_REFN (FETCH_IMM, 1); - eas.s.ea_imm.s.srcbword = LABEL_REFN (FETCH_IMM, 1); - - flag_special = LABEL_REF (FLAG_special); - flag_mp = LABEL_REF (FLAG_m); - flag_Mp = LABEL_REF (FLAG_M); - flag_ap = LABEL_REF (FLAG_a); - flag_Ap = LABEL_REF (FLAG_A); - flag_nonep = LABEL_REF (FLAG_NONE); - flag_nostorep = LABEL_REF (FLAG_NOSTORE); - flag_clearp = LABEL_REF (FLAG_CLEAR); - flag_shiftbyte = LABEL_REF (FLAG_shiftbyte); - flag_shiftword = LABEL_REF (FLAG_shiftword); - flag_multbyte = LABEL_REF (FLAG_multbyte); - flag_multword = LABEL_REF (FLAG_multword); - - - exec_dispatch[O_ADDS] = LABEL_REF (O_ADDS); - exec_dispatch[O_ADDX] = LABEL_REF (O_ADDX); - exec_dispatch[O_ADD] = LABEL_REF (O_ADD); - exec_dispatch[O_ANDC] = LABEL_REF (O_ANDC); - exec_dispatch[O_AND] = LABEL_REF (O_AND); - exec_dispatch[O_BCC] = LABEL_REF (O_BCC); - exec_dispatch[O_BCLR] = LABEL_REF (O_BCLR); - exec_dispatch[O_BCS] = LABEL_REF (O_BCS); - exec_dispatch[O_BEQ] = LABEL_REF (O_BEQ); - exec_dispatch[O_BF] = LABEL_REF (O_BF); - exec_dispatch[O_BGE] = LABEL_REF (O_BGE); - exec_dispatch[O_BGT] = LABEL_REF (O_BGT); - exec_dispatch[O_BHI] = LABEL_REF (O_BHI); - exec_dispatch[O_BHS] = LABEL_REF (O_BHS); - exec_dispatch[O_BLE] = LABEL_REF (O_BLE); - exec_dispatch[O_BLO] = LABEL_REF (O_BLO); - exec_dispatch[O_BLS] = LABEL_REF (O_BLS); - exec_dispatch[O_BLT] = LABEL_REF (O_BLT); - exec_dispatch[O_BMI] = LABEL_REF (O_BMI); - exec_dispatch[O_BNE] = LABEL_REF (O_BNE); - exec_dispatch[O_BNOT] = LABEL_REF (O_BNOT); - exec_dispatch[O_BPL] = LABEL_REF (O_BPL); - exec_dispatch[O_BPT] = LABEL_REF (O_BPT); - exec_dispatch[O_BRA] = LABEL_REF (O_BRA); - exec_dispatch[O_BRN] = LABEL_REF (O_BRN); - exec_dispatch[O_BSET] = LABEL_REF (O_BSET); - exec_dispatch[O_BSR] = LABEL_REF (O_BSR); - exec_dispatch[O_BTST] = LABEL_REF (O_BTST); - exec_dispatch[O_BT] = LABEL_REF (O_BT); - exec_dispatch[O_BVC] = LABEL_REF (O_BVC); - exec_dispatch[O_BVS] = LABEL_REF (O_BVS); - exec_dispatch[O_CLR] = LABEL_REF (O_CLR); - exec_dispatch[O_CMP] = LABEL_REF (O_CMP); - exec_dispatch[O_DADD] = LABEL_REF (O_DADD); - exec_dispatch[O_DIVXU] = LABEL_REF (O_DIVXU); - exec_dispatch[O_DSUB] = LABEL_REF (O_DSUB); - exec_dispatch[O_EXTS] = LABEL_REF (O_EXTS); - exec_dispatch[O_EXTU] = LABEL_REF (O_EXTU); - exec_dispatch[O_JMP] = LABEL_REF (O_JMP); - exec_dispatch[O_JSR] = LABEL_REF (O_JSR); - exec_dispatch[O_LDC] = LABEL_REF (O_LDC); - exec_dispatch[O_LDM] = LABEL_REF (O_LDM); - exec_dispatch[O_LINK] = LABEL_REF (O_LINK); - exec_dispatch[O_MOVFPE] = LABEL_REF (O_MOVFPE); - exec_dispatch[O_MOVTPE] = LABEL_REF (O_MOVTPE); - exec_dispatch[O_MOV] = LABEL_REF (O_MOV); - exec_dispatch[O_MULXU] = LABEL_REF (O_MULXU); - exec_dispatch[O_NEG] = LABEL_REF (O_NEG); - exec_dispatch[O_NOP] = LABEL_REF (O_NOP); - exec_dispatch[O_NOT] = LABEL_REF (O_NOT); - exec_dispatch[O_ORC] = LABEL_REF (O_ORC); - exec_dispatch[O_OR] = LABEL_REF (O_OR); - exec_dispatch[O_PJMP] = LABEL_REF (O_PJMP); - exec_dispatch[O_PJSR] = LABEL_REF (O_PJSR); - exec_dispatch[O_PRTD] = LABEL_REF (O_PRTD); - exec_dispatch[O_PRTS] = LABEL_REF (O_PRTS); - exec_dispatch[O_RECOMPILE] = LABEL_REF (O_RECOMPILE); - - exec_dispatch[O_ROTL] = LABEL_REF (O_ROTL); - exec_dispatch[O_ROTR] = LABEL_REF (O_ROTR); - exec_dispatch[O_ROTXL] = LABEL_REF (O_ROTXL); - exec_dispatch[O_ROTXR] = LABEL_REF (O_ROTXR); - - exec_dispatch[O_RTD] = LABEL_REF (O_RTD); - exec_dispatch[O_RTS] = LABEL_REF (O_RTS); - exec_dispatch[O_SCB_EQ] = LABEL_REF (O_SCB_EQ); - exec_dispatch[O_SCB_F] = LABEL_REF (O_SCB_F); - exec_dispatch[O_SCB_NE] = LABEL_REF (O_SCB_NE); - exec_dispatch[O_SHAL] = LABEL_REF (O_SHAL); - exec_dispatch[O_SHAR] = LABEL_REF (O_SHAR); - exec_dispatch[O_SHLL] = LABEL_REF (O_SHLL); - exec_dispatch[O_SHLR] = LABEL_REF (O_SHLR); - - exec_dispatch[O_SLEEP] = LABEL_REF (O_SLEEP); - exec_dispatch[O_STC] = LABEL_REF (O_STC); - exec_dispatch[O_STM] = LABEL_REF (O_STM); - exec_dispatch[O_SUBS] = LABEL_REF (O_SUBS); - exec_dispatch[O_SUBX] = LABEL_REF (O_SUBX); - exec_dispatch[O_SUB] = LABEL_REF (O_SUB); - exec_dispatch[O_SWAP] = LABEL_REF (O_SWAP); - exec_dispatch[O_TAS] = LABEL_REF (O_TAS); - exec_dispatch[O_TRAPA] = LABEL_REF (O_TRAPA); - exec_dispatch[O_TRAP_VS] = LABEL_REF (O_TRAP_VS); - exec_dispatch[O_TST] = LABEL_REF (O_TST); - exec_dispatch[O_UNLK] = LABEL_REF (O_UNLK); - exec_dispatch[O_XCH] = LABEL_REF (O_XCH); - exec_dispatch[O_XORC] = LABEL_REF (O_XORC); - exec_dispatch[O_XOR] = LABEL_REF (O_XOR); - nop.type = eas.s.ea_nop.s.srcabyte; - cpu.cache[0].opcode = exec_dispatch[O_RECOMPILE]; - cpu.cache[0].srca.type = eas.s.ea_nop.s.srcabyte; - cpu.cache[0].srcb.type = eas.s.ea_nop.s.srcbbyte; - } - - prev = signal (SIGINT, control_c); - prev_seg = signal (SIGSEGV, segv); - - if (step) - { - cpu.exception = SIGTRAP; - } - else - { - cpu.exception = 0; - } - - pc = cpu.regs[R_PC].s[LOW] + (NORMAL_CP << 16); - - GETSR (); - - if (setjmp (jbuf) == 0) { - do - { - int cidx; - decoded_inst *code; - - top: - cidx = cpu.cache_idx[pc]; - code = cpu.cache + cidx; - - FETCH (arga, code->srca, 0); - FETCH (argb, code->srcb, 1); - - - -#ifdef DEBUG - if (debug) - { - printf ("%x %d %s\n", pc, code->opcode, - code->op ? code->op->name : "**"); - } -#endif - - cycles += code->cycles; - insts++; - DISPATCH (code->opcode) - { - LABEL (O_RECOMPILE): - /* This opcode is a fake for when we get to an instruction which - hasn't been compiled */ - compile (pc); - goto top; - break; - LABEL (O_NEG): - arga = -arga; - argb = 0; - res = arga + argb; - break; - LABEL (O_SUBX): - arga += C; - LABEL (O_SUB): - LABEL (O_SUBS): - arga = -arga; - LABEL (O_ADD): - LABEL (O_ADDS): - res = arga + argb; - break; - - LABEL (O_ADDX): - res = arga + argb + C; - break; - - LABEL (O_AND): - LABEL (O_ANDC): - res = arga & argb; - break; - break; - - LABEL (O_BCLR): - arga &= 0xf; - bit = (argb & (1 << arga)); - res = argb & ~(1 << arga); - goto bitop; - - - LABEL (O_BRA): - LABEL (O_BT): - if (1) - goto condtrue; - - LABEL (O_BRN): - LABEL (O_BF): - if (0) - goto condtrue; - break; - - LABEL (O_BHI): - if ((C || Z) == 0) - goto condtrue; - break; - - LABEL (O_BLS): - if ((C || Z)) - goto condtrue; - break; - - LABEL (O_BCS): - LABEL (O_BLO): - if ((C == 1)) - goto condtrue; - break; - - LABEL (O_BCC): - LABEL (O_BHS): - if ((C == 0)) - goto condtrue; - break; - - LABEL (O_BEQ): - if (Z) - goto condtrue; - break; - LABEL (O_BGT): - if (((Z || (N ^ V)) == 0)) - goto condtrue; - break; - - - LABEL (O_BLE): - if (((Z || (N ^ V)) == 1)) - goto condtrue; - break; - - LABEL (O_BGE): - if ((N ^ V) == 0) - goto condtrue; - break; - LABEL (O_BLT): - if ((N ^ V)) - goto condtrue; - break; - LABEL (O_BMI): - if ((N)) - goto condtrue; - break; - LABEL (O_BNE): - if ((Z == 0)) - goto condtrue; - break; - LABEL (O_BPL): - if (N == 0) - goto condtrue; - break; - break; - LABEL (O_BVC): - if ((V == 0)) - goto condtrue; - break; - LABEL (O_BVS): - if ((V == 1)) - goto condtrue; - break; - - LABEL (O_BNOT): - bit = argb & (1<<(arga & 0xf)); - res = argb ^ (1<<(arga & 0xf)); - goto bitop; - break; - - LABEL (O_BSET): - arga = 1 << (arga & 0xf); - bit = argb & arga; - res = argb | arga; - goto bitop; - break; - - LABEL (O_PJMP): - pc = arga; - goto next; - - LABEL (O_UNLK): - { - int t; - SET_NORMREG (R7, GET_NORMREG (R6)); - POPWORD (t); - SET_NORMREG (R6, t); - pc = code->next_pc; - goto next; - } - - LABEL (O_RTS): - { - int cp = pc & 0xff0000; - POPWORD (pc); - pc |= cp; - goto next; - } - break; - - LABEL (O_PRTS): - { - int cp; - int off; - POPWORD (cp); - POPWORD (off); - cp <<= 16; - SET_SEGREG (R_CP, cp); - pc = cp + off; - } - goto next; - - LABEL (O_PJSR): - PUSHWORD (argb & 0xffff); - PUSHWORD (argb >> 16); - pc = (arga & 0xffffff); - goto next; - - LABEL (O_BSR): - LABEL (O_JSR): - PUSHWORD (code->next_pc); - pc = arga | (pc & 0xff0000); - goto next; - - LABEL (O_BTST): - Z = (((argb >> (arga & 0xf)) & 1) == 0); - pc = code->next_pc; - goto next; - - LABEL (O_CLR): - res = 0; - break; - - LABEL (O_CMP): - arga = -arga; - res = arga + argb; - break; - - LABEL (O_DADD): - res = arga + argb + C; - if (res > 99) - { - res -= 100; - C = 1; - } - else - { - C = 0; - } - Z = Z && (res == 0); - break; - - - LABEL (O_DSUB): - res = argb - arga - C; - if (res < 0) - { - res += 100; - C = 1; - } - else - { - C = 0; - } - Z = Z && (res == 0); - break; - - LABEL (O_EXTS): - res = SEXTCHAR (arga); - break; - - LABEL (O_EXTU): - res = (unsigned char) arga; - break; - - LABEL (O_JMP): - pc = arga | (pc & 0xff0000); - goto next; - break; - - LABEL (O_LDM): - - for (tmp = 0; tmp < 7; tmp++) - { - if (argb & (1 << tmp)) - { - POPWORD (cpu.regs[tmp].s[LOW]); - } - } - if (argb & 0x80) - POPWORD (tmp); /* dummy ready for sp */ - goto nextpc; - break; - - LABEL (O_LINK): - PUSHWORD (cpu.regs[R6].s[LOW]); - cpu.regs[R6].s[LOW] = cpu.regs[R7].s[LOW]; - cpu.regs[R7].s[LOW] += argb; - goto nextpc; - - LABEL (O_STC): - LABEL (O_LDC): - LABEL (O_MOVFPE): - LABEL (O_MOVTPE): - LABEL (O_MOV): - LABEL (O_TST): - res = arga; - break; - - LABEL (O_TRAPA): - if (arga == 15) - { - trap (); - } - else - { - PUSHWORD (pc & 0xffff); - if (cpu.maximum) - { - PUSHWORD (NORMAL_CP); - } - PUSHWORD (NORMAL_SR); - if (cpu.maximum) - { - arga = arga * 4 + 0x40; - SET_NORMAL_CPPC (longat (cpu.memory + arga)); - } - else - { - arga = arga * 2 + 0x20; - SET_NORMAL_CPPC (wordat (cpu.memory + arga)); - } - } - break; - - LABEL (O_OR): - LABEL (O_ORC): - res = arga | argb; - break; - - LABEL (O_XOR): - LABEL (O_XORC): - res = arga ^ argb; - break; - - LABEL (O_SCB_F): - { - scb_f: - res = arga - 1; - code->srca.reg.wptr[0] = res; - if (res != -1) - { - pc = argb; - goto next; - } - } - break; - - LABEL (O_SCB_EQ): - if (Z == 1) - break; - else - goto scb_f; - - LABEL (O_SCB_NE): - if (Z == 0) - break; - else - goto scb_f; - - LABEL (O_NOP): - /* If only they were all as simple as this */ - break; - - LABEL (O_ROTL): - res = arga << 1; - C = (res >> argb) & 1; - res |= C; - break; - - - LABEL (O_ROTR): - C = arga & 1; - res = arga >> 1; - res |= (C << (argb - 1)); - break; - - LABEL (O_ROTXL): - res = arga << 1; - res |= C; - C = (res >> argb) & 1; - break; - - LABEL (O_ROTXR): - res = arga >> 1; - res |= (C << (argb - 1)); - C = arga & 1; - break; - - LABEL (O_SHAL): - res = arga << 1; - if (argb == 16) - { - C = (res >> (16)) & 1; - Z = ((res & 0xffff) == 0); - N = ((res & 0x8000) != 0); - } - - else - { - C = (res >> (8)) & 1; - Z = ((res & 0xff) == 0); - N = ((res & 0x80) != 0); - - } - V = C ^ N; - goto none; - - LABEL (O_SHAR): - C = arga & 1; - if (argb == 16) - { - res = ((short) arga) >> 1; - } - else - { - res = (SEXTCHAR (arga)) >> 1; - } - break; - - LABEL (O_SHLL): - res = arga << 1; - C = (res >> argb) & 1; - break; - - LABEL (O_SHLR): - C = arga & 1; - res = arga >> 1; - break; - - LABEL (O_DIVXU): - if (arga == 0) - { - N = V = C = 0; - Z = 1; - cpu.exception = SIGILL; - } - else - { - int d = argb / arga; - int m = argb % arga; - if (code->dst.type == eas.s.ea_reg.s.dstlong) - { - res = (m << 16) | (d & 0xffff); - } - else - { - res = (m << 8) | (d & 0xff); - } - - } - break; - - LABEL (O_MULXU): - res = arga * argb; - break; - - LABEL (O_NOT): - res = ~arga; - break; - - LABEL (O_SWAP): - res = ((arga >> 8) & 0xff) | ((arga << 8) & 0xff00); - break; - - - LABEL (O_STM): - for (tmp = 7; tmp >= 0; tmp--) - { - if (arga & (1 << tmp)) - { - PUSHWORD (cpu.regs[tmp].s[LOW]); - } - } - goto nextpc; - - LABEL (O_TAS): - C = 0; - V = 0; - Z = arga == 0; - N = arga < 0; - res = arga | 0x80; - goto none; - - LABEL (O_PRTD): - LABEL (O_XCH): - LABEL (O_RTD): - cpu.exception = SIGILL; - goto next; - - LABEL (O_TRAP_VS): - LABEL (O_SLEEP): - LABEL (O_BPT): - cpu.exception = SIGTRAP; - goto next; - break; - } - - ENDDISPATCH; - - DISPATCH (code->flags) - { - bitop: - Z = (res & bit) == 0; - pc = code->next_pc; - break; - LABEL (FLAG_multword): - Z = (res & 0xffff) == 0; - N = (res & 0x8000) != 0; - V = 0; - C = 0; - pc = code->next_pc; - break; - - LABEL (FLAG_multbyte): - /* 8*8 -> 16 */ - Z = (res & 0xff) == 0; - N = (res & 0x80) != 0; - V = 0; - C = 0; - pc = code->next_pc; - break; - - LABEL (FLAG_shiftword): - N = (res & 0x8000) != 0; - Z = (res & 0xffff) == 0; - V = 0; - pc = code->next_pc; - break; - - LABEL (FLAG_shiftbyte): - N = (res & 0x80) != 0; - Z = (res & 0xff) == 0; - V = 0; - pc = code->next_pc; - break; - - LABEL (FLAG_special): - pc = code->next_pc; - break; - - LABEL (FLAG_m): - /* Move byte flags */ - /* after a logical instruction */ - N = (res & 0x80) != 0; - Z = (res & 0xff) == 0; - V = (((~arga & ~argb & res) | (arga & argb & ~res)) & 0x80) != 0; - pc = code->next_pc; - break; - - LABEL (FLAG_M): - /* Move word flags */ - /* after a logical instruction */ - N = (res & 0x8000) != 0; - Z = (res & 0xffff) == 0; - V = (((~arga & ~argb & res) | (arga & argb & ~res)) & 0x8000) != 0; - pc = code->next_pc; - break; - - LABEL (FLAG_a): - /* after byte sized arith */ - C = (res & 0x100) != 0; - N = (res & 0x80) != 0; - Z = (res & 0xff) == 0; - V = (((~arga & ~argb & res) | (arga & argb & ~res)) & 0x80) != 0; - pc = code->next_pc; - break; - - LABEL (FLAG_A): - /* after word sized arith */ - C = (res & 0x10000) != 0; - N = (res & 0x8000) != 0; - Z = (res & 0xffff) == 0; - V = (((~arga & ~argb & res) | (arga & argb & ~res)) & 0x8000) != 0; - pc = code->next_pc; - break; - - LABEL (FLAG_NONE): - none:; - /* no flags but store */ - pc = code->next_pc; - break; - LABEL (FLAG_NOSTORE): - /* no flags and no store */ - pc = code->next_pc; - break; - LABEL (FLAG_CLEAR): - /* clear flags */ - N = 0; - Z = 1; - V = 0; - C = 0; - pc = code->next_pc; - break; - condtrue: - pc = arga; - goto next; - } - ENDDISPATCH; - - DISPATCH (code->dst.type) - { - unsigned char *lval; - - LABEL (STORE_CRB): - (*(code->dst.reg.segptr)) = cpu.memory + (res << 16); - break; - - LABEL (STORE_NOP): - break; - - LABEL (STORE_REG_B): - (*(code->dst.reg.bptr)) = res; - break; - - LABEL (STORE_REG_W): - (*(code->dst.reg.wptr)) = res; - break; - - LABEL (STORE_REG_L): - { - int l, r; - - r = (union rtype *) (code->dst.reg.wptr) - &cpu.regs[0]; - r++; - *(code->dst.reg.wptr) = res >> 16; - cpu.regs[r].s[LOW] = res & 0xffff; - - } - - break; - - LABEL (STORE_DISP_W): - lval = displval (code->dst); - setwordat (lval, res); - break; - - LABEL (STORE_DISP_B): - lval = displval (code->dst); - setbyteat (lval, res); - break; - - LABEL (STORE_INC_B): - lval = elval (code->dst, 0); - setbyteat (lval, res); - (*(code->dst.reg.wptr))++; - break; - - LABEL (STORE_INC_W): - lval = elval (code->dst, 0); - setwordat (lval, res); - (*(code->dst.reg.wptr)) += 2; - break; - - LABEL (STORE_DEC_B): - (*(code->dst.reg.wptr))--; - lval = elval (code->dst, 0); - setbyteat (lval, res); - break; - - LABEL (STORE_CRW): - /* Make an up to date sr from the flag state */ - cpu.regs[R_SR].s[LOW] = res; - GETSR (); - break; - - LABEL (STORE_DEC_W): - (*(code->dst.reg.wptr)) -= 2; - lval = elval (code->dst, 0); - setwordat (lval, res); - - break; - - nextpc: - pc = code->next_pc; - - } - ENDDISPATCH; - next:; - } - while (!cpu.exception); - } - - cpu.ticks += get_now () - tick_start; - cpu.cycles += cycles; - cpu.insts += insts; - cpu.regs[R_PC].s[LOW] = pc; - BUILDSR (); - - signal (SIGINT, prev); - signal (SIGSEGV, prev_seg); -} - - - - -int -sim_write (sd, addr, buffer, size) - SIM_DESC sd; - SIM_ADDR addr; - unsigned char *buffer; - int size; -{ - int i; - - init_pointers (); - if (addr < 0 || addr + size > H8500_MSIZE) - return 0; - for (i = 0; i < size; i++) - { - cpu.memory[addr + i] = buffer[i]; - cpu.cache_idx[addr + i] = 0; - } - return size; -} - -int -sim_read (sd, addr, buffer, size) - SIM_DESC sd; - SIM_ADDR addr; - unsigned char *buffer; - int size; -{ - init_pointers (); - if (addr < 0 || addr + size > H8500_MSIZE) - return 0; - memcpy (buffer, cpu.memory + addr, size); - return size; -} - -/* Ripped off from tm-h8500.h */ - -#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 - -/* As above, but with correct seg register glued on */ -#define PR0_REGNUM 8 -#define PR1_REGNUM 9 -#define PR2_REGNUM 10 -#define PR3_REGNUM 11 -#define PR4_REGNUM 12 -#define PR5_REGNUM 13 -#define PR6_REGNUM 14 -#define PR7_REGNUM 15 - -#define SP_REGNUM PR7_REGNUM /* Contains address of top of stack */ -#define FP_REGNUM PR6_REGNUM /* Contains address of executing stack frame */ - - -#define SEG_C_REGNUM 16 /* Segment registers */ -#define SEG_D_REGNUM 17 -#define SEG_E_REGNUM 18 -#define SEG_T_REGNUM 19 - -#define CCR_REGNUM 20 /* Contains processor status */ -#define PC_REGNUM 21 /* Contains program counter */ - -#define CYCLE_REGNUM 22 -#define INST_REGNUM 23 -#define TICK_REGNUM 24 - -int -sim_store_register (sd, rn, value, length) - SIM_DESC sd; - int rn; - unsigned char *value; - int length; -{ - int seg = 0; - int reg = -1; - - init_pointers (); - switch (rn) - { - case PC_REGNUM: - SET_SEGREG (R_CP, (value[1]<<16)); - cpu.regs[R_PC].s[LOW] = (value[2] << 8) | value[3]; - break; - case SEG_C_REGNUM: - case SEG_D_REGNUM: - case SEG_E_REGNUM: - case SEG_T_REGNUM: - seg = rn - SEG_C_REGNUM + R_CP; - reg = -1; - break; - default: - abort (); - case R0_REGNUM: - case R1_REGNUM: - case R2_REGNUM: - case R3_REGNUM: - case R4_REGNUM: - case R5_REGNUM: - case R6_REGNUM: - case R7_REGNUM: - seg = 0; - reg = rn - R0_REGNUM; - break; - case CCR_REGNUM: - seg = 0; - reg = R_SR; - break; - case CYCLE_REGNUM: - cpu.cycles = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]; - return; - case INST_REGNUM: - cpu.insts = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]; - return; - case TICK_REGNUM: - cpu.ticks = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]; - return; - case PR0_REGNUM: - case PR1_REGNUM: - case PR2_REGNUM: - case PR3_REGNUM: - case PR4_REGNUM: - case PR5_REGNUM: - case PR6_REGNUM: - case PR7_REGNUM: - SET_SEGREG (segforreg[rn], value[1]); - reg = rn - PR0_REGNUM; - cpu.regs[reg].s[LOW] = (value[2] << 8) | value[3]; - return; - } - - if (seg) - SET_SEGREG (seg, value[0] << 16); - - if (reg > 0) - { - cpu.regs[reg].s[LOW] = (value[0] << 8) | value[1]; - } - return -1; -} - -int -sim_fetch_register (sd, rn, buf, length) - SIM_DESC sd; - int rn; - unsigned char *buf; - int length; -{ - init_pointers (); - - switch (rn) - { - default: - abort (); - case SEG_C_REGNUM: - case SEG_D_REGNUM: - case SEG_E_REGNUM: - case SEG_T_REGNUM: - buf[0] = GET_SEGREG(rn - SEG_C_REGNUM + R_CP); - break; - case CCR_REGNUM: - buf[0] = cpu.regs[R_SR].s[HIGH]; - buf[1] = cpu.regs[R_SR].s[LOW]; - break; - case PC_REGNUM: - buf[0] = 0; - buf[1] = GET_SEGREG(R_CP); - buf[2] = HIGH_BYTE (cpu.regs[R_PC].s[LOW]); - buf[3] = LOW_BYTE (cpu.regs[R_PC].s[LOW]); - break; - - case PR0_REGNUM: - case PR1_REGNUM: - case PR2_REGNUM: - case PR3_REGNUM: - case PR4_REGNUM: - case PR5_REGNUM: - case PR6_REGNUM: - case PR7_REGNUM: - rn -= PR0_REGNUM; - buf[0] = 0; - buf[1] = GET_SEGREG(segforreg[rn]); - buf[2] = HIGH_BYTE (cpu.regs[rn].s[LOW]); - buf[3] = LOW_BYTE (cpu.regs[rn].s[LOW]); - break; - case R0_REGNUM: - case R1_REGNUM: - case R2_REGNUM: - case R3_REGNUM: - case R4_REGNUM: - case R5_REGNUM: - case R6_REGNUM: - case R7_REGNUM: - buf[0] = HIGH_BYTE (cpu.regs[rn].s[LOW]); - buf[1] = LOW_BYTE (cpu.regs[rn].s[LOW]); - break; - case CYCLE_REGNUM: - buf[0] = cpu.cycles >> 24; - buf[1] = cpu.cycles >> 16; - buf[2] = cpu.cycles >> 8; - buf[3] = cpu.cycles >> 0; - break; - - case TICK_REGNUM: - buf[0] = cpu.ticks >> 24; - buf[1] = cpu.ticks >> 16; - buf[2] = cpu.ticks >> 8; - buf[3] = cpu.ticks >> 0; - break; - - case INST_REGNUM: - buf[0] = cpu.insts >> 24; - buf[1] = cpu.insts >> 16; - buf[2] = cpu.insts >> 8; - buf[3] = cpu.insts >> 0; - break; - } - return -1; -} - -int -sim_trace (sd) - SIM_DESC sd; -{ - - int i; - - for (i = 0; i < 12; i += 2) - { - unsigned char *p = cpu.regs[R_TP].c + ((cpu.regs[R6].s[LOW] + i) & 0xffff); - unsigned short *j = (unsigned short *) p; - - printf ("%04x ", *j); - } - printf ("\n"); - printf ("%02x %02x %02x %02x:%04x %04x %04x %04x %04x %04x %04x %04x %04x\n", - NORMAL_DP, - NORMAL_EP, - NORMAL_TP, - NORMAL_CP, - cpu.regs[R_PC].s[LOW], - cpu.regs[0].s[LOW], - cpu.regs[1].s[LOW], - cpu.regs[2].s[LOW], - cpu.regs[3].s[LOW], - cpu.regs[4].s[LOW], - cpu.regs[5].s[LOW], - cpu.regs[6].s[LOW], - cpu.regs[7].s[LOW]); - sim_resume (sd, 1, 0); - return 0; -} - -void -sim_stop_reason (sd, reason, sigrc) - SIM_DESC sd; - enum sim_stop *reason; - int *sigrc; -{ - *reason = sim_stopped; - *sigrc = cpu.exception; -} - -void -sim_set_simcache_size (n) -{ - if (cpu.cache) - free (cpu.cache); - if (n < 2) - n = 2; - cpu.cache = (decoded_inst *) malloc (sizeof (decoded_inst) * n); - cpu.csize = n; -} - -void -sim_size (n) - int n; -{ - /* Fixed size. */ -} - -void -sim_info (sd, verbose) - SIM_DESC sd; - int verbose; -{ - double timetaken = (double) cpu.ticks / (double) now_persec (); - double virttime = cpu.cycles / 10.0e6; - - (*sim_callback->printf_filtered) (sim_callback, - "\n\ninstructions executed %10d\n", - cpu.insts); - (*sim_callback->printf_filtered) (sim_callback, - "cycles (v approximate) %10d\n", - cpu.cycles); - (*sim_callback->printf_filtered) (sim_callback, - "real time taken %10.4f\n", - timetaken); - (*sim_callback->printf_filtered) (sim_callback, - "virtual time taked %10.4f\n", - virttime); - if (timetaken) - { - (*sim_callback->printf_filtered) (sim_callback, - "simulation ratio %10.4f\n", - virttime / timetaken); - } - - (*sim_callback->printf_filtered) (sim_callback, - "compiles %10d\n", - cpu.compiles); - (*sim_callback->printf_filtered) (sim_callback, - "cache size %10d\n", - cpu.csize); -} - -SIM_DESC -sim_open (kind, cb, abfd, argv) - SIM_OPEN_KIND kind; - host_callback *cb; - struct _bfd *abfd; - char **argv; -{ - sim_kind = kind; - myname = argv[0]; - sim_callback = cb; - /* fudge our descriptor */ - return (SIM_DESC) 1; -} - -void -sim_close (sd, quitting) - SIM_DESC sd; - int quitting; -{ - /* nothing to do */ -} - -SIM_RC -sim_load (sd, prog, abfd, from_tty) - SIM_DESC sd; - char *prog; - bfd *abfd; - int from_tty; -{ - extern bfd *sim_load_file (); /* ??? Don't know where this should live. */ - bfd *prog_bfd; - - prog_bfd = sim_load_file (sd, myname, sim_callback, prog, abfd, - sim_kind == SIM_OPEN_DEBUG, - 0, sim_write); - if (prog_bfd == NULL) - return SIM_RC_FAIL; - if (abfd == NULL) - bfd_close (prog_bfd); - return SIM_RC_OK; -} - -SIM_RC -sim_create_inferior (sd, abfd, argv, env) - SIM_DESC sd; - struct _bfd *abfd; - char **argv; - char **env; -{ - int pc; - bfd_vma start_address; - if (abfd != NULL) - start_address = bfd_get_start_address (abfd); - else - start_address = 0; - - /* ??? We assume this is a 4 byte quantity. */ - pc = start_address; - - sim_store_register (sd, PC_REGNUM, (unsigned char *) &pc, 4); - return SIM_RC_OK; -} - -void -sim_do_command (sd, cmd) - 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_callback = ptr; -} |