// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: main.C
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// ========== Copyright Header End ============================================
#include "read_symbols.h"
#define BUFFER_SIZE (128 << 10)
int process_buffer(Trace* itrace, Trace* otrace,
void* itr_buf, void* otr_buf,
static int buffer_instrs = 0;
void* useless = itr_buf; // no CC warnings
i < ntr && gbl.rcount < gbl.maxRecs && gbl.icount < gbl.maxInstrs;
curcpu = itrace->getCpuID();
if (curcpu == -1 || gbl.cpu[curcpu] == 1) {
if (in_range(itrace->get_pc(), gbl.frompc, gbl.topc) &&
in_range(itrace->get_ea(), gbl.fromea, gbl.toea)) {
prev_icount = gbl.icount;
// -patchcleanrst, -pc_pavadiff, -ea_pavadiff done in count()
// these records should be processed...
// only check for instruction opcode errors?
if (itrace->check_ihash_error()) {
fprintf(stderr, "IHash Error (#%llu ih=%d): "
"Incorrect ihash value in input file.\n",
gbl.rcount - 1 + gbl.skipRecs, itrace->get_ihash());
} else /* if not gbl.checkError */ {
// a valid nonzero ihash is assumed valid
if (itrace->check_ihash_error() == 0) {
if (itrace->get_ihash() >= SPIX_SPARC_IOP_BN) {
"\nIHash Error (#%llu ih=%d): "
"Correcting ihash values in output.\n\n",
gbl.rcount - 1 + gbl.skipRecs, itrace->get_ihash());
gbl.genIHash = true; // generate ihash values
// print or convert trace?
if (gbl.totype == NONE) { // then we're printing
idx = gbl.icount - 1 - gbl.skipInstrs;
} else if (gbl.reorderNoIns) {
idx = gbl.rcount - gbl.icount +
gbl.skipRecs + gbl.skipInstrsRecs;
idx = gbl.rcount - 1 + gbl.skipRecs + gbl.skipInstrsRecs;
} else if (gbl.disassembly) {
} else if (gbl.fromtype == RST && gbl.totype == RST) {
otrace->copy_to_rst(itrace->copy_from_rst());
} else { // then we're converting
itrace->convert_to_master();
if (prev_icount != gbl.icount) { // instruction converted?
otrace->convert_from_master(itrace->get_master());
if ((gbl.totype != NONE && prev_icount != gbl.icount) ||
(gbl.fromtype == RST && gbl.totype == RST)) {
if (buffer_instrs == BUFFER_SIZE) {
fwrite(otr_buf, gbl.tosize, buffer_instrs, gbl.outfp);
void process_trace(Trace* itrace, Trace* otrace,
void* itr_buf, void* otr_buf) {
int i, ntr, buffer_instrs;
if (0 && (gbl.infp != stdin)) {
fseeko(gbl.infp, 0, SEEK_END);
filesize = ftello(gbl.infp);
offset = gbl.skipRecs * gbl.fromsize;
fseeko(gbl.infp, offset, SEEK_SET);
fprintf(stderr, "Fewer than %lld records in file '%s' (%lld).\n",
gbl.skipRecs, gbl.infile, filesize / gbl.fromsize);
master_64bit_trace_t *buf;
buf = (master_64bit_trace_t*) malloc(BUFFER_SIZE *
sizeof(master_64bit_trace_t));
for (i = 0; i < gbl.skipRecs / BUFFER_SIZE; i++) {
if (fread(buf, gbl.fromsize, BUFFER_SIZE, gbl.infp) < BUFFER_SIZE) {
fprintf(stderr, "Fewer than %lld records in file '%s'.\n",
gbl.skipRecs, gbl.infile);
if (gbl.fromtype == RST) {
rstf_unionT * ru = (rstf_unionT *) buf;
if (ru->proto.rtype == RSTHEADER_T) {
if (ru->header.majorVer*1000+ru->header.minorVer <= 2011) {
if (fread(buf, gbl.fromsize, (uint32_t)(gbl.skipRecs % BUFFER_SIZE), gbl.infp) <
gbl.skipRecs % BUFFER_SIZE) {
fprintf(stderr, "Fewer than %lld records in file '%s'.\n",
gbl.skipRecs, gbl.infile);
else if (gbl.skipInstrs) {
// if from type is rst, first record must be rstheader
while ((ntr = fread(itr_buf, gbl.fromsize, BUFFER_SIZE, gbl.infp))) {
if (gbl.fromtype == RST) {
rstf_unionT * ru = (rstf_unionT *) itr_buf;
if (ru->proto.rtype == RSTHEADER_T) {
if (ru->header.majorVer*1000+ru->header.minorVer <= 2011) {
for (i = 0; gbl.icount < gbl.skipInstrs && i < ntr; i++) {
itrace->count(); // -patchcleanrst done here
if (gbl.icount == gbl.skipInstrs) {
buffer_instrs = process_buffer(itrace, otrace, itr_buf, otr_buf, i, ntr);
gbl.skipInstrsRecs = gbl.rcount;
while (gbl.rcount < gbl.maxRecs &&
gbl.icount < gbl.maxInstrs &&
(ntr = fread(itr_buf, gbl.fromsize, BUFFER_SIZE, gbl.infp))) {
buffer_instrs = process_buffer(itrace, otrace, itr_buf, otr_buf, 0, ntr);
// any leftover instrs to fwrite...?
fwrite(otr_buf, gbl.tosize, buffer_instrs, gbl.outfp);
if (gbl.verbose || gbl.countOnly) {
int main(int argc, char *argv[]) {
rtf99 itr_rtf99, otr_rtf99;
Shade5 itr_shade5, otr_shade5;
Shade6x32 itr_shade6x32, otr_shade6x32;
Shade6x64 itr_shade6x64, otr_shade6x64;
Master itr_master, otr_master;
RSTF_Union itr_rstf_union, otr_rstf_union;
// make input trace buffer
itr_buf = calloc(BUFFER_SIZE, gbl.fromsize);
"Could not allocate memory for itr_buf[] in main().\n");
// make output trace buffer, if conversion specified
if (gbl.totype != NONE) {
otr_buf = calloc(BUFFER_SIZE, gbl.tosize);
"Could not allocate memory for otr_buf[] in main().\n");
itrace = &itr_rstf_union;
fprintf(stderr, switch_error_string, "fromtype", "main()", gbl.fromtype);
otrace = &otr_rstf_union;
fprintf(stderr, switch_error_string, "totype", "main()", gbl.totype);
process_trace(itrace, otrace, itr_buf, otr_buf);