• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 
ppHRegClass(HRegClass hrc)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. */
ppHReg(HReg r)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 
ppHRegUsage(HRegUsage * tab)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 */
addHRegUse(HRegUsage * tab,HRegMode mode,HReg reg)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 
ppHRegRemap(HRegRemap * map)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 
initHRegRemap(HRegRemap * map)154 void initHRegRemap ( HRegRemap* map )
155 {
156    map->n_used = 0;
157 }
158 
159 
addToHRegRemap(HRegRemap * map,HReg orig,HReg replacement)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 
lookupHRegRemap(HRegRemap * map,HReg orig)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 
newHInstrArray(void)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 
addHInstr(HInstrArray * ha,HInstr * instr)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