tarmac_parser.cc revision 12641:4c67bbebe381
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}
768
769void
770TarmacParserRecord::dump()
771{
772    ostream &outs = Trace::output();
773
774    // By default TARMAC splits memory accesses into 4-byte chunks (see
775    // 'loadstore-display-width' option in TARMAC plugin)
776    uint32_t written_data = 0;
777    unsigned mem_flags = TheISA::TLB::MustBeOne | 3 |
778        TheISA::TLB::AllowUnaligned;
779
780    ISetState isetstate;
781
782    if (!staticInst->isMicroop() || staticInst->isLastMicroop()) {
783
784        if (parent.macroopInProgress && !staticInst->isLastMicroop()) {
785            // A microop faulted and it was not the last microop -> advance
786            // TARMAC trace to next instruction
787            advanceTrace();
788        }
789
790        parent.macroopInProgress = false;
791
792        auto arm_inst = static_cast<const ArmStaticInst*>(
793            staticInst.get()
794        );
795
796        while (advanceTrace()) {
797            switch (currRecordType) {
798
799              case TARMAC_INST:
800                parsingStarted = true;
801                if (pc.instAddr() != instRecord.addr) {
802                    if (!mismatch)
803                        printMismatchHeader(staticInst, pc);
804                    outs << "diff> [PC] gem5: 0x" << hex << pc.instAddr()
805                         << ", TARMAC: 0x" << instRecord.addr << endl;
806                    mismatch = true;
807                    mismatchOnPcOrOpcode = true;
808                }
809
810                if (arm_inst->encoding() != instRecord.opcode) {
811                    if (!mismatch)
812                        printMismatchHeader(staticInst, pc);
813                    outs << "diff> [opcode] gem5: 0x" << hex
814                         << arm_inst->encoding()
815                         << ", TARMAC: 0x" << instRecord.opcode << endl;
816                    mismatch = true;
817                    mismatchOnPcOrOpcode = true;
818                }
819
820                // Set the Instruction set state.
821                isetstate = pcToISetState(pc);
822
823                if (instRecord.isetstate != isetstate &&
824                    isetstate != ISET_UNSUPPORTED) {
825                    if (!mismatch)
826                        printMismatchHeader(staticInst, pc);
827                    outs << "diff> [iset_state] gem5: "
828                         << iSetStateToStr(isetstate)
829                         << ", TARMAC: "
830                         << iSetStateToStr(instRecord.isetstate);
831                    mismatch = true;
832                }
833
834                // TODO(Giacomo): add support for predicate and mode checking
835                break;
836
837              case TARMAC_REG:
838                destRegRecords.push_back(regRecord);
839                break;
840
841              case TARMAC_MEM:
842                if (!readMemNoEffect(memRecord.addr, (uint8_t*) &written_data,
843                                     memRecord.size, mem_flags))
844                    break;
845                if (written_data != memRecord.data) {
846                    if (!mismatch)
847                        printMismatchHeader(staticInst, pc);
848                    outs << "diff> [mem(0x" << hex << memRecord.addr
849                         << ")] gem5: 0x" << written_data
850                         << ", TARMAC: 0x" << memRecord.data
851                         << endl;
852                }
853                break;
854
855              case TARMAC_UNSUPPORTED:
856                break;
857
858              default:
859                panic("Unknown TARMAC trace record type!");
860            }
861        }
862        // We are done with the current instruction, i.e. all the corresponding
863        // entries in the TARMAC trace have been parsed
864        if (destRegRecords.size()) {
865            TarmacParserRecordEvent *event = new TarmacParserRecordEvent(
866                parent, thread, staticInst, pc, mismatch,
867                mismatchOnPcOrOpcode);
868            mainEventQueue[0]->schedule(event, curTick());
869        } else if (mismatchOnPcOrOpcode && (parent.exitOnDiff ||
870                                            parent.exitOnInsnDiff)) {
871            exitSimLoop("a mismatch with the TARMAC trace has been detected "
872                        "on PC or opcode", 1);
873        }
874    } else {
875        parent.macroopInProgress = true;
876    }
877}
878
879bool
880TarmacParserRecord::advanceTrace()
881{
882    ifstream& trace = parent.trace;
883    trace >> hex;  // All integer values are in hex base
884
885    if (buf[0] != 'I') {
886        trace >> buf;
887        if (trace.eof())
888            return false;
889        trace >> buf >> buf;
890        if (parent.cpuId) {
891            assert((buf[0] == 'c') && (buf[1] == 'p') && (buf[2] == 'u'));
892            trace >> buf;
893        }
894    }
895
896    if (trace.eof())
897        return false;
898
899    if (buf[0] == 'I') {
900        // Instruction trace record
901        if (parsingStarted)
902            return false;
903        currRecordType = TARMAC_INST;
904        instRecord.taken = (buf[1] == 'T');
905        trace >> buf;
906        instRecord.seq_num = atoi(&buf[1]);
907        trace >> instRecord.addr;
908        char c = trace.peek();
909        if (c == ':') {
910            // Skip phys. address and _S/_NS suffix
911            trace >> c >> buf;
912        }
913        trace >> instRecord.opcode;
914        trace >> buf;
915        switch (buf[0]) {
916          case 'A':
917            instRecord.isetstate = ISET_ARM;
918            break;
919          case 'T':
920            instRecord.isetstate = ISET_THUMB;
921            break;
922          case 'O':
923            instRecord.isetstate = ISET_A64;
924            break;
925          default:
926            warn("Invalid TARMAC trace record (seq_num: %lld)",
927                 instRecord.seq_num);
928            instRecord.isetstate = ISET_UNSUPPORTED;
929            currRecordType = TARMAC_UNSUPPORTED;
930            break;
931        }
932        trace.ignore(MaxLineLength, '\n');
933        buf[0] = 0;
934    } else if (buf[0] == 'R') {
935        // Register trace record
936        currRecordType = TARMAC_REG;
937        trace >> buf;
938        strcpy(regRecord.repr, buf);
939        if (buf[0] == 'r' && isdigit(buf[1])) {
940            // R register
941            regRecord.type = REG_R;
942            int base_index = atoi(&buf[1]);
943            char* pch = strchr(buf, '_');
944            if (pch == NULL) {
945                regRecord.index = INTREG_USR(base_index);
946            } else {
947                ++pch;
948                if (strncmp(pch, "usr", 3) == 0)
949                    regRecord.index = INTREG_USR(base_index);
950                else if (strncmp(pch, "fiq", 3) == 0)
951                    regRecord.index = INTREG_FIQ(base_index);
952                else if (strncmp(pch, "irq", 3) == 0)
953                    regRecord.index = INTREG_IRQ(base_index);
954                else if (strncmp(pch, "svc", 3) == 0)
955                    regRecord.index = INTREG_SVC(base_index);
956                else if (strncmp(pch, "mon", 3) == 0)
957                    regRecord.index = INTREG_MON(base_index);
958                else if (strncmp(pch, "abt", 3) == 0)
959                    regRecord.index = INTREG_ABT(base_index);
960                else if (strncmp(pch, "und", 3) == 0)
961                    regRecord.index = INTREG_UND(base_index);
962                else if (strncmp(pch, "hyp", 3) == 0)
963                    regRecord.index = INTREG_HYP(base_index);
964            }
965        // A64 register names are capitalized in AEM TARMAC, unlike A32
966        } else if (buf[0] == 'X' && isdigit(buf[1])) {
967            // X register (A64)
968            regRecord.type = REG_X;
969            regRecord.index = atoi(&buf[1]);
970        } else if (buf[0] == 's' && isdigit(buf[1])) {
971            // S register
972            regRecord.type = REG_S;
973            regRecord.index = atoi(&buf[1]);
974        } else if (buf[0] == 'd' && isdigit(buf[1])) {
975            // D register
976            regRecord.type = REG_D;
977            regRecord.index = atoi(&buf[1]);
978        } else if (buf[0] == 'q' && isdigit(buf[1])) {
979            // Q register
980            regRecord.type = REG_Q;
981            regRecord.index = atoi(&buf[1]);
982        } else if (strncmp(buf, "SP_EL", 5) == 0) {
983            // A64 stack pointer
984            regRecord.type = REG_X;
985            regRecord.index = INTREG_SP0 + atoi(&buf[5]);
986        } else if (miscRegMap.count(buf)) {
987            // Misc. register
988            regRecord.type = REG_MISC;
989            regRecord.index = miscRegMap[buf];
990        } else {
991            // Try match with upper case name (misc. register)
992            string reg_name = buf;
993            transform(reg_name.begin(), reg_name.end(), reg_name.begin(),
994                      ::tolower);
995            if (miscRegMap.count(reg_name.c_str())) {
996                regRecord.type = REG_MISC;
997                regRecord.index = miscRegMap[reg_name.c_str()];
998            } else {
999                warn("Unknown register in TARMAC trace (%s).\n", buf);
1000                currRecordType = TARMAC_UNSUPPORTED;
1001                trace.ignore(MaxLineLength, '\n');
1002                buf[0] = 0;
1003                return true;
1004            }
1005        }
1006        if (regRecord.type == REG_Q) {
1007            trace.ignore();
1008            trace.get(buf, 17);
1009            // buf[16] = '\0';
1010            regRecord.valueHi = strtoull(buf, NULL, 16);
1011            trace.get(buf, 17);
1012            // buf[16] = '\0';
1013            regRecord.valueLo = strtoull(buf, NULL, 16);
1014        } else {
1015            trace >> regRecord.valueLo;
1016            char c = trace.peek();
1017            if (c == ':') {
1018                // 64-bit value with colon in the middle
1019                uint64_t lsw = 0;
1020                trace >> c >> lsw;
1021                regRecord.valueLo = (regRecord.valueLo << 32) | lsw;
1022            }
1023        }
1024        trace.ignore(MaxLineLength, '\n');
1025        buf[0] = 0;
1026    } else if (buf[0] == 'M' && (parent.memWrCheck && buf[1] == 'W')) {
1027        currRecordType = TARMAC_MEM;
1028        memRecord.size = atoi(&buf[2]);
1029        trace >> memRecord.addr;
1030        char c = trace.peek();
1031        if (c == ':') {
1032            // Skip phys. address and _S/_NS suffix
1033            trace >> c >> buf;
1034        }
1035        trace >> memRecord.data;
1036        trace.ignore(MaxLineLength, '\n');
1037        buf[0] = 0;
1038    } else {
1039        currRecordType = TARMAC_UNSUPPORTED;
1040        trace.ignore(MaxLineLength, '\n');
1041        buf[0] = 0;
1042    }
1043
1044    return true;
1045}
1046
1047bool
1048TarmacParserRecord::readMemNoEffect(Addr addr, uint8_t *data, unsigned size,
1049                                    unsigned flags)
1050{
1051    Request* req = &memReq;
1052    TheISA::TLB* dtb = static_cast<TLB*>(thread->getDTBPtr());
1053
1054    req->setVirt(0, addr, size, flags, thread->pcState().instAddr(),
1055                 Request::funcMasterId);
1056
1057    // Translate to physical address
1058    Fault fault = dtb->translateAtomic(req, thread, BaseTLB::Read);
1059
1060    // Ignore read if the address falls into the ignored range
1061    if (parent.ignoredAddrRange.contains(addr))
1062        return false;
1063
1064    // Now do the access
1065    if (fault == NoFault &&
1066        !req->getFlags().isSet(Request::NO_ACCESS)) {
1067        if (req->isLLSC() || req->isMmappedIpr())
1068            // LLSCs and mem. mapped IPRs are ignored
1069            return false;
1070        // the translating proxy will perform the virtual to physical
1071        // translation again
1072        thread->getVirtProxy().readBlob(addr, data, size);
1073    } else {
1074        return false;
1075    }
1076
1077    if (fault != NoFault) {
1078        return false;
1079    }
1080
1081    return true;
1082}
1083
1084void
1085TarmacParser::advanceTraceToStartPc()
1086{
1087    char buf[TarmacParserRecord::MaxLineLength];
1088    Addr pc;
1089    int saved_offset;
1090
1091    trace >> hex;  // All integer values are in hex base
1092
1093    while (true) {
1094        saved_offset = trace.tellg();
1095        trace >> buf >> buf >> buf;
1096        if (cpuId)
1097            trace >> buf;
1098        if (buf[0] == 'I') {
1099            trace >> buf >> pc;
1100            if (pc == startPc) {
1101                // Set file pointer to the beginning of this line
1102                trace.seekg(saved_offset, ios::beg);
1103                return;
1104            } else {
1105                trace.ignore(TarmacParserRecord::MaxLineLength, '\n');
1106            }
1107        } else {
1108            trace.ignore(TarmacParserRecord::MaxLineLength, '\n');
1109        }
1110        if (trace.eof())
1111            panic("End of TARMAC trace reached before start PC\n");
1112    }
1113}
1114
1115const char*
1116TarmacParserRecord::iSetStateToStr(ISetState isetstate) const
1117{
1118    switch (isetstate) {
1119      case ISET_ARM:
1120        return "ARM (A32)";
1121      case ISET_THUMB:
1122        return "Thumb (A32)";
1123      case ISET_A64:
1124        return "A64";
1125      default:
1126        return "UNSUPPORTED";
1127    }
1128}
1129
1130} // namespace Trace
1131
1132Trace::TarmacParser *
1133TarmacParserParams::create()
1134{
1135    return new Trace::TarmacParser(this);
1136}
1137