--- /dev/null
+#include <stdlib.h>
+#include <stdbool.h>
+#include <strings.h>
+#include <assert.h>
+#include "bitmap.h"
+
+unsigned int* bitmap_alloc(int size)
+{
+ return calloc(WORDS_FOR_BITMAP_SIZE(size), sizeof(unsigned int));
+}
+
+void bitmap_set(unsigned int* bitmap, int size, int bit)
+{
+ int word = bit / BITS_PER_WORD;
+ bit = bit & (BITS_PER_WORD - 1);
+
+ assert((bit >= 0) && (bit < size));
+ bitmap[word] |= 1<<bit;
+}
+
+bool bitmap_get(unsigned int* bitmap, int size, int bit)
+{
+ int word = bit / BITS_PER_WORD;
+ bit = bit & (BITS_PER_WORD - 1);
+
+ assert((bit >= 0) && (bit < size));
+ return bitmap[word] & (1<<bit);
+}
+
+int bitmap_findfirst(unsigned int* bitmap, int size)
+{
+ int word;
+
+ for (word=0; word<WORDS_FOR_BITMAP_SIZE(size); word++)
+ {
+ unsigned int w = bitmap[word];
+ if (w)
+ return ffs(w) + word*BITS_PER_WORD;
+ }
+
+ return -1;
+}
+
+void bitmap_and(unsigned int* dest, int size, unsigned int* src)
+{
+ int word;
+ int words = ((size-1) / BITS_PER_WORD) + 1;
+
+ for (word=0; word<words; word++)
+ dest[word] &= src[word];
+}
+
+void bitmap_or(unsigned int* dest, int size, unsigned int* src)
+{
+ int word;
+ int words = ((size-1) / BITS_PER_WORD) + 1;
+
+ for (word=0; word<words; word++)
+ dest[word] |= src[word];
+}
+
--- /dev/null
+#ifndef BITMAP_H
+#define BITMAP_H
+
+extern unsigned int* bitmap_alloc(int size);
+
+extern void bitmap_set(unsigned int* bitmap, int size, int bit);
+extern bool bitmap_get(unsigned int* bitmap, int size, int bit);
+extern int bitmap_findfirst(unsigned int* bitmap, int size);
+extern void bitmap_and(unsigned int* dest, int size, unsigned int* src);
+extern void bitmap_or(unsigned int* dest, int size, unsigned int* src);
+
+#define BITS_PER_WORD (sizeof(unsigned int)*8)
+#define WORDS_FOR_BITMAP_SIZE(n) (((n-1) / BITS_PER_WORD) + 1)
+
+#endif
+
hdrs = {
matching(filenamesof("+ircodes"), "%.h$"),
"./ircodes.h",
- "./mcgg.h"
+ "./mcgg.h",
+ "./mcgg_common.h",
},
}
#include "ircodes.h"
#include "astring.h"
#include "smap.h"
-#include "mcgg.h"
#include "registers.h"
static char rcsid[] = "$Id$";
yyin = infp;
yyparse();
+ analyse_registers();
emitregisterattrs();
emitregisters();
emitdefs(nts, ntnumber);
#include "em_arith.h"
#include "stringlist.h"
#include "array.h"
+#include "mcgg_common.h"
extern char* stringf(char* fmt, ...);
extern void printh(const char* fmt, ...);
extern void printlineno(void);
-#include "mcgg.h"
-
#endif
#ifndef MCGG_H
#define MCGG_H
-/* Excruciating macro which packs ir opcodes and sizes into an int for iburg's benefit.
- *
- * Types are mapped to: I=1, F=2, L=3, D=4
- */
-#define ir_to_esn(iropcode, type) \
- ((iropcode)*5 + \
- (((type) == 'I') ? 1 : \
- ((type) == 'F') ? 2 : \
- ((type) == 'L') ? 3 : \
- ((type) == 'D') ? 4 : 0))
+#include "mcgg_common.h"
#define STATE_TYPE void*
extern NODEPTR_TYPE* burm_kids(NODEPTR_TYPE p, int eruleno, NODEPTR_TYPE kids[]);
extern void burm_trace(NODEPTR_TYPE p, int ruleno, int cost, int bestcost);
-extern void yyerror(char *fmt, ...);
-
struct burm_emitter_data
{
void (*emit_string)(const char* data);
uint32_t attrs;
const char** names;
const struct burm_register_data** aliases;
+ burm_register_bitmap_t bitmap;
};
extern const struct burm_register_data burm_register_data[];
extern const char* burm_register_class_names[];
-enum
-{
- NONTERM_STMT = 1
-};
-
#endif
/* vim: set sw=4 ts=4 expandtab : */
--- /dev/null
+#ifndef MCGG_COMMON_H
+#define MCGG_COMMON_H
+
+/* Excruciating macro which packs ir opcodes and sizes into an int for iburg's benefit.
+ *
+ * Types are mapped to: I=1, F=2, L=3, D=4
+ */
+#define ir_to_esn(iropcode, type) \
+ ((iropcode)*5 + \
+ (((type) == 'I') ? 1 : \
+ ((type) == 'F') ? 2 : \
+ ((type) == 'L') ? 3 : \
+ ((type) == 'D') ? 4 : 0))
+
+enum
+{
+ NONTERM_STMT = 1
+};
+
+#endif
+
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
-#include "mcgg.h"
#include "registers.h"
#include "smap.h"
#include "array.h"
#include "iburg.h"
#include "registers.h"
#include "hashtable.h"
+#include "bitmap.h"
static struct hashtable registers = HASHTABLE_OF_STRINGS;
static struct hashtable registerattrs = HASHTABLE_OF_STRINGS;
+static struct reg** real_registers;
+static int real_register_count;
+
+static struct reg** fake_registers;
+static int fake_register_count;
+
struct reg* makereg(const char* id)
{
struct reg* p = hashtable_get(®isters, (void*)id);
p = calloc(1, sizeof(*p));
p->name = id;
p->number = number++;
- array_append(&p->aliases, p);
hashtable_put(®isters, (void*)id, p);
return p;
struct reg* r = hashtable_get(®isters, (void*)f->data);
if (!r)
yyerror("register '%s' is not defined here", f->data);
+ if (r->aliases.count > 0)
+ yyerror("can't alias '%s' to '%s' because the latter isn't a true hardware register",
+ reg->name, r->name);
array_appendu(®->aliases, r);
- array_appendu(&r->aliases, reg);
f = f->next;
}
return p;
}
+void analyse_registers(void)
+{
+ struct reg* regs[registers.size];
+ struct hashtable_iterator hit = {};
+ int i, j;
+
+ while (hashtable_next(®isters, &hit))
+ {
+ struct reg* r = hit.value;
+ assert((r->number >= 0) && (r->number < registers.size));
+ regs[r->number] = r;
+ }
+
+ real_registers = calloc(registers.size, sizeof(struct reg*));
+ fake_registers = calloc(registers.size, sizeof(struct reg*));
+ real_register_count = 0;
+ fake_register_count = 0;
+
+ for (i=0; i<registers.size; i++)
+ {
+ struct reg* r = regs[i];
+ if (r->aliases.count > 0)
+ fake_registers[fake_register_count++] = r;
+ else
+ real_registers[real_register_count++] = r;
+ }
+
+ for (i=0; i<real_register_count; i++)
+ {
+ struct reg* r = real_registers[i];
+ r->bitmap = bitmap_alloc(real_register_count);
+ bitmap_set(r->bitmap, real_register_count, i);
+ }
+
+ for (i=0; i<fake_register_count; i++)
+ {
+ struct reg* r = fake_registers[i];
+ r->bitmap = bitmap_alloc(real_register_count);
+
+ for (j=0; j<r->aliases.count; j++)
+ {
+ struct reg* alias = r->aliases.item[j];
+ bitmap_or(r->bitmap, real_register_count, alias->bitmap);
+ }
+ }
+
+ printh("typedef unsigned int %Pregister_bitmap_t[%d];\n",
+ WORDS_FOR_BITMAP_SIZE(real_register_count));
+}
+
void emitregisterattrs(void)
{
int i;
assert(r->number == i);
- print("%1{ \"%s\", 0x%x, %Pregister_names_%d_%s, %Pregister_aliases_%d_%s },\n",
+ print("%1{\n%2\"%s\", 0x%x, %Pregister_names_%d_%s, %Pregister_aliases_%d_%s,\n",
r->name, r->attrs, i, r->name, i, r->name);
+ print("%2{ ");
+ for (j=0; j<WORDS_FOR_BITMAP_SIZE(real_register_count); j++)
+ {
+ print("0x%x, ", r->bitmap[j]);
+ }
+ print("},\n");
+ print("%1},\n");
}
print("%1{ NULL }\n");
int number; /* identifying number */
uint32_t attrs; /* bitfield of register attributes */
struct stringlist* names; /* register names */
+ unsigned int* bitmap; /* hardware register bitmap */
ARRAYOF(struct reg) aliases; /* registers that this one aliases */
};
extern void addregaliases(struct reg* reg, struct stringlist* aliases);
extern struct regattr* getregattr(const char* name);
+extern void analyse_registers(void);
+
extern void emitregisterattrs(void);
extern void emitregisters(void);