mem-cache: Add multiple eviction stats
[gem5.git] / src / arch / arm / tracers / tarmac_parser.cc
1 /*
2 * Copyright (c) 2011,2017-2019 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Giacomo Gabrielli
38 */
39
40 #include <algorithm>
41 #include <cctype>
42 #include <cstring>
43 #include <iomanip>
44 #include <string>
45
46 #include "arch/arm/tracers/tarmac_parser.hh"
47
48 #include "arch/arm/tlb.hh"
49 #include "arch/arm/insts/static_inst.hh"
50 #include "config/the_isa.hh"
51 #include "cpu/static_inst.hh"
52 #include "cpu/thread_context.hh"
53 #include "mem/fs_translating_port_proxy.hh"
54 #include "mem/packet.hh"
55 #include "sim/core.hh"
56 #include "sim/faults.hh"
57 #include "sim/sim_exit.hh"
58
59 using namespace std;
60 using namespace ArmISA;
61
62 namespace Trace {
63
64 // TARMAC Parser static variables
65 const int TarmacParserRecord::MaxLineLength;
66 int8_t TarmacParserRecord::maxVectorLength = 0;
67
68 TarmacParserRecord::ParserInstEntry TarmacParserRecord::instRecord;
69 TarmacParserRecord::ParserRegEntry TarmacParserRecord::regRecord;
70 TarmacParserRecord::ParserMemEntry TarmacParserRecord::memRecord;
71 TarmacBaseRecord::TarmacRecordType TarmacParserRecord::currRecordType;
72
73 list<TarmacParserRecord::ParserRegEntry> TarmacParserRecord::destRegRecords;
74 char TarmacParserRecord::buf[TarmacParserRecord::MaxLineLength];
75 TarmacParserRecord::MiscRegMap TarmacParserRecord::miscRegMap = {
76
77 { "cpsr", MISCREG_CPSR },
78 { "nzcv", MISCREG_NZCV },
79
80 // AArch32 CP14 registers
81 { "dbgdidr", MISCREG_DBGDIDR },
82 { "dbgdscrint", MISCREG_DBGDSCRint },
83 { "dbgdccint", MISCREG_DBGDCCINT },
84 { "dbgdtrtxint", MISCREG_DBGDTRTXint },
85 { "dbgdtrrxint", MISCREG_DBGDTRRXint },
86 { "dbgwfar", MISCREG_DBGWFAR },
87 { "dbgvcr", MISCREG_DBGVCR },
88 { "dbgdtrrxext", MISCREG_DBGDTRRXext },
89 { "dbgdscrext", MISCREG_DBGDSCRext },
90 { "dbgdtrtxext", MISCREG_DBGDTRTXext },
91 { "dbgoseccr", MISCREG_DBGOSECCR },
92 { "dbgbvr0", MISCREG_DBGBVR0 },
93 { "dbgbvr1", MISCREG_DBGBVR1 },
94 { "dbgbvr2", MISCREG_DBGBVR2 },
95 { "dbgbvr3", MISCREG_DBGBVR3 },
96 { "dbgbvr4", MISCREG_DBGBVR4 },
97 { "dbgbvr5", MISCREG_DBGBVR5 },
98 { "dbgbcr0", MISCREG_DBGBCR0 },
99 { "dbgbcr1", MISCREG_DBGBCR1 },
100 { "dbgbcr2", MISCREG_DBGBCR2 },
101 { "dbgbcr3", MISCREG_DBGBCR3 },
102 { "dbgbcr4", MISCREG_DBGBCR4 },
103 { "dbgbcr5", MISCREG_DBGBCR5 },
104 { "dbgwvr0", MISCREG_DBGWVR0 },
105 { "dbgwvr1", MISCREG_DBGWVR1 },
106 { "dbgwvr2", MISCREG_DBGWVR2 },
107 { "dbgwvr3", MISCREG_DBGWVR3 },
108 { "dbgwcr0", MISCREG_DBGWCR0 },
109 { "dbgwcr1", MISCREG_DBGWCR1 },
110 { "dbgwcr2", MISCREG_DBGWCR2 },
111 { "dbgwcr3", MISCREG_DBGWCR3 },
112 { "dbgdrar", MISCREG_DBGDRAR },
113 { "dbgbxvr4", MISCREG_DBGBXVR4 },
114 { "dbgbxvr5", MISCREG_DBGBXVR5 },
115 { "dbgoslar", MISCREG_DBGOSLAR },
116 { "dbgoslsr", MISCREG_DBGOSLSR },
117 { "dbgosdlr", MISCREG_DBGOSDLR },
118 { "dbgprcr", MISCREG_DBGPRCR },
119 { "dbgdsar", MISCREG_DBGDSAR },
120 { "dbgclaimset", MISCREG_DBGCLAIMSET },
121 { "dbgclaimclr", MISCREG_DBGCLAIMCLR },
122 { "dbgauthstatus", MISCREG_DBGAUTHSTATUS },
123 { "dbgdevid2", MISCREG_DBGDEVID2 },
124 { "dbgdevid1", MISCREG_DBGDEVID1 },
125 { "dbgdevid0", MISCREG_DBGDEVID0 },
126 { "teecr", MISCREG_TEECR },
127 { "jidr", MISCREG_JIDR },
128 { "teehbr", MISCREG_TEEHBR },
129 { "joscr", MISCREG_JOSCR },
130 { "jmcr", MISCREG_JMCR },
131
132 // AArch32 CP15 registers
133 { "midr", MISCREG_MIDR },
134 { "ctr", MISCREG_CTR },
135 { "tcmtr", MISCREG_TCMTR },
136 { "tlbtr", MISCREG_TLBTR },
137 { "mpidr", MISCREG_MPIDR },
138 { "revidr", MISCREG_REVIDR },
139 { "id_pfr0", MISCREG_ID_PFR0 },
140 { "id_pfr1", MISCREG_ID_PFR1 },
141 { "id_dfr0", MISCREG_ID_DFR0 },
142 { "id_afr0", MISCREG_ID_AFR0 },
143 { "id_mmfr0", MISCREG_ID_MMFR0 },
144 { "id_mmfr1", MISCREG_ID_MMFR1 },
145 { "id_mmfr2", MISCREG_ID_MMFR2 },
146 { "id_mmfr3", MISCREG_ID_MMFR3 },
147 { "id_isar0", MISCREG_ID_ISAR0 },
148 { "id_isar1", MISCREG_ID_ISAR1 },
149 { "id_isar2", MISCREG_ID_ISAR2 },
150 { "id_isar3", MISCREG_ID_ISAR3 },
151 { "id_isar4", MISCREG_ID_ISAR4 },
152 { "id_isar5", MISCREG_ID_ISAR5 },
153 { "ccsidr", MISCREG_CCSIDR },
154 { "clidr", MISCREG_CLIDR },
155 { "aidr", MISCREG_AIDR },
156 { "csselr_ns", MISCREG_CSSELR_NS },
157 { "csselr_s", MISCREG_CSSELR_S },
158 { "vpidr", MISCREG_VPIDR },
159 { "vmpidr", MISCREG_VMPIDR },
160 { "sctlr_ns", MISCREG_SCTLR_NS },
161 { "sctlr_s", MISCREG_SCTLR_S },
162 { "actlr_ns", MISCREG_ACTLR_NS },
163 { "actlr_s", MISCREG_ACTLR_S },
164 { "cpacr", MISCREG_CPACR },
165 { "scr", MISCREG_SCR },
166 { "sder", MISCREG_SDER },
167 { "nsacr", MISCREG_NSACR },
168 { "hsctlr", MISCREG_HSCTLR },
169 { "hactlr", MISCREG_HACTLR },
170 { "hcr", MISCREG_HCR },
171 { "hcr2", MISCREG_HCR2 },
172 { "hdcr", MISCREG_HDCR },
173 { "hcptr", MISCREG_HCPTR },
174 { "hstr", MISCREG_HSTR },
175 { "hacr", MISCREG_HACR },
176 { "ttbr0_ns", MISCREG_TTBR0_NS },
177 { "ttbr0_s", MISCREG_TTBR0_S },
178 { "ttbr1_ns", MISCREG_TTBR1_NS },
179 { "ttbr1_s", MISCREG_TTBR1_S },
180 { "ttbcr_ns", MISCREG_TTBCR_NS },
181 { "ttbcr_s", MISCREG_TTBCR_S },
182 { "htcr", MISCREG_HTCR },
183 { "vtcr", MISCREG_VTCR },
184 { "dacr_ns", MISCREG_DACR_NS },
185 { "dacr_s", MISCREG_DACR_S },
186 { "dfsr_ns", MISCREG_DFSR_NS },
187 { "dfsr_s", MISCREG_DFSR_S },
188 { "ifsr_ns", MISCREG_IFSR_NS },
189 { "ifsr_s", MISCREG_IFSR_S },
190 { "adfsr_ns", MISCREG_ADFSR_NS },
191 { "adfsr_s", MISCREG_ADFSR_S },
192 { "aifsr_ns", MISCREG_AIFSR_NS },
193 { "aifsr_s", MISCREG_AIFSR_S },
194 { "hadfsr", MISCREG_HADFSR },
195 { "haifsr", MISCREG_HAIFSR },
196 { "hsr", MISCREG_HSR },
197 { "dfar_ns", MISCREG_DFAR_NS },
198 { "dfar_s", MISCREG_DFAR_S },
199 { "ifar_ns", MISCREG_IFAR_NS },
200 { "ifar_s", MISCREG_IFAR_S },
201 { "hdfar", MISCREG_HDFAR },
202 { "hifar", MISCREG_HIFAR },
203 { "hpfar", MISCREG_HPFAR },
204 { "icialluis", MISCREG_ICIALLUIS },
205 { "bpiallis", MISCREG_BPIALLIS },
206 { "par_ns", MISCREG_PAR_NS },
207 { "par_s", MISCREG_PAR_S },
208 { "iciallu", MISCREG_ICIALLU },
209 { "icimvau", MISCREG_ICIMVAU },
210 { "cp15isb", MISCREG_CP15ISB },
211 { "bpiall", MISCREG_BPIALL },
212 { "bpimva", MISCREG_BPIMVA },
213 { "dcimvac", MISCREG_DCIMVAC },
214 { "dcisw", MISCREG_DCISW },
215 { "ats1cpr", MISCREG_ATS1CPR },
216 { "ats1cpw", MISCREG_ATS1CPW },
217 { "ats1cur", MISCREG_ATS1CUR },
218 { "ats1cuw", MISCREG_ATS1CUW },
219 { "ats12nsopr", MISCREG_ATS12NSOPR },
220 { "ats12nsopw", MISCREG_ATS12NSOPW },
221 { "ats12nsour", MISCREG_ATS12NSOUR },
222 { "ats12nsouw", MISCREG_ATS12NSOUW },
223 { "dccmvac", MISCREG_DCCMVAC },
224 { "dccsw", MISCREG_DCCSW },
225 { "cp15dsb", MISCREG_CP15DSB },
226 { "cp15dmb", MISCREG_CP15DMB },
227 { "dccmvau", MISCREG_DCCMVAU },
228 { "dccimvac", MISCREG_DCCIMVAC },
229 { "dccisw", MISCREG_DCCISW },
230 { "ats1hr", MISCREG_ATS1HR },
231 { "ats1hw", MISCREG_ATS1HW },
232 { "tlbiallis", MISCREG_TLBIALLIS },
233 { "tlbimvais", MISCREG_TLBIMVAIS },
234 { "tlbiasidis", MISCREG_TLBIASIDIS },
235 { "tlbimvaais", MISCREG_TLBIMVAAIS },
236 { "tlbimvalis", MISCREG_TLBIMVALIS },
237 { "tlbimvaalis", MISCREG_TLBIMVAALIS },
238 { "itlbiall", MISCREG_ITLBIALL },
239 { "itlbimva", MISCREG_ITLBIMVA },
240 { "itlbiasid", MISCREG_ITLBIASID },
241 { "dtlbiall", MISCREG_DTLBIALL },
242 { "dtlbimva", MISCREG_DTLBIMVA },
243 { "dtlbiasid", MISCREG_DTLBIASID },
244 { "tlbiall", MISCREG_TLBIALL },
245 { "tlbimva", MISCREG_TLBIMVA },
246 { "tlbiasid", MISCREG_TLBIASID },
247 { "tlbimvaa", MISCREG_TLBIMVAA },
248 { "tlbimval", MISCREG_TLBIMVAL },
249 { "tlbimvaal", MISCREG_TLBIMVAAL },
250 { "tlbiipas2is", MISCREG_TLBIIPAS2IS },
251 { "tlbiipas2lis", MISCREG_TLBIIPAS2LIS },
252 { "tlbiallhis", MISCREG_TLBIALLHIS },
253 { "tlbimvahis", MISCREG_TLBIMVAHIS },
254 { "tlbiallnsnhis", MISCREG_TLBIALLNSNHIS },
255 { "tlbimvalhis", MISCREG_TLBIMVALHIS },
256 { "tlbiipas2", MISCREG_TLBIIPAS2 },
257 { "tlbiipas2l", MISCREG_TLBIIPAS2L },
258 { "tlbiallh", MISCREG_TLBIALLH },
259 { "tlbimvah", MISCREG_TLBIMVAH },
260 { "tlbiallnsnh", MISCREG_TLBIALLNSNH },
261 { "tlbimvalh", MISCREG_TLBIMVALH },
262 { "pmcr", MISCREG_PMCR },
263 { "pmcntenset", MISCREG_PMCNTENSET },
264 { "pmcntenclr", MISCREG_PMCNTENCLR },
265 { "pmovsr", MISCREG_PMOVSR },
266 { "pmswinc", MISCREG_PMSWINC },
267 { "pmselr", MISCREG_PMSELR },
268 { "pmceid0", MISCREG_PMCEID0 },
269 { "pmceid1", MISCREG_PMCEID1 },
270 { "pmccntr", MISCREG_PMCCNTR },
271 { "pmxevtyper", MISCREG_PMXEVTYPER },
272 { "pmccfiltr", MISCREG_PMCCFILTR },
273 { "pmxevcntr", MISCREG_PMXEVCNTR },
274 { "pmuserenr", MISCREG_PMUSERENR },
275 { "pmintenset", MISCREG_PMINTENSET },
276 { "pmintenclr", MISCREG_PMINTENCLR },
277 { "pmovsset", MISCREG_PMOVSSET },
278 { "l2ctlr", MISCREG_L2CTLR },
279 { "l2ectlr", MISCREG_L2ECTLR },
280 { "prrr_ns", MISCREG_PRRR_NS },
281 { "prrr_s", MISCREG_PRRR_S },
282 { "mair0_ns", MISCREG_MAIR0_NS },
283 { "mair0_s", MISCREG_MAIR0_S },
284 { "nmrr_ns", MISCREG_NMRR_NS },
285 { "nmrr_s", MISCREG_NMRR_S },
286 { "mair1_ns", MISCREG_MAIR1_NS },
287 { "mair1_s", MISCREG_MAIR1_S },
288 { "amair0_ns", MISCREG_AMAIR0_NS },
289 { "amair0_s", MISCREG_AMAIR0_S },
290 { "amair1_ns", MISCREG_AMAIR1_NS },
291 { "amair1_s", MISCREG_AMAIR1_S },
292 { "hmair0", MISCREG_HMAIR0 },
293 { "hmair1", MISCREG_HMAIR1 },
294 { "hamair0", MISCREG_HAMAIR0 },
295 { "hamair1", MISCREG_HAMAIR1 },
296 { "vbar_ns", MISCREG_VBAR_NS },
297 { "vbar_s", MISCREG_VBAR_S },
298 { "mvbar", MISCREG_MVBAR },
299 { "rmr", MISCREG_RMR },
300 { "isr", MISCREG_ISR },
301 { "hvbar", MISCREG_HVBAR },
302 { "fcseidr", MISCREG_FCSEIDR },
303 { "contextidr_ns", MISCREG_CONTEXTIDR_NS },
304 { "contextidr_s", MISCREG_CONTEXTIDR_S },
305 { "tpidrurw_ns", MISCREG_TPIDRURW_NS },
306 { "tpidrurw_s", MISCREG_TPIDRURW_S },
307 { "tpidruro_ns", MISCREG_TPIDRURO_NS },
308 { "tpidruro_s", MISCREG_TPIDRURO_S },
309 { "tpidrprw_ns", MISCREG_TPIDRPRW_NS },
310 { "tpidrprw_s", MISCREG_TPIDRPRW_S },
311 { "htpidr", MISCREG_HTPIDR },
312 { "cntfrq", MISCREG_CNTFRQ },
313 { "cntkctl", MISCREG_CNTKCTL },
314 { "cntp_tval_ns", MISCREG_CNTP_TVAL_NS },
315 { "cntp_tval_s", MISCREG_CNTP_TVAL_S },
316 { "cntp_ctl_ns", MISCREG_CNTP_CTL_NS },
317 { "cntp_ctl_s", MISCREG_CNTP_CTL_S },
318 { "cntv_tval", MISCREG_CNTV_TVAL },
319 { "cntv_ctl", MISCREG_CNTV_CTL },
320 { "cnthctl", MISCREG_CNTHCTL },
321 { "cnthp_tval", MISCREG_CNTHP_TVAL },
322 { "cnthp_ctl", MISCREG_CNTHP_CTL },
323 { "il1data0", MISCREG_IL1DATA0 },
324 { "il1data1", MISCREG_IL1DATA1 },
325 { "il1data2", MISCREG_IL1DATA2 },
326 { "il1data3", MISCREG_IL1DATA3 },
327 { "dl1data0", MISCREG_DL1DATA0 },
328 { "dl1data1", MISCREG_DL1DATA1 },
329 { "dl1data2", MISCREG_DL1DATA2 },
330 { "dl1data3", MISCREG_DL1DATA3 },
331 { "dl1data4", MISCREG_DL1DATA4 },
332 { "ramindex", MISCREG_RAMINDEX },
333 { "l2actlr", MISCREG_L2ACTLR },
334 { "cbar", MISCREG_CBAR },
335 { "httbr", MISCREG_HTTBR },
336 { "vttbr", MISCREG_VTTBR },
337 { "cntpct", MISCREG_CNTPCT },
338 { "cntvct", MISCREG_CNTVCT },
339 { "cntp_cval_ns", MISCREG_CNTP_CVAL_NS },
340 { "cntp_cval_s", MISCREG_CNTP_CVAL_S },
341 { "cntv_cval", MISCREG_CNTV_CVAL },
342 { "cntvoff", MISCREG_CNTVOFF },
343 { "cnthp_cval", MISCREG_CNTHP_CVAL },
344 { "cpumerrsr", MISCREG_CPUMERRSR },
345 { "l2merrsr", MISCREG_L2MERRSR },
346
347 // AArch64 registers (Op0=2)
348 { "mdccint_el1", MISCREG_MDCCINT_EL1 },
349 { "osdtrrx_el1", MISCREG_OSDTRRX_EL1 },
350 { "mdscr_el1", MISCREG_MDSCR_EL1 },
351 { "osdtrtx_el1", MISCREG_OSDTRTX_EL1 },
352 { "oseccr_el1", MISCREG_OSECCR_EL1 },
353 { "dbgbvr0_el1", MISCREG_DBGBVR0_EL1 },
354 { "dbgbvr1_el1", MISCREG_DBGBVR1_EL1 },
355 { "dbgbvr2_el1", MISCREG_DBGBVR2_EL1 },
356 { "dbgbvr3_el1", MISCREG_DBGBVR3_EL1 },
357 { "dbgbvr4_el1", MISCREG_DBGBVR4_EL1 },
358 { "dbgbvr5_el1", MISCREG_DBGBVR5_EL1 },
359 { "dbgbcr0_el1", MISCREG_DBGBCR0_EL1 },
360 { "dbgbcr1_el1", MISCREG_DBGBCR1_EL1 },
361 { "dbgbcr2_el1", MISCREG_DBGBCR2_EL1 },
362 { "dbgbcr3_el1", MISCREG_DBGBCR3_EL1 },
363 { "dbgbcr4_el1", MISCREG_DBGBCR4_EL1 },
364 { "dbgbcr5_el1", MISCREG_DBGBCR5_EL1 },
365 { "dbgwvr0_el1", MISCREG_DBGWVR0_EL1 },
366 { "dbgwvr1_el1", MISCREG_DBGWVR1_EL1 },
367 { "dbgwvr2_el1", MISCREG_DBGWVR2_EL1 },
368 { "dbgwvr3_el1", MISCREG_DBGWVR3_EL1 },
369 { "dbgwcr0_el1", MISCREG_DBGWCR0_EL1 },
370 { "dbgwcr1_el1", MISCREG_DBGWCR1_EL1 },
371 { "dbgwcr2_el1", MISCREG_DBGWCR2_EL1 },
372 { "dbgwcr3_el1", MISCREG_DBGWCR3_EL1 },
373 { "mdccsr_el0", MISCREG_MDCCSR_EL0 },
374 { "mddtr_el0", MISCREG_MDDTR_EL0 },
375 { "mddtrtx_el0", MISCREG_MDDTRTX_EL0 },
376 { "mddtrrx_el0", MISCREG_MDDTRRX_EL0 },
377 { "dbgvcr32_el2", MISCREG_DBGVCR32_EL2 },
378 { "mdrar_el1", MISCREG_MDRAR_EL1 },
379 { "oslar_el1", MISCREG_OSLAR_EL1 },
380 { "oslsr_el1", MISCREG_OSLSR_EL1 },
381 { "osdlr_el1", MISCREG_OSDLR_EL1 },
382 { "dbgprcr_el1", MISCREG_DBGPRCR_EL1 },
383 { "dbgclaimset_el1", MISCREG_DBGCLAIMSET_EL1 },
384 { "dbgclaimclr_el1", MISCREG_DBGCLAIMCLR_EL1 },
385 { "dbgauthstatus_el1", MISCREG_DBGAUTHSTATUS_EL1 },
386 { "teecr32_el1", MISCREG_TEECR32_EL1 },
387 { "teehbr32_el1", MISCREG_TEEHBR32_EL1 },
388
389 // AArch64 registers (Op0=1,3)
390 { "midr_el1", MISCREG_MIDR_EL1 },
391 { "mpidr_el1", MISCREG_MPIDR_EL1 },
392 { "revidr_el1", MISCREG_REVIDR_EL1 },
393 { "id_pfr0_el1", MISCREG_ID_PFR0_EL1 },
394 { "id_pfr1_el1", MISCREG_ID_PFR1_EL1 },
395 { "id_dfr0_el1", MISCREG_ID_DFR0_EL1 },
396 { "id_afr0_el1", MISCREG_ID_AFR0_EL1 },
397 { "id_mmfr0_el1", MISCREG_ID_MMFR0_EL1 },
398 { "id_mmfr1_el1", MISCREG_ID_MMFR1_EL1 },
399 { "id_mmfr2_el1", MISCREG_ID_MMFR2_EL1 },
400 { "id_mmfr3_el1", MISCREG_ID_MMFR3_EL1 },
401 { "id_isar0_el1", MISCREG_ID_ISAR0_EL1 },
402 { "id_isar1_el1", MISCREG_ID_ISAR1_EL1 },
403 { "id_isar2_el1", MISCREG_ID_ISAR2_EL1 },
404 { "id_isar3_el1", MISCREG_ID_ISAR3_EL1 },
405 { "id_isar4_el1", MISCREG_ID_ISAR4_EL1 },
406 { "id_isar5_el1", MISCREG_ID_ISAR5_EL1 },
407 { "mvfr0_el1", MISCREG_MVFR0_EL1 },
408 { "mvfr1_el1", MISCREG_MVFR1_EL1 },
409 { "mvfr2_el1", MISCREG_MVFR2_EL1 },
410 { "id_aa64pfr0_el1", MISCREG_ID_AA64PFR0_EL1 },
411 { "id_aa64pfr1_el1", MISCREG_ID_AA64PFR1_EL1 },
412 { "id_aa64dfr0_el1", MISCREG_ID_AA64DFR0_EL1 },
413 { "id_aa64dfr1_el1", MISCREG_ID_AA64DFR1_EL1 },
414 { "id_aa64afr0_el1", MISCREG_ID_AA64AFR0_EL1 },
415 { "id_aa64afr1_el1", MISCREG_ID_AA64AFR1_EL1 },
416 { "id_aa64isar0_el1", MISCREG_ID_AA64ISAR0_EL1 },
417 { "id_aa64isar1_el1", MISCREG_ID_AA64ISAR1_EL1 },
418 { "id_aa64mmfr0_el1", MISCREG_ID_AA64MMFR0_EL1 },
419 { "id_aa64mmfr1_el1", MISCREG_ID_AA64MMFR1_EL1 },
420 { "id_aa64mmfr2_el1", MISCREG_ID_AA64MMFR2_EL1 },
421 { "ccsidr_el1", MISCREG_CCSIDR_EL1 },
422 { "clidr_el1", MISCREG_CLIDR_EL1 },
423 { "aidr_el1", MISCREG_AIDR_EL1 },
424 { "csselr_el1", MISCREG_CSSELR_EL1 },
425 { "ctr_el0", MISCREG_CTR_EL0 },
426 { "dczid_el0", MISCREG_DCZID_EL0 },
427 { "vpidr_el2", MISCREG_VPIDR_EL2 },
428 { "vmpidr_el2", MISCREG_VMPIDR_EL2 },
429 { "sctlr_el1", MISCREG_SCTLR_EL1 },
430 { "actlr_el1", MISCREG_ACTLR_EL1 },
431 { "cpacr_el1", MISCREG_CPACR_EL1 },
432 { "sctlr_el2", MISCREG_SCTLR_EL2 },
433 { "actlr_el2", MISCREG_ACTLR_EL2 },
434 { "hcr_el2", MISCREG_HCR_EL2 },
435 { "mdcr_el2", MISCREG_MDCR_EL2 },
436 { "cptr_el2", MISCREG_CPTR_EL2 },
437 { "hstr_el2", MISCREG_HSTR_EL2 },
438 { "hacr_el2", MISCREG_HACR_EL2 },
439 { "sctlr_el3", MISCREG_SCTLR_EL3 },
440 { "actlr_el3", MISCREG_ACTLR_EL3 },
441 { "scr_el3", MISCREG_SCR_EL3 },
442 { "sder32_el3", MISCREG_SDER32_EL3 },
443 { "cptr_el3", MISCREG_CPTR_EL3 },
444 { "mdcr_el3", MISCREG_MDCR_EL3 },
445 { "ttbr0_el1", MISCREG_TTBR0_EL1 },
446 { "ttbr1_el1", MISCREG_TTBR1_EL1 },
447 { "tcr_el1", MISCREG_TCR_EL1 },
448 { "ttbr0_el2", MISCREG_TTBR0_EL2 },
449 { "tcr_el2", MISCREG_TCR_EL2 },
450 { "vttbr_el2", MISCREG_VTTBR_EL2 },
451 { "vtcr_el2", MISCREG_VTCR_EL2 },
452 { "ttbr0_el3", MISCREG_TTBR0_EL3 },
453 { "tcr_el3", MISCREG_TCR_EL3 },
454 { "dacr32_el2", MISCREG_DACR32_EL2 },
455 { "spsr_el1", MISCREG_SPSR_EL1 },
456 { "elr_el1", MISCREG_ELR_EL1 },
457 { "sp_el0", MISCREG_SP_EL0 },
458 { "spsel", MISCREG_SPSEL },
459 { "currentel", MISCREG_CURRENTEL },
460 { "nzcv", MISCREG_NZCV },
461 { "daif", MISCREG_DAIF },
462 { "fpcr", MISCREG_FPCR },
463 { "fpsr", MISCREG_FPSR },
464 { "dspsr_el0", MISCREG_DSPSR_EL0 },
465 { "dlr_el0", MISCREG_DLR_EL0 },
466 { "spsr_el2", MISCREG_SPSR_EL2 },
467 { "elr_el2", MISCREG_ELR_EL2 },
468 { "sp_el1", MISCREG_SP_EL1 },
469 { "spsr_irq", MISCREG_SPSR_IRQ_AA64 },
470 { "spsr_abt", MISCREG_SPSR_ABT_AA64 },
471 { "spsr_und", MISCREG_SPSR_UND_AA64 },
472 { "spsr_fiq", MISCREG_SPSR_FIQ_AA64 },
473 { "spsr_el3", MISCREG_SPSR_EL3 },
474 { "elr_el3", MISCREG_ELR_EL3 },
475 { "sp_el2", MISCREG_SP_EL2 },
476 { "afsr0_el1", MISCREG_AFSR0_EL1 },
477 { "afsr1_el1", MISCREG_AFSR1_EL1 },
478 { "esr_el1", MISCREG_ESR_EL1 },
479 { "ifsr32_el2", MISCREG_IFSR32_EL2 },
480 { "afsr0_el2", MISCREG_AFSR0_EL2 },
481 { "afsr1_el2", MISCREG_AFSR1_EL2 },
482 { "esr_el2", MISCREG_ESR_EL2 },
483 { "fpexc32_el2", MISCREG_FPEXC32_EL2 },
484 { "afsr0_el3", MISCREG_AFSR0_EL3 },
485 { "afsr1_el3", MISCREG_AFSR1_EL3 },
486 { "esr_el3", MISCREG_ESR_EL3 },
487 { "far_el1", MISCREG_FAR_EL1 },
488 { "far_el2", MISCREG_FAR_EL2 },
489 { "hpfar_el2", MISCREG_HPFAR_EL2 },
490 { "far_el3", MISCREG_FAR_EL3 },
491 { "ic_ialluis", MISCREG_IC_IALLUIS },
492 { "par_el1", MISCREG_PAR_EL1 },
493 { "ic_iallu", MISCREG_IC_IALLU },
494 { "dc_ivac_xt", MISCREG_DC_IVAC_Xt },
495 { "dc_isw_xt", MISCREG_DC_ISW_Xt },
496 { "at_s1e1r_xt", MISCREG_AT_S1E1R_Xt },
497 { "at_s1e1w_xt", MISCREG_AT_S1E1W_Xt },
498 { "at_s1e0r_xt", MISCREG_AT_S1E0R_Xt },
499 { "at_s1e0w_xt", MISCREG_AT_S1E0W_Xt },
500 { "dc_csw_xt", MISCREG_DC_CSW_Xt },
501 { "dc_cisw_xt", MISCREG_DC_CISW_Xt },
502 { "dc_zva_xt", MISCREG_DC_ZVA_Xt },
503 { "ic_ivau_xt", MISCREG_IC_IVAU_Xt },
504 { "dc_cvac_xt", MISCREG_DC_CVAC_Xt },
505 { "dc_cvau_xt", MISCREG_DC_CVAU_Xt },
506 { "dc_civac_xt", MISCREG_DC_CIVAC_Xt },
507 { "at_s1e2r_xt", MISCREG_AT_S1E2R_Xt },
508 { "at_s1e2w_xt", MISCREG_AT_S1E2W_Xt },
509 { "at_s12e1r_xt", MISCREG_AT_S12E1R_Xt },
510 { "at_s12e1w_xt", MISCREG_AT_S12E1W_Xt },
511 { "at_s12e0r_xt", MISCREG_AT_S12E0R_Xt },
512 { "at_s12e0w_xt", MISCREG_AT_S12E0W_Xt },
513 { "at_s1e3r_xt", MISCREG_AT_S1E3R_Xt },
514 { "at_s1e3w_xt", MISCREG_AT_S1E3W_Xt },
515 { "tlbi_vmalle1is", MISCREG_TLBI_VMALLE1IS },
516 { "tlbi_vae1is_xt", MISCREG_TLBI_VAE1IS_Xt },
517 { "tlbi_aside1is_xt", MISCREG_TLBI_ASIDE1IS_Xt },
518 { "tlbi_vaae1is_xt", MISCREG_TLBI_VAAE1IS_Xt },
519 { "tlbi_vale1is_xt", MISCREG_TLBI_VALE1IS_Xt },
520 { "tlbi_vaale1is_xt", MISCREG_TLBI_VAALE1IS_Xt },
521 { "tlbi_vmalle1", MISCREG_TLBI_VMALLE1 },
522 { "tlbi_vae1_xt", MISCREG_TLBI_VAE1_Xt },
523 { "tlbi_aside1_xt", MISCREG_TLBI_ASIDE1_Xt },
524 { "tlbi_vaae1_xt", MISCREG_TLBI_VAAE1_Xt },
525 { "tlbi_vale1_xt", MISCREG_TLBI_VALE1_Xt },
526 { "tlbi_vaale1_xt", MISCREG_TLBI_VAALE1_Xt },
527 { "tlbi_ipas2e1is_xt", MISCREG_TLBI_IPAS2E1IS_Xt },
528 { "tlbi_ipas2le1is_xt", MISCREG_TLBI_IPAS2LE1IS_Xt },
529 { "tlbi_alle2is", MISCREG_TLBI_ALLE2IS },
530 { "tlbi_vae2is_xt", MISCREG_TLBI_VAE2IS_Xt },
531 { "tlbi_alle1is", MISCREG_TLBI_ALLE1IS },
532 { "tlbi_vale2is_xt", MISCREG_TLBI_VALE2IS_Xt },
533 { "tlbi_vmalls12e1is", MISCREG_TLBI_VMALLS12E1IS },
534 { "tlbi_ipas2e1_xt", MISCREG_TLBI_IPAS2E1_Xt },
535 { "tlbi_ipas2le1_xt", MISCREG_TLBI_IPAS2LE1_Xt },
536 { "tlbi_alle2", MISCREG_TLBI_ALLE2 },
537 { "tlbi_vae2_xt", MISCREG_TLBI_VAE2_Xt },
538 { "tlbi_alle1", MISCREG_TLBI_ALLE1 },
539 { "tlbi_vale2_xt", MISCREG_TLBI_VALE2_Xt },
540 { "tlbi_vmalls12e1", MISCREG_TLBI_VMALLS12E1 },
541 { "tlbi_alle3is", MISCREG_TLBI_ALLE3IS },
542 { "tlbi_vae3is_xt", MISCREG_TLBI_VAE3IS_Xt },
543 { "tlbi_vale3is_xt", MISCREG_TLBI_VALE3IS_Xt },
544 { "tlbi_alle3", MISCREG_TLBI_ALLE3 },
545 { "tlbi_vae3_xt", MISCREG_TLBI_VAE3_Xt },
546 { "tlbi_vale3_xt", MISCREG_TLBI_VALE3_Xt },
547 { "pmintenset_el1", MISCREG_PMINTENSET_EL1 },
548 { "pmintenclr_el1", MISCREG_PMINTENCLR_EL1 },
549 { "pmcr_el0", MISCREG_PMCR_EL0 },
550 { "pmcntenset_el0", MISCREG_PMCNTENSET_EL0 },
551 { "pmcntenclr_el0", MISCREG_PMCNTENCLR_EL0 },
552 { "pmovsclr_el0", MISCREG_PMOVSCLR_EL0 },
553 { "pmswinc_el0", MISCREG_PMSWINC_EL0 },
554 { "pmselr_el0", MISCREG_PMSELR_EL0 },
555 { "pmceid0_el0", MISCREG_PMCEID0_EL0 },
556 { "pmceid1_el0", MISCREG_PMCEID1_EL0 },
557 { "pmccntr_el0", MISCREG_PMCCNTR_EL0 },
558 { "pmxevtyper_el0", MISCREG_PMXEVTYPER_EL0 },
559 { "pmccfiltr_el0", MISCREG_PMCCFILTR_EL0 },
560 { "pmxevcntr_el0", MISCREG_PMXEVCNTR_EL0 },
561 { "pmuserenr_el0", MISCREG_PMUSERENR_EL0 },
562 { "pmovsset_el0", MISCREG_PMOVSSET_EL0 },
563 { "mair_el1", MISCREG_MAIR_EL1 },
564 { "amair_el1", MISCREG_AMAIR_EL1 },
565 { "mair_el2", MISCREG_MAIR_EL2 },
566 { "amair_el2", MISCREG_AMAIR_EL2 },
567 { "mair_el3", MISCREG_MAIR_EL3 },
568 { "amair_el3", MISCREG_AMAIR_EL3 },
569 { "l2ctlr_el1", MISCREG_L2CTLR_EL1 },
570 { "l2ectlr_el1", MISCREG_L2ECTLR_EL1 },
571 { "vbar_el1", MISCREG_VBAR_EL1 },
572 { "rvbar_el1", MISCREG_RVBAR_EL1 },
573 { "isr_el1", MISCREG_ISR_EL1 },
574 { "vbar_el2", MISCREG_VBAR_EL2 },
575 { "rvbar_el2", MISCREG_RVBAR_EL2 },
576 { "vbar_el3", MISCREG_VBAR_EL3 },
577 { "rvbar_el3", MISCREG_RVBAR_EL3 },
578 { "rmr_el3", MISCREG_RMR_EL3 },
579 { "contextidr_el1", MISCREG_CONTEXTIDR_EL1 },
580 { "contextidr_el2", MISCREG_CONTEXTIDR_EL2 },
581 { "tpidr_el1", MISCREG_TPIDR_EL1 },
582 { "tpidr_el0", MISCREG_TPIDR_EL0 },
583 { "tpidrro_el0", MISCREG_TPIDRRO_EL0 },
584 { "tpidr_el2", MISCREG_TPIDR_EL2 },
585 { "tpidr_el3", MISCREG_TPIDR_EL3 },
586 { "cntkctl_el1", MISCREG_CNTKCTL_EL1 },
587 { "cntfrq_el0", MISCREG_CNTFRQ_EL0 },
588 { "cntpct_el0", MISCREG_CNTPCT_EL0 },
589 { "cntvct_el0", MISCREG_CNTVCT_EL0 },
590 { "cntp_tval_el0", MISCREG_CNTP_TVAL_EL0 },
591 { "cntp_ctl_el0", MISCREG_CNTP_CTL_EL0 },
592 { "cntp_cval_el0", MISCREG_CNTP_CVAL_EL0 },
593 { "cntv_tval_el0", MISCREG_CNTV_TVAL_EL0 },
594 { "cntv_ctl_el0", MISCREG_CNTV_CTL_EL0 },
595 { "cntv_cval_el0", MISCREG_CNTV_CVAL_EL0 },
596 { "pmevcntr0_el0", MISCREG_PMEVCNTR0_EL0 },
597 { "pmevcntr1_el0", MISCREG_PMEVCNTR1_EL0 },
598 { "pmevcntr2_el0", MISCREG_PMEVCNTR2_EL0 },
599 { "pmevcntr3_el0", MISCREG_PMEVCNTR3_EL0 },
600 { "pmevcntr4_el0", MISCREG_PMEVCNTR4_EL0 },
601 { "pmevcntr5_el0", MISCREG_PMEVCNTR5_EL0 },
602 { "pmevtyper0_el0", MISCREG_PMEVTYPER0_EL0 },
603 { "pmevtyper1_el0", MISCREG_PMEVTYPER1_EL0 },
604 { "pmevtyper2_el0", MISCREG_PMEVTYPER2_EL0 },
605 { "pmevtyper3_el0", MISCREG_PMEVTYPER3_EL0 },
606 { "pmevtyper4_el0", MISCREG_PMEVTYPER4_EL0 },
607 { "pmevtyper5_el0", MISCREG_PMEVTYPER5_EL0 },
608 { "cntvoff_el2", MISCREG_CNTVOFF_EL2 },
609 { "cnthctl_el2", MISCREG_CNTHCTL_EL2 },
610 { "cnthp_tval_el2", MISCREG_CNTHP_TVAL_EL2 },
611 { "cnthp_ctl_el2", MISCREG_CNTHP_CTL_EL2 },
612 { "cnthp_cval_el2", MISCREG_CNTHP_CVAL_EL2 },
613 { "cntps_tval_el1", MISCREG_CNTPS_TVAL_EL1 },
614 { "cntps_ctl_el1", MISCREG_CNTPS_CTL_EL1 },
615 { "cntps_cval_el1", MISCREG_CNTPS_CVAL_EL1 },
616 { "il1data0_el1", MISCREG_IL1DATA0_EL1 },
617 { "il1data1_el1", MISCREG_IL1DATA1_EL1 },
618 { "il1data2_el1", MISCREG_IL1DATA2_EL1 },
619 { "il1data3_el1", MISCREG_IL1DATA3_EL1 },
620 { "dl1data0_el1", MISCREG_DL1DATA0_EL1 },
621 { "dl1data1_el1", MISCREG_DL1DATA1_EL1 },
622 { "dl1data2_el1", MISCREG_DL1DATA2_EL1 },
623 { "dl1data3_el1", MISCREG_DL1DATA3_EL1 },
624 { "dl1data4_el1", MISCREG_DL1DATA4_EL1 },
625 { "l2actlr_el1", MISCREG_L2ACTLR_EL1 },
626 { "cpuactlr_el1", MISCREG_CPUACTLR_EL1 },
627 { "cpuectlr_el1", MISCREG_CPUECTLR_EL1 },
628 { "cpumerrsr_el1", MISCREG_CPUMERRSR_EL1 },
629 { "l2merrsr_el1", MISCREG_L2MERRSR_EL1 },
630 { "cbar_el1", MISCREG_CBAR_EL1 },
631 };
632
633 void
634 TarmacParserRecord::TarmacParserRecordEvent::process()
635 {
636 ostream &outs = Trace::output();
637
638 list<ParserRegEntry>::iterator it = destRegRecords.begin(),
639 end = destRegRecords.end();
640
641 std::vector<uint64_t> values;
642
643 for (; it != end; ++it) {
644 values.clear();
645 switch (it->type) {
646 case REG_R:
647 case REG_X:
648 values.push_back(thread->readIntReg(it->index));
649 break;
650 case REG_S:
651 if (instRecord.isetstate == ISET_A64) {
652 const ArmISA::VecRegContainer& vc = thread->readVecReg(
653 RegId(VecRegClass, it->index));
654 auto vv = vc.as<uint32_t>();
655 values.push_back(vv[0]);
656 } else {
657 const VecElem elem = thread->readVecElem(
658 RegId(VecElemClass,
659 it->index / NumVecElemPerNeonVecReg,
660 it->index % NumVecElemPerNeonVecReg));
661 values.push_back(elem);
662 }
663 break;
664 case REG_D:
665 if (instRecord.isetstate == ISET_A64) {
666 const ArmISA::VecRegContainer& vc = thread->readVecReg(
667 RegId(VecRegClass, it->index));
668 auto vv = vc.as<uint64_t>();
669 values.push_back(vv[0]);
670 } else {
671 const VecElem w0 = thread->readVecElem(
672 RegId(VecElemClass,
673 it->index / NumVecElemPerNeonVecReg,
674 it->index % NumVecElemPerNeonVecReg));
675 const VecElem w1 = thread->readVecElem(
676 RegId(VecElemClass,
677 (it->index + 1) / NumVecElemPerNeonVecReg,
678 (it->index + 1) % NumVecElemPerNeonVecReg));
679
680 values.push_back((uint64_t)(w1) << 32 | w0);
681 }
682 break;
683 case REG_P:
684 {
685 const ArmISA::VecPredRegContainer& pc =
686 thread->readVecPredReg(RegId(VecPredRegClass, it->index));
687 auto pv = pc.as<uint8_t>();
688 uint64_t p = 0;
689 for (int i = maxVectorLength * 8; i > 0; ) {
690 p = (p << 1) | pv[--i];
691 }
692 values.push_back(p);
693 }
694 break;
695 case REG_Q:
696 if (instRecord.isetstate == ISET_A64) {
697 const ArmISA::VecRegContainer& vc = thread->readVecReg(
698 RegId(VecRegClass, it->index));
699 auto vv = vc.as<uint64_t>();
700 values.push_back(vv[0]);
701 values.push_back(vv[1]);
702 } else {
703 const VecElem w0 = thread->readVecElem(
704 RegId(VecElemClass,
705 it->index / NumVecElemPerNeonVecReg,
706 it->index % NumVecElemPerNeonVecReg));
707 const VecElem w1 = thread->readVecElem(
708 RegId(VecElemClass,
709 (it->index + 1) / NumVecElemPerNeonVecReg,
710 (it->index + 1) % NumVecElemPerNeonVecReg));
711 const VecElem w2 = thread->readVecElem(
712 RegId(VecElemClass,
713 (it->index + 2) / NumVecElemPerNeonVecReg,
714 (it->index + 2) % NumVecElemPerNeonVecReg));
715 const VecElem w3 = thread->readVecElem(
716 RegId(VecElemClass,
717 (it->index + 3) / NumVecElemPerNeonVecReg,
718 (it->index + 3) % NumVecElemPerNeonVecReg));
719
720 values.push_back((uint64_t)(w1) << 32 | w0);
721 values.push_back((uint64_t)(w3) << 32 | w2);
722 }
723 break;
724 case REG_Z:
725 {
726 int8_t i = maxVectorLength;
727 const TheISA::VecRegContainer& vc = thread->readVecReg(
728 RegId(VecRegClass, it->index));
729 auto vv = vc.as<uint64_t>();
730 while (i > 0) {
731 values.push_back(vv[--i]);
732 }
733 }
734 break;
735 case REG_MISC:
736 if (it->index == MISCREG_CPSR) {
737 // Read condition codes from aliased integer regs
738 CPSR cpsr = thread->readMiscRegNoEffect(it->index);
739 cpsr.nz = thread->readCCReg(CCREG_NZ);
740 cpsr.c = thread->readCCReg(CCREG_C);
741 cpsr.v = thread->readCCReg(CCREG_V);
742 cpsr.ge = thread->readCCReg(CCREG_GE);
743 values.push_back(cpsr);
744 } else if (it->index == MISCREG_NZCV) {
745 CPSR cpsr = 0;
746 cpsr.nz = thread->readCCReg(CCREG_NZ);
747 cpsr.c = thread->readCCReg(CCREG_C);
748 cpsr.v = thread->readCCReg(CCREG_V);
749 values.push_back(cpsr);
750 } else if (it->index == MISCREG_FPCR) {
751 // Read FPSCR and extract FPCR value
752 FPSCR fpscr = thread->readMiscRegNoEffect(MISCREG_FPSCR);
753 const uint32_t ones = (uint32_t)(-1);
754 FPSCR fpcrMask = 0;
755 fpcrMask.ioe = ones;
756 fpcrMask.dze = ones;
757 fpcrMask.ofe = ones;
758 fpcrMask.ufe = ones;
759 fpcrMask.ixe = ones;
760 fpcrMask.ide = ones;
761 fpcrMask.len = ones;
762 fpcrMask.stride = ones;
763 fpcrMask.rMode = ones;
764 fpcrMask.fz = ones;
765 fpcrMask.dn = ones;
766 fpcrMask.ahp = ones;
767 values.push_back(fpscr & fpcrMask);
768 } else if (it->index == MISCREG_FPSR) {
769 // Read FPSCR and extract FPSR value
770 FPSCR fpscr = thread->readMiscRegNoEffect(MISCREG_FPSCR);
771 const uint32_t ones = (uint32_t)(-1);
772 FPSCR fpsrMask = 0;
773 fpsrMask.ioc = ones;
774 fpsrMask.dzc = ones;
775 fpsrMask.ofc = ones;
776 fpsrMask.ufc = ones;
777 fpsrMask.ixc = ones;
778 fpsrMask.idc = ones;
779 fpsrMask.qc = ones;
780 fpsrMask.v = ones;
781 fpsrMask.c = ones;
782 fpsrMask.z = ones;
783 fpsrMask.n = ones;
784 values.push_back(fpscr & fpsrMask);
785 } else {
786 values.push_back(thread->readMiscRegNoEffect(it->index));
787 }
788 break;
789 default:
790 panic("Unknown TARMAC trace record type!");
791 }
792
793 bool same = true;
794 if (values.size() != it->values.size()) same = false;
795
796 uint32_t size = values.size();
797 if (size > it->values.size())
798 size = it->values.size();
799
800 if (same) {
801 for (int i = 0; i < size; ++i) {
802 if (values[i] != it->values[i]) {
803 same = false;
804 break;
805 }
806 }
807 }
808
809 if (!same) {
810 if (!mismatch) {
811 TarmacParserRecord::printMismatchHeader(inst, pc);
812 mismatch = true;
813 }
814 outs << "diff> [" << it->repr << "] gem5: 0x" << hex;
815 for (auto v : values)
816 outs << setw(16) << setfill('0') << v;
817
818 outs << ", TARMAC: 0x" << hex;
819 for (auto v : it->values)
820 outs << setw(16) << setfill('0') << v;
821 outs << endl;
822 }
823 }
824 destRegRecords.clear();
825
826 if (mismatchOnPcOrOpcode && (parent.exitOnDiff ||
827 parent.exitOnInsnDiff))
828 exitSimLoop("a mismatch with the TARMAC trace has been detected "
829 "on PC or opcode", 1);
830 if (mismatch && parent.exitOnDiff)
831 exitSimLoop("a mismatch with the TARMAC trace has been detected "
832 "on data value", 1);
833 }
834
835 const char *
836 TarmacParserRecord::TarmacParserRecordEvent::description() const
837 {
838 return "TARMAC parser record event";
839 }
840
841
842 void
843 TarmacParserRecord::printMismatchHeader(const StaticInstPtr staticInst,
844 ArmISA::PCState pc)
845 {
846 ostream &outs = Trace::output();
847 outs << "\nMismatch between gem5 and TARMAC trace @ " << dec << curTick()
848 << " ticks\n"
849 << "[seq_num: " << dec << instRecord.seq_num
850 << ", opcode: 0x" << hex << (staticInst->machInst & 0xffffffff)
851 << ", PC: 0x" << pc.pc()
852 << ", disasm: " << staticInst->disassemble(pc.pc()) << "]"
853 << endl;
854 }
855
856 TarmacParserRecord::TarmacParserRecord(Tick _when, ThreadContext *_thread,
857 const StaticInstPtr _staticInst,
858 PCState _pc,
859 TarmacParser& _parent,
860 const StaticInstPtr _macroStaticInst)
861 : TarmacBaseRecord(_when, _thread, _staticInst,
862 _pc, _macroStaticInst),
863 parsingStarted(false), mismatch(false),
864 mismatchOnPcOrOpcode(false), parent(_parent)
865 {
866 memReq = std::make_shared<Request>();
867 if (maxVectorLength == 0) {
868 maxVectorLength = ArmStaticInst::getCurSveVecLen<uint64_t>(_thread);
869 }
870 }
871
872 void
873 TarmacParserRecord::dump()
874 {
875 ostream &outs = Trace::output();
876
877 uint64_t written_data = 0;
878 unsigned mem_flags = ArmISA::TLB::MustBeOne | 3 |
879 ArmISA::TLB::AllowUnaligned;
880
881 ISetState isetstate;
882
883 if (!staticInst->isMicroop() || staticInst->isLastMicroop()) {
884
885 if (parent.macroopInProgress && !staticInst->isLastMicroop()) {
886 // A microop faulted and it was not the last microop -> advance
887 // TARMAC trace to next instruction
888 advanceTrace();
889 }
890
891 parent.macroopInProgress = false;
892
893 auto arm_inst = static_cast<const ArmStaticInst*>(
894 staticInst.get()
895 );
896
897 while (advanceTrace()) {
898 switch (currRecordType) {
899
900 case TARMAC_INST:
901 parsingStarted = true;
902 if (pc.instAddr() != instRecord.addr) {
903 if (!mismatch)
904 printMismatchHeader(staticInst, pc);
905 outs << "diff> [PC] gem5: 0x" << hex << pc.instAddr()
906 << ", TARMAC: 0x" << instRecord.addr << endl;
907 mismatch = true;
908 mismatchOnPcOrOpcode = true;
909 }
910
911 if (arm_inst->encoding() != instRecord.opcode) {
912 if (!mismatch)
913 printMismatchHeader(staticInst, pc);
914 outs << "diff> [opcode] gem5: 0x" << hex
915 << arm_inst->encoding()
916 << ", TARMAC: 0x" << instRecord.opcode << endl;
917 mismatch = true;
918 mismatchOnPcOrOpcode = true;
919 }
920
921 // Set the Instruction set state.
922 isetstate = pcToISetState(pc);
923
924 if (instRecord.isetstate != isetstate &&
925 isetstate != ISET_UNSUPPORTED) {
926 if (!mismatch)
927 printMismatchHeader(staticInst, pc);
928 outs << "diff> [iset_state] gem5: "
929 << iSetStateToStr(isetstate)
930 << ", TARMAC: "
931 << iSetStateToStr(instRecord.isetstate);
932 mismatch = true;
933 }
934
935 // TODO(Giacomo): add support for predicate and mode checking
936 break;
937
938 case TARMAC_REG:
939 destRegRecords.push_back(regRecord);
940 break;
941
942 case TARMAC_MEM:
943 if (!readMemNoEffect(memRecord.addr, (uint8_t*) &written_data,
944 memRecord.size, mem_flags))
945 break;
946 if (written_data != memRecord.data) {
947 if (!mismatch)
948 printMismatchHeader(staticInst, pc);
949 outs << "diff> [mem(0x" << hex << memRecord.addr
950 << ")] gem5: 0x" << written_data
951 << ", TARMAC: 0x" << memRecord.data
952 << endl;
953 }
954 break;
955
956 case TARMAC_UNSUPPORTED:
957 break;
958
959 default:
960 panic("Unknown TARMAC trace record type!");
961 }
962 }
963 // We are done with the current instruction, i.e. all the corresponding
964 // entries in the TARMAC trace have been parsed
965 if (destRegRecords.size()) {
966 TarmacParserRecordEvent *event = new TarmacParserRecordEvent(
967 parent, thread, staticInst, pc, mismatch,
968 mismatchOnPcOrOpcode);
969 mainEventQueue[0]->schedule(event, curTick());
970 } else if (mismatchOnPcOrOpcode && (parent.exitOnDiff ||
971 parent.exitOnInsnDiff)) {
972 exitSimLoop("a mismatch with the TARMAC trace has been detected "
973 "on PC or opcode", 1);
974 }
975 } else {
976 parent.macroopInProgress = true;
977 }
978 }
979
980 bool
981 TarmacParserRecord::advanceTrace()
982 {
983 ifstream& trace = parent.trace;
984 trace >> hex; // All integer values are in hex base
985
986 if (buf[0] != 'I') {
987 trace >> buf;
988 if (trace.eof())
989 return false;
990 trace >> buf >> buf;
991 if (parent.cpuId) {
992 assert((buf[0] == 'c') && (buf[1] == 'p') && (buf[2] == 'u'));
993 trace >> buf;
994 }
995 }
996
997 if (trace.eof())
998 return false;
999
1000 if (buf[0] == 'I') {
1001 // Instruction trace record
1002 if (parsingStarted)
1003 return false;
1004 currRecordType = TARMAC_INST;
1005 instRecord.taken = (buf[1] == 'T');
1006 trace >> buf;
1007 instRecord.seq_num = atoi(&buf[1]);
1008 trace >> instRecord.addr;
1009 char c = trace.peek();
1010 if (c == ':') {
1011 // Skip phys. address and _S/_NS suffix
1012 trace >> c >> buf;
1013 }
1014 trace >> instRecord.opcode;
1015 trace >> buf;
1016 switch (buf[0]) {
1017 case 'A':
1018 instRecord.isetstate = ISET_ARM;
1019 break;
1020 case 'T':
1021 instRecord.isetstate = ISET_THUMB;
1022 break;
1023 case 'O':
1024 instRecord.isetstate = ISET_A64;
1025 break;
1026 default:
1027 warn("Invalid TARMAC trace record (seq_num: %lld)",
1028 instRecord.seq_num);
1029 instRecord.isetstate = ISET_UNSUPPORTED;
1030 currRecordType = TARMAC_UNSUPPORTED;
1031 break;
1032 }
1033 trace.ignore(MaxLineLength, '\n');
1034 buf[0] = 0;
1035 } else if (buf[0] == 'R') {
1036 // Register trace record
1037 currRecordType = TARMAC_REG;
1038 regRecord.values.clear();
1039 trace >> buf;
1040 strcpy(regRecord.repr, buf);
1041 if (std::tolower(buf[0]) == 'r' && isdigit(buf[1])) {
1042 // R register
1043 regRecord.type = REG_R;
1044 int base_index = atoi(&buf[1]);
1045 char* pch = strchr(buf, '_');
1046 if (pch == NULL) {
1047 regRecord.index = INTREG_USR(base_index);
1048 } else {
1049 ++pch;
1050 if (strncmp(pch, "usr", 3) == 0)
1051 regRecord.index = INTREG_USR(base_index);
1052 else if (strncmp(pch, "fiq", 3) == 0)
1053 regRecord.index = INTREG_FIQ(base_index);
1054 else if (strncmp(pch, "irq", 3) == 0)
1055 regRecord.index = INTREG_IRQ(base_index);
1056 else if (strncmp(pch, "svc", 3) == 0)
1057 regRecord.index = INTREG_SVC(base_index);
1058 else if (strncmp(pch, "mon", 3) == 0)
1059 regRecord.index = INTREG_MON(base_index);
1060 else if (strncmp(pch, "abt", 3) == 0)
1061 regRecord.index = INTREG_ABT(base_index);
1062 else if (strncmp(pch, "und", 3) == 0)
1063 regRecord.index = INTREG_UND(base_index);
1064 else if (strncmp(pch, "hyp", 3) == 0)
1065 regRecord.index = INTREG_HYP(base_index);
1066 }
1067 } else if (std::tolower(buf[0]) == 'x' && isdigit(buf[1])) {
1068 // X register (A64)
1069 regRecord.type = REG_X;
1070 regRecord.index = atoi(&buf[1]);
1071 } else if (std::tolower(buf[0]) == 's' && isdigit(buf[1])) {
1072 // S register
1073 regRecord.type = REG_S;
1074 regRecord.index = atoi(&buf[1]);
1075 } else if (std::tolower(buf[0]) == 'd' && isdigit(buf[1])) {
1076 // D register
1077 regRecord.type = REG_D;
1078 regRecord.index = atoi(&buf[1]);
1079 } else if (std::tolower(buf[0]) == 'q' && isdigit(buf[1])) {
1080 // Q register
1081 regRecord.type = REG_Q;
1082 regRecord.index = atoi(&buf[1]);
1083 } else if (std::tolower(buf[0]) == 'z' && isdigit(buf[1])) {
1084 // Z (SVE vector) register
1085 regRecord.type = REG_Z;
1086 regRecord.index = atoi(&buf[1]);
1087 } else if (std::tolower(buf[0]) == 'p' && isdigit(buf[1])) {
1088 // P (SVE predicate) register
1089 regRecord.type = REG_P;
1090 regRecord.index = atoi(&buf[1]);
1091 } else if (strncmp(buf, "SP_EL", 5) == 0) {
1092 // A64 stack pointer
1093 regRecord.type = REG_X;
1094 regRecord.index = INTREG_SP0 + atoi(&buf[5]);
1095 } else if (miscRegMap.count(buf)) {
1096 // Misc. register
1097 regRecord.type = REG_MISC;
1098 regRecord.index = miscRegMap[buf];
1099 } else {
1100 // Try match with upper case name (misc. register)
1101 string reg_name = buf;
1102 transform(reg_name.begin(), reg_name.end(), reg_name.begin(),
1103 ::tolower);
1104 if (miscRegMap.count(reg_name.c_str())) {
1105 regRecord.type = REG_MISC;
1106 regRecord.index = miscRegMap[reg_name.c_str()];
1107 } else {
1108 warn("Unknown register in TARMAC trace (%s).\n", buf);
1109 currRecordType = TARMAC_UNSUPPORTED;
1110 trace.ignore(MaxLineLength, '\n');
1111 buf[0] = 0;
1112 return true;
1113 }
1114 }
1115 if (regRecord.type == REG_Q) {
1116 trace.ignore();
1117 trace.get(buf, 17);
1118 uint64_t hi = strtoull(buf, NULL, 16);
1119 trace.get(buf, 17);
1120 uint64_t lo = strtoull(buf, NULL, 16);
1121 regRecord.values.push_back(lo);
1122 regRecord.values.push_back(hi);
1123 } else if (regRecord.type == REG_Z) {
1124 regRecord.values.resize(maxVectorLength);
1125 for (uint8_t i = 0; i < maxVectorLength; ++i) {
1126 uint64_t v;
1127 trace >> v;
1128 char c;
1129 trace >> c;
1130 assert(c == '_');
1131
1132 uint64_t lsw = 0;
1133 trace >> lsw;
1134 v = (v << 32) | lsw;
1135 if (i < maxVectorLength - 1) trace >> c;
1136 regRecord.values[i] = v;
1137 }
1138 } else {
1139 // REG_P values are also parsed here
1140 uint64_t v;
1141 trace >> v;
1142 char c = trace.peek();
1143 if ((c == ':') || (c == '_')) {
1144 // 64-bit value with : or _ in the middle
1145 uint64_t lsw = 0;
1146 trace >> c >> lsw;
1147 v = (v << 32) | lsw;
1148 }
1149 regRecord.values.push_back(v);
1150 }
1151 trace.ignore(MaxLineLength, '\n');
1152 buf[0] = 0;
1153 } else if (buf[0] == 'M' && (parent.memWrCheck && buf[1] == 'W')) {
1154 currRecordType = TARMAC_MEM;
1155 memRecord.size = atoi(&buf[2]);
1156 trace >> memRecord.addr;
1157 char c = trace.peek();
1158 if (c == ':') {
1159 // Skip phys. address and _S/_NS suffix
1160 trace >> c >> buf;
1161 }
1162 uint64_t data = 0;
1163 trace >> data;
1164 c = trace.peek();
1165 if (c == '_') {
1166 // 64-bit value with _ in the middle
1167 uint64_t lsw = 0;
1168 trace >> c >> lsw;
1169 data = (data << 32) | lsw;
1170 }
1171 memRecord.data = data;
1172 trace.ignore(MaxLineLength, '\n');
1173 buf[0] = 0;
1174 } else {
1175 currRecordType = TARMAC_UNSUPPORTED;
1176 trace.ignore(MaxLineLength, '\n');
1177 buf[0] = 0;
1178 }
1179
1180 return true;
1181 }
1182
1183 bool
1184 TarmacParserRecord::readMemNoEffect(Addr addr, uint8_t *data, unsigned size,
1185 unsigned flags)
1186 {
1187 const RequestPtr &req = memReq;
1188 ArmISA::TLB* dtb = static_cast<TLB*>(thread->getDTBPtr());
1189
1190 req->setVirt(0, addr, size, flags, thread->pcState().instAddr(),
1191 Request::funcMasterId);
1192
1193 // Translate to physical address
1194 Fault fault = dtb->translateAtomic(req, thread, BaseTLB::Read);
1195
1196 // Ignore read if the address falls into the ignored range
1197 if (parent.ignoredAddrRange.contains(addr))
1198 return false;
1199
1200 // Now do the access
1201 if (fault == NoFault &&
1202 !req->getFlags().isSet(Request::NO_ACCESS)) {
1203 if (req->isLLSC() || req->isMmappedIpr())
1204 // LLSCs and mem. mapped IPRs are ignored
1205 return false;
1206 // the translating proxy will perform the virtual to physical
1207 // translation again
1208 thread->getVirtProxy().readBlob(addr, data, size);
1209 } else {
1210 return false;
1211 }
1212
1213 if (fault != NoFault) {
1214 return false;
1215 }
1216
1217 return true;
1218 }
1219
1220 void
1221 TarmacParser::advanceTraceToStartPc()
1222 {
1223 char buf[TarmacParserRecord::MaxLineLength];
1224 Addr pc;
1225 int saved_offset;
1226
1227 trace >> hex; // All integer values are in hex base
1228
1229 while (true) {
1230 saved_offset = trace.tellg();
1231 trace >> buf >> buf >> buf;
1232 if (cpuId)
1233 trace >> buf;
1234 if (buf[0] == 'I') {
1235 trace >> buf >> pc;
1236 if (pc == startPc) {
1237 // Set file pointer to the beginning of this line
1238 trace.seekg(saved_offset, ios::beg);
1239 return;
1240 } else {
1241 trace.ignore(TarmacParserRecord::MaxLineLength, '\n');
1242 }
1243 } else {
1244 trace.ignore(TarmacParserRecord::MaxLineLength, '\n');
1245 }
1246 if (trace.eof())
1247 panic("End of TARMAC trace reached before start PC\n");
1248 }
1249 }
1250
1251 const char*
1252 TarmacParserRecord::iSetStateToStr(ISetState isetstate) const
1253 {
1254 switch (isetstate) {
1255 case ISET_ARM:
1256 return "ARM (A32)";
1257 case ISET_THUMB:
1258 return "Thumb (A32)";
1259 case ISET_A64:
1260 return "A64";
1261 default:
1262 return "UNSUPPORTED";
1263 }
1264 }
1265
1266 } // namespace Trace
1267
1268 Trace::TarmacParser *
1269 TarmacParserParams::create()
1270 {
1271 return new Trace::TarmacParser(this);
1272 }