void appendvreg(struct vreg* vreg)
{
- appendf("($%d:%d=%%%d", vreg->value->ir->id, vreg->value->subid, vreg->id);
+ appendf("($%d:%d=%%%d:%s",
+ vreg->value->ir->id, vreg->value->subid, vreg->id,
+ vreg->regclass ? vreg->regclass->name : "?");
if (vreg->hreg != -1)
appendf("=R%d", vreg->hreg);
if (vreg->is_spilt)
if (usage->corrupted)
appendf("!");
appendf("$%d:%d", value->ir->id, value->subid);
+ if (value->regclass != UNASSIGNED_REGCLASS)
+ appendf(",%d", value->regclass);
}
}
}
{
struct ir* ir = calloc(1, sizeof(struct ir));
ir->value.ir = ir;
+ ir->value.regclass = UNASSIGNED_REGCLASS;
ir->id = next_id++;
ir->opcode = opcode;
ir->size = size;
#include "ircodes.h"
+#define UNASSIGNED_REGCLASS (-1)
+
struct value
{
struct ir* ir;
static void setup_regclass(struct vreg* vreg, struct value* value)
{
- const struct burm_regclass_data* regclass = &burm_regclass_data[value->regclass];
- assert(!vreg->regclass || (vreg->regclass == regclass));
-
- if (!vreg->regclass)
+ const struct burm_regclass_data* regclass =
+ (value->regclass == UNASSIGNED_REGCLASS)
+ ? NULL
+ : &burm_regclass_data[value->regclass];
+ assert(!vreg->regclass || !regclass || (vreg->regclass == regclass));
+
+ tracef('V', "V: %%%d has class %s; value $%d has class %s\n",
+ vreg->id,
+ vreg->regclass ? vreg->regclass->name : "?",
+ value->ir->id,
+ regclass ? regclass->name : "?");
+
+ if (!vreg->regclass && regclass)
{
+ tracef('V', "V: assigning register class %s to %%%d from $%d\n",
+ regclass->name, vreg->id, value->ir->id);
memcpy(vreg->registers, regclass->bitmap, sizeof(burm_register_bitmap_t));
vreg->regclass = regclass;
}
int i;
insn->value.ir = current_ir;
+ insn->value.regclass = UNASSIGNED_REGCLASS;
/* hop IDs count in preorder, so the result is always in $thing:0. */
insn->value.subid = hop_id++;
new_wordir(delta)
);
ir->left->root = ir->left->left->root = ir->left->right->root = ir->root;
+ ir->left->bb = ir->left->left->bb = ir->left->right->bb = current_bb;
ir->right = value_ir;
delta += ir->size;
ir = new_ir1(IR_STACKADJUST, EM_pointersize, new_wordir(-delta));
ir->left->root = ir->root = ir;
+ ir->left->bb = ir->bb = current_bb;
array_insert(¤t_bb->irs, ir, runstart);
cursor++;
}
static struct graph affinity;
static ARRAYOF(struct vreg) simplified;
+static void bitmap_trace(void* bitmap, int size)
+{
+ uint8_t* p = bitmap;
+ int bytes = ((size-1) / 8) + 1;
+ int i;
+
+ for (i=0; i<bytes; i++)
+ tracef('R', "%02x ", p[i]);
+}
+
static struct vreg* actual(struct vreg* vreg)
{
if (!vreg)
{
vmaster = actual(vmaster);
vslave = actual(vslave);
+ if (tracing('R'))
+ {
+ if (vmaster->regclass)
+ {
+ tracef('R', "R: master is %10s ", vmaster->regclass->name);
+ bitmap_trace(vmaster->registers, burm_register_count);
+ tracef('R', "\n");
+ }
+ if (vslave->regclass)
+ {
+ tracef('R', "R: slave is %10s ", vslave->regclass->name);
+ bitmap_trace(vslave->registers, burm_register_count);
+ tracef('R', "\n");
+ }
+ }
+
if (vmaster->regclass && vslave->regclass)
{
bitmap_and(vmaster->registers, burm_register_count, vslave->registers);
}
if (hop->is_move && invreg1 && outvreg1)
+ {
+ tracef('R', "R: adding affinity edge between %%%d and %%%d:\n",
+ invreg1->id, outvreg1->id);
+ hop_print('R', hop);
graph_add_edge(&affinity, invreg1, outvreg1);
+ }
}
/* Ensure that registers which are constrained to be in the same hreg for input
{
struct value* value = hit.key;
struct vreg* vreg = hit.value;
- tracef(k, " $%d.%d->%%%d", value->ir->id, value->subid, vreg->id);
+ tracef(k, " $%d.%d->%%%d(%s)",
+ value->ir->id, value->subid, vreg->id,
+ vreg->regclass ? vreg->regclass->name : "?");
}
tracef(k, "\n");
}
{
struct value* value = hit.key;
struct vreg* vreg = hit.value;
- tracef(k, " $%d.%d->%%%d", value->ir->id, value->subid, vreg->id);
+ tracef(k, " $%d.%d->%%%d(%s)",
+ value->ir->id, value->subid, vreg->id,
+ vreg->regclass ? vreg->regclass->name : "?");
}
tracef(k, "\n");
}
materialise_stack();
while (hashtable_next(&jumptable->targets, &hit))
{
- int value = (int) hit.key;
+ int value = (int)(intptr_t) hit.key;
struct basicblock* target = hit.value;
struct basicblock* nextblock = bb_get(NULL);
matching(filenamesof("+yacc"), "%.c$")
},
deps = {
+ "./registers.h",
"./iburg.h",
"+lib",
"+yacc",
extern void setregnames(struct reg* reg, struct stringlist* names);
extern void addregattr(struct reg* reg, const char* regattr);
extern void addregusage(struct reg* reg, struct stringlist* uses);
-extern struct regattr* getregattr(const char* name);
extern void analyse_registers(void);
extern void emitregisters(void);
extern struct regattr* findregattr(const char* name);
+extern struct regattr* makeregattr(const char* name);
#endif