* 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:
parent
1bcfe5fa30
commit
d252301029
5 changed files with 701 additions and 250 deletions
|
@ -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)"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue