From: Julian Seward Date: Sat, 10 Jul 2004 12:22:40 +0000 (+0000) Subject: Add to repo. X-Git-Tag: svn/VALGRIND_3_0_1^2~1266 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9788218844909a32adbe5cf01bbe6a72e9e36d70;p=thirdparty%2Fvalgrind.git Add to repo. git-svn-id: svn://svn.valgrind.org/vex/trunk@68 --- diff --git a/VEX/priv/host-generic/host_regs.c b/VEX/priv/host-generic/host_regs.c new file mode 100644 index 0000000000..1616ed4d8f --- /dev/null +++ b/VEX/priv/host-generic/host_regs.c @@ -0,0 +1,223 @@ + +/*---------------------------------------------------------------*/ +/*--- ---*/ +/*--- This file (host_regs.c) is ---*/ +/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/ +/*--- ---*/ +/*---------------------------------------------------------------*/ + +#include "libvex_basictypes.h" +#include "libvex.h" + +#include "vex_util.h" +#include "host_regs.h" + + +HReg mkHReg ( UInt regno, HRegClass rc, Bool virtual ) +{ + UInt r24 = regno & 0x00FFFFFF; + /* This is critical. The register number field may only + occupy 24 bits. */ + if (r24 != regno) + vpanic("mkHReg: regno exceeds 2^24"); + return regno | (((UInt)rc) << 28) | (virtual ? (1<<24) : 0); +} + +HRegClass hregClass ( HReg r ) +{ + UInt rc = r; + rc = (rc >> 28) & 0x0F; + vassert(rc == HRcInt || rc == HRcFloat || rc == HRcVector + || rc == HRcInt64 || rc == HRcVector128); + return (HRegClass)rc; +} + +Bool hregIsVirtual ( HReg r ) +{ + return (((UInt)r) & (1<<24)) ? True : False; +} + +UInt hregNumber ( HReg r ) +{ + return ((UInt)r) & 0x00FFFFFF; +} + +void ppHRegClass ( HRegClass hrc ) +{ + switch (hrc) { + case HRcInt: vex_printf("HRcInt32"); break; + case HRcInt64: vex_printf("HRcInt64"); break; + case HRcFloat: vex_printf("HRcFloat"); break; + case HRcVector: vex_printf("HRcVector64"); break; + case HRcVector128: vex_printf("HRcVector128"); break; + default: vpanic("ppHRegClass"); + } +} + +/* Generic printing for registers. */ +void ppHReg ( HReg r ) +{ + Char* maybe_v = hregIsVirtual(r) ? "v" : ""; + Int regNo = hregNumber(r); + switch (hregClass(r)) { + case HRcInt: vex_printf("%%%sr%d", maybe_v, regNo); return; + case HRcInt64: vex_printf("%%%sR%d", maybe_v, regNo); return; + case HRcFloat: vex_printf("%%%sf%d", maybe_v, regNo); return; + case HRcVector: vex_printf("%%%sv%d", maybe_v, regNo); return; + case HRcVector128: vex_printf("%%%sV%d", maybe_v, regNo); return; + default: vpanic("ppHReg"); + } +} + + +/*---------------------------------------------------------*/ +/*--- Helpers for recording reg usage (for reg-alloc) ---*/ +/*---------------------------------------------------------*/ + +void ppHRegUsage ( HRegUsage* tab ) +{ + Int i; + Char* str; + vex_printf("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: vpanic("ppHRegUsage"); + } + vex_printf(" %s ", str); + ppHReg(tab->hreg[i]); + vex_printf("\n"); + } + vex_printf("}\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 addHRegUse ( HRegUsage* tab, HRegMode mode, HReg reg ) +{ + 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. */ + vassert(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 */ + } + vassert( (mode == HRmRead && tab->mode[i] == HRmWrite) + || (mode == HRmWrite && tab->mode[i] == HRmRead) ); + tab->mode[i] = HRmModify; + } +} + + +/*---------------------------------------------------------*/ +/*--- Indicating register remappings (for reg-alloc) ---*/ +/*---------------------------------------------------------*/ + +void ppHRegRemap ( HRegRemap* map ) +{ + Int i; + vex_printf("HRegRemap {\n"); + for (i = 0; i < map->n_used; i++) { + vex_printf(" "); + ppHReg(map->orig[i]); + vex_printf(" --> "); + ppHReg(map->replacement[i]); + vex_printf("\n"); + } + vex_printf("}\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) + vpanic("addToHRegMap: duplicate entry"); + if (!hregIsVirtual(orig)) + vpanic("addToHRegMap: orig is not a vreg"); + if (hregIsVirtual(replacement)) + vpanic("addToHRegMap: replacement is not a vreg"); + + vassert(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; + if (!hregIsVirtual(orig)) + return orig; + for (i = 0; i < map->n_used; i++) + if (map->orig[i] == orig) + return map->replacement[i]; + vpanic("lookupHRegRemap: not found"); +} + +/*---------------------------------------------------------*/ +/*--- Abstract instructions ---*/ +/*---------------------------------------------------------*/ + +HInstrArray* newHInstrArray ( void ) +{ + HInstrArray* ha = LibVEX_Alloc(sizeof(HInstrArray)); + ha->arr_size = 4; + ha->arr_used = 0; + ha->arr = LibVEX_Alloc(ha->arr_size * sizeof(HInstr*)); + ha->n_vregs = 0; + return ha; +} + +void addHInstr ( HInstrArray* ha, HInstr* instr ) +{ + vassert(ha->arr_used <= ha->arr_size); + if (ha->arr_used < ha->arr_size) { + ha->arr[ha->arr_used] = instr; + ha->arr_used++; + } else { + Int i; + HInstr** arr2 = LibVEX_Alloc(ha->arr_size * 2 * sizeof(HInstr*)); + for (i = 0; i < ha->arr_size; i++) + arr2[i] = ha->arr[i]; + ha->arr_size *= 2; + ha->arr = arr2; + addHInstr(ha, instr); + } +} + + +/*---------------------------------------------------------------*/ +/*--- end host_regs.c ---*/ +/*---------------------------------------------------------------*/