Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / rst / trconv / main.C
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: main.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#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25#include "read_symbols.h"
26#include "trconv.H"
27
28#define BUFFER_SIZE (128 << 10)
29
30int process_buffer(Trace* itrace, Trace* otrace,
31 void* itr_buf, void* otr_buf,
32 int start, int ntr) {
33 int i;
34 static int buffer_instrs = 0;
35 uint64_t prev_icount;
36 int curcpu = -1;
37 void* useless = itr_buf; // no CC warnings
38
39 for (i = start;
40 i < ntr && gbl.rcount < gbl.maxRecs && gbl.icount < gbl.maxInstrs;
41 i++) {
42 itrace->count();
43
44 curcpu = itrace->getCpuID();
45 if (curcpu == -1 || gbl.cpu[curcpu] == 1) {
46 if (in_range(itrace->get_pc(), gbl.frompc, gbl.topc) &&
47 in_range(itrace->get_ea(), gbl.fromea, gbl.toea)) {
48 prev_icount = gbl.icount;
49 // -patchcleanrst, -pc_pavadiff, -ea_pavadiff done in count()
50
51 // these records should be processed...
52 if (!gbl.countOnly) {
53 // only check for instruction opcode errors?
54 if (gbl.checkError) {
55 if (itrace->check_ihash_error()) {
56 fprintf(stderr, "IHash Error (#%llu ih=%d): "
57 "Incorrect ihash value in input file.\n",
58 gbl.rcount - 1 + gbl.skipRecs, itrace->get_ihash());
59 }
60 } else /* if not gbl.checkError */ {
61 // is ihash valid?
62 if (gbl.checkIHash) {
63 // a valid nonzero ihash is assumed valid
64 if (itrace->check_ihash_error() == 0) {
65 if (itrace->get_ihash() >= SPIX_SPARC_IOP_BN) {
66 gbl.checkIHash = false;
67 }
68 } else { // ERROR!!!
69 fprintf(stderr,
70 "\nIHash Error (#%llu ih=%d): "
71 "Correcting ihash values in output.\n\n",
72 gbl.rcount - 1 + gbl.skipRecs, itrace->get_ihash());
73 gbl.checkIHash = false;
74 gbl.genIHash = true; // generate ihash values
75 }
76 } // if gbl.checkIHash
77
78 // generate ihash?
79 if (gbl.genIHash) {
80 itrace->gen_ihash();
81 }
82
83 // print or convert trace?
84 if (gbl.totype == NONE) { // then we're printing
85 uint64_t idx;
86
87 if (gbl.reorderIns) {
88 idx = gbl.icount - 1 - gbl.skipInstrs;
89 } else if (gbl.reorderNoIns) {
90 idx = gbl.rcount - gbl.icount +
91 gbl.skipRecs + gbl.skipInstrsRecs;
92 } else {
93 idx = gbl.rcount - 1 + gbl.skipRecs + gbl.skipInstrsRecs;
94 }
95
96 if (gbl.record) {
97 itrace->print_rec(idx);
98 } else if (gbl.disassembly) {
99 itrace->print_dasm(idx);
100 } else {
101 itrace->print_verb(idx);
102 }
103 } else if (gbl.fromtype == RST && gbl.totype == RST) {
104 otrace->copy_to_rst(itrace->copy_from_rst());
105 } else { // then we're converting
106 itrace->convert_to_master();
107
108 if (prev_icount != gbl.icount) { // instruction converted?
109 otrace->convert_from_master(itrace->get_master());
110 }
111 }
112 } // checkError?
113 } // if !gbl.countOnly
114
115 if ((gbl.totype != NONE && prev_icount != gbl.icount) ||
116 (gbl.fromtype == RST && gbl.totype == RST)) {
117 otrace->inc_tr();
118 buffer_instrs++;
119
120 if (buffer_instrs == BUFFER_SIZE) {
121 otrace->reset_tr();
122 fwrite(otr_buf, gbl.tosize, buffer_instrs, gbl.outfp);
123 buffer_instrs = 0;
124 }
125 }
126 } // in_range pc, ea?
127 }
128
129 itrace->inc_tr();
130 }
131
132 return buffer_instrs;
133}
134
135void process_trace(Trace* itrace, Trace* otrace,
136 void* itr_buf, void* otr_buf) {
137 int i, ntr, buffer_instrs;
138
139 itrace->set_tr(itr_buf);
140 if (otrace != NULL) {
141 otrace->set_tr(otr_buf);
142 }
143
144 if (gbl.skipRecs) {
145
146 if (0 && (gbl.infp != stdin)) {
147 off_t offset;
148 off_t filesize;
149
150 fseeko(gbl.infp, 0, SEEK_END);
151 filesize = ftello(gbl.infp);
152
153 offset = gbl.skipRecs * gbl.fromsize;
154
155 if (offset < filesize) {
156 fseeko(gbl.infp, offset, SEEK_SET);
157 } else {
158 fprintf(stderr, "Fewer than %lld records in file '%s' (%lld).\n",
159 gbl.skipRecs, gbl.infile, filesize / gbl.fromsize);
160 exit(2);
161 }
162 } else {
163 master_64bit_trace_t *buf;
164
165 buf = (master_64bit_trace_t*) malloc(BUFFER_SIZE *
166 sizeof(master_64bit_trace_t));
167
168 for (i = 0; i < gbl.skipRecs / BUFFER_SIZE; i++) {
169 if (fread(buf, gbl.fromsize, BUFFER_SIZE, gbl.infp) < BUFFER_SIZE) {
170 fprintf(stderr, "Fewer than %lld records in file '%s'.\n",
171 gbl.skipRecs, gbl.infile);
172 exit(2);
173 if (gbl.fromtype == RST) {
174 rstf_unionT * ru = (rstf_unionT *) buf;
175 if (ru->proto.rtype == RSTHEADER_T) {
176 if (ru->header.majorVer*1000+ru->header.minorVer <= 2011) {
177 gbl.rstf_pre212 = true;
178 }
179 } // if rstheader
180 } // if fromtype==rst
181 } // if not end-of-file
182 } // for skip recs
183
184 if (fread(buf, gbl.fromsize, (uint32_t)(gbl.skipRecs % BUFFER_SIZE), gbl.infp) <
185 gbl.skipRecs % BUFFER_SIZE) {
186 fprintf(stderr, "Fewer than %lld records in file '%s'.\n",
187 gbl.skipRecs, gbl.infile);
188 exit(2);
189 }
190
191 free(buf);
192 }
193 }
194
195 else if (gbl.skipInstrs) {
196 // if from type is rst, first record must be rstheader
197
198 while ((ntr = fread(itr_buf, gbl.fromsize, BUFFER_SIZE, gbl.infp))) {
199 if (gbl.fromtype == RST) {
200 rstf_unionT * ru = (rstf_unionT *) itr_buf;
201 if (ru->proto.rtype == RSTHEADER_T) {
202 if (ru->header.majorVer*1000+ru->header.minorVer <= 2011) {
203 gbl.rstf_pre212 = true;
204 }
205 }
206 }
207 for (i = 0; gbl.icount < gbl.skipInstrs && i < ntr; i++) {
208 itrace->count(); // -patchcleanrst done here
209 itrace->inc_tr();
210 }
211
212 if (gbl.icount == gbl.skipInstrs) {
213 break;
214 }
215
216 itrace->reset_tr();
217 }
218
219 buffer_instrs = process_buffer(itrace, otrace, itr_buf, otr_buf, i, ntr);
220
221 if (gbl.verify) {
222 itrace->verify();
223 }
224
225 itrace->reset_tr();
226
227 gbl.skipInstrsRecs = gbl.rcount;
228 gbl.rcount = 0;
229 gbl.icount = 0;
230 }
231
232 while (gbl.rcount < gbl.maxRecs &&
233 gbl.icount < gbl.maxInstrs &&
234 (ntr = fread(itr_buf, gbl.fromsize, BUFFER_SIZE, gbl.infp))) {
235 buffer_instrs = process_buffer(itrace, otrace, itr_buf, otr_buf, 0, ntr);
236
237 if (gbl.verify) {
238 itrace->verify();
239 }
240
241 itrace->reset_tr();
242 }
243
244 // any leftover instrs to fwrite...?
245 if (buffer_instrs) {
246 fwrite(otr_buf, gbl.tosize, buffer_instrs, gbl.outfp);
247 }
248
249 if (gbl.verbose || gbl.countOnly) {
250 print_counts(gbl.msgfp);
251 }
252}
253
254int main(int argc, char *argv[]) {
255 void* itr_buf;
256 void* otr_buf;
257 Trace* itrace;
258 Trace* otrace;
259 rtf99 itr_rtf99, otr_rtf99;
260 Shade5 itr_shade5, otr_shade5;
261 Shade6x32 itr_shade6x32, otr_shade6x32;
262 Shade6x64 itr_shade6x64, otr_shade6x64;
263 Master itr_master, otr_master;
264 RSTF_Union itr_rstf_union, otr_rstf_union;
265
266 init_globals(argv);
267 parse_args(argc, argv);
268
269 // make input trace buffer
270 itr_buf = calloc(BUFFER_SIZE, gbl.fromsize);
271 if (itr_buf == NULL) {
272 fprintf(stderr,
273 "Could not allocate memory for itr_buf[] in main().\n");
274 exit(2);
275 }
276
277 // make output trace buffer, if conversion specified
278 if (gbl.totype != NONE) {
279 otr_buf = calloc(BUFFER_SIZE, gbl.tosize);
280 if (otr_buf == NULL) {
281 fprintf(stderr,
282 "Could not allocate memory for otr_buf[] in main().\n");
283 exit(2);
284 }
285 }
286
287 switch (gbl.fromtype) {
288 case RTF99:
289 itrace = &itr_rtf99;
290 break;
291 case SHADE5:
292 itrace = &itr_shade5;
293 break;
294 case SHADE6x32:
295 itrace = &itr_shade6x32;
296 break;
297 case SHADE6x64:
298 itrace = &itr_shade6x64;
299 break;
300 case MASTER64:
301 itrace = &itr_master;
302 break;
303 case RST:
304 itrace = &itr_rstf_union;
305 break;
306 case NONE:
307 usage(argv[0]);
308 exit(1);
309 default:
310 fprintf(stderr, switch_error_string, "fromtype", "main()", gbl.fromtype);
311 exit(2);
312 }
313
314 switch (gbl.totype) {
315 case RTF99:
316 otrace = &otr_rtf99;
317 break;
318 case SHADE5:
319 otrace = &otr_shade5;
320 break;
321 case SHADE6x32:
322 otrace = &otr_shade6x32;
323 break;
324 case SHADE6x64:
325 otrace = &otr_shade6x64;
326 break;
327 case MASTER64:
328 otrace = &otr_master;
329 break;
330 case RST:
331 otrace = &otr_rstf_union;
332 break;
333 case NONE:
334 otrace = NULL;
335 break;
336 default:
337 fprintf(stderr, switch_error_string, "totype", "main()", gbl.totype);
338 exit(2);
339 }
340
341 process_trace(itrace, otrace, itr_buf, otr_buf);
342
343 return 0;
344} // main()