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 |