diff options
author | Martin Hunt <hunt@redhat.com> | 1996-11-09 00:38:07 +0000 |
---|---|---|
committer | Martin Hunt <hunt@redhat.com> | 1996-11-09 00:38:07 +0000 |
commit | 849c575f9757b1c2d001dc771d6b1f77d3254003 (patch) | |
tree | 3a951bfed636d6cf0c9866f394a4aab332ff8a93 /sim/d10v/gencode.c | |
parent | 4dc42997c3010339ee538f0e791765ad75492ae9 (diff) | |
download | gdb-849c575f9757b1c2d001dc771d6b1f77d3254003.zip gdb-849c575f9757b1c2d001dc771d6b1f77d3254003.tar.gz gdb-849c575f9757b1c2d001dc771d6b1f77d3254003.tar.bz2 |
Fri Nov 8 16:19:55 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
* d10v-sim.h (simops): Add flag is_long.
(State): Add pc_changed. Instructions which update the PC should
use the JMP macro which sets this.
(JMP): New macro. Sets the PC and the pc_changed flag.
* gencode.c (write_opcodes): Add is_long field.
* interp.c (lookup_hash): If we blindly apply a short opcode's mask
to a long opcode we could get a false match. Check the opcode size.
(hash): Add a size field to the hash table.
(sim_open): Initialize size field in hash table.
(sim_resume): Change to logic for setting the PC. Used to increment the
PC if it had not been changed. This didn't allow single-instruction loops.
Now checks the flag State.pc_changed. Also now stops when ^C is received.
(dmem_addr): Fix translation of data segments to unified memory.
(sim_ctrl_c): New function. When ^C is received, set stop_simulator flag.
* simops.c: Changed all branch and jump instructions to use new JMP macro.
(OP_20000000): Corrected trace information to show this is a ldi.l, not
a ldi.s instruction.
Diffstat (limited to 'sim/d10v/gencode.c')
-rw-r--r-- | sim/d10v/gencode.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/sim/d10v/gencode.c b/sim/d10v/gencode.c new file mode 100644 index 0000000..71e92e8 --- /dev/null +++ b/sim/d10v/gencode.c @@ -0,0 +1,146 @@ +#include "d10v_sim.h" + +static void write_header PARAMS ((void)); +static void write_opcodes PARAMS ((void)); +static void write_template PARAMS ((void)); + +int +main (argc, argv) + int argc; + char *argv[]; +{ + if ((argc > 1) && (strcmp (argv[1],"-h") == 0)) + write_header(); + else if ((argc > 1) && (strcmp (argv[1],"-t") == 0)) + write_template (); + else + write_opcodes(); + return 0; +} + + +static void +write_header () +{ + struct d10v_opcode *opcode; + + for (opcode = (struct d10v_opcode *)d10v_opcodes; opcode->name; opcode++) + if (opcode->format != OPCODE_FAKE) + printf("void OP_%X PARAMS ((void));\t\t/* %s */\n",opcode->opcode, opcode->name); +} + + +/* write_template creates a file all required functions, ready */ +/* to be filled out */ + +static void +write_template () +{ + struct d10v_opcode *opcode; + int i,j; + + printf ("#include \"d10v_sim.h\"\n"); + printf ("#include \"simops.h\"\n"); + + for (opcode = (struct d10v_opcode *)d10v_opcodes; opcode->name; opcode++) + { + if (opcode->format != OPCODE_FAKE) + { + printf("/* %s */\nvoid\nOP_%X ()\n{\n",opcode->name,opcode->opcode); + + /* count operands */ + j = 0; + for (i=0;i<6;i++) + { + int flags = d10v_operands[opcode->operands[i]].flags; + if ((flags & OPERAND_REG) || (flags & OPERAND_NUM) || (flags & OPERAND_ADDR)) + j++; + } + switch (j) + { + case 0: + printf ("printf(\" %s\\n\");\n",opcode->name); + break; + case 1: + printf ("printf(\" %s\\t%%x\\n\",OP[0]);\n",opcode->name); + break; + case 2: + printf ("printf(\" %s\\t%%x,%%x\\n\",OP[0],OP[1]);\n",opcode->name); + break; + case 3: + printf ("printf(\" %s\\t%%x,%%x,%%x\\n\",OP[0],OP[1],OP[2]);\n",opcode->name); + break; + default: + fprintf (stderr,"Too many operands: %d\n",j); + } + printf ("}\n\n"); + } + } +} + + +long Opcodes[512]; +static int curop=0; + +check_opcodes( long op) +{ + int i; + + for (i=0;i<curop;i++) + if (Opcodes[i] == op) + fprintf(stderr,"DUPLICATE OPCODES: %x\n",op); +} + + +static void +write_opcodes () +{ + struct d10v_opcode *opcode; + int i, j; + + /* write out opcode table */ + printf ("#include \"d10v_sim.h\"\n"); + printf ("#include \"simops.h\"\n\n"); + printf ("struct simops Simops[] = {\n"); + + for (opcode = (struct d10v_opcode *)d10v_opcodes; opcode->name; opcode++) + { + if (opcode->format != OPCODE_FAKE) + { + printf (" { %ld,%d,%ld,%d,%d,%d,%d,OP_%X,", opcode->opcode, + (opcode->format & LONG_OPCODE) ? 1 : 0, opcode->mask, opcode->format, + opcode->cycles, opcode->unit, opcode->exec_type, opcode->opcode); + + /* REMOVE ME */ + check_opcodes (opcode->opcode); + Opcodes[curop++] = opcode->opcode; + + j = 0; + for (i=0;i<6;i++) + { + int flags = d10v_operands[opcode->operands[i]].flags; + if ((flags & OPERAND_REG) || (flags & OPERAND_NUM) || (flags & OPERAND_ADDR)) + j++; + } + printf ("%d,{",j); + + j = 0; + for (i=0;i<6;i++) + { + int flags = d10v_operands[opcode->operands[i]].flags; + int shift = d10v_operands[opcode->operands[i]].shift; + if ((flags & OPERAND_REG) || (flags & OPERAND_NUM)|| (flags & OPERAND_ADDR)) + { + if (j) + printf (", "); + if ((flags & OPERAND_REG) && (opcode->format == LONG_L)) + shift += 15; + printf ("%d,%d,%d",shift,d10v_operands[opcode->operands[i]].bits,flags); + j = 1; + } + } + printf ("}},\n"); + } + } + printf ("{ 0,0,0,0,0,0,NULL,0,{ }},\n};\n"); +} |