Allow gencode.c to generate input to the igen generator.

This commit is contained in:
Andrew Cagney 1997-09-25 04:23:24 +00:00
parent eb2e3c85ca
commit e63bc706fe
2 changed files with 489 additions and 201 deletions

View file

@ -1,3 +1,16 @@
Thu Sep 25 11:15:22 1997 Andrew Cagney <cagney@b1.cygnus.com>
* Makefile.in (tmp.igen): Add target. Generate igen input from
gencode file.
* gencode.c (FEATURE_IGEN): Define.
(main): Add --igen option. Generate output in igen format.
(process_instructions): Format output according to igen option.
(print_igen_insn_format): New function.
(print_igen_insn_models): New function.
(process_instructions): Only issue warnings and ignore
instructions when no FEATURE_IGEN.
Wed Sep 24 17:38:57 1997 Andrew Cagney <cagney@b1.cygnus.com>
* interp.c (COP_SD, COP_LD): Add UNUSED to pacify GCC for some

View file

@ -116,6 +116,7 @@
#define FEATURE_WARN_MEM (1 << 27) /* 0 = nothing; 1 = generate warnings when memory problems are noticed */
#define FEATURE_WARN_R31 (1 << 28) /* 0 = nothing; 1 = generate warnings if r31 used dangerously */
#define FEATURE_WARN_RESULT (1 << 29) /* 0 = nothing; 1 = generate warnings when undefined results may occur */
#define FEATURE_IGEN (1 << 20) /* 0 = nothing; 1 = generate igen formatted output file */
/* We used to enable FEATURE_WARN_ZERO, but it is perfectly legitimate to
have the zero register as a destination -- the zero register just doesn't
@ -375,7 +376,9 @@ typedef enum {
#define DOUBLEWORD (3) /* 64bit */
#define SINGLE (4) /* single precision FP */
#define DOUBLE (5) /* double precision FP */
/* start-sanitize-r5900 */
#define QUADWORD (6) /* 128bit */
/* end-sanitize-r5900 */
/* Shorthand to get the size field from the flags value: */
#define GETDATASIZEINSN(i) (((i)->flags >> SIM_SH_SIZE) & SIM_MASK_SIZE)
@ -965,6 +968,168 @@ static const struct instruction MIPS16_DECODE[] = {
{"XOR", 1, "11101wwwyyy01110", RR, XOR, NONE }
};
/*---------------------------------------------------------------------------*/
static void print_igen_insn_format PARAMS ((const char *bitmap,
inst_type mark,
int data_size,
const char *options,
const char *name));
static void
print_igen_insn_format (bitmap, mark, data_size, options, name)
const char *bitmap;
inst_type mark;
int data_size;
const char *options;
const char *name;
{
const char *chp;
char lch = *bitmap;
for (chp = bitmap; *chp != '\0'; chp++)
{
if ((isdigit (lch) && !isdigit (*chp))
|| (!isdigit (lch) && isdigit (*chp))
|| (!isdigit (lch) && !isdigit (*chp) && lch != *chp))
{
lch = *chp;
printf (",");
}
switch (*chp)
{
case '?':
printf ("*");
break;
case '<':
printf ("s"); /* good guess */
break;
default:
printf ("%c", *chp);
break;
}
}
printf (":");
switch (mark)
{
case NORMAL:
printf ("NORMAL");
break;
case SPECIAL:
printf ("SPECIAL");
break;
case REGIMM:
printf ("REGIMM");
break;
case COP1:
printf ("COP1");
break;
case COP1X:
printf ("COP1X");
break;
case COP1S: /* These instructions live in the reserved FP format values: 0..15,18-19,22-31 */
printf ("COP1S");
break;
case MMINORM:
printf ("MMINORM");
break;
case MMI0:
printf ("MMI0");
break;
case MMI1:
printf ("MMI1");
break;
case MMI2:
printf ("MMI2");
break;
case MMI3:
printf ("MMI3");
break;
/* mips16 encoding types. */
case I:
printf ("I");
break;
case RI:
printf ("RI");
break;
case RR:
printf ("RR");
break;
case RRI:
printf ("RRI");
break;
case RRR:
printf ("RRR");
break;
case RRI_A:
printf ("RRI_A");
break;
case ISHIFT:
printf ("ISHIFT");
break;
case I8:
printf ("I8");
break;
case I8_MOVR32:
printf ("I8_MOVR32");
break;
case I8_MOV32R:
printf ("I8_MOV32R");
break;
case I64:
printf ("I64");
break;
case RI64:
printf ("RI64");
break;
}
printf (":");
switch (data_size)
{
case DOUBLEWORD:
printf ("64");
break;
/* start-sanitize-r5900 */
case QUADWORD:
printf ("128");
break;
/* end-sanitize-r5900 */
default:
printf ("32");
}
printf (":%s:%s\n", options, name);
}
static void print_igen_insn_models PARAMS ((unsigned int isa));
static void
print_igen_insn_models (isa)
unsigned int isa;
{
/* common mips ISAs */
switch ((isa & MASK_ISA))
{
case 1:
printf ("*mipsI:\n");
case 2:
printf ("*mipsII:\n");
case 3:
printf ("*mipsIII:\n");
}
/* processor specific ISAs */
if ((isa & ARCH_VR4100))
printf ("*vr4100:\n");
/* start-sanitize-r5900 */
if ((isa & ARCH_R5900))
printf ("*r5900:\n");
/* end-sanitize-r5900 */
if ((isa & ARCH_R3900))
printf ("*r3900:\n");
}
/*---------------------------------------------------------------------------*/
static int bitmap_val PARAMS ((const char *, int, int));
static void build_mips16_operands PARAMS ((const char *));
static void build_instruction
@ -988,9 +1153,11 @@ name_for_data_len( insn )
else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
return "DOUBLEWORD";
/* start-sanitize-r5900 */
else if (GETDATASIZEINSN(insn) == QUADWORD)
return "QUADWORD";
/* end-sanitize-r5900 */
else
return 0;
}
@ -1011,9 +1178,11 @@ letter_for_data_len( insn )
else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
return "D";
/* start-sanitize-r5900 */
else if (GETDATASIZEINSN(insn) == QUADWORD)
return "Q";
/* end-sanitize-r5900 */
else
return 0;
}
@ -1035,9 +1204,11 @@ type_for_data_len( insn , is_signed )
else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
return 0;
/* start-sanitize-r5900 */
else if (GETDATASIZEINSN(insn) == QUADWORD)
return 0;
/* end-sanitize-r5900 */
else
return 0;
}
@ -1058,9 +1229,11 @@ max_for_data_len( insn )
else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
return 0;
/* start-sanitize-r5900 */
else if (GETDATASIZEINSN(insn) == QUADWORD)
return 0;
/* end-sanitize-r5900 */
else
return 0;
}
@ -1081,9 +1254,11 @@ min_for_data_len( insn )
else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
return 0;
/* start-sanitize-r5900 */
else if (GETDATASIZEINSN(insn) == QUADWORD)
return 0;
/* end-sanitize-r5900 */
else
return 0;
}
@ -1104,9 +1279,11 @@ umax_for_data_len( insn )
else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
return 0;
/* start-sanitize-r5900 */
else if (GETDATASIZEINSN(insn) == QUADWORD)
return 0;
/* end-sanitize-r5900 */
else
return 0;
}
@ -1127,9 +1304,11 @@ bits_for_data_len( insn )
else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
return "64";
/* start-sanitize-r5900 */
else if (GETDATASIZEINSN(insn) == QUADWORD)
return "128";
/* end-sanitize-r5900 */
else
return 0;
}
@ -1756,6 +1935,8 @@ process_instructions(doarch,features)
if (doisa == 0)
doisa = maxisa;
if (!(features & FEATURE_IGEN))
{
printf("#if defined(SIM_MANIFESTS)\n");
printf("#define MIPSISA (%d)\n",doisa);
if (proc64)
@ -1874,6 +2055,7 @@ process_instructions(doarch,features)
printf("switch (num)\n") ;
printf("{\n");
}
for (loop = 0; (loop < limit); loop++) {
/* First check if the insn is in a requested isa# independent set,
@ -1885,7 +2067,8 @@ process_instructions(doarch,features)
if (((isa & doarch & MASK_ISA_INDEP)
|| (((isa & MASK_ISA) <= doisa)
&& (((isa & MASK_ISA_DEP) == 0) || ((isa & MASK_ISA_DEP) & doarch) != 0)))
&& (!(MIPS_DECODE[loop].flags & FP) || ((MIPS_DECODE[loop].flags & FP) && dofp))) {
&& (!(MIPS_DECODE[loop].flags & FP) || ((MIPS_DECODE[loop].flags & FP) && dofp))
|| (features & FEATURE_IGEN)) {
unsigned int onemask;
unsigned int zeromask;
unsigned int dontmask;
@ -1895,7 +2078,8 @@ process_instructions(doarch,features)
convert_bitmap(MIPS_DECODE[loop].bitmap,&onemask,&zeromask,&dontmask);
if (!(MIPS_DECODE[loop].flags & COPROC)
&& ((GETDATASIZEINSN(&MIPS_DECODE[loop]) == DOUBLEWORD) && !proc64)) {
&& ((GETDATASIZEINSN(&MIPS_DECODE[loop]) == DOUBLEWORD) && !proc64)
&& !(features & FEATURE_IGEN)) {
fprintf(stderr,"DOUBLEWORD width specified for non 64-bit processor for instruction \"%s\"\n",MIPS_DECODE[loop].name);
exit(4);
}
@ -1986,6 +2170,8 @@ process_instructions(doarch,features)
exit(5) ;
}
if (!(features & FEATURE_IGEN))
{
printf("case %d : /* \"%s\" %s */\n",number,MIPS_DECODE[loop].name,MIPS_DECODE[loop].bitmap) ;
#if defined(DEBUG)
@ -2003,6 +2189,24 @@ process_instructions(doarch,features)
}
printf(" {\n") ;
}
else
{
/* start-sanitize-cygnus-never */
/* If any sanitization occures, this line should be printed */
if ((MIPS_DECODE[loop].isa & ARCH_R5900))
printf ("// %s-%s-%s\n", "start", "sanitize", "r5900");
/* end-sanitize-cygnus-never */
printf ("\n");
print_igen_insn_format (MIPS_DECODE[loop].bitmap,
MIPS_DECODE[loop].mark, /* format-name */
GETDATASIZEINSN (&MIPS_DECODE[loop]), /* filter-flags */
"", /* options */
MIPS_DECODE[loop].name);
print_igen_insn_models (MIPS_DECODE[loop].isa);
printf ("{\n") ;
printf (" unsigned32 instruction = instruction_0;\n");
}
/* Get hold of the operands */
/* NOTE: If we wanted to make the simulator code smaller, we
@ -2022,15 +2226,33 @@ process_instructions(doarch,features)
build_instruction (doisa, features, 0, &MIPS_DECODE[loop]);
printf(" }\n") ;
if (!(features & FEATURE_IGEN))
{
printf(" }\n") ;
printf(" break ;\n") ;
}
else
{
printf ("}\n");
printf ("\n");
/* start-sanitize-cygnus-never */
/* When sanitized, this output should never be produced */
if ((MIPS_DECODE[loop].isa & ARCH_R5900))
printf ("// %s-%s-%s\n", "end", "sanitize", "r5900");
/* end-sanitize-cygnus-never */
}
}
}
if (!(features & FEATURE_IGEN))
{
printf("default : /* Unrecognised instruction */\n") ;
printf(" SignalException(ReservedInstruction,instruction);\n") ;
printf(" break ;\n") ;
printf("}\n}\n") ;
}
/* Handle mips16 instructions. The switch table looks like this:
0 - 31: I, RI, and RRI instructions by major.
@ -2042,6 +2264,8 @@ process_instructions(doarch,features)
82 - 89: I64 and RI64 instructions by funct + 82
90 - 97: jalr (RR minor 0) by y + 90
*/
if (!(features & FEATURE_IGEN))
{
printf ("else {\n");
printf ("static int extendval;\n");
printf ("static int have_extendval;\n");
@ -2058,6 +2282,7 @@ process_instructions(doarch,features)
printf ("case 0x1f: num = 82 + ((instruction & 0x700) >> 8); break;\n");
printf ("default: break;\n}\n");
printf ("switch (num)\n{\n");
}
for (loop = 0; loop < sizeof MIPS16_DECODE / sizeof MIPS16_DECODE[0]; loop++)
{
@ -2108,10 +2333,25 @@ process_instructions(doarch,features)
abort ();
}
if (!(features & FEATURE_IGEN))
{
printf ("case %d: /* \"%s\" %s */\n", num, MIPS16_DECODE[loop].name,
bitmap);
printf (" {\n");
}
else
{
printf ("\n");
print_igen_insn_format (bitmap,
MIPS16_DECODE[loop].mark, /* format-name */
GETDATASIZEINSN (&MIPS16_DECODE[loop]), /* filter-flags */
"", /* options */
MIPS16_DECODE[loop].name);
printf ("*mips16:\n");
printf ("{\n");
printf (" unsigned32 instruction = instruction_0;\n");
}
build_mips16_operands (bitmap);
@ -2127,16 +2367,27 @@ process_instructions(doarch,features)
}
printf (" }\n");
if (!(features & FEATURE_IGEN))
{
printf (" }\n") ;
printf (" break ;\n") ;
}
else
{
printf ("}\n");
printf ("\n");
}
}
if (!(features & FEATURE_IGEN))
{
printf ("default : /* Unrecognised instruction */\n") ;
printf (" SignalException(ReservedInstruction,instruction);\n") ;
printf (" break ;\n") ;
printf ("}\n}\n") ;
printf("#endif /* simulator engine */\n");
}
return ;
}
@ -2643,11 +2894,13 @@ build_instruction (doisa, features, mips16, insn)
datalen = 8;
accesslength = "AccessLength_DOUBLEWORD";
break ;
/* start-sanitize-r5900 */
case QUADWORD :
datalen = 16;
accesslength = "AccessLength_QUADWORD";
break ;
/* end-sanitize-r5900 */
}
if (insn->flags & REG)
@ -2687,10 +2940,13 @@ build_instruction (doisa, features, mips16, insn)
switch (datalen) {
case 8:
if (!(features & FEATURE_IGEN))
{
if (!proc64) {
fprintf(stderr,"DOUBLEWORD shifted memory transfers only valid for 64-bit processors \"%s\"\n",insn->name);
exit(4);
}
}
/* fall through to... */
case 4:
{
@ -2786,6 +3042,8 @@ build_instruction (doisa, features, mips16, insn)
exit(6);
}
} else { /* normal memory transfer */
if (!(features & FEATURE_IGEN))
{
if (!(insn->flags & COPROC) && ((datalen == 8) || ((datalen == 4) & (insn->flags & UNSIGNED))) && !proc64) {
fprintf(stderr,"Operation not available with 32bit wide memory access \"%s\"\n",insn->name);
exit(4);
@ -2795,6 +3053,7 @@ build_instruction (doisa, features, mips16, insn)
will mean adding a run-time check into the code
sequence. */
}
}
if (isload) {
#if 1 /* see the comments attached to LOADDRMASK above */
@ -2808,14 +3067,22 @@ build_instruction (doisa, features, mips16, insn)
printf(" unsigned int byte UNUSED;\n");
/* TODO: This should really also check for 32bit world performing 32bit access */
if (datalen < 8) /* not for DOUBLEWORD or QUADWORD*/
if (datalen < 8)
/* not for DOUBLEWORD */
/* start-sanitize-r5900 */
/* not for QUADWORD */
/* end-sanitize-r5900 */
printf(" paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));\n");
printf(" LoadMemory(&memval,&memval1,uncached,%s,paddr,vaddr,isDATA,isREAL);\n",accesslength);
/* The following will only make sense if the
"LoadMemory" above returns a DOUBLEWORD entity */
if (datalen < 8) { /* not for DOUBLEWORD or QUADWORD*/
if (datalen < 8) {
/* not for DOUBLEWORD */
/* start-sanitize-r5900 */
/* not for QUADWORD */
/* end-sanitize-r5900 */
int valmask;
switch (datalen) {
case 1:
@ -2905,10 +3172,13 @@ build_instruction (doisa, features, mips16, insn)
else
printf(" memval = ((uword64) op2 << (8 * byte));\n");
} else if (datalen <= 8) { /* SD and SCD */
if (! (features & FEATURE_IGEN))
{
if (!(insn->flags & COPROC) && ((datalen == 8) || ((datalen == 4) & (insn->flags & UNSIGNED))) && !proc64) {
fprintf(stderr,"Operation not available with 32bit wide memory access \"%s\"\n",insn->name);
exit(4);
}
}
if (insn->flags & COPROC)
printf(" memval = (uword64)COP_SD(%s,%s);\n",
((insn->flags & REG)
@ -4226,6 +4496,7 @@ main(argc,argv)
{"fast", 0,0,'f'},
{"help", 0,0,'h'},
{"warnings",0,0,'w'},
{"igen", 0,0,'i'},
{0, 0,0,0}
};
@ -4242,6 +4513,10 @@ main(argc,argv)
features |= FEATURE_FAST;
break;
case 'i' : /* igen formatted output */
features |= FEATURE_IGEN;
break;
case 'w' : /* warnings */
features |= FEATURE_WARNINGS;
/* TODO: Future extension: Allow better control over the warnings generated: