[RFA] sh-sim: free up some room in jump_table

Michael Snyder
2004-02-07T00:29:09Z

[-- Attachment #1: Type: text/plain, Size: 914 bytes --]

Joern,

This is an advance hint that I am working on the next generation LSI
from Renesas. Apparently at this stage I am allowed to mention its
name (sh2a), but nothing more. ;-/

The first thing I need to do is free up some room for new insns.
The jump table is just about full (it can only hold 255 entries).
This patch splits the dsp instructions (the contents of movsxy_tab)
into their own jump table. As a side benefit, it's no longer
necessary to swap them in and out of the main jump table at
runtime. This gives us room to add lots of new instructions.
It passes all my regression tests (and I have some that I haven't
submitted yet).

Earlier today, you mentioned your concern about runtime efficiency.
I haven't done any performance testing, but since this makes the
main switch statement smaller, I imagine it might have some benefit
(similar to ifdeffing out the contents of movsxy_tab).

Michael

[-- Attachment #2: tables --]
[-- Type: text/plain, Size: 5627 bytes --]

2004-02-06 Michael Snyder <msnyder@redhat.com>

* gencode.c: Split sh_dsp_table out of jump_table,
to allow room for more new instructions.
(filltable): Let index be initialized to one at each call.
(gensim_caselist): Finish the switch statement at each call.
(gensim): Let sim_resume use two separate jump tables:
one for dsp instructions, and one for everything else.
(main): Zero out the table between calls to filltable.
(op tab): Use SET_NIP consistantly.

* interp.c (init_dsp): It is no longer necessary to swap
sh_dsp_table in and out of sh_jump_table.

Index: gencode.c
===================================================================
RCS file: /cvs/src/src/sim/sh/gencode.c,v
retrieving revision 1.26
diff -p -r1.26 gencode.c
*** gencode.c 27 Jan 2004 23:30:01 -0000 1.26
--- gencode.c 7 Feb 2004 00:06:41 -0000
*************** op tab[] =
*** 1102,1108 ****
},

{ "", "", "sleep", "0000000000011011",
! "nip += trap (0xc3, &R0, PC, memory, maskl, maskw, endianw);",
},

{ "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
--- 1102,1108 ----
},

{ "", "", "sleep", "0000000000011011",
! "SET_NIP (nip + trap (0xc3, &R0, PC, memory, maskl, maskw, endianw));",
},

{ "n", "", "stc <CREG_M>,<REG_N>", "0000nnnnmmmm0010",
*************** op tab[] =
*** 1192,1199 ****

{ "0", "", "trapa #<imm>", "11000011i8*1....",
"long imm = 0xff & i;",
! "if (i < 20 || i == 33 || i == 34 || i == 0xc3)",
! " nip += trap (i, &R0, PC, memory, maskl, maskw, endianw);",
#if 0
"else {",
/* SH-[12] */
--- 1192,1200 ----

{ "0", "", "trapa #<imm>", "11000011i8*1....",
"long imm = 0xff & i;",
! "if (i < 20 || i == 33 || i == 34 || i == 0xc3) {",
! " SET_NIP (nip + trap (i, &R0, PC, memory, maskl, maskw, endianw));",
! "}",
#if 0
"else {",
/* SH-[12] */
*************** op movsxy_tab[] =
*** 1516,1522 ****
},
{ "", "", "ppi", "1111100000000000",
"ppi_insn (RIAT (nip));",
! "nip += 2;",
"iword &= 0xf7ff; goto top;",
},
#endif
--- 1517,1523 ----
},
{ "", "", "ppi", "1111100000000000",
"ppi_insn (RIAT (nip));",
! "SET_NIP (nip + 2);",
"iword &= 0xf7ff; goto top;",
},
#endif
*************** static void
*** 2438,2444 ****
filltable (p)
op *p;
{
! static int index = 1;

sorttab ();
for (; p->name; p++)
--- 2439,2445 ----
filltable (p)
op *p;
{
! int index = 1;

sorttab ();
for (; p->name; p++)
*************** gensim_caselist (p)
*** 2669,2683 ****
char *r;
for (r = p->defs; *r; r++)
{
! if (*r == '0') printf(" CDEF (0);\n");
! if (*r == 'n') printf(" CDEF (n);\n");
! if (*r == 'm') printf(" CDEF (m);\n");
}
}

printf (" break;\n");
printf (" }\n");
}
}

static void
--- 2670,2689 ----
char *r;
for (r = p->defs; *r; r++)
{
! if (*r == '0') printf (" CDEF (0);\n");
! if (*r == 'n') printf (" CDEF (n);\n");
! if (*r == 'm') printf (" CDEF (m);\n");
}
}

