Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / rst / rstzip3 / rstzip_v3 / rstzip3.C
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: rstzip3.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.C
22 * the RZ3 compressor/decompressor
23 *
24 * Copyright (C) 2003 Sun Microsystems, Inc.
25 * All Rights Reserved
26 */
27
28
29#ident "@(#)1.4 06/28/04 SMI rstzip3.C"
30
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <assert.h>
36#include <strings.h>
37#include <unistd.h>
38#include <ctype.h>
39
40#include "zlib.h"
41
42#include "rstf/rstf.h"
43
44#include "rstzip3.h"
45
46#include "rz3_section.h"
47
48
49rz3_bitarray_descr rstzip3::bitarray_descr[] = {
50
51 {"rtype_key_array ", 2, rz3_bufsize_default},
52 {"rtype_array ", 8, rz3_bufsize_default >>4},
53
54 {"cpuid_pred_array ", 1, rz3_bufsize_default},
55 {"raw_cpuid_array ", 10, (rz3_bufsize_default>>4)}, // was 6 in older versions
56
57 {"instr_pred_all_array ", 1, rz3_bufsize_default},
58 {"instr_pred_raw_array ", 8, rz3_bufsize_default>>4}, // was 7 in v3.19 and older
59
60 {"raw_instr_array ", 32, (rz3_bufsize_default>>4)},
61
62 {"dcti_ea_va_pred_array ", 1, rz3_bufsize_default>>4},
63
64 {"value_iszero_array ", 1, rz3_bufsize_default>>2},
65
66 {"valuecache_level_array ", 3, rz3_bufsize_default>>2},
67
68
69 {"valuecache_data0_array ", rz3_valuecache_idxbits0 + rz3_valuecache_lsbits0, rz3_bufsize_default>>2},
70 {"valuecache_data1_array ", rz3_valuecache_idxbits1 + rz3_valuecache_lsbits1, rz3_bufsize_default>>3},
71 {"valuecache_data2_array ", rz3_valuecache_idxbits2 + rz3_valuecache_lsbits2, rz3_bufsize_default>>4},
72 {"valuecache_data3_array ", rz3_valuecache_idxbits3 + rz3_valuecache_lsbits3, rz3_bufsize_default>>5},
73 {"valuecache_data4_array ", rz3_valuecache_idxbits4 + rz3_valuecache_lsbits4, rz3_bufsize_default>>6},
74 {"valuecache_data5_array ", rz3_valuecache_idxbits5 + rz3_valuecache_lsbits5, rz3_bufsize_default>>7},
75 {"valuecache_data6_array ", rz3_valuecache_idxbits6 + rz3_valuecache_lsbits6, rz3_bufsize_default>>8},
76
77 {"raw_value64_array ", 64, rz3_bufsize_default>>6},
78
79 {"regval_postInstr_array ", 1, (rz3_bufsize_default>>1)},
80 {"regval_regtype_pred_array ", 1, rz3_bufsize_default},
81 {"regval_raw_regtype_array ", 8, rz3_bufsize_default>>4},
82 {"regval_regid_pred_array ", 1, rz3_bufsize_default},
83 {"regval_raw_regid_array ", 8, rz3_bufsize_default>>4},
84
85 {"memval_fields_array ", 1, rz3_bufsize_default>>4},
86 {"memval_size_array ", 3, rz3_bufsize_default>>4},
87 {"memval_addr36_43_array ", 8, rz3_bufsize_default>>6},
88 {"memval_addr04_35_array ", 32, rz3_bufsize_default>>6},
89
90 {"pavadiff_ictxt_pred_array ", 1, rz3_bufsize_default>>2},
91 {"pavadiff_raw_ictxt_array ", 13, rz3_bufsize_default>>4},
92 {"pavadiff_pc_pa_va_pred_array ", 1, rz3_bufsize_default>>2},
93 {"pavadiff_ea_valid_array ", 1, rz3_bufsize_default>>2},
94 {"pavadiff_dctxt_pred_array ", 1, rz3_bufsize_default>>2},
95 {"pavadiff_raw_dctxt_array ", 13, rz3_bufsize_default>>4},
96 {"pavadiff_ea_pa_va_pred_array ", 1, rz3_bufsize_default>>2},
97 {"pavadiff_lookahead_array ", 1, rz3_bufsize_default>>8},
98
99 {"tlb_info_array ", 30, rz3_bufsize_default>>4}, // was 26bytes in v3.19 and older
100
101 {"trap_info_array ", 49, rz3_bufsize_default>>4},
102
103 {"dma_iswrite_array ", 1, rz3_bufsize_default>>6},
104 {"dma_nbytes_array ", 32, rz3_bufsize_default>>6},
105
106 {"rfs_rtype_pred_array ", 1, rz3_bufsize_default>>4},
107 {"rfs_pc_pred_array ", 1, rz3_bufsize_default>>4},
108 {"rfs_instr_pred_array ", 1, rz3_bufsize_default>>4},
109 {"rfs_bt_pred_array ", 1, rz3_bufsize_default>>4},
110 {"rfs_cw_raw_reftype_array ", 3, rz3_bufsize_default>>4},
111 {"rfs_raw_cpuid_array ", 10, rz3_bufsize_default>>4},
112 {"rfs_cw_dma_size_array ", 32, rz3_bufsize_default>>6},
113 {"rfs_cw_asi_array ", 8, rz3_bufsize_default>>4},
114 {"rfs_cw_pf_fcn_array ", 5, rz3_bufsize_default>>6},
115 {"rfs_cw_va_valid_array ", 1, rz3_bufsize_default>>4},
116 {"rfs_cw_pa_pred_array ", 1, rz3_bufsize_default>>4},
117
118}; // struct rz3_bitarray_descr rstzip3::bitarray_descr[]
119
120
121
122// the rel field is a parameter relative to which to print stats
123// (in addition to per record and per instr). eg raw-regvals per regval.
124// ps_max => none
125struct rz3_perf_stats_descr rstzip3::perf_stats_descr[] = {
126
127
128 {"nrecords ", rstzip3::ps_MAX},
129 {"instr_counts ", rstzip3::ps_MAX},
130
131 {"brpred_refs ", rstzip3::ps_MAX},
132 {"brpred_misses ", rstzip3::ps_brpred_refs},
133
134 {"an_misses ", rstzip3::ps_MAX},
135
136 {"ras_refs ", rstzip3::ps_MAX},
137 {"ras_misses ", rstzip3::ps_ras_refs},
138
139 {"ea_valid_misses ", rstzip3::ps_MAX},
140 {"ea_va_valuecache_refs ", rstzip3::ps_MAX},
141 {"ea_va_valuecache_misses ", rstzip3::ps_ea_va_valuecache_refs},
142
143 {"regval_records ", rstzip3::ps_MAX},
144 {"regval_raw_regtype_count ", rstzip3::ps_regval_records},
145 {"regval_raw_regid_count ", rstzip3::ps_regval_records},
146 {"regval_valuecache_refs ", rstzip3::ps_regval_records},
147 {"regval_valuecache_misses ", rstzip3::ps_regval_valuecache_refs},
148
149 {"pavadiff_count ", rstzip3::ps_MAX},
150 {"pavadiff_ictxt_misses ", rstzip3::ps_pavadiff_count},
151 {"pavadiff_raw_pc_pa ", rstzip3::ps_pavadiff_count},
152 {"pavadiff_ea_valid_count ", rstzip3::ps_pavadiff_count},
153 {"pavadiff_dctxt_misses ", rstzip3::ps_pavadiff_count},
154 {"pavadiff_raw_ea_pa_va ", rstzip3::ps_pavadiff_count}
155
156}; // struct rz3_perf_stats_descr rstzip3::perf_stats_descr = {}
157
158
159rstzip3::rstzip3(const char * fname, const char * mode)
160{
161 rz3_error = false;
162
163 verbose = false;
164 stats = false;
165 g0_nonzero_warn = true; // will be set to false after first instance unless verbose
166
167 if ((mode == NULL) || (mode[0] == 0)) {
168 fprintf(stderr, "ERROR: rz3: mode must be specified as \"r\" or \"w\"\n");
169 rz3_error = true;
170 return;
171 } else if (strcmp(mode, "r") == 0) {
172 c_nd = false;
173 } else if (strcmp(mode, "w") == 0) {
174 c_nd = true;
175 } else {
176 fprintf(stderr, "ERROR: rz3: mode must be specified as \"r\" or \"w\"\n");
177 rz3_error = true;
178 return;
179 }
180
181 header = new rz3_header;
182
183 shdr = new rz3_section_header(this);
184
185 if (c_nd) {
186
187 rz3_bufsize = rz3_bufsize_default;
188
189 if (fname != NULL) {
190 gzf = gzopen(fname, "w");
191 if (gzf == NULL) {
192 fprintf(stderr, "ERROR: rz3: failed gzopen of output file "); perror(fname);
193 rz3_error = true;
194 return;
195 }
196 } else {
197 gzf = gzdopen(STDOUT_FILENO, "w");
198 if (gzf == NULL) {
199 perror("ERROR: rz3: failed gzdopen of STDOUT");
200 rz3_error = true;
201 return;
202 }
203 }
204
205 // write header
206 strcpy(header->magic, rz3_hdr_magic);
207 header->major_version = rstzip3_major_version;
208 header->minor_version = rstzip3_minor_version;
209 header->reserved16 = 0;
210 header->reserved32 = 0;
211 gzwrite(gzf, header, sizeof(rz3_header));
212
213 strcpy(shdr->magic, rz3_shdr_magic);
214
215 rstf_pre212 = false; // set to true if necessary upon reading rst header record
216
217 pre320 = false;
218
219 pre323 = false;
220
221 } else /* decompress */ {
222 if (fname != NULL) {
223 gzf = gzopen(fname, "r");
224 if (gzf == NULL) {
225 fprintf(stderr, "ERROR: rz3: failed gzopen of input file "); perror(fname);
226 rz3_error = true;
227 return;
228 }
229 } else /* stdin */{
230 gzf = gzdopen(STDIN_FILENO, "r");
231 if (gzf == NULL) {
232 perror("ERROR: rz3: failed gzdopen of STDIN");
233 rz3_error = true;
234 return;
235 }
236 }
237
238 // read header
239 int nbytes = gzread(gzf, header, sizeof(rz3_header));
240 if (nbytes != sizeof(rz3_header)) {
241 int errnum;
242 fprintf(stderr, "ERROR: gzread rz3 header from input file: %s"); gzerror(gzf, &errnum);
243 fprintf(stderr, "errnum %d\n", errnum);
244 rz3_error = true;
245 return;
246 }
247
248 // check header
249 if ((header->magic[0] == 0) || strcmp(rz3_hdr_magic, header->magic)) {
250 fprintf(stderr, "ERROR: rz3 header magic string mismatch\n");
251 if (verbose) {
252 fprintf(stderr, " expected: %s\n", rz3_hdr_magic);
253 fprintf(stderr, " saw: ");
254 int i;
255 for (i=0; i<15; i++) {
256 if (isprint(header->magic[i])) fprintf(stderr, "%c", header->magic[i]); else fprintf(stderr, "\\%03o", (int) header->magic[i]);
257 }
258 }
259 rz3_error = true;
260 return;
261 }
262
263 // version must be >= 3.15. v3.14beta was the first beta version which is not supported
264 if ((header->major_version == 3) && (header->minor_version == 14)) {
265 fprintf(stderr, "ERROR: rstzip v3.14beta is an unsupported version.\n");
266 fprintf(stderr, "Please decompress this file using the stand-alone rstzip v3.14beta binary,\n");
267 fprintf(stderr, "and recompress using the latest rstzip3 compressor\n");
268 rz3_error = true;
269 return;
270 }
271
272 // check if our major/minor version is >= version number from file
273 float f1 = rstzip3_major_version + rstzip3_minor_version/1000.0;
274 float f2 = header->major_version + header->minor_version/1000.0;
275 if (f2 > f1) {
276 fprintf(stderr, "ERROR: version number of compressed file (%d.%03d) is greater than this build (%d.%03d)\n",
277 header->major_version, header->minor_version, rstzip3_major_version, rstzip3_minor_version);
278 rz3_error = true;
279 return;
280 }
281
282 if ((header->major_version == 3) && (header->minor_version <= 19)) {
283 pre320 = true;
284 } else {
285 pre320 = false;
286 }
287 rstf_pre212 = false; // this variable is ignored during decompression
288
289 if ((header->major_version == 3) && (header->minor_version <= 21)) {
290 rz3_bufsize = rz3_bufsize_pre322;
291 } else {
292 rz3_bufsize = rz3_bufsize_default;
293 }
294
295 if ((header->major_version == 3) && (header->minor_version <= 22)) {
296 pre323 = true;
297 } else {
298 pre323 = false;
299 }
300 } // compress/decompress?
301
302 sdata = new rz3_section_data(shdr, pre320);
303
304 clear(); // clear prediction-related state variables
305
306 tdata = new rz3_percpu_data * [rz3_max_ncpus];
307
308 int i;
309 for (i=0; i<(rz3_max_ncpus); i++) {
310 tdata[i] = NULL;
311 }
312
313
314 interface_buffer = new rstf_unionT[rz3_bufsize];
315 interface_buffer_size = interface_buffer_count = 0;
316
317 rfs_phase = false;
318 rfs_cw_phase = false;
319 rfs_bt_phase = false;
320
321 nsections = 0;
322
323 perf_stats = new int [ps_MAX];
324 perf_stat_totals = new int64_t [ps_MAX];
325 for (i=0; i<ps_MAX; i++) {
326 perf_stat_totals[i] = 0;
327 }
328 raw_v64_count=0;
329 if (!c_nd) {
330 // testfp = fopen("/tmp/rz3tmp.rst", "w");
331 } else {
332 testfp = NULL;
333 }
334} // rstzip3::rstzip3(const char * fname, const char * mode)
335
336
337rstzip3::~rstzip3()
338{
339 if (c_nd) {
340 if (interface_buffer_count != 0) {
341 compress_buffer(interface_buffer, interface_buffer_count);
342 interface_buffer_count = 0;
343 }
344 } else {
345 // caller did not wait to read all decompressed records. ignore
346 }
347 if (sdata != NULL) {
348 if (verbose) sdata->print_totals();
349 if (verbose) {
350 int i;
351 for (i=0; i<rz3_max_ncpus; i++) {
352 if (tdata[i] != NULL) {
353 tdata[i]->valuecache->Report(stderr);
354 }
355 }
356 }
357 if (stats) print_stat_totals();
358 }
359
360 if (gzf != NULL) {
361 gzclose(gzf); gzf = NULL;
362 }
363
364 delete shdr; shdr = NULL;
365 delete sdata; sdata = NULL;
366
367 int i;
368 for (i=0; i<(rz3_max_ncpus); i++) {
369 if (tdata[i] != NULL) {
370 delete tdata[i]; tdata[i] = NULL;
371 }
372 }
373 delete [] tdata; tdata = NULL;
374
375 if (interface_buffer != NULL) {
376 delete [] interface_buffer;
377 }
378} // rstzip3::~rstzip3()
379
380
381
382int rstzip3::compress(rstf_unionT * buf, int nrec)
383{
384 // if interface buffer count is non-zero, copy in records to fill up buffer
385 int done = 0;
386 if (interface_buffer_count) {
387 int n = (rz3_bufsize - interface_buffer_count);
388 if (n > nrec) n = nrec;
389 memcpy(interface_buffer+interface_buffer_count, buf, n*sizeof(rstf_unionT));
390 interface_buffer_count += n;
391 if (interface_buffer_count == rz3_bufsize) {
392 compress_buffer(interface_buffer, rz3_bufsize);
393 interface_buffer_count = 0;
394 }
395 done += n;
396 if (done == nrec) {
397 return done;
398 }
399 }
400
401 // at this point, there are no records waiting to be compressed in the buffer
402 while((nrec-done) >= rz3_bufsize) {
403 compress_buffer(buf+done, rz3_bufsize);
404 done += rz3_bufsize;
405 }
406
407 // at this point, the buffer is empty; there may be some records left to be
408 // compressed, but not enough to fill the buffer
409 if (done < nrec) {
410 memcpy(interface_buffer, buf+done, (nrec-done)*sizeof(rstf_unionT));
411 interface_buffer_count += (nrec-done);
412 }
413 return nrec;
414
415} // int rstzip3::compress(rstf_unionT * buf, int nrec)
416
417
418int rstzip3::decompress(rstf_unionT * buf, int nrec)
419{
420 // if there are some records ready to be
421 // copied out, copy out as many as possible
422 int done = 0;
423 if (interface_buffer_count) {
424 int n = interface_buffer_count;
425 if (n > nrec) n = nrec;
426
427 memcpy(buf+done, interface_buffer+(interface_buffer_size-interface_buffer_count), n*sizeof(rstf_unionT));
428 interface_buffer_count -= n;
429 done += n;
430 if (done == nrec) return nrec;
431 }
432
433 // at this point, if we haven't returned, done < nrec and interface_buffer_count == 0
434 // decompress the next section.
435 while((nrec-done) >= rz3_bufsize) {
436 int n = decompress_buffer(buf+done, rz3_bufsize); // returns the actual number of records decmopressed
437 // this should be equal to rz3_bufsize unless we reached the end of file
438 if (n == 0) return done;
439 done += n;
440 }
441
442 // at this point, the number of records that can be copied to the caller is < rz3_bufsize.
443 // to avoid buffer overflow, we use the interface buffer once again
444 while(done < nrec) {
445 interface_buffer_size = decompress_buffer(interface_buffer, rz3_bufsize);
446 if (interface_buffer_size == 0) return done;
447
448 interface_buffer_count = interface_buffer_size;
449
450 // how many can we copy out?
451 int n = interface_buffer_size;
452 if (n > (nrec-done)) n = (nrec-done);
453
454 // copy and update (decrement) buffer count
455 memcpy(buf+done, interface_buffer+(interface_buffer_size-interface_buffer_count), n*sizeof(rstf_unionT));
456 done += n;
457 interface_buffer_count -= n;
458 }
459 // at this point done = nrec.
460 return nrec;
461
462} // rstzip3::decompress(rstf_unionT * buf, int nrec)
463
464
465bool rstzip3::error() {
466 return rz3_error;
467} // bool rstzip3::error() {
468
469
470
471void rstzip3::setverbose() {
472 verbose = true;
473} // rstzip3::setverbose()
474
475
476void rstzip3::setstats() {
477 stats = true;
478} // void rstzip3::setstats() {
479
480
481
482void rstzip3::clear()
483{
484 pred_cpuid = 0;
485 last_instr_cpuid = 0;
486 rfs_cw_phase = false;
487 rfs_bt_phase = false;
488 rfs_nrecords = 0;
489 rfs_records_seen = 0;
490 prev_rtype = 0;
491} // void rstzip3::clear()
492
493void rstzip3::clear_stats()
494{
495 // bzero(perf_stats, ps_MAX * sizeof(int));
496 memset(perf_stats, 0, ps_MAX * sizeof(int));
497} // void rstzip3::clear_stats()
498
499
500void rstzip3::print_stats()
501{
502 int i;
503 fprintf(stderr, "\nPerformance statistics for this section:\n");
504 for (i=0; i<ps_MAX; i++) {
505 fprintf(stderr, "%s \t%d \t%0.4f%%/rec \t%0.4f%%/instr", perf_stats_descr[i].name, perf_stats[i],
506 perf_stats[i]*100.0/perf_stats[ps_nrecords], perf_stats[i]*100.0/perf_stats[ps_instr_count]);
507
508 if (perf_stats_descr[i].rel != ps_MAX) {
509 int rel = perf_stats_descr[i].rel;
510 fprintf(stderr, " \t%0.4f%%/%s", perf_stats[i]*100.0/perf_stats[rel], perf_stats_descr[rel].name);
511 }
512 fprintf(stderr, "\n");
513 }
514} // void rstzip3::print_stats()
515
516
517void rstzip3::print_stat_totals()
518{
519 int i;
520 fprintf(stderr, "\nOverall performance statistics:\n");
521 for (i=0; i<ps_MAX; i++) {
522 fprintf(stderr, "total %s \t%lld \t%0.4f%%/rec \t%0.4f%%/instr", perf_stats_descr[i].name, perf_stat_totals[i],
523 perf_stat_totals[i]*100.0/perf_stat_totals[ps_nrecords], perf_stat_totals[i]*100.0/perf_stat_totals[ps_instr_count]);
524
525 if (perf_stats_descr[i].rel != ps_MAX) {
526 int rel = perf_stats_descr[i].rel;
527 fprintf(stderr, " \t%0.4f%%/%s", perf_stat_totals[i]*100.0/perf_stat_totals[rel], perf_stats_descr[rel].name);
528 }
529 fprintf(stderr, "\n");
530 }
531} // void rstzip3::print_stat_totals()
532
533
534
535void rstzip3::update_stats()
536{
537 // update some stats using sdata array counts
538 perf_stats[ps_nrecords] = shdr->nrecords;
539 perf_stats[ps_instr_count] = shdr->rz3_bitarray_counts[instr_pred_all_array];
540 // brpred_refs
541 // brpred_misses
542 // an_misses
543 // ras_refs
544 // ras_misses
545 // ea_valid_misses
546 // ea_lookup_table_misses
547 perf_stats[ps_regval_records] = shdr->rz3_bitarray_counts[regval_postInstr_array];
548 perf_stats[ps_regval_raw_regtype_count] = shdr->rz3_bitarray_counts[regval_raw_regtype_array];
549 perf_stats[ps_regval_raw_regid_count] = shdr->rz3_bitarray_counts[regval_raw_regid_array];
550 perf_stats[ps_pavadiff_count] = shdr->rz3_bitarray_counts[pavadiff_ictxt_pred_array];
551 perf_stats[ps_pavadiff_ictxt_misses] = shdr->rz3_bitarray_counts[pavadiff_raw_ictxt_array];
552 perf_stats[ps_pavadiff_ea_valid_count] = shdr->rz3_bitarray_counts[pavadiff_dctxt_pred_array];
553 perf_stats[ps_pavadiff_dctxt_misses] = shdr->rz3_bitarray_counts[pavadiff_raw_dctxt_array];
554
555 int i;
556 for (i=0; i<ps_MAX; i++) {
557 perf_stat_totals[i] += perf_stats[i];
558 }
559} // void rstzip3::update_stats()
560
561