mirror of
https://github.com/ctm/syn68k.git
synced 2024-11-25 07:32:17 +00:00
148 lines
3.7 KiB
C
148 lines
3.7 KiB
C
#include "bucket.h"
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <ctype.h>
|
|
#include "amode.h"
|
|
|
|
#if 0
|
|
#define IS_MOVE(n, x) (((n) & 0xC000) == 0 && (((n) & 0x3000) != 0) \
|
|
&& !strncmp ((x), "move", 4))
|
|
#endif
|
|
|
|
|
|
int
|
|
main (int argc, char *argv[])
|
|
{
|
|
int num_buckets;
|
|
static unsigned short bucket_map[65536];
|
|
static Bucket bucket[65536];
|
|
static struct {
|
|
unsigned char has_amode, has_reversed_amode;
|
|
const char *name;
|
|
} amode_info[65536];
|
|
int num_amode_infos = 0;
|
|
int pass;
|
|
int i;
|
|
|
|
if (argc != 2)
|
|
{
|
|
fprintf (stderr, "Usage: %s <file>", argv[0]);
|
|
exit (-1);
|
|
}
|
|
|
|
num_buckets = 1;
|
|
bucket[0].name = "unmapped_spew";
|
|
|
|
for (pass = 2; pass >= 0; pass--)
|
|
{
|
|
FILE *fp;
|
|
char cmd[1024];
|
|
|
|
sprintf (cmd, "zcat %s", argv[1]);
|
|
fp = popen (cmd, "r");
|
|
assert (fp != NULL);
|
|
|
|
while (!feof (fp))
|
|
{
|
|
int opcode, has_amode, has_reversed_amode, litmask, litbits;
|
|
char name[1024]; /* Fixed length arrays usually bad, but not here. */
|
|
|
|
if (fscanf (fp, " %d %d %d %d %d %s", &opcode, &has_amode,
|
|
&has_reversed_amode, &litmask, &litbits, name) != 6)
|
|
break;
|
|
|
|
/* Make sure we have the right # of amodes for this pass. */
|
|
if (has_amode + has_reversed_amode != pass)
|
|
continue;
|
|
|
|
/* See if anything else with the same root name exists, and if it
|
|
* does, assume we have at least as many addressing modes as that
|
|
* guy. Why? Well, the syngen process loses info about the
|
|
* existence of amodes/reverse amodes in favor of rewriting the
|
|
* 68k.scm code you give it to special case amodes like registers.
|
|
* This hack will try to determine if there were originally amodes
|
|
* in this opcode.
|
|
*/
|
|
for (i = num_amode_infos - 1; i >= 0; i--)
|
|
if (!strcmp (amode_info[i].name, name))
|
|
{
|
|
has_amode |= amode_info[i].has_amode;
|
|
has_reversed_amode |= amode_info[i].has_reversed_amode;
|
|
break;
|
|
}
|
|
|
|
/* If we didn't find a match, add a new entry to the table and
|
|
* remember what amodes it has.
|
|
*/
|
|
if (i < 0)
|
|
{
|
|
amode_info[num_amode_infos].has_amode = has_amode;
|
|
amode_info[num_amode_infos].has_reversed_amode
|
|
= has_reversed_amode;
|
|
amode_info[num_amode_infos].name
|
|
= strcpy (malloc (strlen (name) + 1), name);
|
|
num_amode_infos++;
|
|
}
|
|
|
|
/* Generate the canonical name. */
|
|
if (has_amode)
|
|
sprintf (name + strlen (name), " %s",
|
|
amode_to_string (opcode & 0x3F));
|
|
if (has_reversed_amode)
|
|
sprintf (name + strlen (name), ", %s",
|
|
amode_to_string (((opcode >> 9) & 7)
|
|
| ((opcode >> 3) & 0x38)));
|
|
|
|
/* Look for a bucket with the same canonical name.
|
|
* Isn't O(n^2) great?
|
|
*/
|
|
for (i = num_buckets - 1; i >= 0; i--)
|
|
if (!strcmp (bucket[i].name, name)
|
|
&& bucket[i].litmask == litmask
|
|
&& bucket[i].litbits == litbits)
|
|
{
|
|
bucket_map[opcode] = i;
|
|
break;
|
|
}
|
|
|
|
/* Did we fail to find a matching bucket? If so, make a new one. */
|
|
if (i < 0)
|
|
{
|
|
Bucket *b = &bucket[num_buckets++];
|
|
b->name = strcpy (malloc (strlen (name) + 1), name);
|
|
b->litbits = litbits;
|
|
b->litmask = litmask;
|
|
b->count = 0;
|
|
bucket_map[opcode] = b - bucket;
|
|
}
|
|
}
|
|
pclose (fp);
|
|
}
|
|
|
|
printf ("#include \"bucket.h\"\n"
|
|
"\n"
|
|
"Bucket bucket[%d] = {\n",
|
|
num_buckets);
|
|
for (i = 0; i < num_buckets; i++)
|
|
printf (" { \"%s\", 0 },\n", bucket[i].name);
|
|
puts ("};\n"
|
|
"\n"
|
|
"const unsigned short bucket_map[65536] = {");
|
|
|
|
for (i = 0; i < 65536; i++)
|
|
{
|
|
if (i % 8 == 0)
|
|
fputs ("\n ", stdout);
|
|
printf (" 0x%04X,", (unsigned) bucket_map[i]);
|
|
}
|
|
|
|
printf ("\n"
|
|
"};\n"
|
|
"const int num_buckets = %d;\n",
|
|
num_buckets);
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|