blob: 745f22861fb136c1cf0d84128735db809f5f5e36 [file] [log] [blame]
/*---------------------------------------------------------------*/
/*--- ---*/
/*--- This file (host_regs.c) is ---*/
/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
/*--- ---*/
/*---------------------------------------------------------------*/
#include <stdio.h>
#include "basictypes.h"
#include "host_regs.h"
HReg mkHReg ( UInt regno, HRegClass rc, Bool virtual )
{
assert((regno & 0xFF000000) == 0);
return (regno << 8) | (((UInt)rc) << 4) | (virtual ? 1 : 0);
}
HRegClass hregClass ( HReg r )
{
UInt rc = (r & 0x000000F0) >> 4;
assert(rc <= 2);
return (HRegClass)rc;
}
Bool hregIsVirtual ( HReg r )
{
return (r & 1) ? True : False;
}
UInt hregNumber ( HReg r )
{
return (((UInt)r) >> 8);
}
/* Generic printing for registers. */
void ppHReg ( FILE* f, HReg r )
{
Char* maybe_v = hregIsVirtual(r) ? "v" : "";
Int regNo = hregNumber(r);
switch (hregClass(r)) {
case HRcInt: fprintf(f, "%%%sr%d", maybe_v, regNo); return;
case HRcFloat: fprintf(f, "%%%sf%d", maybe_v, regNo); return;
case HRcVector: fprintf(f, "%%%sv%d", maybe_v, regNo); return;
default: panic("ppHReg");
}
}
/*---------------------------------------------------------*/
/*--- 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 ---*/
/*---------------------------------------------------------------*/