tarmac_parser.cc revision 12749:223c83ed9979
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 TheISA;
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    { "ccsidr_el1", MISCREG_CCSIDR_EL1 },
419    { "clidr_el1", MISCREG_CLIDR_EL1 },
420    { "aidr_el1", MISCREG_AIDR_EL1 },
421    { "csselr_el1", MISCREG_CSSELR_EL1 },
422    { "ctr_el0", MISCREG_CTR_EL0 },
423    { "dczid_el0", MISCREG_DCZID_EL0 },
424    { "vpidr_el2", MISCREG_VPIDR_EL2 },
425    { "vmpidr_el2", MISCREG_VMPIDR_EL2 },
426    { "sctlr_el1", MISCREG_SCTLR_EL1 },
427    { "actlr_el1", MISCREG_ACTLR_EL1 },
428    { "cpacr_el1", MISCREG_CPACR_EL1 },
429    { "sctlr_el2", MISCREG_SCTLR_EL2 },
430    { "actlr_el2", MISCREG_ACTLR_EL2 },
431    { "hcr_el2", MISCREG_HCR_EL2 },
432    { "mdcr_el2", MISCREG_MDCR_EL2 },
433    { "cptr_el2", MISCREG_CPTR_EL2 },
434    { "hstr_el2", MISCREG_HSTR_EL2 },
435    { "hacr_el2", MISCREG_HACR_EL2 },
436    { "sctlr_el3", MISCREG_SCTLR_EL3 },
437    { "actlr_el3", MISCREG_ACTLR_EL3 },
438    { "scr_el3", MISCREG_SCR_EL3 },
439    { "sder32_el3", MISCREG_SDER32_EL3 },
440    { "cptr_el3", MISCREG_CPTR_EL3 },
441    { "mdcr_el3", MISCREG_MDCR_EL3 },
442    { "ttbr0_el1", MISCREG_TTBR0_EL1 },
443    { "ttbr1_el1", MISCREG_TTBR1_EL1 },
444    { "tcr_el1", MISCREG_TCR_EL1 },
445    { "ttbr0_el2", MISCREG_TTBR0_EL2 },
446    { "tcr_el2", MISCREG_TCR_EL2 },
447    { "vttbr_el2", MISCREG_VTTBR_EL2 },
448    { "vtcr_el2", MISCREG_VTCR_EL2 },
449    { "ttbr0_el3", MISCREG_TTBR0_EL3 },
450    { "tcr_el3", MISCREG_TCR_EL3 },
451    { "dacr32_el2", MISCREG_DACR32_EL2 },
452    { "spsr_el1", MISCREG_SPSR_EL1 },
453    { "elr_el1", MISCREG_ELR_EL1 },
454    { "sp_el0", MISCREG_SP_EL0 },
455    { "spsel", MISCREG_SPSEL },
456    { "currentel", MISCREG_CURRENTEL },
457    { "nzcv", MISCREG_NZCV },
458    { "daif", MISCREG_DAIF },
459    { "fpcr", MISCREG_FPCR },
460    { "fpsr", MISCREG_FPSR },
461    { "dspsr_el0", MISCREG_DSPSR_EL0 },
462    { "dlr_el0", MISCREG_DLR_EL0 },
463    { "spsr_el2", MISCREG_SPSR_EL2 },
464    { "elr_el2", MISCREG_ELR_EL2 },
465    { "sp_el1", MISCREG_SP_EL1 },
466    { "spsr_irq", MISCREG_SPSR_IRQ_AA64 },
467    { "spsr_abt", MISCREG_SPSR_ABT_AA64 },
468    { "spsr_und", MISCREG_SPSR_UND_AA64 },
469    { "spsr_fiq", MISCREG_SPSR_FIQ_AA64 },
470    { "spsr_el3", MISCREG_SPSR_EL3 },
471    { "elr_el3", MISCREG_ELR_EL3 },
472    { "sp_el2", MISCREG_SP_EL2 },
473    { "afsr0_el1", MISCREG_AFSR0_EL1 },
474    { "afsr1_el1", MISCREG_AFSR1_EL1 },
475    { "esr_el1", MISCREG_ESR_EL1 },
476    { "ifsr32_el2", MISCREG_IFSR32_EL2 },
477    { "afsr0_el2", MISCREG_AFSR0_EL2 },
478    { "afsr1_el2", MISCREG_AFSR1_EL2 },
479    { "esr_el2", MISCREG_ESR_EL2 },
480    { "fpexc32_el2", MISCREG_FPEXC32_EL2 },
481    { "afsr0_el3", MISCREG_AFSR0_EL3 },
482    { "afsr1_el3", MISCREG_AFSR1_EL3 },
483    { "esr_el3", MISCREG_ESR_EL3 },
484    { "far_el1", MISCREG_FAR_EL1 },
485    { "far_el2", MISCREG_FAR_EL2 },
486    { "hpfar_el2", MISCREG_HPFAR_EL2 },
487    { "far_el3", MISCREG_FAR_EL3 },
488    { "ic_ialluis", MISCREG_IC_IALLUIS },
489    { "par_el1", MISCREG_PAR_EL1 },
490    { "ic_iallu", MISCREG_IC_IALLU },
491    { "dc_ivac_xt", MISCREG_DC_IVAC_Xt },
492    { "dc_isw_xt", MISCREG_DC_ISW_Xt },
493    { "at_s1e1r_xt", MISCREG_AT_S1E1R_Xt },
494    { "at_s1e1w_xt", MISCREG_AT_S1E1W_Xt },
495    { "at_s1e0r_xt", MISCREG_AT_S1E0R_Xt },
496    { "at_s1e0w_xt", MISCREG_AT_S1E0W_Xt },
497    { "dc_csw_xt", MISCREG_DC_CSW_Xt },
498    { "dc_cisw_xt", MISCREG_DC_CISW_Xt },
499    { "dc_zva_xt", MISCREG_DC_ZVA_Xt },
500    { "ic_ivau_xt", MISCREG_IC_IVAU_Xt },
501    { "dc_cvac_xt", MISCREG_DC_CVAC_Xt },
502    { "dc_cvau_xt", MISCREG_DC_CVAU_Xt },
503    { "dc_civac_xt", MISCREG_DC_CIVAC_Xt },
504    { "at_s1e2r_xt", MISCREG_AT_S1E2R_Xt },
505    { "at_s1e2w_xt", MISCREG_AT_S1E2W_Xt },
506    { "at_s12e1r_xt", MISCREG_AT_S12E1R_Xt },
507    { "at_s12e1w_xt", MISCREG_AT_S12E1W_Xt },
508    { "at_s12e0r_xt", MISCREG_AT_S12E0R_Xt },
509    { "at_s12e0w_xt", MISCREG_AT_S12E0W_Xt },
510    { "at_s1e3r_xt", MISCREG_AT_S1E3R_Xt },
511    { "at_s1e3w_xt", MISCREG_AT_S1E3W_Xt },
512    { "tlbi_vmalle1is", MISCREG_TLBI_VMALLE1IS },
513    { "tlbi_vae1is_xt", MISCREG_TLBI_VAE1IS_Xt },
514    { "tlbi_aside1is_xt", MISCREG_TLBI_ASIDE1IS_Xt },
515    { "tlbi_vaae1is_xt", MISCREG_TLBI_VAAE1IS_Xt },
516    { "tlbi_vale1is_xt", MISCREG_TLBI_VALE1IS_Xt },
517    { "tlbi_vaale1is_xt", MISCREG_TLBI_VAALE1IS_Xt },
518    { "tlbi_vmalle1", MISCREG_TLBI_VMALLE1 },
519    { "tlbi_vae1_xt", MISCREG_TLBI_VAE1_Xt },
520    { "tlbi_aside1_xt", MISCREG_TLBI_ASIDE1_Xt },
521    { "tlbi_vaae1_xt", MISCREG_TLBI_VAAE1_Xt },
522    { "tlbi_vale1_xt", MISCREG_TLBI_VALE1_Xt },
523    { "tlbi_vaale1_xt", MISCREG_TLBI_VAALE1_Xt },
524    { "tlbi_ipas2e1is_xt", MISCREG_TLBI_IPAS2E1IS_Xt },
525    { "tlbi_ipas2le1is_xt", MISCREG_TLBI_IPAS2LE1IS_Xt },
526    { "tlbi_alle2is", MISCREG_TLBI_ALLE2IS },
527    { "tlbi_vae2is_xt", MISCREG_TLBI_VAE2IS_Xt },
528    { "tlbi_alle1is", MISCREG_TLBI_ALLE1IS },
529    { "tlbi_vale2is_xt", MISCREG_TLBI_VALE2IS_Xt },
530    { "tlbi_vmalls12e1is", MISCREG_TLBI_VMALLS12E1IS },
531    { "tlbi_ipas2e1_xt", MISCREG_TLBI_IPAS2E1_Xt },
532    { "tlbi_ipas2le1_xt", MISCREG_TLBI_IPAS2LE1_Xt },
533    { "tlbi_alle2", MISCREG_TLBI_ALLE2 },
534    { "tlbi_vae2_xt", MISCREG_TLBI_VAE2_Xt },
535    { "tlbi_alle1", MISCREG_TLBI_ALLE1 },
536    { "tlbi_vale2_xt", MISCREG_TLBI_VALE2_Xt },
537    { "tlbi_vmalls12e1", MISCREG_TLBI_VMALLS12E1 },
538    { "tlbi_alle3is", MISCREG_TLBI_ALLE3IS },
539    { "tlbi_vae3is_xt", MISCREG_TLBI_VAE3IS_Xt },
540    { "tlbi_vale3is_xt", MISCREG_TLBI_VALE3IS_Xt },
541    { "tlbi_alle3", MISCREG_TLBI_ALLE3 },
542    { "tlbi_vae3_xt", MISCREG_TLBI_VAE3_Xt },
543    { "tlbi_vale3_xt", MISCREG_TLBI_VALE3_Xt },
544    { "pmintenset_el1", MISCREG_PMINTENSET_EL1 },
545    { "pmintenclr_el1", MISCREG_PMINTENCLR_EL1 },
546    { "pmcr_el0", MISCREG_PMCR_EL0 },
547    { "pmcntenset_el0", MISCREG_PMCNTENSET_EL0 },
548    { "pmcntenclr_el0", MISCREG_PMCNTENCLR_EL0 },
549    { "pmovsclr_el0", MISCREG_PMOVSCLR_EL0 },
550    { "pmswinc_el0", MISCREG_PMSWINC_EL0 },
551    { "pmselr_el0", MISCREG_PMSELR_EL0 },
552    { "pmceid0_el0", MISCREG_PMCEID0_EL0 },
553    { "pmceid1_el0", MISCREG_PMCEID1_EL0 },
554    { "pmccntr_el0", MISCREG_PMCCNTR_EL0 },
555    { "pmxevtyper_el0", MISCREG_PMXEVTYPER_EL0 },
556    { "pmccfiltr_el0", MISCREG_PMCCFILTR_EL0 },
557    { "pmxevcntr_el0", MISCREG_PMXEVCNTR_EL0 },
558    { "pmuserenr_el0", MISCREG_PMUSERENR_EL0 },
559    { "pmovsset_el0", MISCREG_PMOVSSET_EL0 },
560    { "mair_el1", MISCREG_MAIR_EL1 },
561    { "amair_el1", MISCREG_AMAIR_EL1 },
562    { "mair_el2", MISCREG_MAIR_EL2 },
563    { "amair_el2", MISCREG_AMAIR_EL2 },
564    { "mair_el3", MISCREG_MAIR_EL3 },
565    { "amair_el3", MISCREG_AMAIR_EL3 },
566    { "l2ctlr_el1", MISCREG_L2CTLR_EL1 },
567    { "l2ectlr_el1", MISCREG_L2ECTLR_EL1 },
568    { "vbar_el1", MISCREG_VBAR_EL1 },
569    { "rvbar_el1", MISCREG_RVBAR_EL1 },
570    { "isr_el1", MISCREG_ISR_EL1 },
571    { "vbar_el2", MISCREG_VBAR_EL2 },
572    { "rvbar_el2", MISCREG_RVBAR_EL2 },
573    { "vbar_el3", MISCREG_VBAR_EL3 },
574    { "rvbar_el3", MISCREG_RVBAR_EL3 },
575    { "rmr_el3", MISCREG_RMR_EL3 },
576    { "contextidr_el1", MISCREG_CONTEXTIDR_EL1 },
577    { "contextidr_el2", MISCREG_CONTEXTIDR_EL2 },
578    { "tpidr_el1", MISCREG_TPIDR_EL1 },
579    { "tpidr_el0", MISCREG_TPIDR_EL0 },
580    { "tpidrro_el0", MISCREG_TPIDRRO_EL0 },
581    { "tpidr_el2", MISCREG_TPIDR_EL2 },
582    { "tpidr_el3", MISCREG_TPIDR_EL3 },
583    { "cntkctl_el1", MISCREG_CNTKCTL_EL1 },
584    { "cntfrq_el0", MISCREG_CNTFRQ_EL0 },
585    { "cntpct_el0", MISCREG_CNTPCT_EL0 },
586    { "cntvct_el0", MISCREG_CNTVCT_EL0 },
587    { "cntp_tval_el0", MISCREG_CNTP_TVAL_EL0 },
588    { "cntp_ctl_el0", MISCREG_CNTP_CTL_EL0 },
589    { "cntp_cval_el0", MISCREG_CNTP_CVAL_EL0 },
590    { "cntv_tval_el0", MISCREG_CNTV_TVAL_EL0 },
591    { "cntv_ctl_el0", MISCREG_CNTV_CTL_EL0 },
592    { "cntv_cval_el0", MISCREG_CNTV_CVAL_EL0 },
593    { "pmevcntr0_el0", MISCREG_PMEVCNTR0_EL0 },
594    { "pmevcntr1_el0", MISCREG_PMEVCNTR1_EL0 },
595    { "pmevcntr2_el0", MISCREG_PMEVCNTR2_EL0 },
596    { "pmevcntr3_el0", MISCREG_PMEVCNTR3_EL0 },
597    { "pmevcntr4_el0", MISCREG_PMEVCNTR4_EL0 },
598    { "pmevcntr5_el0", MISCREG_PMEVCNTR5_EL0 },
599    { "pmevtyper0_el0", MISCREG_PMEVTYPER0_EL0 },
600    { "pmevtyper1_el0", MISCREG_PMEVTYPER1_EL0 },
601    { "pmevtyper2_el0", MISCREG_PMEVTYPER2_EL0 },
602    { "pmevtyper3_el0", MISCREG_PMEVTYPER3_EL0 },
603    { "pmevtyper4_el0", MISCREG_PMEVTYPER4_EL0 },
604    { "pmevtyper5_el0", MISCREG_PMEVTYPER5_EL0 },
605    { "cntvoff_el2", MISCREG_CNTVOFF_EL2 },
606    { "cnthctl_el2", MISCREG_CNTHCTL_EL2 },
607    { "cnthp_tval_el2", MISCREG_CNTHP_TVAL_EL2 },
608    { "cnthp_ctl_el2", MISCREG_CNTHP_CTL_EL2 },
609    { "cnthp_cval_el2", MISCREG_CNTHP_CVAL_EL2 },
610    { "cntps_tval_el1", MISCREG_CNTPS_TVAL_EL1 },
611    { "cntps_ctl_el1", MISCREG_CNTPS_CTL_EL1 },
612    { "cntps_cval_el1", MISCREG_CNTPS_CVAL_EL1 },
613    { "il1data0_el1", MISCREG_IL1DATA0_EL1 },
614    { "il1data1_el1", MISCREG_IL1DATA1_EL1 },
615    { "il1data2_el1", MISCREG_IL1DATA2_EL1 },
616    { "il1data3_el1", MISCREG_IL1DATA3_EL1 },
617    { "dl1data0_el1", MISCREG_DL1DATA0_EL1 },
618    { "dl1data1_el1", MISCREG_DL1DATA1_EL1 },
619    { "dl1data2_el1", MISCREG_DL1DATA2_EL1 },
620    { "dl1data3_el1", MISCREG_DL1DATA3_EL1 },
621    { "dl1data4_el1", MISCREG_DL1DATA4_EL1 },
622    { "l2actlr_el1", MISCREG_L2ACTLR_EL1 },
623    { "cpuactlr_el1", MISCREG_CPUACTLR_EL1 },
624    { "cpuectlr_el1", MISCREG_CPUECTLR_EL1 },
625    { "cpumerrsr_el1", MISCREG_CPUMERRSR_EL1 },
626    { "l2merrsr_el1", MISCREG_L2MERRSR_EL1 },
627    { "cbar_el1", MISCREG_CBAR_EL1 },
628};
629
630void
631TarmacParserRecord::TarmacParserRecordEvent::process()
632{
633    ostream &outs = Trace::output();
634
635    list<ParserRegEntry>::iterator it = destRegRecords.begin(),
636                                   end = destRegRecords.end();
637
638    uint64_t value_hi, value_lo;
639    bool check_value_hi = false;
640
641    for (; it != end; ++it) {
642        switch (it->type) {
643          case REG_R:
644          case REG_X:
645            value_lo = thread->readIntReg(it->index);
646            break;
647          case REG_S:
648            if (instRecord.isetstate == ISET_A64)
649                value_lo = thread->readFloatRegBits(it->index * 4);
650            else
651                value_lo = thread->readFloatRegBits(it->index);
652            break;
653          case REG_D:
654            if (instRecord.isetstate == ISET_A64)
655                value_lo = thread->readFloatRegBits(it->index * 4) |
656                    (uint64_t) thread->readFloatRegBits(it->index * 4 + 1) <<
657                    32;
658            else
659                value_lo = thread->readFloatRegBits(it->index * 2) |
660                    (uint64_t) thread->readFloatRegBits(it->index * 2 + 1) <<
661                    32;
662            break;
663          case REG_Q:
664            check_value_hi = true;
665            if (instRecord.isetstate == ISET_A64) {
666                value_lo = thread->readFloatRegBits(it->index * 4) |
667                    (uint64_t) thread->readFloatRegBits(it->index * 4 + 1) <<
668                    32;
669                value_hi = thread->readFloatRegBits(it->index * 4 + 2) |
670                    (uint64_t) thread->readFloatRegBits(it->index * 4 + 3) <<
671                    32;
672            } else {
673                value_lo = thread->readFloatRegBits(it->index * 2) |
674                    (uint64_t) thread->readFloatRegBits(it->index * 2 + 1) <<
675                    32;
676                value_hi = thread->readFloatRegBits(it->index * 2 + 2) |
677                    (uint64_t) thread->readFloatRegBits(it->index * 2 + 3) <<
678                    32;
679            }
680            break;
681          case REG_MISC:
682            if (it->index == MISCREG_CPSR) {
683                // Read condition codes from aliased integer regs
684                CPSR cpsr = thread->readMiscRegNoEffect(it->index);
685                cpsr.nz = thread->readCCReg(CCREG_NZ);
686                cpsr.c = thread->readCCReg(CCREG_C);
687                cpsr.v = thread->readCCReg(CCREG_V);
688                cpsr.ge = thread->readCCReg(CCREG_GE);
689                value_lo = cpsr;
690            } else if (it->index == MISCREG_NZCV) {
691                CPSR cpsr = 0;
692                cpsr.nz = thread->readCCReg(CCREG_NZ);
693                cpsr.c = thread->readCCReg(CCREG_C);
694                cpsr.v = thread->readCCReg(CCREG_V);
695                value_lo = cpsr;
696            } else {
697                value_lo = thread->readMiscRegNoEffect(it->index);
698            }
699            break;
700          default:
701            panic("Unknown TARMAC trace record type!");
702        }
703
704        if (value_lo != it->valueLo ||
705            (check_value_hi && (value_hi != it->valueHi))) {
706            if (!mismatch)
707                TarmacParserRecord::printMismatchHeader(inst, pc);
708            outs << "diff> [" << it->repr << "] gem5: 0x";
709            if (check_value_hi)
710                outs << hex << setfill('0') << setw(16) << value_hi
711                     << setfill('0') << setw(16) << value_lo;
712            else
713                outs << hex << value_lo;
714            outs << ", TARMAC: 0x";
715            if (check_value_hi)
716                outs << hex << setfill('0') << setw(16) << it->valueHi
717                     << setfill('0') << setw(16) << it->valueLo << endl;
718            else
719                outs << it->valueLo << endl;
720            mismatch = true;
721        }
722
723        check_value_hi = false;
724    }
725    destRegRecords.clear();
726
727    if (mismatchOnPcOrOpcode && (parent.exitOnDiff ||
728                                 parent.exitOnInsnDiff))
729        exitSimLoop("a mismatch with the TARMAC trace has been detected "
730                    "on PC or opcode", 1);
731    if (mismatch && parent.exitOnDiff)
732        exitSimLoop("a mismatch with the TARMAC trace has been detected "
733                    "on data value", 1);
734}
735
736const char *
737TarmacParserRecord::TarmacParserRecordEvent::description() const
738{
739    return "TARMAC parser record event";
740}
741
742
743void
744TarmacParserRecord::printMismatchHeader(const StaticInstPtr staticInst,
745                                        TheISA::PCState pc)
746{
747    ostream &outs = Trace::output();
748    outs << "\nMismatch between gem5 and TARMAC trace @ " << dec << curTick()
749         << " ticks\n"
750         << "[seq_num: " << dec << instRecord.seq_num
751         << ", opcode: 0x" << hex << (staticInst->machInst & 0xffffffff)
752         << ", PC: 0x" << pc.pc()
753         << ", disasm: " <<  staticInst->disassemble(pc.pc()) << "]"
754         << endl;
755}
756
757TarmacParserRecord::TarmacParserRecord(Tick _when, ThreadContext *_thread,
758                                       const StaticInstPtr _staticInst,
759                                       PCState _pc,
760                                       TarmacParser& _parent,
761                                       const StaticInstPtr _macroStaticInst)
762    : TarmacBaseRecord(_when, _thread, _staticInst,
763                       _pc, _macroStaticInst),
764      parsingStarted(false), mismatch(false),
765      mismatchOnPcOrOpcode(false), parent(_parent)
766{
767    memReq = std::make_shared<Request>();
768}
769
770void
771TarmacParserRecord::dump()
772{
773    ostream &outs = Trace::output();
774
775    // By default TARMAC splits memory accesses into 4-byte chunks (see
776    // 'loadstore-display-width' option in TARMAC plugin)
777    uint32_t written_data = 0;
778    unsigned mem_flags = TheISA::TLB::MustBeOne | 3 |
779        TheISA::TLB::AllowUnaligned;
780
781    ISetState isetstate;
782
783    if (!staticInst->isMicroop() || staticInst->isLastMicroop()) {
784
785        if (parent.macroopInProgress && !staticInst->isLastMicroop()) {
786            // A microop faulted and it was not the last microop -> advance
787            // TARMAC trace to next instruction
788            advanceTrace();
789        }
790
791        parent.macroopInProgress = false;
792
793        auto arm_inst = static_cast<const ArmStaticInst*>(
794            staticInst.get()
795        );
796
797        while (advanceTrace()) {
798            switch (currRecordType) {
799
800              case TARMAC_INST:
801                parsingStarted = true;
802                if (pc.instAddr() != instRecord.addr) {
803                    if (!mismatch)
804                        printMismatchHeader(staticInst, pc);
805                    outs << "diff> [PC] gem5: 0x" << hex << pc.instAddr()
806                         << ", TARMAC: 0x" << instRecord.addr << endl;
807                    mismatch = true;
808                    mismatchOnPcOrOpcode = true;
809                }
810
811                if (arm_inst->encoding() != instRecord.opcode) {
812                    if (!mismatch)
813                        printMismatchHeader(staticInst, pc);
814                    outs << "diff> [opcode] gem5: 0x" << hex
815                         << arm_inst->encoding()
816                         << ", TARMAC: 0x" << instRecord.opcode << endl;
817                    mismatch = true;
818                    mismatchOnPcOrOpcode = true;
819                }
820
821                // Set the Instruction set state.
822                isetstate = pcToISetState(pc);
823
824                if (instRecord.isetstate != isetstate &&
825                    isetstate != ISET_UNSUPPORTED) {
826                    if (!mismatch)
827                        printMismatchHeader(staticInst, pc);
828                    outs << "diff> [iset_state] gem5: "
829                         << iSetStateToStr(isetstate)
830                         << ", TARMAC: "
831                         << iSetStateToStr(instRecord.isetstate);
832                    mismatch = true;
833                }
834
835                // TODO(Giacomo): add support for predicate and mode checking
836                break;
837
838              case TARMAC_REG:
839                destRegRecords.push_back(regRecord);
840                break;
841
842              case TARMAC_MEM:
843                if (!readMemNoEffect(memRecord.addr, (uint8_t*) &written_data,
844                                     memRecord.size, mem_flags))
845                    break;
846                if (written_data != memRecord.data) {
847                    if (!mismatch)
848                        printMismatchHeader(staticInst, pc);
849                    outs << "diff> [mem(0x" << hex << memRecord.addr
850                         << ")] gem5: 0x" << written_data
851                         << ", TARMAC: 0x" << memRecord.data
852                         << endl;
853                }
854                break;
855
856              case TARMAC_UNSUPPORTED:
857                break;
858
859              default:
860                panic("Unknown TARMAC trace record type!");
861            }
862        }
863        // We are done with the current instruction, i.e. all the corresponding
864        // entries in the TARMAC trace have been parsed
865        if (destRegRecords.size()) {
866            TarmacParserRecordEvent *event = new TarmacParserRecordEvent(
867                parent, thread, staticInst, pc, mismatch,
868                mismatchOnPcOrOpcode);
869            mainEventQueue[0]->schedule(event, curTick());
870        } else if (mismatchOnPcOrOpcode && (parent.exitOnDiff ||
871                                            parent.exitOnInsnDiff)) {
872            exitSimLoop("a mismatch with the TARMAC trace has been detected "
873                        "on PC or opcode", 1);
874        }
875    } else {
876        parent.macroopInProgress = true;
877    }
878}
879
880bool
881TarmacParserRecord::advanceTrace()
882{
883    ifstream& trace = parent.trace;
884    trace >> hex;  // All integer values are in hex base
885
886    if (buf[0] != 'I') {
887        trace >> buf;
888        if (trace.eof())
889            return false;
890        trace >> buf >> buf;
891        if (parent.cpuId) {
892            assert((buf[0] == 'c') && (buf[1] == 'p') && (buf[2] == 'u'));
893            trace >> buf;
894        }
895    }
896
897    if (trace.eof())
898        return false;
899
900    if (buf[0] == 'I') {
901        // Instruction trace record
902        if (parsingStarted)
903            return false;
904        currRecordType = TARMAC_INST;
905        instRecord.taken = (buf[1] == 'T');
906        trace >> buf;
907        instRecord.seq_num = atoi(&buf[1]);
908        trace >> instRecord.addr;
909        char c = trace.peek();
910        if (c == ':') {
911            // Skip phys. address and _S/_NS suffix
912            trace >> c >> buf;
913        }
914        trace >> instRecord.opcode;
915        trace >> buf;
916        switch (buf[0]) {
917          case 'A':
918            instRecord.isetstate = ISET_ARM;
919            break;
920          case 'T':
921            instRecord.isetstate = ISET_THUMB;
922            break;
923          case 'O':
924            instRecord.isetstate = ISET_A64;
925            break;
926          default:
927            warn("Invalid TARMAC trace record (seq_num: %lld)",
928                 instRecord.seq_num);
929            instRecord.isetstate = ISET_UNSUPPORTED;
930            currRecordType = TARMAC_UNSUPPORTED;
931            break;
932        }
933        trace.ignore(MaxLineLength, '\n');
934        buf[0] = 0;
935    } else if (buf[0] == 'R') {
936        // Register trace record
937        currRecordType = TARMAC_REG;
938        trace >> buf;
939        strcpy(regRecord.repr, buf);
940        if (buf[0] == 'r' && isdigit(buf[1])) {
941            // R register
942            regRecord.type = REG_R;
943            int base_index = atoi(&buf[1]);
944            char* pch = strchr(buf, '_');
945            if (pch == NULL) {
946                regRecord.index = INTREG_USR(base_index);
947            } else {
948                ++pch;
949                if (strncmp(pch, "usr", 3) == 0)
950                    regRecord.index = INTREG_USR(base_index);
951                else if (strncmp(pch, "fiq", 3) == 0)
952                    regRecord.index = INTREG_FIQ(base_index);
953                else if (strncmp(pch, "irq", 3) == 0)
954                    regRecord.index = INTREG_IRQ(base_index);
955                else if (strncmp(pch, "svc", 3) == 0)
956                    regRecord.index = INTREG_SVC(base_index);
957                else if (strncmp(pch, "mon", 3) == 0)
958                    regRecord.index = INTREG_MON(base_index);
959                else if (strncmp(pch, "abt", 3) == 0)
960                    regRecord.index = INTREG_ABT(base_index);
961                else if (strncmp(pch, "und", 3) == 0)
962                    regRecord.index = INTREG_UND(base_index);
963                else if (strncmp(pch, "hyp", 3) == 0)
964                    regRecord.index = INTREG_HYP(base_index);
965            }
966        // A64 register names are capitalized in AEM TARMAC, unlike A32
967        } else if (buf[0] == 'X' && isdigit(buf[1])) {
968            // X register (A64)
969            regRecord.type = REG_X;
970            regRecord.index = atoi(&buf[1]);
971        } else if (buf[0] == 's' && isdigit(buf[1])) {
972            // S register
973            regRecord.type = REG_S;
974            regRecord.index = atoi(&buf[1]);
975        } else if (buf[0] == 'd' && isdigit(buf[1])) {
976            // D register
977            regRecord.type = REG_D;
978            regRecord.index = atoi(&buf[1]);
979        } else if (buf[0] == 'q' && isdigit(buf[1])) {
980            // Q register
981            regRecord.type = REG_Q;
982            regRecord.index = atoi(&buf[1]);
983        } else if (strncmp(buf, "SP_EL", 5) == 0) {
984            // A64 stack pointer
985            regRecord.type = REG_X;
986            regRecord.index = INTREG_SP0 + atoi(&buf[5]);
987        } else if (miscRegMap.count(buf)) {
988            // Misc. register
989            regRecord.type = REG_MISC;
990            regRecord.index = miscRegMap[buf];
991        } else {
992            // Try match with upper case name (misc. register)
993            string reg_name = buf;
994            transform(reg_name.begin(), reg_name.end(), reg_name.begin(),
995                      ::tolower);
996            if (miscRegMap.count(reg_name.c_str())) {
997                regRecord.type = REG_MISC;
998                regRecord.index = miscRegMap[reg_name.c_str()];
999            } else {
1000                warn("Unknown register in TARMAC trace (%s).\n", buf);
1001                currRecordType = TARMAC_UNSUPPORTED;
1002                trace.ignore(MaxLineLength, '\n');
1003                buf[0] = 0;
1004                return true;
1005            }
1006        }
1007        if (regRecord.type == REG_Q) {
1008            trace.ignore();
1009            trace.get(buf, 17);
1010            // buf[16] = '\0';
1011            regRecord.valueHi = strtoull(buf, NULL, 16);
1012            trace.get(buf, 17);
1013            // buf[16] = '\0';
1014            regRecord.valueLo = strtoull(buf, NULL, 16);
1015        } else {
1016            trace >> regRecord.valueLo;
1017            char c = trace.peek();
1018            if (c == ':') {
1019                // 64-bit value with colon in the middle
1020                uint64_t lsw = 0;
1021                trace >> c >> lsw;
1022                regRecord.valueLo = (regRecord.valueLo << 32) | lsw;
1023            }
1024        }
1025        trace.ignore(MaxLineLength, '\n');
1026        buf[0] = 0;
1027    } else if (buf[0] == 'M' && (parent.memWrCheck && buf[1] == 'W')) {
1028        currRecordType = TARMAC_MEM;
1029        memRecord.size = atoi(&buf[2]);
1030        trace >> memRecord.addr;
1031        char c = trace.peek();
1032        if (c == ':') {
1033            // Skip phys. address and _S/_NS suffix
1034            trace >> c >> buf;
1035        }
1036        trace >> memRecord.data;
1037        trace.ignore(MaxLineLength, '\n');
1038        buf[0] = 0;
1039    } else {
1040        currRecordType = TARMAC_UNSUPPORTED;
1041        trace.ignore(MaxLineLength, '\n');
1042        buf[0] = 0;
1043    }
1044
1045    return true;
1046}
1047
1048bool
1049TarmacParserRecord::readMemNoEffect(Addr addr, uint8_t *data, unsigned size,
1050                                    unsigned flags)
1051{
1052    const RequestPtr &req = memReq;
1053    TheISA::TLB* dtb = static_cast<TLB*>(thread->getDTBPtr());
1054
1055    req->setVirt(0, addr, size, flags, thread->pcState().instAddr(),
1056                 Request::funcMasterId);
1057
1058    // Translate to physical address
1059    Fault fault = dtb->translateAtomic(req, thread, BaseTLB::Read);
1060
1061    // Ignore read if the address falls into the ignored range
1062    if (parent.ignoredAddrRange.contains(addr))
1063        return false;
1064
1065    // Now do the access
1066    if (fault == NoFault &&
1067        !req->getFlags().isSet(Request::NO_ACCESS)) {
1068        if (req->isLLSC() || req->isMmappedIpr())
1069            // LLSCs and mem. mapped IPRs are ignored
1070            return false;
1071        // the translating proxy will perform the virtual to physical
1072        // translation again
1073        thread->getVirtProxy().readBlob(addr, data, size);
1074    } else {
1075        return false;
1076    }
1077
1078    if (fault != NoFault) {
1079        return false;
1080    }
1081
1082    return true;
1083}
1084
1085void
1086TarmacParser::advanceTraceToStartPc()
1087{
1088    char buf[TarmacParserRecord::MaxLineLength];
1089    Addr pc;
1090    int saved_offset;
1091
1092    trace >> hex;  // All integer values are in hex base
1093
1094    while (true) {
1095        saved_offset = trace.tellg();
1096        trace >> buf >> buf >> buf;
1097        if (cpuId)
1098            trace >> buf;
1099        if (buf[0] == 'I') {
1100            trace >> buf >> pc;
1101            if (pc == startPc) {
1102                // Set file pointer to the beginning of this line
1103                trace.seekg(saved_offset, ios::beg);
1104                return;
1105            } else {
1106                trace.ignore(TarmacParserRecord::MaxLineLength, '\n');
1107            }
1108        } else {
1109            trace.ignore(TarmacParserRecord::MaxLineLength, '\n');
1110        }
1111        if (trace.eof())
1112            panic("End of TARMAC trace reached before start PC\n");
1113    }
1114}
1115
1116const char*
1117TarmacParserRecord::iSetStateToStr(ISetState isetstate) const
1118{
1119    switch (isetstate) {
1120      case ISET_ARM:
1121        return "ARM (A32)";
1122      case ISET_THUMB:
1123        return "Thumb (A32)";
1124      case ISET_A64:
1125        return "A64";
1126      default:
1127        return "UNSUPPORTED";
1128    }
1129}
1130
1131} // namespace Trace
1132
1133Trace::TarmacParser *
1134TarmacParserParams::create()
1135{
1136    return new Trace::TarmacParser(this);
1137}
1138