decode: Add a facility field to the instruction decode tables
[microwatt.git] / scripts / fmt_log / fmt_log.c
1 #include <stddef.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4
5 typedef unsigned long long u64;
6
7 struct log_entry {
8 u64 nia_lo: 42;
9 u64 nia_hi: 1;
10 u64 ic_ra_valid: 1;
11 u64 ic_access_ok: 1;
12 u64 ic_is_miss: 1;
13 u64 ic_is_hit: 1;
14 u64 ic_way: 3;
15 u64 ic_state: 1;
16 u64 ic_part_nia: 4;
17 u64 ic_fetch_failed: 1;
18 u64 ic_stall_out: 1;
19 u64 ic_wb_stall: 1;
20 u64 ic_wb_cyc: 1;
21 u64 ic_wb_stb: 1;
22 u64 ic_wb_adr: 3;
23 u64 ic_wb_ack: 1;
24
25 u64 ic_insn: 32;
26 u64 ic_valid: 1;
27 u64 d1_valid: 1;
28 u64 d1_unit: 2;
29 u64 d1_part_nia: 4;
30 u64 d1_insn_type: 6;
31 u64 d2_bypass_a: 1;
32 u64 d2_bypass_b: 1;
33 u64 d2_bypass_c: 1;
34 u64 d2_stall_out: 1;
35 u64 d2_stopped_out: 1;
36 u64 d2_valid: 1;
37 u64 d2_part_nia: 4;
38 u64 e1_flush_out: 1;
39 u64 e1_stall_out: 1;
40 u64 e1_redirect: 1;
41 u64 e1_valid: 1;
42 u64 e1_write_enable: 1;
43 u64 e1_unused: 3;
44
45 u64 e1_irq_state: 1;
46 u64 e1_irq: 1;
47 u64 e1_exception: 1;
48 u64 e1_msr_dr: 1;
49 u64 e1_msr_ir: 1;
50 u64 e1_msr_pr: 1;
51 u64 e1_msr_ee: 1;
52 u64 pad1: 5;
53 u64 ls_state: 3;
54 u64 ls_dw_done: 1;
55 u64 ls_min_done: 1;
56 u64 ls_do_valid: 1;
57 u64 ls_mo_valid: 1;
58 u64 ls_lo_valid: 1;
59 u64 ls_eo_except: 1;
60 u64 ls_stall_out: 1;
61 u64 pad2: 1;
62 u64 dc_state: 3;
63 u64 dc_ra_valid: 1;
64 u64 dc_tlb_way: 3;
65 u64 dc_stall_out: 1;
66 u64 dc_op: 3;
67 u64 dc_do_valid: 1;
68 u64 dc_do_error: 1;
69 u64 dc_wb_cyc: 1;
70 u64 dc_wb_stb: 1;
71 u64 dc_wb_ack: 1;
72 u64 dc_wb_stall: 1;
73 u64 dc_wb_adr: 3;
74 u64 cr_wr_mask: 8;
75 u64 cr_wr_data: 4;
76 u64 cr_wr_enable: 1;
77 u64 reg_wr_reg: 7;
78 u64 reg_wr_enable: 1;
79
80 u64 reg_wr_data;
81 };
82
83 #define FLAG(i, y) (log.i? y: ' ')
84 #define FLGA(i, y, z) (log.i? y: z)
85 #define PNIA(f) (full_nia[log.f] & 0xff)
86
87 const char *units[4] = { "--", "al", "ls", "fp" };
88 const char *ops[64] =
89 {
90 "illegal", "nop ", "add ", "and ", "attn ", "b ", "bc ", "bcreg ",
91 "bperm ", "cmp ", "cmpb ", "cmpeqb ", "cmprb ", "cntz ", "crop ", "darn ",
92 "dcbf ", "dcbst ", "dcbt ", "dcbtst ", "dcbz ", "div ", "dive ", "exts ",
93 "extswsl", "fpop ", "fpopi ", "icbi ", "icbt ", "isel ", "isync ", "ld ",
94 "st ", "mcrxrx ", "mfcr ", "mfmsr ", "mfspr ", "mod ", "mtcrf ", "mtmsr ",
95 "mtspr ", "mull64 ", "mulh64 ", "mulh32 ", "or ", "popcnt ", "prty ", "rfid ",
96 "rlc ", "rlcl ", "rlcr ", "sc ", "setb ", "shl ", "shr ", "sync ",
97 "tlbie ", "trap ", "xor ", "bcd ", "addg6s ", "ffail ", "?62 ", "?63 "
98 };
99
100 const char *spr_names[13] =
101 {
102 "lr ", "ctr", "sr0", "sr1", "hr0", "hr1", "sg0", "sg1",
103 "sg2", "sg3", "hg0", "hg1", "xer"
104 };
105
106 int main(int ac, char **av)
107 {
108 struct log_entry log;
109 u64 full_nia[16];
110 long int lineno = 1;
111 FILE *f;
112 const char *filename;
113 int i;
114 long int ncompl = 0;
115
116 if (ac != 1 && ac != 2) {
117 fprintf(stderr, "Usage: %s [filename]\n", av[0]);
118 exit(1);
119 }
120 f = stdin;
121 if (ac == 2) {
122 filename = av[1];
123 f = fopen(filename, "rb");
124 if (f == NULL) {
125 perror(filename);
126 exit(1);
127 }
128 }
129
130 for (i = 0; i < 15; ++i)
131 full_nia[i] = i << 2;
132
133 while (fread(&log, sizeof(log), 1, f) == 1) {
134 full_nia[log.nia_lo & 0xf] = (log.nia_hi? 0xc000000000000000: 0) |
135 (log.nia_lo << 2);
136 if (lineno % 20 == 1) {
137 printf(" fetch1 NIA icache decode1 decode2 execute1 loadstore dcache CR GSPR\n");
138 printf(" ---------------- TAHW S -WB-- pN --insn-- pN un op pN byp FR IIE MSR WC SD MM CE SRTO DE -WB-- c ms reg val\n");
139 printf(" LdMy t csnSa IA IA it IA abc le srx EPID em tw rd mx tAwp vr csnSa 0 k\n");
140 }
141 printf("%4ld %c0000%.11llx %c ", lineno,
142 (log.nia_hi? 'c': '0'),
143 (unsigned long long)log.nia_lo << 2,
144 FLAG(ic_stall_out, '|'));
145 printf("%c%c%c%d %c %c%c%d%c%c %.2llx ",
146 FLGA(ic_ra_valid, ' ', 'T'),
147 FLGA(ic_access_ok, ' ', 'X'),
148 FLGA(ic_is_hit, 'H', FLGA(ic_is_miss, 'M', ' ')),
149 log.ic_way,
150 FLAG(ic_state, 'W'),
151 FLAG(ic_wb_cyc, 'c'),
152 FLAG(ic_wb_stb, 's'),
153 log.ic_wb_adr,
154 FLAG(ic_wb_stall, 'S'),
155 FLAG(ic_wb_ack, 'a'),
156 PNIA(ic_part_nia));
157 if (log.ic_valid)
158 printf("%.8x", log.ic_insn);
159 else if (log.ic_fetch_failed)
160 printf("!!!!!!!!");
161 else
162 printf("--------");
163 printf(" %c%c %.2llx ",
164 FLAG(ic_valid, '>'),
165 FLAG(d2_stall_out, '|'),
166 PNIA(d1_part_nia));
167 if (log.d1_valid)
168 printf("%s %s",
169 units[log.d1_unit],
170 ops[log.d1_insn_type]);
171 else
172 printf("-- -------");
173 printf(" %c%c ",
174 FLAG(d1_valid, '>'),
175 FLAG(d2_stall_out, '|'));
176 printf("%.2llx %c%c%c %c%c ",
177 PNIA(d2_part_nia),
178 FLAG(d2_bypass_a, 'a'),
179 FLAG(d2_bypass_b, 'b'),
180 FLAG(d2_bypass_c, 'c'),
181 FLAG(d2_valid, '>'),
182 FLAG(e1_stall_out, '|'));
183 printf("%c%c %c%c%c %c%c%c%c %c%c ",
184 FLAG(e1_flush_out, 'F'),
185 FLAG(e1_redirect, 'R'),
186 FLAG(e1_irq_state, 'w'),
187 FLAG(e1_irq, 'I'),
188 FLAG(e1_exception, 'X'),
189 FLAG(e1_msr_ee, 'E'),
190 FLGA(e1_msr_pr, 'u', 's'),
191 FLAG(e1_msr_ir, 'I'),
192 FLAG(e1_msr_dr, 'D'),
193 FLAG(e1_write_enable, 'W'),
194 FLAG(e1_valid, 'C'));
195 printf("%c %d%d %c%c %c%c %c ",
196 FLAG(ls_stall_out, '|'),
197 log.ls_state,
198 log.ls_dw_done,
199 FLAG(ls_mo_valid, 'M'),
200 FLAG(ls_min_done, 'm'),
201 FLAG(ls_lo_valid, 'C'),
202 FLAG(ls_eo_except, 'X'),
203 FLAG(ls_do_valid, '>'));
204 printf("%d%c%d%d %c%c %c%c%d%c%c ",
205 log.dc_state,
206 FLAG(dc_ra_valid, 'R'),
207 log.dc_tlb_way,
208 log.dc_op,
209 FLAG(dc_do_valid, 'V'),
210 FLAG(dc_do_error, 'E'),
211 FLAG(dc_wb_cyc, 'c'),
212 FLAG(dc_wb_stb, 's'),
213 log.dc_wb_adr,
214 FLAG(dc_wb_stall, 'S'),
215 FLAG(dc_wb_ack, 'a'));
216 if (log.cr_wr_enable)
217 printf("%x>%.2x ", log.cr_wr_data, log.cr_wr_mask);
218 else
219 printf(" ");
220 if (log.reg_wr_enable) {
221 if (log.reg_wr_reg < 32 || log.reg_wr_reg > 44)
222 printf("r%02d", log.reg_wr_reg);
223 else
224 printf("%s", spr_names[log.reg_wr_reg - 32]);
225 printf("=%.16llx", log.reg_wr_data);
226 }
227 printf("\n");
228 ++lineno;
229 if (log.ls_lo_valid || log.e1_valid)
230 ++ncompl;
231 }
232 printf("%ld instructions completed, %.2f CPI\n", ncompl,
233 (double)(lineno - 1) / ncompl);
234 exit(0);
235 }