blob: 267b7cea9126942fca589462cb71e034f16121f8 [file] [log] [blame]
sewardja704d352004-07-10 12:22:40 +00001
2/*---------------------------------------------------------------*/
sewardj752f9062010-05-03 21:38:49 +00003/*--- begin host_generic_regs.c ---*/
sewardja704d352004-07-10 12:22:40 +00004/*---------------------------------------------------------------*/
5
sewardjf8ed9d82004-11-12 17:40:23 +00006/*
sewardj752f9062010-05-03 21:38:49 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjf8ed9d82004-11-12 17:40:23 +00009
sewardj89ae8472013-10-18 14:12:58 +000010 Copyright (C) 2004-2013 OpenWorks LLP
sewardj752f9062010-05-03 21:38:49 +000011 info@open-works.net
sewardjf8ed9d82004-11-12 17:40:23 +000012
sewardj752f9062010-05-03 21:38:49 +000013 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.
sewardjf8ed9d82004-11-12 17:40:23 +000017
sewardj752f9062010-05-03 21:38:49 +000018 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
sewardj7bd6ffe2005-08-03 16:07:36 +000026 02110-1301, USA.
27
sewardj752f9062010-05-03 21:38:49 +000028 The GNU General Public License is contained in the file COPYING.
sewardjf8ed9d82004-11-12 17:40:23 +000029
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.
sewardjf8ed9d82004-11-12 17:40:23 +000034*/
35
sewardja704d352004-07-10 12:22:40 +000036#include "libvex_basictypes.h"
37#include "libvex.h"
38
sewardjcef7d3e2009-07-02 12:21:59 +000039#include "main_util.h"
40#include "host_generic_regs.h"
sewardja704d352004-07-10 12:22:40 +000041
42
sewardja704d352004-07-10 12:22:40 +000043void ppHRegClass ( HRegClass hrc )
44{
45 switch (hrc) {
sewardj4a31b262004-12-01 02:24:44 +000046 case HRcInt32: vex_printf("HRcInt32"); break;
47 case HRcInt64: vex_printf("HRcInt64"); break;
sewardj6c299f32009-12-31 18:00:12 +000048 case HRcFlt32: vex_printf("HRcFlt32"); break;
sewardj4a31b262004-12-01 02:24:44 +000049 case HRcFlt64: vex_printf("HRcFlt64"); break;
50 case HRcVec64: vex_printf("HRcVec64"); break;
51 case HRcVec128: vex_printf("HRcVec128"); break;
sewardja704d352004-07-10 12:22:40 +000052 default: vpanic("ppHRegClass");
53 }
54}
55
56/* Generic printing for registers. */
57void ppHReg ( HReg r )
58{
florian55085f82012-11-21 00:36:55 +000059 const HChar* maybe_v = hregIsVirtual(r) ? "v" : "";
sewardja8415ff2005-01-21 20:55:36 +000060 Int regNo = hregNumber(r);
sewardja704d352004-07-10 12:22:40 +000061 switch (hregClass(r)) {
sewardj4a31b262004-12-01 02:24:44 +000062 case HRcInt32: vex_printf("%%%sr%d", maybe_v, regNo); return;
63 case HRcInt64: vex_printf("%%%sR%d", maybe_v, regNo); return;
sewardj6c299f32009-12-31 18:00:12 +000064 case HRcFlt32: vex_printf("%%%sF%d", maybe_v, regNo); return;
65 case HRcFlt64: vex_printf("%%%sD%d", maybe_v, regNo); return;
sewardj4a31b262004-12-01 02:24:44 +000066 case HRcVec64: vex_printf("%%%sv%d", maybe_v, regNo); return;
67 case HRcVec128: vex_printf("%%%sV%d", maybe_v, regNo); return;
sewardja704d352004-07-10 12:22:40 +000068 default: vpanic("ppHReg");
69 }
70}
71
72
73/*---------------------------------------------------------*/
74/*--- Helpers for recording reg usage (for reg-alloc) ---*/
75/*---------------------------------------------------------*/
76
77void ppHRegUsage ( HRegUsage* tab )
78{
sewardj4a6f3842005-03-26 11:59:23 +000079 Int i;
florian55085f82012-11-21 00:36:55 +000080 const HChar* str;
sewardja704d352004-07-10 12:22:40 +000081 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
sewardja704d352004-07-10 12:22:40 +000097/* 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++)
florian79efdc62013-02-11 00:47:35 +0000106 if (sameHReg(tab->hreg[i], reg))
sewardja704d352004-07-10 12:22:40 +0000107 break;
108 if (i == tab->n_used) {
109 /* Not found, add new entry. */
sewardj2778bcf2004-09-09 02:45:30 +0000110 vassert(tab->n_used < N_HREG_USAGE);
sewardja704d352004-07-10 12:22:40 +0000111 tab->hreg[tab->n_used] = reg;
112 tab->mode[tab->n_used] = mode;
113 tab->n_used++;
114 } else {
115 /* Found: combine or ignore. */
sewardj3f21fd32005-10-22 12:46:06 +0000116 /* 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 {
sewardja704d352004-07-10 12:22:40 +0000129 tab->mode[i] = HRmModify;
sewardja704d352004-07-10 12:22:40 +0000130 }
sewardja704d352004-07-10 12:22:40 +0000131 }
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++)
florian79efdc62013-02-11 00:47:35 +0000164 if (sameHReg(map->orig[i], orig))
sewardja704d352004-07-10 12:22:40 +0000165 vpanic("addToHRegMap: duplicate entry");
166 if (!hregIsVirtual(orig))
167 vpanic("addToHRegMap: orig is not a vreg");
168 if (hregIsVirtual(replacement))
florian81c22f02011-08-19 02:58:51 +0000169 vpanic("addToHRegMap: replacement is a vreg");
sewardja704d352004-07-10 12:22:40 +0000170
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++)
florian79efdc62013-02-11 00:47:35 +0000184 if (sameHReg(map->orig[i], orig))
sewardja704d352004-07-10 12:22:40 +0000185 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
sewardjcfe046e2013-01-17 14:23:53 +0000221/*---------------------------------------------------------*/
222/*--- C-Call return-location actions ---*/
223/*---------------------------------------------------------*/
224
225void ppRetLoc ( RetLoc ska )
226{
sewardj74142b82013-08-08 10:28:59 +0000227 switch (ska.pri) {
228 case RLPri_INVALID:
229 vex_printf("RLPri_INVALID"); return;
230 case RLPri_None:
231 vex_printf("RLPri_None"); return;
232 case RLPri_Int:
233 vex_printf("RLPri_Int"); return;
234 case RLPri_2Int:
235 vex_printf("RLPri_2Int"); return;
236 case RLPri_V128SpRel:
237 vex_printf("RLPri_V128SpRel(%d)", ska.spOff); return;
238 case RLPri_V256SpRel:
239 vex_printf("RLPri_V256SpRel(%d)", ska.spOff); return;
240 default:
241 vpanic("ppRetLoc");
sewardjcfe046e2013-01-17 14:23:53 +0000242 }
243}
244
245
sewardja704d352004-07-10 12:22:40 +0000246/*---------------------------------------------------------------*/
sewardjcef7d3e2009-07-02 12:21:59 +0000247/*--- end host_generic_regs.c ---*/
sewardja704d352004-07-10 12:22:40 +0000248/*---------------------------------------------------------------*/