| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
| 3 * Use of this source code is governed by a BSD-style license that can be | |
| 4 * found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 /* | |
| 8 * Generates file nc_subregs.h | |
| 9 * | |
| 10 * TODO(karl) Fix naming conventions for array names so that they | |
| 11 * are consistent. | |
| 12 */ | |
| 13 | |
| 14 #include "native_client/src/trusted/validator/x86/decoder/generator/nacl_regsgen
.h" | |
| 15 | |
| 16 #include "native_client/src/include/portability_io.h" | |
| 17 #include "native_client/src/shared/platform/nacl_log.h" | |
| 18 #include "native_client/src/trusted/validator/x86/nacl_regs.h" | |
| 19 #include "native_client/src/trusted/validator/x86/nacl_regs32.h" | |
| 20 #include "native_client/src/trusted/validator/x86/nacl_regs64.h" | |
| 21 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_tab
legen.h" | |
| 22 | |
| 23 /* Contains mapping from nacl operand kind, to the | |
| 24 * the corresponding general purpose 64 bit register index | |
| 25 * that it is a subpart of. | |
| 26 * That is, the index into NaClRegTable64, or NACL_REGISTER_UNDEFINED | |
| 27 * if not a general purpose register. | |
| 28 */ | |
| 29 static int nacl_gp_subreg_index[NaClOpKindEnumSize]; | |
| 30 | |
| 31 /* | |
| 32 * Contains the mapping from nacl operand kind, to the | |
| 33 * corresponding general purpose 64 bit register index. | |
| 34 * That is, the index into NaClRegTable64, or NACL_REGISTERED_UNDEFIND | |
| 35 * if not a general purpose 64 bit register. | |
| 36 */ | |
| 37 static int nacl_gp_reg_64_index[NaClOpKindEnumSize]; | |
| 38 | |
| 39 /* | |
| 40 * Define the default buffer size to use. | |
| 41 */ | |
| 42 #define BUFFER_SIZE 256 | |
| 43 | |
| 44 /* | |
| 45 * Given a subregister table, and a table corresponding to | |
| 46 * how those subregisters layout to the corresponding registers | |
| 47 * in the 64 bit table (i.e. NaClRegTable64), update the | |
| 48 * regsiter index to map the corresponding operand kinds to | |
| 49 * the corresponding 64 bit table entries. | |
| 50 * | |
| 51 * Parameters: | |
| 52 * register_index - Table from operand kind to position in 64-bit table. | |
| 53 * register_index_name - Name of register_index (for debugging messages). | |
| 54 * subreg_table - Table of subregisters to fold into register_index. | |
| 55 * subreg_table_name - Name of subreg_table (for debugging messages). | |
| 56 * to64Index - Mapping from subregister to corresponding position in | |
| 57 * NaClRegTable64. | |
| 58 */ | |
| 59 static void NaClFoldSubregisters( | |
| 60 int register_index[NaClOpKindEnumSize], | |
| 61 const char* register_index_name, | |
| 62 const NaClOpKind* subreg_table, | |
| 63 const char* subreg_tablename, | |
| 64 const int* to64index, | |
| 65 const int subreg_table_size, | |
| 66 const int register_undefined) { | |
| 67 int i; | |
| 68 for (i = 0; i < subreg_table_size; ++i) { | |
| 69 NaClOpKind subreg = subreg_table[i]; | |
| 70 if (subreg != RegUnknown) { | |
| 71 int old_index = register_index[subreg]; | |
| 72 if (old_index == register_undefined) { | |
| 73 register_index[subreg] = to64index[i]; | |
| 74 } else if (old_index != to64index[i]) { | |
| 75 NaClLog(LOG_INFO, "%s[%d] = %s, cant replace %s[%s] = %d with %d\n", | |
| 76 subreg_tablename, i, NaClOpKindName(subreg), | |
| 77 register_index_name, | |
| 78 NaClOpKindName(subreg), | |
| 79 old_index, | |
| 80 to64index[i]); | |
| 81 NaClFatal("Fix before continuing\n"); | |
| 82 } | |
| 83 } | |
| 84 } | |
| 85 } | |
| 86 | |
| 87 /* | |
| 88 * Define a mapping from NaClRegTable8Rex_32 indices, to the corresponding | |
| 89 * register index in NaClRegTable64_32, for which each register in | |
| 90 * NaClRegTable8Rex_32 is a subregister in NaClRegTable64_32, assuming the | |
| 91 * REX prefix isn't defined for the instruction. | |
| 92 * Note: this index will only be used if the corresponding index in | |
| 93 * NaClRegTable8NoRex_32 is not RegUnknown. | |
| 94 */ | |
| 95 static const int NaClRegTable8NoRexTo64_32[NACL_REG_TABLE_SIZE_32] = { | |
| 96 0, | |
| 97 1, | |
| 98 2, | |
| 99 3, | |
| 100 0, | |
| 101 1, | |
| 102 2, | |
| 103 3, | |
| 104 }; | |
| 105 | |
| 106 /* | |
| 107 * Define a mapping from NaClRegTable8Rex_64 indices, to the corresponding | |
| 108 * register index in NaClRegTable64_64, for which each register in | |
| 109 * NaClRegTable8Rex_64 is a subregister in NaClRegTable64_64, assuming the | |
| 110 * REX prefix isn't defined for the instruction. | |
| 111 * Note: this index will only be used if the corresponding index in | |
| 112 * NaClRegTable8NoRex_64 is not RegUnknown. | |
| 113 */ | |
| 114 static const int NaClRegTable8NoRexTo64_64[NACL_REG_TABLE_SIZE_64] = { | |
| 115 0, | |
| 116 1, | |
| 117 2, | |
| 118 3, | |
| 119 0, | |
| 120 1, | |
| 121 2, | |
| 122 3, | |
| 123 0, | |
| 124 0, | |
| 125 0, | |
| 126 0, | |
| 127 0, | |
| 128 0, | |
| 129 0, | |
| 130 0 | |
| 131 }; | |
| 132 | |
| 133 /* Define a mapping from NaClRegTable8Rex_32 indices, to the corresponding | |
| 134 * register index in NaClRegTable64_32, for which each register in | |
| 135 * NaClRegTable8Rex_32 is a subregister in NaClRegTable64_32, assuming the | |
| 136 * REX prefix is defined for the instruction. | |
| 137 * Note: this index will only be used if the corresponding index in | |
| 138 * NaClRegTable8Rex_32 is not RegUnknown. | |
| 139 */ | |
| 140 static const int NaClRegTable8RexTo64_32[NACL_REG_TABLE_SIZE_32] = { | |
| 141 0, | |
| 142 1, | |
| 143 2, | |
| 144 3, | |
| 145 0, | |
| 146 1, | |
| 147 2, | |
| 148 3 | |
| 149 }; | |
| 150 | |
| 151 /* Define a mapping from NaClRegTable8Rex_64 indices, to the corresponding | |
| 152 * register index in NaClRegTable64_64, for which each register in | |
| 153 * NaClRegTable8Rex is a subregister in NaClRegTable64_64, assuming the | |
| 154 * REX prefix is defined for the instruction. | |
| 155 * Note: this index will only be used if the corresponding index in | |
| 156 * NaClRegTable8Rex_64 is not RegUnknown. | |
| 157 */ | |
| 158 static const int NaClRegTable8RexTo64_64[NACL_REG_TABLE_SIZE_64] = { | |
| 159 0, | |
| 160 1, | |
| 161 2, | |
| 162 3, | |
| 163 4, | |
| 164 5, | |
| 165 6, | |
| 166 7, | |
| 167 8, | |
| 168 9, | |
| 169 10, | |
| 170 11, | |
| 171 12, | |
| 172 13, | |
| 173 14, | |
| 174 15 | |
| 175 }; | |
| 176 | |
| 177 /* Define the default mapping for register tables for register indexes | |
| 178 * in NaClRegTable64_32. This table does no reordering. | |
| 179 */ | |
| 180 static const int NaClRegTableDefaultTo64_32[NACL_REG_TABLE_SIZE_32] = { | |
| 181 0, | |
| 182 1, | |
| 183 2, | |
| 184 3, | |
| 185 4, | |
| 186 5, | |
| 187 6, | |
| 188 7, | |
| 189 }; | |
| 190 | |
| 191 /* Define the default mapping for register tables for register indexes | |
| 192 * in NaClRegTable64_64. This table does no reordering. | |
| 193 */ | |
| 194 static const int NaClRegTableDefaultTo64_64[NACL_REG_TABLE_SIZE_64] = { | |
| 195 0, | |
| 196 1, | |
| 197 2, | |
| 198 3, | |
| 199 4, | |
| 200 5, | |
| 201 6, | |
| 202 7, | |
| 203 8, | |
| 204 9, | |
| 205 10, | |
| 206 11, | |
| 207 12, | |
| 208 13, | |
| 209 14, | |
| 210 15 | |
| 211 }; | |
| 212 | |
| 213 /* | |
| 214 * Build NaClSubreg64RegRex and NaClSubreg64RegNoRex using encoded register | |
| 215 * tables. | |
| 216 */ | |
| 217 static void NaClBuildGpRegisterIndexes( | |
| 218 const NaClOpKind* reg_table_8_no_rex, | |
| 219 const int* reg_table_8_no_rex_to_64, | |
| 220 const NaClOpKind* reg_table_8_rex, | |
| 221 const int* reg_table_8_rex_to_64, | |
| 222 const NaClOpKind* reg_table_16, | |
| 223 const NaClOpKind* reg_table_32, | |
| 224 const NaClOpKind* reg_table_64, | |
| 225 const int* reg_table_default_to_64, | |
| 226 int subreg_table_size, | |
| 227 int register_undefined) { | |
| 228 int i; | |
| 229 | |
| 230 /* Initialize indices to general purpose registers to defaultx. */ | |
| 231 for (i = 0; i < NaClOpKindEnumSize; ++i) { | |
| 232 nacl_gp_subreg_index[i] = register_undefined; | |
| 233 nacl_gp_reg_64_index[i] = register_undefined; | |
| 234 } | |
| 235 | |
| 236 /* Fold in subregister to full register map values. */ | |
| 237 NaClFoldSubregisters(nacl_gp_subreg_index, "nacl_gp_subreg_index", | |
| 238 reg_table_8_no_rex, "reg_table_8_no_rex", | |
| 239 reg_table_8_no_rex_to_64, | |
| 240 subreg_table_size, | |
| 241 register_undefined); | |
| 242 NaClFoldSubregisters(nacl_gp_subreg_index, "nacl_gp_subreg_index", | |
| 243 reg_table_8_rex, "rex_table_8_rex", | |
| 244 reg_table_8_rex_to_64, | |
| 245 subreg_table_size, | |
| 246 register_undefined); | |
| 247 NaClFoldSubregisters(nacl_gp_subreg_index, "nacl_gp_subreg_index", | |
| 248 reg_table_16, "reg_table_16", | |
| 249 reg_table_default_to_64, | |
| 250 subreg_table_size, | |
| 251 register_undefined); | |
| 252 NaClFoldSubregisters(nacl_gp_subreg_index, "nacl_gp_subreg_index", | |
| 253 reg_table_32, "reg_table_32", | |
| 254 reg_table_default_to_64, | |
| 255 subreg_table_size, | |
| 256 register_undefined); | |
| 257 NaClFoldSubregisters(nacl_gp_reg_64_index, "nacl_gp_reg_64_index", | |
| 258 reg_table_64, "reg_table_64", | |
| 259 reg_table_default_to_64, | |
| 260 subreg_table_size, | |
| 261 register_undefined); | |
| 262 } | |
| 263 | |
| 264 /* Print out table entries using index values and symbolic constants. */ | |
| 265 static char* NaClPrintIndexName(int i, int register_undefined) { | |
| 266 static char buf[BUFFER_SIZE]; | |
| 267 if (i == register_undefined) { | |
| 268 return "NACL_REGISTER_UNDEFINED"; | |
| 269 } else { | |
| 270 SNPRINTF(buf, BUFFER_SIZE, "%3d", i); | |
| 271 return buf; | |
| 272 } | |
| 273 } | |
| 274 | |
| 275 /* Print out a operand kind lookup table. */ | |
| 276 static void NaClPrintGpRegIndex(struct Gio* f, | |
| 277 const char* register_index_name, | |
| 278 const int register_index[NaClOpKindEnumSize], | |
| 279 int register_undefined) { | |
| 280 NaClOpKind i; | |
| 281 gprintf(f, "static int %s[NaClOpKindEnumSize] = {\n", register_index_name); | |
| 282 for (i = 0; i < NaClOpKindEnumSize; ++i) { | |
| 283 gprintf(f, " /* %20s */ %s,\n", NaClOpKindName(i), | |
| 284 NaClPrintIndexName(register_index[i], register_undefined)); | |
| 285 } | |
| 286 gprintf(f, "};\n\n"); | |
| 287 } | |
| 288 | |
| 289 void NaClPrintGpRegisterIndexes_32(struct Gio* f) { | |
| 290 NaClBuildGpRegisterIndexes(NaClRegTable8NoRex_32, | |
| 291 NaClRegTable8NoRexTo64_32, | |
| 292 NaClRegTable8Rex_32, | |
| 293 NaClRegTable8RexTo64_32, | |
| 294 NaClRegTable16_32, | |
| 295 NaClRegTable32_32, | |
| 296 NaClRegTable64_32, | |
| 297 NaClRegTableDefaultTo64_32, | |
| 298 NACL_REG_TABLE_SIZE_32, | |
| 299 NACL_REGISTER_UNDEFINED_32); | |
| 300 NaClPrintGpRegIndex(f, "NaClGpSubregIndex", nacl_gp_subreg_index, | |
| 301 NACL_REGISTER_UNDEFINED_32); | |
| 302 NaClPrintGpRegIndex(f, "NaClGpReg64Index", nacl_gp_reg_64_index, | |
| 303 NACL_REGISTER_UNDEFINED_32); | |
| 304 } | |
| 305 | |
| 306 void NaClPrintGpRegisterIndexes_64(struct Gio* f) { | |
| 307 NaClBuildGpRegisterIndexes(NaClRegTable8NoRex_64, | |
| 308 NaClRegTable8NoRexTo64_64, | |
| 309 NaClRegTable8Rex_64, | |
| 310 NaClRegTable8RexTo64_64, | |
| 311 NaClRegTable16_64, | |
| 312 NaClRegTable32_64, | |
| 313 NaClRegTable64_64, | |
| 314 NaClRegTableDefaultTo64_64, | |
| 315 NACL_REG_TABLE_SIZE_64, | |
| 316 NACL_REGISTER_UNDEFINED_64); | |
| 317 NaClPrintGpRegIndex(f, "NaClGpSubregIndex", nacl_gp_subreg_index, | |
| 318 NACL_REGISTER_UNDEFINED_64); | |
| 319 NaClPrintGpRegIndex(f, "NaClGpReg64Index", nacl_gp_reg_64_index, | |
| 320 NACL_REGISTER_UNDEFINED_64); | |
| 321 } | |
| OLD | NEW |