Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: rz3_section.C | |
4 | // Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
5 | // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
6 | // | |
7 | // The above named program is free software; you can redistribute it and/or | |
8 | // modify it under the terms of the GNU General Public | |
9 | // License version 2 as published by the Free Software Foundation. | |
10 | // | |
11 | // The above named program is distributed in the hope that it will be | |
12 | // useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | // General Public License for more details. | |
15 | // | |
16 | // You should have received a copy of the GNU General Public | |
17 | // License along with this work; if not, write to the Free Software | |
18 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
19 | // | |
20 | // ========== Copyright Header End ============================================ | |
21 | /* rz3_section.C | |
22 | * rz3 section header, section data, per-cpu temporary data etc | |
23 | */ | |
24 | ||
25 | #include "rstzip3.h" | |
26 | #include "rz3_section.h" | |
27 | #include "rz3utils.h" | |
28 | ||
29 | #if defined(ARCH_AMD64) | |
30 | #include "rstf/byteswap.h" | |
31 | #endif | |
32 | ||
33 | ||
34 | void rz3_section_header::clear() | |
35 | { | |
36 | nrecords = 0; | |
37 | ||
38 | bzero(rz3_bitarray_counts, sizeof(uint32_t) * rstzip3::bitarray_count); | |
39 | ||
40 | } // rz3_section_header::clear() | |
41 | ||
42 | ||
43 | bool rz3_section_header::write(gzFile gzf) | |
44 | { | |
45 | #if defined(ARCH_AMD64) | |
46 | flip_endianess(); | |
47 | #endif | |
48 | ||
49 | return (gzwrite(gzf, this, sizeof(rz3_section_header_file)) == sizeof(rz3_section_header_file)); | |
50 | } // bool rz3_section_header::write(gzFile gzf) | |
51 | ||
52 | ||
53 | bool rz3_section_header::read(gzFile gzf) | |
54 | { | |
55 | int bytes_read = gzread(gzf, this, sizeof(rz3_section_header_file)); | |
56 | if (bytes_read == 0) { | |
57 | /* end of file */ | |
58 | return false; | |
59 | } | |
60 | ||
61 | if (bytes_read != sizeof(rz3_section_header_file)) { | |
62 | int errnum; | |
63 | fprintf(stderr, "rz3_section_header::read() - gzread error (bytes read=%d, req = %d) %s\n", | |
64 | bytes_read, sizeof(rz3_section_header_file), gzerror(gzf, &errnum)); | |
65 | fprintf(stderr, "errnum %d\n", errnum); | |
66 | return false; | |
67 | } | |
68 | ||
69 | #if defined(ARCH_AMD64) | |
70 | flip_endianess(); | |
71 | #endif | |
72 | ||
73 | // sanity checks | |
74 | ||
75 | return sanity_check(); | |
76 | ||
77 | } // bool rz3_section_header::read(gzFile gzf) | |
78 | ||
79 | ||
80 | bool rz3_section_header::sanity_check() { | |
81 | // check magic number | |
82 | if ((magic[0] == 0) || strcmp(magic, rz3_shdr_magic)) { | |
83 | fprintf(stderr, "rz3 section_header magic mismatch\n"); | |
84 | return false; | |
85 | } | |
86 | ||
87 | if ((nrecords <= 0) || (nrecords > rz3obj->rz3_bufsize)) { | |
88 | fprintf(stderr, "rz3 section header: invalid value of nrecords (%d not between 1 and %d)\n", nrecords, rz3obj->rz3_bufsize); | |
89 | return false; | |
90 | } | |
91 | ||
92 | return true; | |
93 | } | |
94 | ||
95 | ||
96 | #if defined(ARCH_AMD64) | |
97 | void rz3_section_header::flip_endianess() { | |
98 | nrecords = byteswap32(nrecords); | |
99 | CompressedBufferSize = byteswap64(CompressedBufferSize); | |
100 | for (int i=0; i<rstzip3::bitarray_count; i++) { | |
101 | rz3_bitarray_counts[i] = byteswap32(rz3_bitarray_counts[i]); | |
102 | } | |
103 | } | |
104 | #endif | |
105 | ||
106 | ||
107 | ||
108 | rz3_section_data::rz3_section_data(rz3_section_header * arg_shdr, bool pre320) | |
109 | { | |
110 | shdr = arg_shdr; | |
111 | ||
112 | // raw_records_array = new rz3_rst_array(rz3_bufsize); // only allocates bufsize/512 pointers. array grows on demand | |
113 | ||
114 | int i; | |
115 | for (i=0; i<rstzip3::bitarray_count; i++) { | |
116 | int nbits = rstzip3::bitarray_descr[i].nbits; | |
117 | ||
118 | // this is a sub-optimal way of coding this, but we need to | |
119 | // special case things for version differences and backward | |
120 | // compatibility... (2004/12/23, 2005/01/11) | |
121 | if (pre320) { | |
122 | switch(i) { | |
123 | case rstzip3::raw_cpuid_array: | |
124 | nbits = 6; | |
125 | break; | |
126 | case rstzip3::instr_pred_raw_array: | |
127 | nbits = 7; | |
128 | break; | |
129 | case rstzip3::tlb_info_array: | |
130 | nbits = 26; | |
131 | break; | |
132 | default: | |
133 | break; | |
134 | } // switch i | |
135 | } // if pre320 | |
136 | ||
137 | int size_hint = rstzip3::bitarray_descr[i].size_hint; | |
138 | bitarrays[i] = new rz3_bitarray(rstzip3::bitarray_descr[i].name, nbits, size_hint); | |
139 | total_rz3_bitarray_counts[i] = 0; | |
140 | total_rz3_bitarray_sums[i] = 0; | |
141 | } | |
142 | ||
143 | total_nrecords = 0; | |
144 | total_CompressedBufferSize = 0; | |
145 | ||
146 | } // rz3_section_data::() | |
147 | ||
148 | ||
149 | rz3_section_data::~rz3_section_data() | |
150 | { | |
151 | ||
152 | // delete raw_records_array; raw_records_array = NULL; | |
153 | ||
154 | int i; | |
155 | for (i=0; i<rstzip3::bitarray_count; i++) { | |
156 | delete bitarrays[i]; bitarrays[i] = NULL; | |
157 | } | |
158 | ||
159 | } // rz3_section_data::~() | |
160 | ||
161 | ||
162 | ||
163 | void rz3_section_data::clear() | |
164 | { | |
165 | int i; | |
166 | ||
167 | for (i=0; i<rstzip3::bitarray_count; i++) { | |
168 | bitarrays[i]->clear(); | |
169 | } | |
170 | ||
171 | // raw_records_array->clear(); | |
172 | ||
173 | } // rz3_section_data::clear() | |
174 | ||
175 | ||
176 | void rz3_section_data::print() | |
177 | { | |
178 | ||
179 | fprintf(stderr, "\nSection array sizes:\n"); | |
180 | fprintf(stderr, "nrecords = %d\n", shdr->nrecords); | |
181 | ||
182 | int instr_count = bitarrays[rstzip3::instr_pred_all_array]->Count(); | |
183 | ||
184 | ||
185 | int i; | |
186 | for (i=0; i<rstzip3::bitarray_count; i++) { | |
187 | int count = shdr->rz3_bitarray_counts[i]; | |
188 | fprintf(stderr, "# %s = %6d (%7.4f%%/instr, %7.4f%%/rec) %7.4f bits/rec %7.4f%% of all bits", | |
189 | rstzip3::bitarray_descr[i].name, count, count*100.0/instr_count, count*100.0/shdr->nrecords, | |
190 | count*rstzip3::bitarray_descr[i].nbits*1.0/shdr->nrecords, count*rstzip3::bitarray_descr[i].nbits*100.0/(8*shdr->CompressedBufferSize)); | |
191 | if (rstzip3::bitarray_descr[i].nbits == 1) { | |
192 | uint64_t sum = bitarrays[i]->GetSum(); | |
193 | fprintf(stderr, " set-bit-count=%lld (%7.4f%%))\n", sum, sum*100.0/count); | |
194 | } else { | |
195 | fprintf(stderr, "\n"); | |
196 | } | |
197 | } | |
198 | ||
199 | // int count = raw_records_array->Count(); | |
200 | // fprintf(stderr, "# raw_records_array = %d (%3.4f%%/instr, \t%3.4f%%/rec)\n", count, count*100.0/instr_count, count*100.0/shdr->nrecords); | |
201 | ||
202 | fprintf(stderr, "Size of compressed buffer is %lld (%7.4f bytes/instr, %7.4f bytes/rec)\n", | |
203 | shdr->CompressedBufferSize, shdr->CompressedBufferSize*1.0/instr_count, shdr->CompressedBufferSize*1.0/shdr->nrecords); | |
204 | ||
205 | } // rz3_section_data::print() | |
206 | ||
207 | ||
208 | void rz3_section_data::print_totals() | |
209 | { | |
210 | ||
211 | fprintf(stderr, "\nTotal section array sizes:\n"); | |
212 | fprintf(stderr, "nrecords = %d\n", total_nrecords); | |
213 | ||
214 | int instr_count = total_rz3_bitarray_counts[rstzip3::instr_pred_all_array]; | |
215 | ||
216 | ||
217 | int i; | |
218 | for (i=0; i<rstzip3::bitarray_count; i++) { | |
219 | int count = total_rz3_bitarray_counts[i]; | |
220 | fprintf(stderr, "# total %s = %6d (%7.4f%%/instr, %7.4f%%/rec) %7.4f bits/rec %7.4f%% of all bits", | |
221 | rstzip3::bitarray_descr[i].name, count, count*100.0/instr_count, count*100.0/total_nrecords, | |
222 | count*rstzip3::bitarray_descr[i].nbits*1.0/total_nrecords, count*rstzip3::bitarray_descr[i].nbits*100.0/(8*total_CompressedBufferSize)); | |
223 | if (rstzip3::bitarray_descr[i].nbits == 1) { | |
224 | uint64_t sum = total_rz3_bitarray_sums[i]; | |
225 | fprintf(stderr, " set-bit-count=%lld (%7.4f%%))\n", sum, sum*100.0/count); | |
226 | } else { | |
227 | fprintf(stderr, "\n"); | |
228 | } | |
229 | } | |
230 | ||
231 | // int count = raw_records_array->Count(); | |
232 | // fprintf(stderr, "# raw_records_array = %d (%3.4f%%/instr, \t%3.4f%%/rec)\n", count, count*100.0/instr_count, count*100.0/shdr->nrecords); | |
233 | ||
234 | fprintf(stderr, "Total size of compressed buffer is %lld (%7.4f bytes/instr, %7.4f bytes/rec)\n", | |
235 | total_CompressedBufferSize, total_CompressedBufferSize*1.0/instr_count, total_CompressedBufferSize*1.0/total_nrecords); | |
236 | ||
237 | } // rz3_section_data::print() | |
238 | ||
239 | ||
240 | ||
241 | void rz3_section_data::update_counts() | |
242 | { | |
243 | shdr->CompressedBufferSize = sizeof(rz3_section_header); | |
244 | ||
245 | int i; | |
246 | for (i=0; i<rstzip3::bitarray_count; i++) { | |
247 | shdr->rz3_bitarray_counts[i] = bitarrays[i]->Count(); | |
248 | total_rz3_bitarray_counts[i] += shdr->rz3_bitarray_counts[i]; | |
249 | shdr->CompressedBufferSize += bitarrays[i]->GetMemBufSize(); | |
250 | if (rstzip3::bitarray_descr[i].nbits == 1) { | |
251 | total_rz3_bitarray_sums[i] += bitarrays[i]->GetSum(); | |
252 | } | |
253 | } | |
254 | total_nrecords += shdr->nrecords; | |
255 | total_CompressedBufferSize += shdr->CompressedBufferSize; | |
256 | ||
257 | } // void rz3_section_data::update_counts() | |
258 | ||
259 | ||
260 | // return false if error | |
261 | bool rz3_section_data::write(gzFile gzf) | |
262 | { | |
263 | uint64_t membufsz = shdr->rz3obj->rz3_bufsize; | |
264 | uint8_t * membuf = new uint8_t [membufsz]; | |
265 | ||
266 | int i; | |
267 | for (i=0; i<rstzip3::bitarray_count; i++) { | |
268 | uint64_t sz = bitarrays[i]->GetMemBufSize(); | |
269 | if (sz > membufsz) { | |
270 | membufsz = sz; | |
271 | delete [] membuf; | |
272 | membuf = new uint8_t [membufsz]; | |
273 | } | |
274 | bitarrays[i]->CopyTo(membuf); | |
275 | if (gzwrite(gzf, membuf, sz) != sz) { | |
276 | return false; | |
277 | } | |
278 | } // for each array | |
279 | ||
280 | delete [] membuf; | |
281 | return true; | |
282 | } // rz3_section_data::write() | |
283 | ||
284 | ||
285 | ||
286 | ||
287 | bool rz3_section_data::read(gzFile gzf) | |
288 | { | |
289 | uint64_t membufsz = shdr->rz3obj->rz3_bufsize; | |
290 | uint8_t * membuf = new uint8_t [membufsz]; | |
291 | ||
292 | int i; | |
293 | for (i=0; i<rstzip3::bitarray_count; i++) { | |
294 | uint64_t sz = bitarrays[i]->ComputeMemBufSize(shdr->rz3_bitarray_counts[i]); | |
295 | if (sz > membufsz) { | |
296 | membufsz = sz; | |
297 | delete [] membuf; | |
298 | membuf = new uint8_t [membufsz]; | |
299 | } | |
300 | if (gzread(gzf, membuf, sz) != sz) { | |
301 | return false; | |
302 | } | |
303 | int bytes_copied = (int) bitarrays[i]->CopyFrom(membuf, shdr->rz3_bitarray_counts[i]); | |
304 | if (bytes_copied != sz) { | |
305 | fprintf(stderr, "rz3_section_data: error reading %lld bytes into %s", sz, rstzip3::bitarray_descr[i]); | |
306 | return false; | |
307 | } | |
308 | } // for each array | |
309 | ||
310 | delete [] membuf; | |
311 | return true; | |
312 | } | |
313 | ||
314 | ||
315 | ||
316 | ||
317 | // return false if error | |
318 | bool rz3_section_data::write(FILE * fp) | |
319 | { | |
320 | uint64_t membufsz = shdr->rz3obj->rz3_bufsize; | |
321 | uint8_t * membuf = new uint8_t [membufsz]; | |
322 | ||
323 | int i; | |
324 | for (i=0; i<rstzip3::bitarray_count; i++) { | |
325 | uint64_t sz = bitarrays[i]->GetMemBufSize(); | |
326 | if (sz > membufsz) { | |
327 | membufsz = sz; | |
328 | delete [] membuf; | |
329 | membuf = new uint8_t [membufsz]; | |
330 | } | |
331 | bitarrays[i]->CopyTo(membuf); | |
332 | if (fwrite(membuf, 1, sz, fp) != sz) { | |
333 | return false; | |
334 | } | |
335 | } // for each array | |
336 | ||
337 | delete [] membuf; | |
338 | return true; | |
339 | } // rz3_section_data::write() | |
340 | ||
341 | ||
342 | ||
343 | ||
344 | bool rz3_section_data::read(FILE * fp) | |
345 | { | |
346 | uint64_t membufsz = shdr->rz3obj->rz3_bufsize; | |
347 | uint8_t * membuf = new uint8_t [membufsz]; | |
348 | ||
349 | int i; | |
350 | for (i=0; i<rstzip3::bitarray_count; i++) { | |
351 | uint64_t sz = bitarrays[i]->ComputeMemBufSize(shdr->rz3_bitarray_counts[i]); | |
352 | if (sz > membufsz) { | |
353 | membufsz = sz; | |
354 | delete [] membuf; | |
355 | membuf = new uint8_t [membufsz]; | |
356 | } | |
357 | if (fread(membuf, 1, sz, fp) != sz) { | |
358 | return false; | |
359 | } | |
360 | int bytes_copied = (int) bitarrays[i]->CopyFrom(membuf, shdr->rz3_bitarray_counts[i]); | |
361 | if (bytes_copied != sz) { | |
362 | fprintf(stderr, "rz3_section_data: error reading %lld bytes into %s", sz, rstzip3::bitarray_descr[i]); | |
363 | return false; | |
364 | } | |
365 | } // for each array | |
366 | ||
367 | delete [] membuf; | |
368 | return true; | |
369 | } | |
370 | ||
371 | ||
372 | ||
373 | ||
374 | rz3_percpu_data::rz3_percpu_data(int arg_cpuid) | |
375 | { | |
376 | ||
377 | cpuid = arg_cpuid; | |
378 | ||
379 | icache = new rz3iu_icache; | |
380 | ||
381 | bp = new rz3iu_brpred; | |
382 | ||
383 | jmpl_table = new rz3_table<uint64_t>(rz3_tdata_jmpl_table_size); | |
384 | ||
385 | itlb = new rz3_table<uint64_t>(rz3_tdata_itlb_size); | |
386 | dtlb = new rz3_table<uint64_t>(rz3_tdata_dtlb_size); | |
387 | ||
388 | ras = new rz3_ras; | |
389 | ||
390 | char vcname[32]; | |
391 | sprintf(vcname, "cpu%d", cpuid); | |
392 | valuecache = new rz3_valuecache(vcname); | |
393 | ||
394 | rfs_pc_pred_table = new rz3_table<uint64_t>(rz3_tdata_rfs_pc_pred_table_size); | |
395 | ||
396 | regval_regtype_tbl[0] = new uint8_t [rz3_tdata_regval_regtype_tbl_size]; | |
397 | regval_regtype_tbl[1] = new uint8_t [rz3_tdata_regval_regtype_tbl_size]; | |
398 | ||
399 | regval_regid_tbl[0] = new uint8_t [rz3_tdata_regval_regid_tbl_size]; | |
400 | regval_regid_tbl[1] = new uint8_t [rz3_tdata_regval_regid_tbl_size]; | |
401 | ||
402 | regs = new uint64_t [32]; | |
403 | ||
404 | clear(); | |
405 | } // rz3_percpu_data::rz3_tmp_data() | |
406 | ||
407 | ||
408 | void rz3_percpu_data::clear() | |
409 | { | |
410 | pred_pc = 0x0; | |
411 | pred_npc = 0x0; | |
412 | pred_icontext = 0x0; | |
413 | pred_dcontext = 0x0; | |
414 | pred_amask = 0; | |
415 | pred_an = 0; | |
416 | pred_hpriv = 0; | |
417 | pred_pr = 0; | |
418 | call_delay_slot = false; | |
419 | pending_pavadiff_idx = -1; | |
420 | pending_pavadiff_pc_pa_va_pred = false; | |
421 | pending_pavadiff_ea_pa_va_pred = false; | |
422 | ||
423 | prev_pc = 0x0; | |
424 | ||
425 | rfs_prev_npc = 0x0; | |
426 | ||
427 | icache->clear(); | |
428 | ||
429 | bp->clear(); | |
430 | ||
431 | ras->clear(); | |
432 | ||
433 | jmpl_table->clear(); | |
434 | ||
435 | itlb->clear(); | |
436 | dtlb->clear(); | |
437 | ||
438 | valuecache->Clear(); | |
439 | ||
440 | rfs_pc_pred_table->clear(); | |
441 | ||
442 | bzero(regval_regtype_tbl[0], rz3_tdata_regval_regtype_tbl_size); | |
443 | bzero(regval_regtype_tbl[1], rz3_tdata_regval_regtype_tbl_size); | |
444 | bzero(regval_regid_tbl[0], rz3_tdata_regval_regid_tbl_size); | |
445 | bzero(regval_regid_tbl[1], rz3_tdata_regval_regid_tbl_size); | |
446 | ||
447 | last_instr = 0x0; | |
448 | bzero(regs, 32*sizeof(uint64_t)); | |
449 | ccr = 0; | |
450 | } // rz3_percpu_data::clear() | |
451 | ||
452 | ||
453 | rz3_percpu_data::~rz3_percpu_data() { | |
454 | delete icache; | |
455 | delete bp; | |
456 | delete jmpl_table; | |
457 | delete itlb; | |
458 | delete dtlb; | |
459 | delete valuecache; | |
460 | delete rfs_pc_pred_table; | |
461 | delete regval_regtype_tbl[0]; | |
462 | delete regval_regtype_tbl[1]; | |
463 | delete regval_regid_tbl[0]; | |
464 | delete regval_regid_tbl[1]; | |
465 | ||
466 | delete [] regs; | |
467 | } // rz3_percpu_data::~() |