gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
tarmac_parser.cc
Go to the documentation of this file.
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 
47 
48 #include "arch/arm/tlb.hh"
50 #include "config/the_isa.hh"
51 #include "cpu/static_inst.hh"
52 #include "cpu/thread_context.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(
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(
673  it->index / NumVecElemPerNeonVecReg,
674  it->index % NumVecElemPerNeonVecReg));
675  const VecElem w1 = thread->readVecElem(
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  {
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(
705  it->index / NumVecElemPerNeonVecReg,
706  it->index % NumVecElemPerNeonVecReg));
707  const VecElem w1 = thread->readVecElem(
709  (it->index + 1) / NumVecElemPerNeonVecReg,
710  (it->index + 1) % NumVecElemPerNeonVecReg));
711  const VecElem w2 = thread->readVecElem(
713  (it->index + 2) / NumVecElemPerNeonVecReg,
714  (it->index + 2) % NumVecElemPerNeonVecReg));
715  const VecElem w3 = thread->readVecElem(
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,
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
874 {
875  ostream &outs = Trace::output();
876 
877  uint64_t written_data = 0;
878  unsigned mem_flags = ArmISA::TLB::MustBeOne | 3 |
880 
881  ISetState isetstate;
882 
884 
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)
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)
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)
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)
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()) {
969  mainEventQueue[0]->schedule(event, curTick());
970  } else if (mismatchOnPcOrOpcode && (parent.exitOnDiff ||
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
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;
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)",
1029  instRecord.isetstate = ISET_UNSUPPORTED;
1031  break;
1032  }
1033  trace.ignore(MaxLineLength, '\n');
1034  buf[0] = 0;
1035  } else if (buf[0] == 'R') {
1036  // Register trace record
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);
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')) {
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 {
1176  trace.ignore(MaxLineLength, '\n');
1177  buf[0] = 0;
1178  }
1179 
1180  return true;
1181 }
1182 
1183 bool
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(),
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
1222 {
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*
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 
1269 TarmacParserParams::create()
1270 {
1271  return new Trace::TarmacParser(this);
1272 }
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
std::ifstream trace
TARMAC trace file.
TheISA::PCState pc
Definition: insttracer.hh:69
static IntRegIndex INTREG_USR(unsigned index)
Definition: intregs.hh:329
Bitfield< 28 > v
decltype(nullptr) constexpr NoFault
Definition: types.hh:245
static IntRegIndex INTREG_SVC(unsigned index)
Definition: intregs.hh:365
ISetState
ARM instruction set state.
Definition: tarmac_base.hh:77
Event triggered to check the value of the destination registers.
Bitfield< 7 > i
virtual BaseTLB * getDTBPtr()=0
static TarmacRecordType currRecordType
Type of last parsed record.
static IntRegIndex INTREG_IRQ(unsigned index)
Definition: intregs.hh:437
virtual TheISA::PCState pcState() const =0
static ParserRegEntry regRecord
Buffer for register trace records.
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:406
bool exitOnInsnDiff
If true, the simulation is stopped as the first mismatch is detected on PC or opcode.
std::shared_ptr< Request > RequestPtr
Definition: request.hh:83
static ISetState pcToISetState(ArmISA::PCState pc)
Returns the Instruction Set State according to the current PCState.
Definition: tarmac_base.cc:102
const char * iSetStateToStr(ISetState isetstate) const
Returns the string representation of an instruction set state.
ThreadContext * thread
Definition: insttracer.hh:65
virtual const std::string & disassemble(Addr pc, const SymbolTable *symtab=0) const
Return string representation of disassembled instruction.
Definition: static_inst.cc:123
bool parsingStarted
True if a TARMAC instruction record has already been parsed for this instruction. ...
virtual PortProxy & getVirtProxy()=0
Addr size
The size of the memory request.
Definition: insttracer.hh:84
RequestPtr memReq
Request for memory write checks.
bool mismatch
True if a mismatch has been detected for this instruction.
vector< EventQueue * > mainEventQueue
Array for main event queues.
Definition: eventq.cc:59
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:586
Definition: ccregs.hh:42
uint32_t VecElem
Definition: registers.hh:70
ThreadContext is the external interface to all thread state for anything outside of the CPU...
bool cpuId
If true, the trace format includes the CPU id.
static std::list< ParserRegEntry > destRegRecords
List of records of destination registers.
Tarmac Parser: this tracer parses an existing Tarmac trace and it diffs it with gem5 simulation statu...
bool mismatchOnPcOrOpcode
True if a mismatch has been detected for this instruction on PC or opcode.
Vector Register Native Elem lane.
Definition: reg_class.hh:62
const ExtMachInst machInst
The binary machine instruction.
Definition: static_inst.hh:229
bool readMemNoEffect(Addr addr, uint8_t *data, unsigned size, unsigned flags)
Performs a memory access to read the value written by a previous write.
Tick curTick()
The current simulated tick.
Definition: core.hh:47
Bitfield< 4 > pc
static MiscRegMap miscRegMap
static ParserInstEntry instRecord
Buffer for instruction trace records.
uint64_t Tick
Tick count type.
Definition: types.hh:63
static int8_t maxVectorLength
Max.
::DummyVecRegContainer VecRegContainer
Definition: registers.hh:53
VecPredReg::Container VecPredRegContainer
Definition: registers.hh:79
Bitfield< 19, 16 > lo
static ParserMemEntry memRecord
Buffer for memory access trace records (stores only).
static IntRegIndex INTREG_MON(unsigned index)
Definition: intregs.hh:383
STL list class.
Definition: stl.hh:54
union Trace::InstRecord::@120 data
std::ostream & output()
Get the ostream from the current global logger.
Definition: trace.cc:81
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
static IntRegIndex INTREG_UND(unsigned index)
Definition: intregs.hh:419
Bitfield< 10, 5 > event
This master id is used for functional requests that don&#39;t come from a particular device.
Definition: request.hh:212
void advanceTraceToStartPc()
Helper function to advance the trace up to startPc.
void readBlob(Addr addr, void *p, int size) const
Higher level interfaces based on the above.
Definition: port_proxy.hh:179
static IntRegIndex INTREG_FIQ(unsigned index)
Definition: intregs.hh:455
unsigned flags
The flags that were assigned to the request.
Definition: insttracer.hh:85
static void printMismatchHeader(const StaticInstPtr inst, ArmISA::PCState pc)
Print a mismatch header containing the instruction fields as reported by gem5.
The request should not cause a memory access.
Definition: request.hh:138
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
Schedule an event to exit the simulation loop (returning to Python) at the end of the current cycle (...
Definition: sim_events.cc:90
Bitfield< 29 > c
static IntRegIndex INTREG_ABT(unsigned index)
Definition: intregs.hh:401
Declaration of the Packet class.
VecReg::Container VecRegContainer
Definition: registers.hh:73
GenericISA::SimplePCState< MachInst > PCState
Definition: types.hh:43
static IntRegIndex INTREG_HYP(unsigned index)
Definition: intregs.hh:347
AddrRange ignoredAddrRange
Ignored addresses (ignored if empty).
TranslatingPortProxy Object Declaration for FS.
bool macroopInProgress
True if a macroop is currently in progress.
StaticInstPtr staticInst
Definition: insttracer.hh:68
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:79
bool advanceTrace()
Advances the TARMAC trace up to the next instruction, register, or memory access record.
static char buf[MaxLineLength]
Buffer used for trace file parsing.
bool memWrCheck
If true, memory write accesses are checked.
Vector Register.
Definition: reg_class.hh:60
#define warn(...)
Definition: logging.hh:212
bool exitOnDiff
If true, the simulation is stopped as the first mismatch is detected.
constexpr unsigned NumVecElemPerNeonVecReg
Definition: registers.hh:66
Bitfield< 0 > p
T * get() const
Directly access the pointer itself without taking a reference.
Definition: refcnt.hh:221
static const int MaxLineLength
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
Addr addr
The address that was accessed.
Definition: insttracer.hh:83
bool isMicroop() const
Definition: static_inst.hh:197
Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, Mode mode, ArmTranslationType tranType)
Definition: tlb.cc:1187
bool isLastMicroop() const
Definition: static_inst.hh:199

Generated on Fri Feb 28 2020 16:26:57 for gem5 by doxygen 1.8.13