printf (" break;\n");
printf (" }\n");
}
+ printf (" default:\n");
+ printf (" {\n");
+ printf (" RAISE_EXCEPTION (SIGILL);\n");
+ printf (" }\n");
+ printf (" }\n");
}

static void
*************** gensim ()
*** 2696,2711 ****
printf ("#define DSP_xy(R) ((R)==0 ? 8 : (R)==2 ? 9 : (R)==1 ? 10 : 11)\n");
printf ("/* DSP_yx = [y0, y1, x0, x1]. */\n");
printf ("#define DSP_yx(R) ((R)==0 ? 10 : (R)==1 ? 11 : (R)==2 ? 8 : 9)\n");
! printf (" switch (jump_table[iword]) {\n");
!
! gensim_caselist (tab);
gensim_caselist (movsxy_tab);
!
! printf (" default:\n");
! printf (" {\n");
! printf (" RAISE_EXCEPTION (SIGILL);\n");
! printf (" }\n");
! printf (" }\n");
printf ("}\n");
}

--- 2702,2713 ----
printf ("#define DSP_xy(R) ((R)==0 ? 8 : (R)==2 ? 9 : (R)==1 ? 10 : 11)\n");
printf ("/* DSP_yx = [y0, y1, x0, x1]. */\n");
printf ("#define DSP_yx(R) ((R)==0 ? 10 : (R)==1 ? 11 : (R)==2 ? 8 : 9)\n");
! printf (" if (target_dsp && \n");
! printf (" (iword & 0xf000) == 0xf000)\n");
! printf (" switch (sh_dsp_table[iword & 0xfff]) {\n");
gensim_caselist (movsxy_tab);
! printf (" else switch (jump_table[iword]) {\n");
! gensim_caselist (tab);
printf ("}\n");
}

*************** main (ac, av)
*** 3017,3022 ****
--- 3019,3025 ----
else if (strcmp (av[1], "-x") == 0)
{
filltable (tab);
+ memset (table, 0, sizeof table);
filltable (movsxy_tab);
gensim ();
}
Index: interp.c
===================================================================
RCS file: /cvs/src/src/sim/sh/interp.c,v
retrieving revision 1.14
diff -p -r1.14 interp.c
*** interp.c 10 Jan 2004 00:43:28 -0000 1.14
--- interp.c 7 Feb 2004 00:06:41 -0000
*************** static void
*** 1571,1577 ****
init_dsp (abfd)
struct bfd *abfd;
{
- int was_dsp = target_dsp;
unsigned long mach = bfd_get_mach (abfd);

if (mach == bfd_mach_sh_dsp ||
--- 1571,1576 ----
*************** init_dsp (abfd)
*** 1640,1657 ****
{
saved_state.asregs.xram_start = 1;
saved_state.asregs.yram_start = 1;
- }
-
- if (target_dsp != was_dsp)
- {
- int i, tmp;
-
- for (i = sizeof sh_dsp_table - 1; i >= 0; i--)
- {
- tmp = sh_jump_table[0xf000 + i];
- sh_jump_table[0xf000 + i] = sh_dsp_table[i];
- sh_dsp_table[i] = tmp;
- }
}
}

--- 1639,1644 ----