Support stuff for register allocation.
git-svn-id: svn://svn.valgrind.org/vex/trunk@28 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/host_regs.c b/host_regs.c
index 2810896..745f228 100644
--- a/host_regs.c
+++ b/host_regs.c
@@ -49,3 +49,116 @@
}
}
+
+/*---------------------------------------------------------*/
+/*--- Helpers for recording reg usage (for reg-alloc) ---*/
+/*---------------------------------------------------------*/
+
+void ppHRegUsage ( FILE* f, HRegUsage* tab )
+{
+ Int i;
+ Char* str;
+ fprintf(f, "HRegUsage {\n");
+ for (i = 0; i < tab->n_used; i++) {
+ switch (tab->mode[i]) {
+ case HRmRead: str = "Read "; break;
+ case HRmWrite: str = "Write "; break;
+ case HRmModify: str = "Modify "; break;
+ default: panic("ppHRegUsage");
+ }
+ fprintf(f, " %s ", str);
+ ppHReg(f, tab->hreg[i]);
+ fprintf(f, "\n");
+ }
+ fprintf(f, "}\n");
+}
+
+
+void initHRegUsage ( HRegUsage* tab )
+{
+ tab->n_used = 0;
+}
+
+
+/* Add a register to a usage table. Combine incoming read uses with
+ existing write uses into a modify use, and vice versa. Do not
+ create duplicate entries -- each reg should only be mentioned once.
+*/
+void addHRegUsage ( HRegUsage* tab, HReg reg, HRegMode mode )
+{
+ Int i;
+ /* Find it ... */
+ for (i = 0; i < tab->n_used; i++)
+ if (tab->hreg[i] == reg)
+ break;
+ if (i == tab->n_used) {
+ /* Not found, add new entry. */
+ assert(tab->n_used+1 < N_HREG_USAGE);
+ tab->hreg[tab->n_used] = reg;
+ tab->mode[tab->n_used] = mode;
+ tab->n_used++;
+ } else {
+ /* Found: combine or ignore. */
+ if (tab->mode[i] == mode)
+ return; /* duplicate, ignore */
+ if (mode == HRmModify) {
+ tab->mode[i] = HRmModify;
+ return; /* modify mode makes previous mode irrelevant */
+ }
+ assert( (mode == HRmRead && tab->mode[i] == HRmWrite)
+ || (mode == HRmWrite && tab->mode[i] == HRmRead) );
+ tab->mode[i] = HRmModify;
+ }
+}
+
+
+/*---------------------------------------------------------*/
+/*--- Indicating register remappings (for reg-alloc) ---*/
+/*---------------------------------------------------------*/
+
+void ppHRegRemap ( FILE* f, HRegRemap* map )
+{
+ Int i;
+ fprintf(f, "HRegRemap {\n");
+ for (i = 0; i < map->n_used; i++) {
+ fprintf(f, " ");
+ ppHReg(f, tab->orig[i]);
+ fprintf(f, " --> ");
+ ppHReg(f, tab->replacement[i]);
+ fprintf(f, "\n");
+ }
+ fprintf(f, "}\n");
+}
+
+
+void initHRegRemap ( HRegRemap* map )
+{
+ map->n_used = 0;
+}
+
+
+void addToHRegRemap ( HRegRemap* map, HReg orig, HReg replacement )
+{
+ Int i;
+ for (i = 0; i < map->n_used; i++)
+ if (map->orig[i] == orig)
+ panic("addToHRegMap: duplicate entry");
+ assert(map->n_used+1 < N_HREG_REMAP);
+ map->orig[map->n_used] = orig;
+ map->replacement[map->n_used] = replacement;
+ map->n_used++;
+}
+
+
+HReg lookupHRegRemap ( HRegRemap* map, HReg orig )
+{
+ Int i;
+ for (i = 0; i < map->n_used; i++)
+ if (map->orig[i] == orig)
+ return map->replacement[i];
+ panic("lookupHRegRemap: not found");
+}
+
+/*---------------------------------------------------------------*/
+/*--- host_regs.c ---*/
+/*---------------------------------------------------------------*/