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-2013 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 const 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 const 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 (sameHReg(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 (sameHReg(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 (sameHReg(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 /*--- C-Call return-location actions ---*/ 223 /*---------------------------------------------------------*/ 224 225 void ppRetLoc ( RetLoc ska ) 226 { 227 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"); 242 } 243 } 244 245 246 /*---------------------------------------------------------------*/ 247 /*--- end host_generic_regs.c ---*/ 248 /*---------------------------------------------------------------*/ 249