1/*
2 * Copyright (c) 2011,2017-2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Giacomo Gabrielli
38 */
39
40#include <algorithm>
41#include <cctype>
42#include <cstring>
43#include <iomanip>
44#include <string>
45
46#include "arch/arm/tracers/tarmac_parser.hh"
47
48#include "arch/arm/tlb.hh"
49#include "arch/arm/insts/static_inst.hh"
50#include "config/the_isa.hh"
51#include "cpu/static_inst.hh"
52#include "cpu/thread_context.hh"
53#include "mem/fs_translating_port_proxy.hh"
54#include "mem/packet.hh"
55#include "sim/core.hh"
56#include "sim/faults.hh"
57#include "sim/sim_exit.hh"
58
59using namespace std;
60using namespace ArmISA;
61
62namespace Trace {
63
64// TARMAC Parser static variables
65const int TarmacParserRecord::MaxLineLength;
66
67TarmacParserRecord::ParserInstEntry TarmacParserRecord::instRecord;
68TarmacParserRecord::ParserRegEntry TarmacParserRecord::regRecord;
69TarmacParserRecord::ParserMemEntry TarmacParserRecord::memRecord;
70TarmacBaseRecord::TarmacRecordType TarmacParserRecord::currRecordType;
71
72list<TarmacParserRecord::ParserRegEntry> TarmacParserRecord::destRegRecords;
73char TarmacParserRecord::buf[TarmacParserRecord::MaxLineLength];
74TarmacParserRecord::MiscRegMap TarmacParserRecord::miscRegMap = {
75
76    { "cpsr", MISCREG_CPSR },
77    { "nzcv", MISCREG_NZCV },
78
79    // AArch32 CP14 registers
80    { "dbgdidr", MISCREG_DBGDIDR },
81    { "dbgdscrint", MISCREG_DBGDSCRint },
82    { "dbgdccint", MISCREG_DBGDCCINT },
83    { "dbgdtrtxint", MISCREG_DBGDTRTXint },
84    { "dbgdtrrxint", MISCREG_DBGDTRRXint },
85    { "dbgwfar", MISCREG_DBGWFAR },
86    { "dbgvcr", MISCREG_DBGVCR },
87    { "dbgdtrrxext", MISCREG_DBGDTRRXext },
88    { "dbgdscrext", MISCREG_DBGDSCRext },
89    { "dbgdtrtxext", MISCREG_DBGDTRTXext },
90    { "dbgoseccr", MISCREG_DBGOSECCR },
91    { "dbgbvr0", MISCREG_DBGBVR0 },
92    { "dbgbvr1", MISCREG_DBGBVR1 },
93    { "dbgbvr2", MISCREG_DBGBVR2 },
94    { "dbgbvr3", MISCREG_DBGBVR3 },
95    { "dbgbvr4", MISCREG_DBGBVR4 },
96    { "dbgbvr5", MISCREG_DBGBVR5 },
97    { "dbgbcr0", MISCREG_DBGBCR0 },
98    { "dbgbcr1", MISCREG_DBGBCR1 },
99    { "dbgbcr2", MISCREG_DBGBCR2 },
100    { "dbgbcr3", MISCREG_DBGBCR3 },
101    { "dbgbcr4", MISCREG_DBGBCR4 },
102    { "dbgbcr5", MISCREG_DBGBCR5 },
103    { "dbgwvr0", MISCREG_DBGWVR0 },
104    { "dbgwvr1", MISCREG_DBGWVR1 },
105    { "dbgwvr2", MISCREG_DBGWVR2 },
106    { "dbgwvr3", MISCREG_DBGWVR3 },
107    { "dbgwcr0", MISCREG_DBGWCR0 },
108    { "dbgwcr1", MISCREG_DBGWCR1 },
109    { "dbgwcr2", MISCREG_DBGWCR2 },
110    { "dbgwcr3", MISCREG_DBGWCR3 },
111    { "dbgdrar", MISCREG_DBGDRAR },
112    { "dbgbxvr4", MISCREG_DBGBXVR4 },
113    { "dbgbxvr5", MISCREG_DBGBXVR5 },
114    { "dbgoslar", MISCREG_DBGOSLAR },
115    { "dbgoslsr", MISCREG_DBGOSLSR },
116    { "dbgosdlr", MISCREG_DBGOSDLR },
117    { "dbgprcr", MISCREG_DBGPRCR },
118    { "dbgdsar", MISCREG_DBGDSAR },
119    { "dbgclaimset", MISCREG_DBGCLAIMSET },
120    { "dbgclaimclr", MISCREG_DBGCLAIMCLR },
121    { "dbgauthstatus", MISCREG_DBGAUTHSTATUS },
122    { "dbgdevid2", MISCREG_DBGDEVID2 },
123    { "dbgdevid1", MISCREG_DBGDEVID1 },
124    { "dbgdevid0", MISCREG_DBGDEVID0 },
125    { "teecr", MISCREG_TEECR },
126    { "jidr", MISCREG_JIDR },
127    { "teehbr", MISCREG_TEEHBR },
128    { "joscr", MISCREG_JOSCR },
129    { "jmcr", MISCREG_JMCR },
130
131    // AArch32 CP15 registers
132    { "midr", MISCREG_MIDR },
133    { "ctr", MISCREG_CTR },
134    { "tcmtr", MISCREG_TCMTR },
135    { "tlbtr", MISCREG_TLBTR },
136    { "mpidr", MISCREG_MPIDR },
137    { "revidr", MISCREG_REVIDR },
138    { "id_pfr0", MISCREG_ID_PFR0 },
139    { "id_pfr1", MISCREG_ID_PFR1 },
140    { "id_dfr0", MISCREG_ID_DFR0 },
141    { "id_afr0", MISCREG_ID_AFR0 },
142    { "id_mmfr0", MISCREG_ID_MMFR0 },
143    { "id_mmfr1", MISCREG_ID_MMFR1 },
144    { "id_mmfr2", MISCREG_ID_MMFR2 },
145    { "id_mmfr3", MISCREG_ID_MMFR3 },
146    { "id_isar0", MISCREG_ID_ISAR0 },
147    { "id_isar1", MISCREG_ID_ISAR1 },
148    { "id_isar2", MISCREG_ID_ISAR2 },
149    { "id_isar3", MISCREG_ID_ISAR3 },
150    { "id_isar4", MISCREG_ID_ISAR4 },
151    { "id_isar5", MISCREG_ID_ISAR5 },
152    { "ccsidr", MISCREG_CCSIDR },
153    { "clidr", MISCREG_CLIDR },
154    { "aidr", MISCREG_AIDR },
155    { "csselr_ns", MISCREG_CSSELR_NS },
156    { "csselr_s", MISCREG_CSSELR_S },
157    { "vpidr", MISCREG_VPIDR },
158    { "vmpidr", MISCREG_VMPIDR },
159    { "sctlr_ns", MISCREG_SCTLR_NS },
160    { "sctlr_s", MISCREG_SCTLR_S },
161    { "actlr_ns", MISCREG_ACTLR_NS },
162    { "actlr_s", MISCREG_ACTLR_S },
163    { "cpacr", MISCREG_CPACR },
164    { "scr", MISCREG_SCR },
165    { "sder", MISCREG_SDER },
166    { "nsacr", MISCREG_NSACR },
167    { "hsctlr", MISCREG_HSCTLR },
168    { "hactlr", MISCREG_HACTLR },
169    { "hcr", MISCREG_HCR },
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
631void
632TarmacParserRecord::TarmacParserRecordEvent::process()
633{
634    ostream &outs = Trace::output();
635
636    list<ParserRegEntry>::iterator it = destRegRecords.begin(),
637                                   end = destRegRecords.end();
638
639    uint64_t value_hi, value_lo;
640    bool check_value_hi = false;
641
642    for (; it != end; ++it) {
643        switch (it->type) {
644          case REG_R:
645          case REG_X:
646            value_lo = thread->readIntReg(it->index);
647            break;
648          case REG_S:
649            if (instRecord.isetstate == ISET_A64)
650                value_lo = thread->readFloatReg(it->index * 4);
651            else
652                value_lo = thread->readFloatReg(it->index);
653            break;
654          case REG_D:
655            if (instRecord.isetstate == ISET_A64)
656                value_lo = thread->readFloatReg(it->index * 4) |
657                    (uint64_t) thread->readFloatReg(it->index * 4 + 1) <<
658                    32;
659            else
660                value_lo = thread->readFloatReg(it->index * 2) |
661                    (uint64_t) thread->readFloatReg(it->index * 2 + 1) <<
662                    32;
663            break;
664          case REG_Q:
665            check_value_hi = true;
666            if (instRecord.isetstate == ISET_A64) {
667                value_lo = thread->readFloatReg(it->index * 4) |
668                    (uint64_t) thread->readFloatReg(it->index * 4 + 1) <<
669                    32;
670                value_hi = thread->readFloatReg(it->index * 4 + 2) |
671                    (uint64_t) thread->readFloatReg(it->index * 4 + 3) <<
672                    32;
673            } else {
674                value_lo = thread->readFloatReg(it->index * 2) |
675                    (uint64_t) thread->readFloatReg(it->index * 2 + 1) <<
676                    32;
677                value_hi = thread->readFloatReg(it->index * 2 + 2) |
678                    (uint64_t) thread->readFloatReg(it->index * 2 + 3) <<
679                    32;
680            }
681            break;
682          case REG_MISC:
683            if (it->index == MISCREG_CPSR) {
684                // Read condition codes from aliased integer regs
685                CPSR cpsr = thread->readMiscRegNoEffect(it->index);
686                cpsr.nz = thread->readCCReg(CCREG_NZ);
687                cpsr.c = thread->readCCReg(CCREG_C);
688                cpsr.v = thread->readCCReg(CCREG_V);
689                cpsr.ge = thread->readCCReg(CCREG_GE);
690                value_lo = cpsr;
691            } else if (it->index == MISCREG_NZCV) {
692                CPSR cpsr = 0;
693                cpsr.nz = thread->readCCReg(CCREG_NZ);
694                cpsr.c = thread->readCCReg(CCREG_C);
695                cpsr.v = thread->readCCReg(CCREG_V);
696                value_lo = cpsr;
697            } else {
698                value_lo = thread->readMiscRegNoEffect(it->index);
699            }
700            break;
701          default:
702            panic("Unknown TARMAC trace record type!");
703        }
704
705        if (value_lo != it->valueLo ||
706            (check_value_hi && (value_hi != it->valueHi))) {
707            if (!mismatch)
708                TarmacParserRecord::printMismatchHeader(inst, pc);
709            outs << "diff> [" << it->repr << "] gem5: 0x";
710            if (check_value_hi)
711                outs << hex << setfill('0') << setw(16) << value_hi
712                     << setfill('0') << setw(16) << value_lo;
713            else
714                outs << hex << value_lo;
715            outs << ", TARMAC: 0x";
716            if (check_value_hi)
717                outs << hex << setfill('0') << setw(16) << it->valueHi
718                     << setfill('0') << setw(16) << it->valueLo << endl;
719            else
720                outs << it->valueLo << endl;
721            mismatch = true;
722        }
723
724        check_value_hi = false;
725    }
726    destRegRecords.clear();
727
728    if (mismatchOnPcOrOpcode && (parent.exitOnDiff ||
729                                 parent.exitOnInsnDiff))
730        exitSimLoop("a mismatch with the TARMAC trace has been detected "
731                    "on PC or opcode", 1);
732    if (mismatch && parent.exitOnDiff)
733        exitSimLoop("a mismatch with the TARMAC trace has been detected "
734                    "on data value", 1);
735}
736
737const char *
738TarmacParserRecord::TarmacParserRecordEvent::description() const
739{
740    return "TARMAC parser record event";
741}
742
743
744void
745TarmacParserRecord::printMismatchHeader(const StaticInstPtr staticInst,
746                                        ArmISA::PCState pc)
747{
748    ostream &outs = Trace::output();
749    outs << "\nMismatch between gem5 and TARMAC trace @ " << dec << curTick()
750         << " ticks\n"
751         << "[seq_num: " << dec << instRecord.seq_num
752         << ", opcode: 0x" << hex << (staticInst->machInst & 0xffffffff)
753         << ", PC: 0x" << pc.pc()
754         << ", disasm: " <<  staticInst->disassemble(pc.pc()) << "]"
755         << endl;
756}
757
758TarmacParserRecord::TarmacParserRecord(Tick _when, ThreadContext *_thread,
759                                       const StaticInstPtr _staticInst,
760                                       PCState _pc,
761                                       TarmacParser& _parent,
762                                       const StaticInstPtr _macroStaticInst)
763    : TarmacBaseRecord(_when, _thread, _staticInst,
764                       _pc, _macroStaticInst),
765      parsingStarted(false), mismatch(false),
766      mismatchOnPcOrOpcode(false), parent(_parent)
767{
768    memReq = std::make_shared<Request>();
769}
770
771void
772TarmacParserRecord::dump()
773{
774    ostream &outs = Trace::output();
775
776    // By default TARMAC splits memory accesses into 4-byte chunks (see
777    // 'loadstore-display-width' option in TARMAC plugin)
778    uint32_t written_data = 0;
779    unsigned mem_flags = ArmISA::TLB::MustBeOne | 3 |
780        ArmISA::TLB::AllowUnaligned;
781
782    ISetState isetstate;
783
784    if (!staticInst->isMicroop() || staticInst->isLastMicroop()) {
785
786        if (parent.macroopInProgress && !staticInst->isLastMicroop()) {
787            // A microop faulted and it was not the last microop -> advance
788            // TARMAC trace to next instruction
789            advanceTrace();
790        }
791
792        parent.macroopInProgress = false;
793
794        auto arm_inst = static_cast<const ArmStaticInst*>(
795            staticInst.get()
796        );
797
798        while (advanceTrace()) {
799            switch (currRecordType) {
800
801              case TARMAC_INST:
802                parsingStarted = true;
803                if (pc.instAddr() != instRecord.addr) {
804                    if (!mismatch)
805                        printMismatchHeader(staticInst, pc);
806                    outs << "diff> [PC] gem5: 0x" << hex << pc.instAddr()
807                         << ", TARMAC: 0x" << instRecord.addr << endl;
808                    mismatch = true;
809                    mismatchOnPcOrOpcode = true;
810                }
811
812                if (arm_inst->encoding() != instRecord.opcode) {
813                    if (!mismatch)
814                        printMismatchHeader(staticInst, pc);
815                    outs << "diff> [opcode] gem5: 0x" << hex
816                         << arm_inst->encoding()
817                         << ", TARMAC: 0x" << instRecord.opcode << endl;
818                    mismatch = true;
819                    mismatchOnPcOrOpcode = true;
820                }
821
822                // Set the Instruction set state.
823                isetstate = pcToISetState(pc);
824
825                if (instRecord.isetstate != isetstate &&
826                    isetstate != ISET_UNSUPPORTED) {
827                    if (!mismatch)
828                        printMismatchHeader(staticInst, pc);
829                    outs << "diff> [iset_state] gem5: "
830                         << iSetStateToStr(isetstate)
831                         << ", TARMAC: "
832                         << iSetStateToStr(instRecord.isetstate);
833                    mismatch = true;
834                }
835
836                // TODO(Giacomo): add support for predicate and mode checking
837                break;
838
839              case TARMAC_REG:
840                destRegRecords.push_back(regRecord);
841                break;
842
843              case TARMAC_MEM:
844                if (!readMemNoEffect(memRecord.addr, (uint8_t*) &written_data,
845                                     memRecord.size, mem_flags))
846                    break;
847                if (written_data != memRecord.data) {
848                    if (!mismatch)
849                        printMismatchHeader(staticInst, pc);
850                    outs << "diff> [mem(0x" << hex << memRecord.addr
851                         << ")] gem5: 0x" << written_data
852                         << ", TARMAC: 0x" << memRecord.data
853                         << endl;
854                }
855                break;
856
857              case TARMAC_UNSUPPORTED:
858                break;
859
860              default:
861                panic("Unknown TARMAC trace record type!");
862            }
863        }
864        // We are done with the current instruction, i.e. all the corresponding
865        // entries in the TARMAC trace have been parsed
866        if (destRegRecords.size()) {
867            TarmacParserRecordEvent *event = new TarmacParserRecordEvent(
868                parent, thread, staticInst, pc, mismatch,
869                mismatchOnPcOrOpcode);
870            mainEventQueue[0]->schedule(event, curTick());
871        } else if (mismatchOnPcOrOpcode && (parent.exitOnDiff ||
872                                            parent.exitOnInsnDiff)) {
873            exitSimLoop("a mismatch with the TARMAC trace has been detected "
874                        "on PC or opcode", 1);
875        }
876    } else {
877        parent.macroopInProgress = true;
878    }
879}
880
881bool
882TarmacParserRecord::advanceTrace()
883{
884    ifstream& trace = parent.trace;
885    trace >> hex;  // All integer values are in hex base
886
887    if (buf[0] != 'I') {
888        trace >> buf;
889        if (trace.eof())
890            return false;
891        trace >> buf >> buf;
892        if (parent.cpuId) {
893            assert((buf[0] == 'c') && (buf[1] == 'p') && (buf[2] == 'u'));
894            trace >> buf;
895        }
896    }
897
898    if (trace.eof())
899        return false;
900
901    if (buf[0] == 'I') {
902        // Instruction trace record
903        if (parsingStarted)
904            return false;
905        currRecordType = TARMAC_INST;
906        instRecord.taken = (buf[1] == 'T');
907        trace >> buf;
908        instRecord.seq_num = atoi(&buf[1]);
909        trace >> instRecord.addr;
910        char c = trace.peek();
911        if (c == ':') {
912            // Skip phys. address and _S/_NS suffix
913            trace >> c >> buf;
914        }
915        trace >> instRecord.opcode;
916        trace >> buf;
917        switch (buf[0]) {
918          case 'A':
919            instRecord.isetstate = ISET_ARM;
920            break;
921          case 'T':
922            instRecord.isetstate = ISET_THUMB;
923            break;
924          case 'O':
925            instRecord.isetstate = ISET_A64;
926            break;
927          default:
928            warn("Invalid TARMAC trace record (seq_num: %lld)",
929                 instRecord.seq_num);
930            instRecord.isetstate = ISET_UNSUPPORTED;
931            currRecordType = TARMAC_UNSUPPORTED;
932            break;
933        }
934        trace.ignore(MaxLineLength, '\n');
935        buf[0] = 0;
936    } else if (buf[0] == 'R') {
937        // Register trace record
938        currRecordType = TARMAC_REG;
939        trace >> buf;
940        strcpy(regRecord.repr, buf);
941        if (buf[0] == 'r' && isdigit(buf[1])) {
942            // R register
943            regRecord.type = REG_R;
944            int base_index = atoi(&buf[1]);
945            char* pch = strchr(buf, '_');
946            if (pch == NULL) {
947                regRecord.index = INTREG_USR(base_index);
948            } else {
949                ++pch;
950                if (strncmp(pch, "usr", 3) == 0)
951                    regRecord.index = INTREG_USR(base_index);
952                else if (strncmp(pch, "fiq", 3) == 0)
953                    regRecord.index = INTREG_FIQ(base_index);
954                else if (strncmp(pch, "irq", 3) == 0)
955                    regRecord.index = INTREG_IRQ(base_index);
956                else if (strncmp(pch, "svc", 3) == 0)
957                    regRecord.index = INTREG_SVC(base_index);
958                else if (strncmp(pch, "mon", 3) == 0)
959                    regRecord.index = INTREG_MON(base_index);
960                else if (strncmp(pch, "abt", 3) == 0)
961                    regRecord.index = INTREG_ABT(base_index);
962                else if (strncmp(pch, "und", 3) == 0)
963                    regRecord.index = INTREG_UND(base_index);
964                else if (strncmp(pch, "hyp", 3) == 0)
965                    regRecord.index = INTREG_HYP(base_index);
966            }
967        // A64 register names are capitalized in AEM TARMAC, unlike A32
968        } else if (buf[0] == 'X' && isdigit(buf[1])) {
969            // X register (A64)
970            regRecord.type = REG_X;
971            regRecord.index = atoi(&buf[1]);
972        } else if (buf[0] == 's' && isdigit(buf[1])) {
973            // S register
974            regRecord.type = REG_S;
975            regRecord.index = atoi(&buf[1]);
976        } else if (buf[0] == 'd' && isdigit(buf[1])) {
977            // D register
978            regRecord.type = REG_D;
979            regRecord.index = atoi(&buf[1]);
980        } else if (buf[0] == 'q' && isdigit(buf[1])) {
981            // Q register
982            regRecord.type = REG_Q;
983            regRecord.index = atoi(&buf[1]);
984        } else if (strncmp(buf, "SP_EL", 5) == 0) {
985            // A64 stack pointer
986            regRecord.type = REG_X;
987            regRecord.index = INTREG_SP0 + atoi(&buf[5]);
988        } else if (miscRegMap.count(buf)) {
989            // Misc. register
990            regRecord.type = REG_MISC;
991            regRecord.index = miscRegMap[buf];
992        } else {
993            // Try match with upper case name (misc. register)
994            string reg_name = buf;
995            transform(reg_name.begin(), reg_name.end(), reg_name.begin(),
996                      ::tolower);
997            if (miscRegMap.count(reg_name.c_str())) {
998                regRecord.type = REG_MISC;
999                regRecord.index = miscRegMap[reg_name.c_str()];
1000            } else {
1001                warn("Unknown register in TARMAC trace (%s).\n", buf);
1002                currRecordType = TARMAC_UNSUPPORTED;
1003                trace.ignore(MaxLineLength, '\n');
1004                buf[0] = 0;
1005                return true;
1006            }
1007        }
1008        if (regRecord.type == REG_Q) {
1009            trace.ignore();
1010            trace.get(buf, 17);
1011            // buf[16] = '\0';
1012            regRecord.valueHi = strtoull(buf, NULL, 16);
1013            trace.get(buf, 17);
1014            // buf[16] = '\0';
1015            regRecord.valueLo = strtoull(buf, NULL, 16);
1016        } else {
1017            trace >> regRecord.valueLo;
1018            char c = trace.peek();
1019            if (c == ':') {
1020                // 64-bit value with colon in the middle
1021                uint64_t lsw = 0;
1022                trace >> c >> lsw;
1023                regRecord.valueLo = (regRecord.valueLo << 32) | lsw;
1024            }
1025        }
1026        trace.ignore(MaxLineLength, '\n');
1027        buf[0] = 0;
1028    } else if (buf[0] == 'M' && (parent.memWrCheck && buf[1] == 'W')) {
1029        currRecordType = TARMAC_MEM;
1030        memRecord.size = atoi(&buf[2]);
1031        trace >> memRecord.addr;
1032        char c = trace.peek();
1033        if (c == ':') {
1034            // Skip phys. address and _S/_NS suffix
1035            trace >> c >> buf;
1036        }
1037        trace >> memRecord.data;
1038        trace.ignore(MaxLineLength, '\n');
1039        buf[0] = 0;
1040    } else {
1041        currRecordType = TARMAC_UNSUPPORTED;
1042        trace.ignore(MaxLineLength, '\n');
1043        buf[0] = 0;
1044    }
1045
1046    return true;
1047}
1048
1049bool
1050TarmacParserRecord::readMemNoEffect(Addr addr, uint8_t *data, unsigned size,
1051                                    unsigned flags)
1052{
1053    const RequestPtr &req = memReq;
1054    ArmISA::TLB* dtb = static_cast<TLB*>(thread->getDTBPtr());
1055
1056    req->setVirt(0, addr, size, flags, thread->pcState().instAddr(),
1057                 Request::funcMasterId);
1058
1059    // Translate to physical address
1060    Fault fault = dtb->translateAtomic(req, thread, BaseTLB::Read);
1061
1062    // Ignore read if the address falls into the ignored range
1063    if (parent.ignoredAddrRange.contains(addr))
1064        return false;
1065
1066    // Now do the access
1067    if (fault == NoFault &&
1068        !req->getFlags().isSet(Request::NO_ACCESS)) {
1069        if (req->isLLSC() || req->isMmappedIpr())
1070            // LLSCs and mem. mapped IPRs are ignored
1071            return false;
1072        // the translating proxy will perform the virtual to physical
1073        // translation again
1074        thread->getVirtProxy().readBlob(addr, data, size);
1075    } else {
1076        return false;
1077    }
1078
1079    if (fault != NoFault) {
1080        return false;
1081    }
1082
1083    return true;
1084}
1085
1086void
1087TarmacParser::advanceTraceToStartPc()
1088{
1089    char buf[TarmacParserRecord::MaxLineLength];
1090    Addr pc;
1091    int saved_offset;
1092
1093    trace >> hex;  // All integer values are in hex base
1094
1095    while (true) {
1096        saved_offset = trace.tellg();
1097        trace >> buf >> buf >> buf;
1098        if (cpuId)
1099            trace >> buf;
1100        if (buf[0] == 'I') {
1101            trace >> buf >> pc;
1102            if (pc == startPc) {
1103                // Set file pointer to the beginning of this line
1104                trace.seekg(saved_offset, ios::beg);
1105                return;
1106            } else {
1107                trace.ignore(TarmacParserRecord::MaxLineLength, '\n');
1108            }
1109        } else {
1110            trace.ignore(TarmacParserRecord::MaxLineLength, '\n');
1111        }
1112        if (trace.eof())
1113            panic("End of TARMAC trace reached before start PC\n");
1114    }
1115}
1116
1117const char*
1118TarmacParserRecord::iSetStateToStr(ISetState isetstate) const
1119{
1120    switch (isetstate) {
1121      case ISET_ARM:
1122        return "ARM (A32)";
1123      case ISET_THUMB:
1124        return "Thumb (A32)";
1125      case ISET_A64:
1126        return "A64";
1127      default:
1128        return "UNSUPPORTED";
1129    }
1130}
1131
1132} // namespace Trace
1133
1134Trace::TarmacParser *
1135TarmacParserParams::create()
1136{
1137    return new Trace::TarmacParser(this);
1138}
1139