]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add to repo.
authorJulian Seward <jseward@acm.org>
Sat, 10 Jul 2004 12:22:40 +0000 (12:22 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 10 Jul 2004 12:22:40 +0000 (12:22 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@68

VEX/priv/host-generic/host_regs.c [new file with mode: 0644]

diff --git a/VEX/priv/host-generic/host_regs.c b/VEX/priv/host-generic/host_regs.c
new file mode 100644 (file)
index 0000000..1616ed4
--- /dev/null
@@ -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 ---*/
+/*---------------------------------------------------------------*/