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

Generated on Fri Jul 3 2020 15:42:40 for gem5 by doxygen 1.8.13