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-2011 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
43void 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. */
57void 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
77void 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*/
101void 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
139void 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
154void initHRegRemap ( HRegRemap* map )
155{
156   map->n_used = 0;
157}
158
159
160void 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 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
178HReg 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
193HInstrArray* 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
203void 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