Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: diffrst.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 "rstf/rstf.h" | |
26 | #include "spix6plus/ITYPES.h" | |
27 | #include "cpuid.h" | |
28 | ||
29 | #define ALWAYS (11) | |
30 | #define NEVER (12) | |
31 | #define ATRACE (13) | |
32 | ||
33 | static int isldst(int ih) { | |
34 | return (ih_isload(ih) || ih_isstore(ih)); | |
35 | } | |
36 | ||
37 | void usage(char* argv[]) { | |
38 | fprintf(stderr, | |
39 | "Usage: %s [-allowdiff ihash|timestamp]+ rstfile1 rstfile2\n\n", | |
40 | argv[0]); | |
41 | fprintf(stderr, | |
42 | "Reads two rst files, writes nonidentical records to diff.rst.\n" | |
43 | "\n" | |
44 | " -allowdiff\n" | |
45 | " ihash Do not compare ihash values\n" | |
46 | " timestamp Do not compare cpu timestamp values\n" | |
47 | " ntbranchea Allow orig nt branch ea to be pc+4 instead of pc+8...\n" | |
48 | " cpuid Allow cpuid fields to differ\n" | |
49 | " rstfile Use - to read from stdin.\n" | |
50 | "\n"); | |
51 | } | |
52 | ||
53 | int doerror(uint64_t rec, rstf_unionT* rst_orig, rstf_unionT* rst_new, FILE* outfp) { | |
54 | rstf_stringT string; | |
55 | ||
56 | string.rtype = STRDESC_T; | |
57 | sprintf(string.string, "Rec# %llu", rec); | |
58 | ||
59 | printf("%s differs\n", string.string); | |
60 | fflush(stdout); | |
61 | ||
62 | fwrite(&string, sizeof(rstf_stringT), 1, outfp); | |
63 | fwrite(rst_orig, sizeof(rstf_unionT), 1, outfp); | |
64 | fwrite(rst_new, sizeof(rstf_unionT), 1, outfp); | |
65 | fflush(outfp); | |
66 | ||
67 | return 1; | |
68 | } | |
69 | ||
70 | int main(int argc, char* argv[]) { | |
71 | rstf_unionT rst[3]; | |
72 | FILE* infp0; | |
73 | FILE* infp1; | |
74 | FILE* outfp; | |
75 | bool allowihashdiff; | |
76 | bool allowtimestampdiff; | |
77 | bool allowntbrancheadiff; | |
78 | bool allowcpuiddiff; | |
79 | uint64_t i, diffrecs; | |
80 | char* a; | |
81 | char* b; | |
82 | char* filename[2]; | |
83 | ||
84 | if (argc < 3) { | |
85 | usage(argv); | |
86 | exit(1); | |
87 | } | |
88 | ||
89 | // Set default flags | |
90 | allowihashdiff = false; | |
91 | allowtimestampdiff = false; | |
92 | allowntbrancheadiff = false; | |
93 | allowcpuiddiff = false; | |
94 | ||
95 | // Parse command line args | |
96 | for (i = 1; i < argc; i++) { | |
97 | a = argv[i]; | |
98 | b = (i < argc) ? argv[i+1] : NULL; | |
99 | ||
100 | if (strcmp("-allowdiff", a) == 0) { | |
101 | if (strcmp("ihash", b) == 0) { | |
102 | allowihashdiff = true; | |
103 | } else if (strcmp("timestamp", b) == 0) { | |
104 | allowtimestampdiff = true; | |
105 | } else if (strcmp("ntbranchea", b) == 0) { | |
106 | allowntbrancheadiff = true; | |
107 | } else if (strcmp("cpuid", b) == 0) { | |
108 | allowcpuiddiff = true; | |
109 | } | |
110 | ||
111 | i++; | |
112 | } else if (i == argc - 2) { | |
113 | if (strcmp("-", a) == 0) { | |
114 | infp0 = stdin; | |
115 | } else { | |
116 | infp0 = fopen(a, "r"); | |
117 | } | |
118 | ||
119 | filename[0] = a; | |
120 | } else if (i == argc - 1) { | |
121 | if (strcmp("-", a) == 0) { | |
122 | infp1 = stdin; | |
123 | filename[1] = a; | |
124 | } else { | |
125 | infp1 = fopen(a, "r"); | |
126 | } | |
127 | } else { | |
128 | usage(argv); | |
129 | fprintf(stderr, "Error: unknown input parameter %s\n", a); | |
130 | exit(1); | |
131 | } | |
132 | } | |
133 | ||
134 | outfp = fopen("diff.rst", "w"); | |
135 | diffrecs = 0; | |
136 | ||
137 | for (i = 0; 1; i++) { | |
138 | fread(&rst[0], sizeof(rstf_unionT), 1, infp0); | |
139 | fread(&rst[1], sizeof(rstf_unionT), 1, infp1); | |
140 | ||
141 | // File size difference? | |
142 | if (feof(infp0) || feof(infp1)) { | |
143 | break; | |
144 | } | |
145 | ||
146 | // Are records the different? | |
147 | if (memcmp(&rst[0], &rst[1], sizeof(rstf_unionT)) != 0) { | |
148 | if (rst[0].proto.rtype == INSTR_T) { | |
149 | rst[2] = rst[0]; | |
150 | ||
151 | // Check ihash | |
152 | if (allowihashdiff == true) { | |
153 | rst[2].instr.ihash = rst[1].instr.ihash; | |
154 | } | |
155 | ||
156 | // Check not taken branch ea | |
157 | if (allowntbrancheadiff == true) { | |
158 | if (ih_isbranch(rst[2].instr.ihash) && rst[2].instr.bt == 0) { | |
159 | if (rst[2].instr.ea_va == rst[1].instr.ea_va - 4) { | |
160 | rst[2].instr.ea_va = rst[1].instr.ea_va; | |
161 | } | |
162 | } | |
163 | } | |
164 | ||
165 | if (allowcpuiddiff == true) { | |
166 | rst[2].instr.cpuid = rst[0].instr.cpuid; | |
167 | } | |
168 | ||
169 | // Ignore invalid ea's | |
170 | if (rst[2].instr.ea_valid == 0) { | |
171 | rst[2].instr.ea_va = rst[1].instr.ea_va; | |
172 | } | |
173 | ||
174 | if (memcmp(&rst[2], &rst[1], sizeof(rstf_unionT)) != 0) { | |
175 | diffrecs += doerror(i, &rst[0], &rst[1], outfp); | |
176 | } | |
177 | } else if (rst[0].proto.rtype == CPU_T) { | |
178 | if (rst[0].cpu.cpu != rst[1].cpu.cpu) { | |
179 | if (allowcpuiddiff == false) { | |
180 | diffrecs += doerror(i, &rst[0], &rst[1], outfp); | |
181 | } | |
182 | } else if (allowtimestampdiff == false) { | |
183 | if (rst[0].cpu.timestamp != rst[1].cpu.timestamp) { | |
184 | diffrecs += doerror(i, &rst[0], &rst[1], outfp); | |
185 | } | |
186 | } | |
187 | } else if (allowcpuiddiff == true) { | |
188 | rst[2] = rst[0]; | |
189 | setRstCpuID(&rst[2], getRstCpuID(&rst[1])); | |
190 | ||
191 | if (memcmp(&rst[2], &rst[1], sizeof(rstf_unionT)) != 0) { | |
192 | diffrecs += doerror(i, &rst[0], &rst[1], outfp); | |
193 | } | |
194 | } else { | |
195 | diffrecs += doerror(i, &rst[0], &rst[1], outfp); | |
196 | } | |
197 | } | |
198 | } | |
199 | ||
200 | fprintf(stdout, "\nTotal: %llu recs differ\n", diffrecs); | |
201 | ||
202 | if (feof(infp0) == 0 || feof(infp1) == 0) { | |
203 | fprintf(stdout, "\nWarning: input filesizes differ.\n"); | |
204 | } | |
205 | ||
206 | fclose(infp0); | |
207 | fclose(infp1); | |
208 | fclose(outfp); | |
209 | ||
210 | return 0; | |
211 | } |