1b8021494Sopenharmony_ciAArch64 Simulator state trace
2b8021494Sopenharmony_ci=============================
3b8021494Sopenharmony_ci
4b8021494Sopenharmony_ciThe AArch64 Simulator can be configured to produce traces of instruction
5b8021494Sopenharmony_ciexecution, register contents, and memory accesses. The trace is designed to be
6b8021494Sopenharmony_ciintuitive for human readers, but this document describes the format of the
7b8021494Sopenharmony_citrace, so that post-processing tools can confidently parse the output.
8b8021494Sopenharmony_ci
9b8021494Sopenharmony_ciIn VIXL's own test runner, the trace is controlled by the `--trace*` options.
10b8021494Sopenharmony_ciRun `test-runner --help` for details.
11b8021494Sopenharmony_ci
12b8021494Sopenharmony_ciBasic structure
13b8021494Sopenharmony_ci---------------
14b8021494Sopenharmony_ci
15b8021494Sopenharmony_ciExecuted instructions show the address, the encoding of the instruction and the
16b8021494Sopenharmony_cidisassembly (as produced by VIXL's Disassembler). For example:
17b8021494Sopenharmony_ci
18b8021494Sopenharmony_ci    0x00007fbe2a6a9044  d299d200		mov x0, #0xce90
19b8021494Sopenharmony_ci
20b8021494Sopenharmony_ciThe first field is the address of the instruction, with exactly 16 hexadecimal
21b8021494Sopenharmony_cicharacters and a leading 0x, and is followed by two spaces. The second field is
22b8021494Sopenharmony_cithe instruction encoding, with exactly eight hexadecimal characters (and no
23b8021494Sopenharmony_cileading 0x). This is followed by two _tab_ characters, and the instruction
24b8021494Sopenharmony_cidisassembly. The following regular expression can be used to capture each field:
25b8021494Sopenharmony_ci
26b8021494Sopenharmony_ci    (0x[0-9a-f]{16})  ([0-9a-f]{8})\t\t(.*)
27b8021494Sopenharmony_ci
28b8021494Sopenharmony_ciFollowing each instruction are zero or more lines of state update. Most notably,
29b8021494Sopenharmony_cithese represent the register state updates and memory accesses that occurred
30b8021494Sopenharmony_ciduring simulation of the instruction. All of these lines begin with a '#'
31b8021494Sopenharmony_cicharacter, so that they can be easily identified, and filtered if necessary. For
32b8021494Sopenharmony_ciexample:
33b8021494Sopenharmony_ci
34b8021494Sopenharmony_ci    0x00007fd2221c907c  8b82200e		add x14, x0, x2, asr #8
35b8021494Sopenharmony_ci    #            x14: 0xfffedcba98765432
36b8021494Sopenharmony_ci    0x00007fd2221c9080  0b81200f		add w15, w0, w1, asr #8
37b8021494Sopenharmony_ci    #            w15:         0xff89abcd
38b8021494Sopenharmony_ci
39b8021494Sopenharmony_ciNote that the Simulator uses these state update lines to describe its initial
40b8021494Sopenharmony_cistate. As a result, there will be state trace output before the first simulated
41b8021494Sopenharmony_ciinstruction, and parsers need to be tolerant of this.
42b8021494Sopenharmony_ci
43b8021494Sopenharmony_ciNote that padding white space is used liberally to keep values vertically
44b8021494Sopenharmony_cialigned throughout the trace (as shown with the write to `w15` in the example
45b8021494Sopenharmony_ciabove). Similarly, some compound values are split into parts using the C++14
46b8021494Sopenharmony_ciliteral separator (`'`) character. Refer to the "Memory accesses" section
47b8021494Sopenharmony_ci(below) for examples.
48b8021494Sopenharmony_ci
49b8021494Sopenharmony_ciOrdering
50b8021494Sopenharmony_ci--------
51b8021494Sopenharmony_ci
52b8021494Sopenharmony_ciVIXL guarantees that each instruction is printed before its associated state
53b8021494Sopenharmony_citrace.
54b8021494Sopenharmony_ci
55b8021494Sopenharmony_ciState trace must be interpreted sequentially, line by line. VIXL avoids updating
56b8021494Sopenharmony_cithe same register more than once (because it makes the trace hard for humans to
57b8021494Sopenharmony_ciread), but this can occur in some situations, and should be supported by
58b8021494Sopenharmony_ciparsers.
59b8021494Sopenharmony_ci
60b8021494Sopenharmony_ciThe state is intended to be consistent with architectural execution at the start
61b8021494Sopenharmony_ciof each instruction and at the end of the whole trace, but no such guarantees
62b8021494Sopenharmony_ciare made about the traced state _between_ instructions. VIXL prioritises
63b8021494Sopenharmony_cihuman-readability when choosing the ordering of state updates.
64b8021494Sopenharmony_ci
65b8021494Sopenharmony_ciIf simulated registers are modified externally, for example using
66b8021494Sopenharmony_ci`WriteRegister` from C++ code, their state will (by default) be logged
67b8021494Sopenharmony_ciimmediately. In the full trace, it will appear as though the (runtime) call or
68b8021494Sopenharmony_cireturn instruction modified the state. This is consistent with the guarantees
69b8021494Sopenharmony_ciabove, but it can result in single instructions appearing to generate a large
70b8021494Sopenharmony_cinumber of state updates.
71b8021494Sopenharmony_ci
72b8021494Sopenharmony_ciThere is no upper limit on the number of state update lines that any one
73b8021494Sopenharmony_ciinstruction can generate.
74b8021494Sopenharmony_ci
75b8021494Sopenharmony_ciWhole register trace
76b8021494Sopenharmony_ci--------------------
77b8021494Sopenharmony_ci
78b8021494Sopenharmony_ciThe simplest form of state trace has the form "`REG: VALUE`", meaning that
79b8021494Sopenharmony_cithe register `REG` has the specified value, and any high-order bits in aliased
80b8021494Sopenharmony_ciregisters are set to zero.
81b8021494Sopenharmony_ci
82b8021494Sopenharmony_ci    0x00007fd2221c907c  8b82200e		add x14, x0, x2, asr #8
83b8021494Sopenharmony_ci    #            x14: 0xfffedcba98765432
84b8021494Sopenharmony_ci
85b8021494Sopenharmony_ciNote that to correctly track state, parsers need to be aware of architectural
86b8021494Sopenharmony_ciregister aliasing rules. Also, VIXL uses some standard register aliases, such as
87b8021494Sopenharmony_ci`lr` (`x30`). To avoid misinterpreting a register alias (and thereby potentially
88b8021494Sopenharmony_cimissing an aliased register update), some tools may need to treat an
89b8021494Sopenharmony_ciunrecognised register name as an error.
90b8021494Sopenharmony_ci
91b8021494Sopenharmony_ciThis trace format attempts to represent _architectural_ register writes.
92b8021494Sopenharmony_ciHowever, this is not strictly checked or enforced.
93b8021494Sopenharmony_ci
94b8021494Sopenharmony_ci`VALUE` is always shown in hexadecimal (raw bits) form, with a leading `0x` and
95b8021494Sopenharmony_cienough digits to exactly fill `REG`. `VALUE` may also include annotations (for
96b8021494Sopenharmony_ciexample to show FP arithmetic values) in parentheses. These annotations are for
97b8021494Sopenharmony_cithe benefit of human readers, and parsers may ignore them.
98b8021494Sopenharmony_ci
99b8021494Sopenharmony_ciNote that SVE registers _always_ use the partial register trace format,
100b8021494Sopenharmony_cidescribed below, so a plain `z` or `p` register will never be used in a whole
101b8021494Sopenharmony_ciregister trace. This is true even if the vector length is configured to 16
102b8021494Sopenharmony_cibytes.
103b8021494Sopenharmony_ci
104b8021494Sopenharmony_ciPartial register trace
105b8021494Sopenharmony_ci----------------------
106b8021494Sopenharmony_ci
107b8021494Sopenharmony_ciSometimes, VIXL needs to show _part_ of a register without implying that the
108b8021494Sopenharmony_cirest of the register is zeroed. A partial register value is indicated by a bit
109b8021494Sopenharmony_cirange in angled brackets after the register name: "`REG<MSB:LSB>: VALUE`".
110b8021494Sopenharmony_ciThis format is used for stores, for example.
111b8021494Sopenharmony_ci
112b8021494Sopenharmony_ciSVE register updates are split across multiple lines, and therefore always use
113b8021494Sopenharmony_cithe partial register trace format. For example (with a 384-bit VL):
114b8021494Sopenharmony_ci
115b8021494Sopenharmony_ci    0x00007fb1978da044  04214000		index z0.b, #0, #1
116b8021494Sopenharmony_ci    #   z0<383:256>: 0x2f2e2d2c2b2a29282726252423222120
117b8021494Sopenharmony_ci    #   z0<255:128>: 0x1f1e1d1c1b1a19181716151413121110
118b8021494Sopenharmony_ci    #     z0<127:0>: 0x0f0e0d0c0b0a09080706050403020100
119b8021494Sopenharmony_ci
120b8021494Sopenharmony_ciNote that VIXL will omit whole lines where they are unnecessary, for example if
121b8021494Sopenharmony_cithey have no active (predicated) lanes. Parsers should not assume that every
122b8021494Sopenharmony_cipart of a register will appear in such cases.
123b8021494Sopenharmony_ci
124b8021494Sopenharmony_ciThe `VALUE` has the same format as in the whole register trace, except in the
125b8021494Sopenharmony_cicase of SVE `p` registers (as described below).
126b8021494Sopenharmony_ci
127b8021494Sopenharmony_ciSVE `p` registers
128b8021494Sopenharmony_ci-----------------
129b8021494Sopenharmony_ci
130b8021494Sopenharmony_ciFor `p` registers, we try to keep the lanes vertically aligned with the
131b8021494Sopenharmony_cicorresponding parts of the `z` registers that they affect. To do this, we use a
132b8021494Sopenharmony_cibinary format, with a leading `0b`, and spaces between each digit. For example:
133b8021494Sopenharmony_ci
134b8021494Sopenharmony_ci    0x00007f66e539b0b8  04f54607		index z7.d, x16, #-11
135b8021494Sopenharmony_ci    #     z7<127:0>: 0x00000000000000150000000000000020
136b8021494Sopenharmony_ci    0x00007f66e539b0bc  25d8e3a7		ptrue p7.d, all
137b8021494Sopenharmony_ci    #      p7<15:0>: 0b 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1
138b8021494Sopenharmony_ci
139b8021494Sopenharmony_ciMemory accesses
140b8021494Sopenharmony_ci---------------
141b8021494Sopenharmony_ci
142b8021494Sopenharmony_ciThe pattern for a memory access is "`VALUE OP ADDRESS`", where:
143b8021494Sopenharmony_ci
144b8021494Sopenharmony_ci- `VALUE` is a hexadecimal value, with visual separators (') between
145b8021494Sopenharmony_ci  structure components,
146b8021494Sopenharmony_ci- `OP` is `"->"` for a store, or `"<-"` for a load,
147b8021494Sopenharmony_ci- `ADDRESS` is the (hexadecimal) address of the access.
148b8021494Sopenharmony_ci
149b8021494Sopenharmony_ciAccesses shown in this style are always contiguous, and with little-endian
150b8021494Sopenharmony_cisemantics. However, a given instruction might have multiple lines of memory
151b8021494Sopenharmony_ciaccess trace, particularly if the instruction performs non-contiguous accesses.
152b8021494Sopenharmony_ci
153b8021494Sopenharmony_ciIn the case of simple accesses, the `VALUE` is shared with register value trace:
154b8021494Sopenharmony_ci
155b8021494Sopenharmony_ci    0x00007f3835372058  e400e401		st1b { z1.b }, p1, [x0]
156b8021494Sopenharmony_ci    #      z1<127:0>: 0xd4d7dadde0e3e6e9eceff2f5f8fbfe01 -> 0x000055d170298e90
157b8021494Sopenharmony_ci
158b8021494Sopenharmony_ciSign-extending loads show the whole resulting register value, with the (smaller)
159b8021494Sopenharmony_ciaccess represented on a separate line. This makes the (differing) values in the
160b8021494Sopenharmony_ciregister and in memory unambiguous, without parsers needing to understand the
161b8021494Sopenharmony_ciinstruction set:
162b8021494Sopenharmony_ci
163b8021494Sopenharmony_ci    0x00007f47922d0068  79800306		ldrsh x6, [x24]
164b8021494Sopenharmony_ci    #             x6: 0xffffffffffff8080
165b8021494Sopenharmony_ci    #                                  ╙─ 0x8080 <- 0x00007fffbc197708
166b8021494Sopenharmony_ci
167b8021494Sopenharmony_ciSome instructions access several different memory locations. In these cases,
168b8021494Sopenharmony_cieach access is given its own line, with the highest lane index first so that
169b8021494Sopenharmony_ci(for contiguous accesses) the lowest address ends up at the bottom:
170b8021494Sopenharmony_ci
171b8021494Sopenharmony_ci    0x00007fa6001e9060  e4217c0a		st2b { z10.b, z11.b }, p7, [x0, x1]
172b8021494Sopenharmony_ci    #     z10<127:0>: 0x0f0e0d0c0b0a09080706050403020100
173b8021494Sopenharmony_ci    #     z11<127:0>: 0x1f1e1d1c1b1a19181716151413121110
174b8021494Sopenharmony_ci    #                    ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╙─ 0x10'00 -> 0x00007ffe485d2f90
175b8021494Sopenharmony_ci    #                    ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╙─── 0x11'01 -> 0x00007ffe485d2f92
176b8021494Sopenharmony_ci    #                    ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╙───── 0x12'02 -> 0x00007ffe485d2f94
177b8021494Sopenharmony_ci    #                    ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╙─────── 0x13'03 -> 0x00007ffe485d2f96
178b8021494Sopenharmony_ci    #                    ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╙───────── 0x14'04 -> 0x00007ffe485d2f98
179b8021494Sopenharmony_ci    #                    ║ ║ ║ ║ ║ ║ ║ ║ ║ ║ ╙─────────── 0x15'05 -> 0x00007ffe485d2f9a
180b8021494Sopenharmony_ci    #                    ║ ║ ║ ║ ║ ║ ║ ║ ║ ╙───────────── 0x16'06 -> 0x00007ffe485d2f9c
181b8021494Sopenharmony_ci    #                    ║ ║ ║ ║ ║ ║ ║ ║ ╙─────────────── 0x17'07 -> 0x00007ffe485d2f9e
182b8021494Sopenharmony_ci    #                    ║ ║ ║ ║ ║ ║ ║ ╙───────────────── 0x18'08 -> 0x00007ffe485d2fa0
183b8021494Sopenharmony_ci    #                    ║ ║ ║ ║ ║ ║ ╙─────────────────── 0x19'09 -> 0x00007ffe485d2fa2
184b8021494Sopenharmony_ci    #                    ║ ║ ║ ║ ║ ╙───────────────────── 0x1a'0a -> 0x00007ffe485d2fa4
185b8021494Sopenharmony_ci    #                    ║ ║ ║ ║ ╙─────────────────────── 0x1b'0b -> 0x00007ffe485d2fa6
186b8021494Sopenharmony_ci    #                    ║ ║ ║ ╙───────────────────────── 0x1c'0c -> 0x00007ffe485d2fa8
187b8021494Sopenharmony_ci    #                    ║ ║ ╙─────────────────────────── 0x1d'0d -> 0x00007ffe485d2faa
188b8021494Sopenharmony_ci    #                    ║ ╙───────────────────────────── 0x1e'0e -> 0x00007ffe485d2fac
189b8021494Sopenharmony_ci    #                    ╙─────────────────────────────── 0x1f'0f -> 0x00007ffe485d2fae
190b8021494Sopenharmony_ci
191b8021494Sopenharmony_ciThe line-drawing characters are encoded as UTF-8 (as is this document). There is
192b8021494Sopenharmony_cicurrently no locale handling in VIXL, so this is not configurable. However,
193b8021494Sopenharmony_cisince these annotations are for the benefit of human readers, parsers can safely
194b8021494Sopenharmony_ciignore them, and treat the whole trace as an ASCII byte stream (ignoring 8-bit
195b8021494Sopenharmony_cicharacters). This is useful in situations where UTF-8 handling carries an
196b8021494Sopenharmony_ciunacceptable performance cost.
197b8021494Sopenharmony_ci
198b8021494Sopenharmony_ciIn the future, VIXL may offer an option to avoid printing these annotations, so
199b8021494Sopenharmony_cithat the trace is restricted to single-byte characters.
200b8021494Sopenharmony_ci
201b8021494Sopenharmony_ciFloating-point value annotations
202b8021494Sopenharmony_ci--------------------------------
203b8021494Sopenharmony_ci
204b8021494Sopenharmony_ciSome floating-point operations produce register trace that annotates the raw
205b8021494Sopenharmony_civalues with the corresponding FP arithmetic values. This is for the benefit of
206b8021494Sopenharmony_cihuman readers (and has limited precision). Such annotations follow the `VALUE`
207b8021494Sopenharmony_ciin parentheses.
208b8021494Sopenharmony_ci
209b8021494Sopenharmony_ciScalar form:
210b8021494Sopenharmony_ci
211b8021494Sopenharmony_ci    #             s1:                         0x3f800000 (1.000) <- 0x00007ffdc64d2314
212b8021494Sopenharmony_ci
213b8021494Sopenharmony_ciVector form, updating all S lanes using a load:
214b8021494Sopenharmony_ci
215b8021494Sopenharmony_ci    #            v16: 0x1211100f0e0d0c0b0a09080706050403 (4.577e-28, 1.739e-30, 6.598e-33, 2.502e-35)
216b8021494Sopenharmony_ci    #                          ║       ║       ║       ╙─ 0x06050403 <- 0x00007ffe56fd7863
217b8021494Sopenharmony_ci    #                          ║       ║       ╙───────── 0x0a090807 <- 0x00007ffe56fd7867
218b8021494Sopenharmony_ci    #                          ║       ╙───────────────── 0x0e0d0c0b <- 0x00007ffe56fd786b
219b8021494Sopenharmony_ci    #                          ╙───────────────────────── 0x1211100f <- 0x00007ffe56fd786f
220b8021494Sopenharmony_ci
221b8021494Sopenharmony_ciVector form, updating a single S lane using a load:
222b8021494Sopenharmony_ci
223b8021494Sopenharmony_ci    #             v2: 0x03020100040302017ff0f0027f80f000 (..., 1.540e-36, ...)
224b8021494Sopenharmony_ci    #                                  ╙───────────────── 0x04030201 <- 0x00007ffc7b2e3ca1
225b8021494Sopenharmony_ci
226b8021494Sopenharmony_ciVector form, replicating a single struct load to all S lanes:
227b8021494Sopenharmony_ci
228b8021494Sopenharmony_ci    #            v15: 0x100f0e0d100f0e0d100f0e0d100f0e0d (2.821e-29, 2.821e-29, 2.821e-29, 2.821e-29)
229b8021494Sopenharmony_ci    #            v16: 0x14131211141312111413121114131211 (7.425e-27, 7.425e-27, 7.425e-27, 7.425e-27)
230b8021494Sopenharmony_ci    #            v17: 0x18171615181716151817161518171615 (1.953e-24, 1.953e-24, 1.953e-24, 1.953e-24)
231b8021494Sopenharmony_ci    #                          ╙───────╨───────╨───────╨─ 0x18171615'14131211'100f0e0d <- 0x00007ffdd64d847d
232