Home | History | Annotate | Download | only in priv
      1 
      2 /*---------------------------------------------------------------*/
      3 /*--- begin                               host_generic_regs.c ---*/
      4 /*---------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2004-2010 OpenWorks LLP
     11       info (at) open-works.net
     12 
     13    This program is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License as
     15    published by the Free Software Foundation; either version 2 of the
     16    License, or (at your option) any later version.
     17 
     18    This program is distributed in the hope that it will be useful, but
     19    WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21    General Public License for more details.
     22 
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     26    02110-1301, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 
     30    Neither the names of the U.S. Department of Energy nor the
     31    University of California nor the names of its contributors may be
     32    used to endorse or promote products derived from this software
     33    without prior written permission.
     34 */
     35 
     36 #include "libvex_basictypes.h"
     37 #include "libvex.h"
     38 
     39 #include "main_util.h"
     40 #include "host_generic_regs.h"
     41 
     42 
     43 void ppHRegClass ( HRegClass hrc )
     44 {
     45    switch (hrc) {
     46       case HRcInt32:   vex_printf("HRcInt32"); break;
     47       case HRcInt64:   vex_printf("HRcInt64"); break;
     48       case HRcFlt32:   vex_printf("HRcFlt32"); break;
     49       case HRcFlt64:   vex_printf("HRcFlt64"); break;
     50       case HRcVec64:   vex_printf("HRcVec64"); break;
     51       case HRcVec128:  vex_printf("HRcVec128"); break;
     52       default: vpanic("ppHRegClass");
     53    }
     54 }
     55 
     56 /* Generic printing for registers. */
     57 void ppHReg ( HReg r )
     58 {
     59    HChar* maybe_v = hregIsVirtual(r) ? "v" : "";
     60    Int    regNo   = hregNumber(r);
     61    switch (hregClass(r)) {
     62       case HRcInt32:   vex_printf("%%%sr%d", maybe_v, regNo); return;
     63       case HRcInt64:   vex_printf("%%%sR%d", maybe_v, regNo); return;
     64       case HRcFlt32:   vex_printf("%%%sF%d", maybe_v, regNo); return;
     65       case HRcFlt64:   vex_printf("%%%sD%d", maybe_v, regNo); return;
     66       case HRcVec64:   vex_printf("%%%sv%d", maybe_v, regNo); return;
     67       case HRcVec128:  vex_printf("%%%sV%d", maybe_v, regNo); return;
     68       default: vpanic("ppHReg");
     69    }
     70 }
     71 
     72 
     73 /*---------------------------------------------------------*/
     74 /*--- Helpers for recording reg usage (for reg-alloc)   ---*/
     75 /*---------------------------------------------------------*/
     76 
     77 void ppHRegUsage ( HRegUsage* tab )
     78 {
     79    Int    i;
     80    HChar* str;
     81    vex_printf("HRegUsage {\n");
     82    for (i = 0; i < tab->n_used; i++) {
     83       switch (tab->mode[i]) {
     84          case HRmRead:   str = "Read   "; break;
     85          case HRmWrite:  str = "Write  "; break;
     86          case HRmModify: str = "Modify "; break;
     87          default: vpanic("ppHRegUsage");
     88       }
     89       vex_printf("   %s ", str);
     90       ppHReg(tab->hreg[i]);
     91       vex_printf("\n");
     92    }
     93    vex_printf("}\n");
     94 }
     95 
     96 
     97 /* Add a register to a usage table.  Combine incoming read uses with
     98    existing write uses into a modify use, and vice versa.  Do not
     99    create duplicate entries -- each reg should only be mentioned once.
    100 */
    101 void addHRegUse ( HRegUsage* tab, HRegMode mode, HReg reg )
    102 {
    103    Int i;
    104    /* Find it ... */
    105    for (i = 0; i < tab->n_used; i++)
    106       if (tab->hreg[i] == reg)
    107          break;
    108    if (i == tab->n_used) {
    109       /* Not found, add new entry. */
    110       vassert(tab->n_used < N_HREG_USAGE);
    111       tab->hreg[tab->n_used] = reg;
    112       tab->mode[tab->n_used] = mode;
    113       tab->n_used++;
    114    } else {
    115       /* Found: combine or ignore. */
    116       /* This is a greatest-lower-bound operation in the poset:
    117 
    118             R   W
    119              \ /
    120               M
    121 
    122          Need to do: tab->mode[i] = GLB(tab->mode, mode).  In this
    123          case very simple -- if tab->mode[i] != mode then result must
    124          be M.
    125       */
    126       if (tab->mode[i] == mode) {
    127          /* duplicate, ignore */
    128       } else {
    129          tab->mode[i] = HRmModify;
    130       }
    131    }
    132 }
    133 
    134 
    135 /*---------------------------------------------------------*/
    136 /*--- Indicating register remappings (for reg-alloc)    ---*/
    137 /*---------------------------------------------------------*/
    138 
    139 void ppHRegRemap ( HRegRemap* map )
    140 {
    141    Int   i;
    142    vex_printf("HRegRemap {\n");
    143    for (i = 0; i < map->n_used; i++) {
    144       vex_printf("   ");
    145       ppHReg(map->orig[i]);
    146       vex_printf("  -->  ");
    147       ppHReg(map->replacement[i]);
    148       vex_printf("\n");
    149    }
    150    vex_printf("}\n");
    151 }
    152 
    153 
    154 void initHRegRemap ( HRegRemap* map )
    155 {
    156    map->n_used = 0;
    157 }
    158 
    159 
    160 void addToHRegRemap ( HRegRemap* map, HReg orig, HReg replacement )
    161 {
    162    Int i;
    163    for (i = 0; i < map->n_used; i++)
    164       if (map->orig[i] == orig)
    165          vpanic("addToHRegMap: duplicate entry");
    166    if (!hregIsVirtual(orig))
    167       vpanic("addToHRegMap: orig is not a vreg");
    168    if (hregIsVirtual(replacement))
    169       vpanic("addToHRegMap: replacement is not a vreg");
    170 
    171    vassert(map->n_used+1 < N_HREG_REMAP);
    172    map->orig[map->n_used]        = orig;
    173    map->replacement[map->n_used] = replacement;
    174    map->n_used++;
    175 }
    176 
    177 
    178 HReg lookupHRegRemap ( HRegRemap* map, HReg orig )
    179 {
    180    Int i;
    181    if (!hregIsVirtual(orig))
    182       return orig;
    183    for (i = 0; i < map->n_used; i++)
    184       if (map->orig[i] == orig)
    185          return map->replacement[i];
    186    vpanic("lookupHRegRemap: not found");
    187 }
    188 
    189 /*---------------------------------------------------------*/
    190 /*--- Abstract instructions                             ---*/
    191 /*---------------------------------------------------------*/
    192 
    193 HInstrArray* newHInstrArray ( void )
    194 {
    195    HInstrArray* ha = LibVEX_Alloc(sizeof(HInstrArray));
    196    ha->arr_size = 4;
    197    ha->arr_used = 0;
    198    ha->arr      = LibVEX_Alloc(ha->arr_size * sizeof(HInstr*));
    199    ha->n_vregs  = 0;
    200    return ha;
    201 }
    202 
    203 void addHInstr ( HInstrArray* ha, HInstr* instr )
    204 {
    205    vassert(ha->arr_used <= ha->arr_size);
    206    if (ha->arr_used < ha->arr_size) {
    207       ha->arr[ha->arr_used] = instr;
    208       ha->arr_used++;
    209    } else {
    210       Int      i;
    211       HInstr** arr2 = LibVEX_Alloc(ha->arr_size * 2 * sizeof(HInstr*));
    212       for (i = 0; i < ha->arr_size; i++)
    213          arr2[i] = ha->arr[i];
    214       ha->arr_size *= 2;
    215       ha->arr = arr2;
    216       addHInstr(ha, instr);
    217    }
    218 }
    219 
    220 
    221 /*---------------------------------------------------------------*/
    222 /*--- end                                 host_generic_regs.c ---*/
    223 /*---------------------------------------------------------------*/
    224