* gencode.c (write_header): Add "insn" and "extension" arguments

to the OP_* declarations.
        (write_template): Similarly for function templates.
        * interp.c (insn, extension): Remove global variables.  Instead
        pass them as arguments to the OP_* functions.
        * mn10300_sim.h: Remove decls for "insn" and "extension".
        * simops.c (OP_*): Accept "insn" and "extension" as arguments
        instead of using globals.
Starting to clean things up.
This commit is contained in:
Jeff Law 1996-12-06 21:19:37 +00:00
parent 1bcfe5fa30
commit d252301029
5 changed files with 701 additions and 250 deletions

View file

@ -1,3 +1,14 @@
Fri Dec 6 14:13:34 1996 Jeffrey A Law (law@cygnus.com)
* gencode.c (write_header): Add "insn" and "extension" arguments
to the OP_* declarations.
(write_template): Similarly for function templates.
* interp.c (insn, extension): Remove global variables. Instead
pass them as arguments to the OP_* functions.
* mn10300_sim.h: Remove decls for "insn" and "extension".
* simops.c (OP_*): Accept "insn" and "extension" as arguments
instead of using globals.
Thu Dec 5 22:26:31 1996 Jeffrey A Law (law@cygnus.com)
* simops.c: Fix typos in "mov am,(d16,an)" and "mov am,(d32,an)"

View file

