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-2012 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 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