@ -28,7 +28,7 @@ write_header ()
struct mn10300_opcode *opcode;
for (opcode = (struct mn10300_opcode *)mn10300_opcodes; opcode->name; opcode++)
printf("void OP_%X PARAMS ((void));\t\t/* %s */\n",
printf("void OP_%X PARAMS ((unsigned long, unsigned long));\t\t/* %s */\n",
opcode->opcode, opcode->name);
}
@ -47,7 +47,7 @@ write_template ()
for (opcode = (struct mn10300_opcode *)mn10300_opcodes; opcode->name; opcode++)
{
printf("/* %s */\nvoid\nOP_%X ()\n{\n", opcode->name, opcode->opcode);
printf("/* %s */\nvoid\nOP_%X ()\n unsigned long insn, extension;\n{\n", opcode->name, opcode->opcode);
/* count operands */
j = 0;

View file

@ -17,10 +17,9 @@ int mn10300_debug;
uint32 OP[4];
static struct hash_entry *lookup_hash PARAMS ((uint32 ins));
static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int));
static long hash PARAMS ((long));
static void init_system PARAMS ((void));
#define MAX_HASH 63
struct hash_entry
@ -34,22 +33,83 @@ struct hash_entry
struct hash_entry hash_table[MAX_HASH+1];
/* This probably doesn't do a very good job at bucket filling, but
it's simple... */
static INLINE long
hash(insn)
long insn;
{
/* XXX */
/* These are one byte insns. */
if ((insn & 0xffffff00) == 0)
{
if ((insn & 0xf0) == 0x00
|| (insn & 0xf0) == 0x40)
return (insn & 0xf3) & 0x3f;
if ((insn & 0xf0) == 0x10
|| (insn & 0xf0) == 0x30
|| (insn & 0xf0) == 0x50)
return (insn & 0xfc) & 0x3f;
if ((insn & 0xf0) == 0x60
|| (insn & 0xf0) == 0x70
|| (insn & 0xf0) == 0x80
|| (insn & 0xf0) == 0x90
|| (insn & 0xf0) == 0xa0
|| (insn & 0xf0) == 0xb0
|| (insn & 0xf0) == 0xe0)
return (insn & 0xf0) & 0x3f;
return (insn & 0xff) & 0x3f;
}
/* These are two byte insns */
if ((insn & 0xffff0000) == 0)
{
if ((insn & 0xf000) == 0x2000
|| (insn & 0xf000) == 0x5000)
return ((insn & 0xfc00) >> 8) & 0x3f;
if ((insn & 0xf000) == 0x4000)
return ((insn & 0xf300) >> 8) & 0x3f;
if ((insn & 0xf000) == 0x8000
|| (insn & 0xf000) == 0x9000
|| (insn & 0xf000) == 0xa000
|| (insn & 0xf000) == 0xb000)
return ((insn & 0xf000) >> 8) & 0x3f;
return ((insn & 0xff00) >> 8) & 0x3f;
}
/* These are three byte insns. */
if ((insn & 0xff000000) == 0)
{
if ((insn & 0xf00000) == 0x000000)
return ((insn & 0xf30000) >> 16) & 0x3f;
if ((insn & 0xf00000) == 0x200000
|| (insn & 0xf00000) == 0x300000)
return ((insn & 0xfc0000) >> 16) & 0x3f;
return ((insn & 0xff0000) >> 16) & 0x3f;
}
/* These are four byte or larger insns. */
return ((insn & 0xff000000) >> 24) & 0x3f;
}
static struct hash_entry *
lookup_hash (ins)
lookup_hash (ins, length)
uint32 ins;
int length;
{
struct hash_entry *h;
h = &hash_table[hash(ins)];
while ((ins & h->mask) != h->opcode)
while ((ins & h->mask) != h->opcode
|| (length != h->ops->length))
{
if (h->next == NULL)
{
@ -119,6 +179,28 @@ put_word (addr, data)
}
uint32
load_mem_big (addr, len)
SIM_ADDR addr;
int len;
{
uint8 *p = addr + State.mem;
switch (len)
{
case 1:
return p[0];
case 2:
return p[0] << 8 | p[1];
case 3:
return p[0] << 16 | p[1] << 8 | p[2];
case 4:
return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
default:
abort ();
}
}
uint32
load_mem (addr, len)
SIM_ADDR addr;
@ -132,6 +214,8 @@ load_mem (addr, len)
return p[0];
case 2:
return p[1] << 8 | p[0];
case 3:
return p[2] << 16 | p[1] << 8 | p[0];
case 4:
return p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0];
default:
@ -270,7 +354,7 @@ sim_resume (step, siggnal)
{
uint32 inst, opcode;
reg_t oldpc;
struct interrupt_generator *intgen;
struct hash_entry *h;
if (step)
State.exception = SIGTRAP;
@ -279,15 +363,137 @@ sim_resume (step, siggnal)
do
{
/* Fetch the current instruction. */
inst = RLW (PC);
oldpc = PC;
opcode = (inst & 0x07e0) >> 5;
unsigned long insn, extension;
/* Decode the opcode field. */
if ((opcode & 0x30) == 0
|| (opcode & 0x38) == 0x10)
/* Fetch the current instruction. */
inst = load_mem_big (PC, 1);
oldpc = PC;
/* These are one byte insns. */
if ((inst & 0xf3) == 0x00
|| (inst & 0xf0) == 0x10
|| (inst & 0xfc) == 0x3c
|| (inst & 0xf3) == 0x41
|| (inst & 0xf3) == 0x40
|| (inst & 0xfc) == 0x50
|| (inst & 0xfc) == 0x54
|| (inst & 0xf0) == 0x60
|| (inst & 0xf0) == 0x70
|| ((inst & 0xf0) == 0x80
&& (inst & 0x0c) >> 2 != (inst & 0x03))
|| ((inst & 0xf0) == 0x90
&& (inst & 0x0c) >> 2 != (inst & 0x03))
|| ((inst & 0xf0) == 0xa0
&& (inst & 0x0c) >> 2 != (inst & 0x03))
|| ((inst & 0xf0) == 0xb0
&& (inst & 0x0c) >> 2 != (inst & 0x03))
|| (inst & 0xff) == 0xcb
|| (inst & 0xfc) == 0xd0
|| (inst & 0xfc) == 0xd4
|| (inst & 0xfc) == 0xd8
|| (inst & 0xf0) == 0xe0)
{
insn = inst;
h = lookup_hash (insn, 1);
extension = 0;
(h->ops->func)(insn, extension);
PC += 1;
}
/* These are two byte insns. */
else if ((inst & 0xf0) == 0x80
|| (inst & 0xf0) == 0x90
|| (inst & 0xf0) == 0xa0
|| (inst & 0xf0) == 0xb0
|| (inst & 0xfc) == 0x20
|| (inst & 0xfc) == 0x28
|| (inst & 0xf3) == 0x43
|| (inst & 0xf3) == 0x42
|| (inst & 0xfc) == 0x58
|| (inst & 0xfc) == 0x5c
|| ((inst & 0xf0) == 0xc0
&& (inst & 0xff) != 0xcb
&& (inst & 0xff) != 0xcc
&& (inst & 0xff) != 0xcd)
|| (inst & 0xff) == 0xf0
|| (inst & 0xff) == 0xf1
|| (inst & 0xff) == 0xf2
|| (inst & 0xff) == 0xf3
|| (inst & 0xff) == 0xf4
|| (inst & 0xff) == 0xf5
|| (inst & 0xff) == 0xf6)
{
insn = load_mem_big (PC, 2);
h = lookup_hash (insn, 2);
extension = 0;
(h->ops->func)(insn, extension);
PC += 2;
}
/* These are three byte insns. */
else if ((inst & 0xff) == 0xf8
|| (inst & 0xff) == 0xcc
|| (inst & 0xff) == 0xf9
|| (inst & 0xf3) == 0x01
|| (inst & 0xf3) == 0x02
|| (inst & 0xf3) == 0x03
|| (inst & 0xfc) == 0x24
|| (inst & 0xfc) == 0x2c
|| (inst & 0xfc) == 0x30
|| (inst & 0xfc) == 0x34
|| (inst & 0xfc) == 0x38
|| (inst & 0xff) == 0xde
|| (inst & 0xff) == 0xdf
|| (inst & 0xff) == 0xcc)
{
insn = load_mem_big (PC, 3);
h = lookup_hash (insn, 3);
extension = 0;
(h->ops->func)(insn, extension);
PC += 3;
}
/* These are four byte insns. */
else if ((inst & 0xff) == 0xfa
|| (inst & 0xff) == 0xfb)
{
insn = load_mem_big (PC, 4);
h = lookup_hash (insn, 4);
extension = 0;
(h->ops->func)();
PC += 4;
}
/* These are five byte insns. */
else if ((inst & 0xff) == 0xcd
|| (inst & 0xff) == 0xdc)
{
insn = load_mem_big (PC, 4);
h = lookup_hash (insn, 5);
extension = load_mem_big (PC + 4, 1);
(h->ops->func)(insn, extension);
PC += 5;
}
/* These are six byte insns. */
else if ((inst & 0xff) == 0xfd
|| (inst & 0xff) == 0xfc)
{
insn = load_mem_big (PC, 4);
h = lookup_hash (insn, 6);
extension = load_mem_big (PC + 4, 2);
(h->ops->func)(insn, extension);
PC += 6;
}
/* Else its a seven byte insns (in theory). */
else
{
insn = load_mem_big (PC, 4);
h = lookup_hash (insn, 7);
extension = load_mem_big (PC + 4, 3);
(h->ops->func)(insn, extension);
PC += 7;
}
}
while (!State.exception);

View file

@ -59,7 +59,7 @@ struct simops
struct _state
{
reg_t regs[10]; /* registers, d0-d3, a0-a3, sp, mdr */
reg_t regs[12]; /* registers, d0-d3, a0-a3, sp, mdr, lar, lir */
reg_t sregs[8]; /* system registers, including psw */
reg_t pc;
uint8 *mem; /* main memory */
@ -68,7 +68,6 @@ struct _state
extern uint32 OP[4];
extern struct simops Simops[];
extern unsigned long insn, extension;
#define PC (State.pc)
@ -82,6 +81,8 @@ extern unsigned long insn, extension;
#define REG_A0 4
#define REG_SP 8
#define REG_MDR 9
#define REG_LAR 10
#define REG_LIR 11
#define SEXT3(x) ((((x)&0x7)^(~0x3))+0x4)

File diff suppressed because it is too large Load diff