1b8021494Sopenharmony_ci#!/usr/bin/env python3
2b8021494Sopenharmony_ci
3b8021494Sopenharmony_ci# Copyright 2016, VIXL authors
4b8021494Sopenharmony_ci# All rights reserved.
5b8021494Sopenharmony_ci#
6b8021494Sopenharmony_ci# Redistribution and use in source and binary forms, with or without
7b8021494Sopenharmony_ci# modification, are permitted provided that the following conditions are met:
8b8021494Sopenharmony_ci#
9b8021494Sopenharmony_ci#   * Redistributions of source code must retain the above copyright notice,
10b8021494Sopenharmony_ci#     this list of conditions and the following disclaimer.
11b8021494Sopenharmony_ci#   * Redistributions in binary form must reproduce the above copyright notice,
12b8021494Sopenharmony_ci#     this list of conditions and the following disclaimer in the documentation
13b8021494Sopenharmony_ci#     and/or other materials provided with the distribution.
14b8021494Sopenharmony_ci#   * Neither the name of ARM Limited nor the names of its contributors may be
15b8021494Sopenharmony_ci#     used to endorse or promote products derived from this software without
16b8021494Sopenharmony_ci#     specific prior written permission.
17b8021494Sopenharmony_ci#
18b8021494Sopenharmony_ci# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
19b8021494Sopenharmony_ci# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20b8021494Sopenharmony_ci# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21b8021494Sopenharmony_ci# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22b8021494Sopenharmony_ci# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23b8021494Sopenharmony_ci# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24b8021494Sopenharmony_ci# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25b8021494Sopenharmony_ci# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26b8021494Sopenharmony_ci# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27b8021494Sopenharmony_ci# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28b8021494Sopenharmony_ci
29b8021494Sopenharmony_ci"""
30b8021494Sopenharmony_ciGenerating tests
31b8021494Sopenharmony_ci================
32b8021494Sopenharmony_ci
33b8021494Sopenharmony_ciFrom the VIXL toplevel directory run:
34b8021494Sopenharmony_ci
35b8021494Sopenharmony_ci    $ ./tools/generate_tests.py
36b8021494Sopenharmony_ci
37b8021494Sopenharmony_ciThe script assumes that `clang-format-4.0` is in the current path. If it isn't,
38b8021494Sopenharmony_ciyou can provide your own:
39b8021494Sopenharmony_ci
40b8021494Sopenharmony_ci    $ ./tools/generate_tests.py --clang-format /patch/to/clang-format
41b8021494Sopenharmony_ci
42b8021494Sopenharmony_ciOnce the script has finished, it will have generated test files, as many as
43b8021494Sopenharmony_cipresent in the `default_config_files` list. For example:
44b8021494Sopenharmony_ci
45b8021494Sopenharmony_ci- test/aarch32/test-assembler-cond-rd-rn-immediate-a32.cc
46b8021494Sopenharmony_ci- test/aarch32/test-assembler-cond-rd-rn-rm-a32.cc
47b8021494Sopenharmony_ci- test/aarch32/test-assembler-cond-rd-rn-rm-q-a32.cc
48b8021494Sopenharmony_ci- test/aarch32/test-assembler-cond-rd-rn-rm-ge-a32.cc
49b8021494Sopenharmony_ci
50b8021494Sopenharmony_ciBecause these test cases need traces in order to build, the script will have
51b8021494Sopenharmony_cigenerated placeholder trace files in `test/aarch32/traces/`. If you look at them
52b8021494Sopenharmony_ciyou'll see they are basically empty:
53b8021494Sopenharmony_ci
54b8021494Sopenharmony_ci    $ cat test/aarch32/traces/sim-cond-rd-rn-immediate-adc-a32.h
55b8021494Sopenharmony_ci    static const TestResult *kReferenceAdc = NULL;
56b8021494Sopenharmony_ci
57b8021494Sopenharmony_ciSo of course, we can now build the test cases but running them will crash. We
58b8021494Sopenharmony_cineed to re-generate traces with real hardware; the test cases do not support
59b8021494Sopenharmony_cirunning in the simulator just yet.
60b8021494Sopenharmony_ci
61b8021494Sopenharmony_ciGenerating traces
62b8021494Sopenharmony_ci=================
63b8021494Sopenharmony_ci
64b8021494Sopenharmony_ciYou need to have either compiled natively for ARM, or cross-compiled
65b8021494Sopenharmony_ci`test-runner`. The traces can then be generated in the same way as with VIXL64.
66b8021494Sopenharmony_ciNote that it takes a few minutes to generate everything.
67b8021494Sopenharmony_ci
68b8021494Sopenharmony_ci    ./tools/generate_simulator_traces.py --runner /path/to/test-runner \
69b8021494Sopenharmony_ci      --aarch32-only
70b8021494Sopenharmony_ci
71b8021494Sopenharmony_ciYou can now rebuild everything. If it all goes well, running the new tests
72b8021494Sopenharmony_cishould pass.
73b8021494Sopenharmony_ci
74b8021494Sopenharmony_ciTest configuration format
75b8021494Sopenharmony_ci=========================
76b8021494Sopenharmony_ci
77b8021494Sopenharmony_ciTODO: Write a simple and well documented complete example configuration file and
78b8021494Sopenharmony_ci      mention it here.
79b8021494Sopenharmony_ci
80b8021494Sopenharmony_ciThe underlying `test_generator` framework reads JSON description files and
81b8021494Sopenharmony_cigenerates tests according to them. These files live in `test/aarch32/config` by
82b8021494Sopenharmony_cidefault, but you may provide your own files with the `--config-files FILE ...`
83b8021494Sopenharmony_ciflag. The JSON format was extended to support C++ like one-line comments.
84b8021494Sopenharmony_ci
85b8021494Sopenharmony_ciEach configuration file will serve to generate one or more test files,
86b8021494Sopenharmony_ciwe even use its file name to choose the name of the test:
87b8021494Sopenharmony_ci
88b8021494Sopenharmony_ci    test/aarch32/config/cond-rd-rn-immediate-a32.json
89b8021494Sopenharmony_ci    `-> test/aarch32/test-simulator-cond-rd-rn-immediate-a32.cc
90b8021494Sopenharmony_ci    `-> test/aarch32/test-assembler-cond-rd-rn-immediate-a32.cc
91b8021494Sopenharmony_ci
92b8021494Sopenharmony_ciIn addition to these test configuration files, we also provide a JSON
93b8021494Sopenharmony_cidescription with shared information. This information represents data types that
94b8021494Sopenharmony_ciinstructions use and lives in `test/aarch32/config/data-types.json`.
95b8021494Sopenharmony_ci
96b8021494Sopenharmony_ciData types description
97b8021494Sopenharmony_ci----------------------
98b8021494Sopenharmony_ci
99b8021494Sopenharmony_ciWe refer to two kinds of data types: `operand` and `input`.
100b8021494Sopenharmony_ci
101b8021494Sopenharmony_ciAn `operand` represents an argument passed to the macro-assembler to generate an
102b8021494Sopenharmony_ciinstruction. For example, a register or an immediate are operands. We can think
103b8021494Sopenharmony_ciof it as "assemble-time" data.
104b8021494Sopenharmony_ci
105b8021494Sopenharmony_ciAs opposed to `operands`, an `input` represents data passed to an instruction at
106b8021494Sopenharmony_ciruntime. For example, it will be the value you write to a register before
107b8021494Sopenharmony_ciexecuting the instruction under test.
108b8021494Sopenharmony_ci
109b8021494Sopenharmony_ciThe `data-types.json` file has the following structure:
110b8021494Sopenharmony_ci
111b8021494Sopenharmony_ci~~~
112b8021494Sopenharmony_ci{
113b8021494Sopenharmony_ci  "operands": [
114b8021494Sopenharmony_ci    // List of operand types.
115b8021494Sopenharmony_ci  ],
116b8021494Sopenharmony_ci  "inputs": [
117b8021494Sopenharmony_ci    // List of input types.
118b8021494Sopenharmony_ci  ]
119b8021494Sopenharmony_ci}
120b8021494Sopenharmony_ci~~~
121b8021494Sopenharmony_ci
122b8021494Sopenharmony_ciEach operand is described with the following structure:
123b8021494Sopenharmony_ci
124b8021494Sopenharmony_ci~~~
125b8021494Sopenharmony_ci{
126b8021494Sopenharmony_ci  // Unique name for this operand type.
127b8021494Sopenharmony_ci  "name": "AllRegistersButPC",
128b8021494Sopenharmony_ci  // C++ type used by VIXL to represent this operand.
129b8021494Sopenharmony_ci  "type": "Register",
130b8021494Sopenharmony_ci  // List of possible variants.
131b8021494Sopenharmony_ci  "variants": [
132b8021494Sopenharmony_ci    "r0",
133b8021494Sopenharmony_ci    "r1",
134b8021494Sopenharmony_ci    "r2",
135b8021494Sopenharmony_ci    "r3",
136b8021494Sopenharmony_ci    "r4",
137b8021494Sopenharmony_ci    "r5",
138b8021494Sopenharmony_ci    "r6",
139b8021494Sopenharmony_ci    "r7",
140b8021494Sopenharmony_ci    "r8",
141b8021494Sopenharmony_ci    "r9",
142b8021494Sopenharmony_ci    "r10",
143b8021494Sopenharmony_ci    "r11",
144b8021494Sopenharmony_ci    "r12",
145b8021494Sopenharmony_ci    "r13",
146b8021494Sopenharmony_ci    "r14"
147b8021494Sopenharmony_ci  ],
148b8021494Sopenharmony_ci  // Default variant to use.
149b8021494Sopenharmony_ci  "default": "r0"
150b8021494Sopenharmony_ci}
151b8021494Sopenharmony_ci~~~
152b8021494Sopenharmony_ci
153b8021494Sopenharmony_ciThe "name" field of the operand will be used by test configuration files in
154b8021494Sopenharmony_ciorder to specify what kind of operands an instruction takes. The "type" field
155b8021494Sopenharmony_cisimply tells the generator what C++ type should be generated, e.g. "Condition",
156b8021494Sopenharmony_ci"Register", "uint32_t", "ShiftType", ...etc.
157b8021494Sopenharmony_ci
158b8021494Sopenharmony_ciInputs are described in a very similar way:
159b8021494Sopenharmony_ci
160b8021494Sopenharmony_ci~~~
161b8021494Sopenharmony_ci{
162b8021494Sopenharmony_ci  // Unique name for this input type.
163b8021494Sopenharmony_ci  "name": "Register",
164b8021494Sopenharmony_ci  // Python type from `test_generator.data_types` to use to generate C++ code
165b8021494Sopenharmony_ci  // for this input.
166b8021494Sopenharmony_ci  "type": "Register",
167b8021494Sopenharmony_ci  // List of possible values.
168b8021494Sopenharmony_ci  "values": [
169b8021494Sopenharmony_ci    "0x00000000",
170b8021494Sopenharmony_ci    "0xffffffff",
171b8021494Sopenharmony_ci    "0xabababab",
172b8021494Sopenharmony_ci    "0x5a5a5a5a"
173b8021494Sopenharmony_ci  ],
174b8021494Sopenharmony_ci  // Default value.
175b8021494Sopenharmony_ci  "default": "0xabababab"
176b8021494Sopenharmony_ci}
177b8021494Sopenharmony_ci~~~
178b8021494Sopenharmony_ci
179b8021494Sopenharmony_ciThe "name" field has the same purpose as for operands. The "type" field however,
180b8021494Sopenharmony_ciis the name of a Python class in `test_generator.data_types`. The type will
181b8021494Sopenharmony_cispecify what C++ code to generate in order to load and record the input value,
182b8021494Sopenharmony_cie.g. how to load a value into a register, how to read and record it.
183b8021494Sopenharmony_ci
184b8021494Sopenharmony_ciWhen adding more tests, one may have to create new data types in this file. For
185b8021494Sopenharmony_ciexample, when we want to test an instruction with a different set of registers.
186b8021494Sopenharmony_ciIf adding new input types which need different C++ code to load and record them,
187b8021494Sopenharmony_cione will have to add it to `test_generator.data_types` and override the
188b8021494Sopenharmony_ci`Epilogue` and `Prologue` methods.
189b8021494Sopenharmony_ci
190b8021494Sopenharmony_ciTest configuration
191b8021494Sopenharmony_ci------------------
192b8021494Sopenharmony_ci
193b8021494Sopenharmony_ciOnce we have all the data types we need described, we need test configuration
194b8021494Sopenharmony_cifiles to describe what instructions to test and with what `inputs` and
195b8021494Sopenharmony_ci`operands` they take.
196b8021494Sopenharmony_ci
197b8021494Sopenharmony_ciThese files have the following structure:
198b8021494Sopenharmony_ci
199b8021494Sopenharmony_ci~~~
200b8021494Sopenharmony_ci{
201b8021494Sopenharmony_ci  "mnemonics": [
202b8021494Sopenharmony_ci    // List of instruction mnemonics to use. These must correspond to
203b8021494Sopenharmony_ci    // `MacroAssembler` methods.
204b8021494Sopenharmony_ci  ],
205b8021494Sopenharmony_ci  "description": {
206b8021494Sopenharmony_ci    "operands": [
207b8021494Sopenharmony_ci      // List of operands the instruction takes.
208b8021494Sopenharmony_ci    ],
209b8021494Sopenharmony_ci    "inputs: [
210b8021494Sopenharmony_ci      // List of inputs the instruction can be affected by.
211b8021494Sopenharmony_ci    ]
212b8021494Sopenharmony_ci  },
213b8021494Sopenharmony_ci  // List of files to generate.
214b8021494Sopenharmony_ci  "test-files": [
215b8021494Sopenharmony_ci    {
216b8021494Sopenharmony_ci      "type": "assembler",
217b8021494Sopenharmony_ci      "mnemonics": [
218b8021494Sopenharmony_ci        // Optional list of instruction mnemonics to use, overriding the
219b8021494Sopenharmony_ci        // top-level list.
220b8021494Sopenharmony_ci      ],
221b8021494Sopenharmony_ci      "test-cases": [
222b8021494Sopenharmony_ci        // List of test cases for "assembler" tests, see below for
223b8021494Sopenharmony_ci        // details.
224b8021494Sopenharmony_ci      ]
225b8021494Sopenharmony_ci    },
226b8021494Sopenharmony_ci    {
227b8021494Sopenharmony_ci      "type": "simulator",
228b8021494Sopenharmony_ci      "test-cases": [
229b8021494Sopenharmony_ci        // List of test cases for "simulator" tests, see below for
230b8021494Sopenharmony_ci        // details.
231b8021494Sopenharmony_ci      ]
232b8021494Sopenharmony_ci    }
233b8021494Sopenharmony_ci  ]
234b8021494Sopenharmony_ci}
235b8021494Sopenharmony_ci~~~
236b8021494Sopenharmony_ci
237b8021494Sopenharmony_ci- List of operands:
238b8021494Sopenharmony_ci
239b8021494Sopenharmony_ciThe operand list describes the actual argument to the `MacroAssembler` method.
240b8021494Sopenharmony_ciFor example, if we take instruction in the form
241b8021494Sopenharmony_ci"XXX.cond rd rn rm shift #amount":
242b8021494Sopenharmony_ci
243b8021494Sopenharmony_ciWe want to generate C++ code as such:
244b8021494Sopenharmony_ci
245b8021494Sopenharmony_ci~~~
246b8021494Sopenharmony_ciCondition cond = ...;
247b8021494Sopenharmony_ciRegister rd = ...;
248b8021494Sopenharmony_ciRegister rn = ...;
249b8021494Sopenharmony_ciRegister rm = ...;
250b8021494Sopenharmony_ciShiftType type = ...;
251b8021494Sopenharmony_ciuint32_t amount = ...;
252b8021494Sopenharmony_ciOperand op(rm, type, amount);
253b8021494Sopenharmony_ci
254b8021494Sopenharmony_ci__ Xxx(cond, rd, rn, op);
255b8021494Sopenharmony_ci~~~
256b8021494Sopenharmony_ci
257b8021494Sopenharmony_ciWe will have the following operand list:
258b8021494Sopenharmony_ci
259b8021494Sopenharmony_ci~~~
260b8021494Sopenharmony_ci"operands": [
261b8021494Sopenharmony_ci  {
262b8021494Sopenharmony_ci    "name": "cond",
263b8021494Sopenharmony_ci    "type": "Condition"
264b8021494Sopenharmony_ci  },
265b8021494Sopenharmony_ci  {
266b8021494Sopenharmony_ci    "name": "rd",
267b8021494Sopenharmony_ci    "type": "AllRegistersButPC"
268b8021494Sopenharmony_ci  },
269b8021494Sopenharmony_ci  {
270b8021494Sopenharmony_ci    "name": "rn",
271b8021494Sopenharmony_ci    "type": "AllRegistersButPC"
272b8021494Sopenharmony_ci  },
273b8021494Sopenharmony_ci  {
274b8021494Sopenharmony_ci    "name": "op",
275b8021494Sopenharmony_ci    "wrapper": "Operand",
276b8021494Sopenharmony_ci    "operands": [
277b8021494Sopenharmony_ci      {
278b8021494Sopenharmony_ci        "name": "rm",
279b8021494Sopenharmony_ci        "operand": "AllRegistersButPC"
280b8021494Sopenharmony_ci      },
281b8021494Sopenharmony_ci      {
282b8021494Sopenharmony_ci        "name": "type",
283b8021494Sopenharmony_ci        "operand": "Shift"
284b8021494Sopenharmony_ci      },
285b8021494Sopenharmony_ci      {
286b8021494Sopenharmony_ci        "name": "amount",
287b8021494Sopenharmony_ci        "operand": "ImmediateShiftAmount"
288b8021494Sopenharmony_ci      }
289b8021494Sopenharmony_ci    ]
290b8021494Sopenharmony_ci  }
291b8021494Sopenharmony_ci]
292b8021494Sopenharmony_ci~~~
293b8021494Sopenharmony_ci
294b8021494Sopenharmony_ciThe "name" field represents the identifier of the operand and will be used as a
295b8021494Sopenharmony_civariable name in the generated code. The "type" field corresponds to an operand
296b8021494Sopenharmony_citype described in the `data-types.json` file as described above.
297b8021494Sopenharmony_ci
298b8021494Sopenharmony_ciWe can see that we've wrapped the last three operands into an "op"
299b8021494Sopenharmony_ciwrapper object. This allows us to tell the generator to wrap these
300b8021494Sopenharmony_cioperands into a `Operand` C++ object.
301b8021494Sopenharmony_ci
302b8021494Sopenharmony_ci- List of inputs:
303b8021494Sopenharmony_ci
304b8021494Sopenharmony_ciThis structure is similar to the operand list, but this time it describes what
305b8021494Sopenharmony_ciinput data the instructions may be affected by at runtime. If we take the same
306b8021494Sopenharmony_ciexample as above, we will have the following list:
307b8021494Sopenharmony_ci
308b8021494Sopenharmony_ci~~~
309b8021494Sopenharmony_ci"inputs": [
310b8021494Sopenharmony_ci  {
311b8021494Sopenharmony_ci    "name": "apsr",
312b8021494Sopenharmony_ci    "type": "NZCV"
313b8021494Sopenharmony_ci  },
314b8021494Sopenharmony_ci  {
315b8021494Sopenharmony_ci    "name": "rd",
316b8021494Sopenharmony_ci    "type": "Register"
317b8021494Sopenharmony_ci  },
318b8021494Sopenharmony_ci  {
319b8021494Sopenharmony_ci    "name": "rn",
320b8021494Sopenharmony_ci    "type": "Register"
321b8021494Sopenharmony_ci  },
322b8021494Sopenharmony_ci  {
323b8021494Sopenharmony_ci    "name": "rm",
324b8021494Sopenharmony_ci    "type": "Register"
325b8021494Sopenharmony_ci  }
326b8021494Sopenharmony_ci]
327b8021494Sopenharmony_ci~~~
328b8021494Sopenharmony_ci
329b8021494Sopenharmony_ciThis will specify what C++ code to generate before and after emitting the
330b8021494Sopenharmony_ciinstruction under test. The C++ code will set and record register values for
331b8021494Sopenharmony_ciexample. See `test_generator.data_types` for more details.
332b8021494Sopenharmony_ci
333b8021494Sopenharmony_ci- Test files and test cases:
334b8021494Sopenharmony_ci
335b8021494Sopenharmony_ciUp until now, we've only just described the environment in which instructions
336b8021494Sopenharmony_cican operate. We need to express what files we want generating, what instructions
337b8021494Sopenharmony_ciwe want to test and what we want them to do.
338b8021494Sopenharmony_ci
339b8021494Sopenharmony_ciAs previously mentioned, a configuration file can control the generation of
340b8021494Sopenharmony_ciseveral test files. We will generate one file per element in the "test-files"
341b8021494Sopenharmony_ciarray:
342b8021494Sopenharmony_ci
343b8021494Sopenharmony_ci~~~
344b8021494Sopenharmony_ci"test-files": [
345b8021494Sopenharmony_ci  {
346b8021494Sopenharmony_ci    "type": "assembler",
347b8021494Sopenharmony_ci    "test-cases": [
348b8021494Sopenharmony_ci      // List of test cases for "assembler" tests, see below for
349b8021494Sopenharmony_ci      // details.
350b8021494Sopenharmony_ci    ]
351b8021494Sopenharmony_ci  },
352b8021494Sopenharmony_ci  {
353b8021494Sopenharmony_ci    "type": "assembler",
354b8021494Sopenharmony_ci    "name": "special-case",
355b8021494Sopenharmony_ci    "mnemonics": [
356b8021494Sopenharmony_ci      // Override the top-level list with a subset of instructions concerned
357b8021494Sopenharmony_ci      // with this special case.
358b8021494Sopenharmony_ci    ],
359b8021494Sopenharmony_ci    "test-cases": [
360b8021494Sopenharmony_ci      // List of test cases for "assembler" tests, see below for
361b8021494Sopenharmony_ci      // details.
362b8021494Sopenharmony_ci    ]
363b8021494Sopenharmony_ci  },
364b8021494Sopenharmony_ci  {
365b8021494Sopenharmony_ci    "type": "simulator",
366b8021494Sopenharmony_ci    "test-cases": [
367b8021494Sopenharmony_ci      // List of test cases for "simulator" tests, see below for
368b8021494Sopenharmony_ci      // details.
369b8021494Sopenharmony_ci    ]
370b8021494Sopenharmony_ci  }
371b8021494Sopenharmony_ci]
372b8021494Sopenharmony_ci~~~
373b8021494Sopenharmony_ci
374b8021494Sopenharmony_ciAbove, we've decided to generate three tests: a "simulator" test and two
375b8021494Sopenharmony_ci"assembler" tests. The resulting files will have names with the following
376b8021494Sopenharmony_cipattern.
377b8021494Sopenharmony_ci
378b8021494Sopenharmony_ci  - "test/aarch32/test-assembler-{configuration name}-a32.cc"
379b8021494Sopenharmony_ci  - "test/aarch32/test-assembler-{configuration name}-special-case-a32.cc"
380b8021494Sopenharmony_ci  - "test/aarch32/test-simulator-{configuration name}-a32.cc"
381b8021494Sopenharmony_ci
382b8021494Sopenharmony_ciThe "type" field describes the kind of testing we want to do, these types are
383b8021494Sopenharmony_cirecognized by the generator and, at the moment, can be one of "simulator",
384b8021494Sopenharmony_ci"assembler", "macro-assembler" and "assembler-negative". Simulator tests will
385b8021494Sopenharmony_cirun each instruction and record the changes while assembler tests will only
386b8021494Sopenharmony_cirecord the code buffer and never execute anything. MacroAssembler tests
387b8021494Sopenharmony_cicurrently only generate code to check that the MacroAssembler does not crash;
388b8021494Sopenharmony_cithe output itself is not yet tested. Because you may want to generate more than
389b8021494Sopenharmony_cione test of the same type, as we are doing in the example, we need a way to
390b8021494Sopenharmony_cidifferentiate them. You may use the optional "name" field for this. Negative
391b8021494Sopenharmony_ciassembler tests check that the instructions described are not allowed, which
392b8021494Sopenharmony_cimeans that an exception is raised when VIXL is built in negative testing mode.
393b8021494Sopenharmony_ci
394b8021494Sopenharmony_ciFinally, we describe how to test the instruction by declaring a list of test
395b8021494Sopenharmony_cicases with the "test-cases" field.
396b8021494Sopenharmony_ci
397b8021494Sopenharmony_ciHere is an example of what we can express:
398b8021494Sopenharmony_ci~~~
399b8021494Sopenharmony_ci[
400b8021494Sopenharmony_ci  // Generate all combinations of instructions where "rd" an "rn" are the same
401b8021494Sopenharmony_ci  // register and "cond" and "rm" are just the default.
402b8021494Sopenharmony_ci  // For example:
403b8021494Sopenharmony_ci  //   __ Xxx(al, r0, r0, r0);
404b8021494Sopenharmony_ci  //   __ Xxx(al, r1, r1, r0);
405b8021494Sopenharmony_ci  //   __ Xxx(al, r2, r2, r0);
406b8021494Sopenharmony_ci  //   ...
407b8021494Sopenharmony_ci  //   __ Xxx(al, r12, r12, r0);
408b8021494Sopenharmony_ci  //   __ Xxx(al, r13, r13, r0);
409b8021494Sopenharmony_ci  //   __ Xxx(al, r14, r14, r0);
410b8021494Sopenharmony_ci  //
411b8021494Sopenharmony_ci  // For each of the instructions above, run them with a different value in "rd"
412b8021494Sopenharmony_ci  // and "rn".
413b8021494Sopenharmony_ci  {
414b8021494Sopenharmony_ci    "name": "RdIsRn",
415b8021494Sopenharmony_ci    "operands": [
416b8021494Sopenharmony_ci      "rd", "rn"
417b8021494Sopenharmony_ci    ],
418b8021494Sopenharmony_ci    "operand-filter": "rd == rn",
419b8021494Sopenharmony_ci    "inputs": [
420b8021494Sopenharmony_ci      "rd", "rn"
421b8021494Sopenharmony_ci    ],
422b8021494Sopenharmony_ci    "input-filter": "rd == rn"
423b8021494Sopenharmony_ci  },
424b8021494Sopenharmony_ci  // Generate all combinations of instructions with different condition codes.
425b8021494Sopenharmony_ci  // For example:
426b8021494Sopenharmony_ci  //   __ Xxx(eq, r0, r0, r0);
427b8021494Sopenharmony_ci  //   __ Xxx(ne, r0, r0, r0);
428b8021494Sopenharmony_ci  //   __ Xxx(cs, r0, r0, r0);
429b8021494Sopenharmony_ci  //   ...
430b8021494Sopenharmony_ci  //   __ Xxx(gt, r0, r0, r0);
431b8021494Sopenharmony_ci  //   __ Xxx(le, r0, r0, r0);
432b8021494Sopenharmony_ci  //   __ Xxx(al, r0, r0, r0);
433b8021494Sopenharmony_ci  //
434b8021494Sopenharmony_ci  // For each of the instructions above, run them against all combinations of
435b8021494Sopenharmony_ci  // NZCV bits.
436b8021494Sopenharmony_ci  {
437b8021494Sopenharmony_ci    "name": "ConditionVersusNZCV",
438b8021494Sopenharmony_ci    "operands": [
439b8021494Sopenharmony_ci      "cond"
440b8021494Sopenharmony_ci    ],
441b8021494Sopenharmony_ci    "inputs": [
442b8021494Sopenharmony_ci      "apsr"
443b8021494Sopenharmony_ci    ]
444b8021494Sopenharmony_ci  },
445b8021494Sopenharmony_ci  // We are interested in testing that the Q bit gets set and cleared, so we've
446b8021494Sopenharmony_ci  // limited the instruction generation to a single instruction and instead have
447b8021494Sopenharmony_ci  // stressed the values put in "rn" and "rm".
448b8021494Sopenharmony_ci  //
449b8021494Sopenharmony_ci  // So for this instruction, we choose to run it will all combinations of
450b8021494Sopenharmony_ci  // values in "rn" and "rm". Additionally, we include "qbit" in the inputs,
451b8021494Sopenharmony_ci  // which will make the test set or clear it before executing the instruction.
452b8021494Sopenharmony_ci  // Note that "qbit" needs to be declared as an input in the instruction
453b8021494Sopenharmony_ci  // description (see "List of inputs" section).
454b8021494Sopenharmony_ci  {
455b8021494Sopenharmony_ci    "name": "Qbit",
456b8021494Sopenharmony_ci    "operands": [
457b8021494Sopenharmony_ci      "rn", "rm"
458b8021494Sopenharmony_ci    ],
459b8021494Sopenharmony_ci    "inputs": [
460b8021494Sopenharmony_ci      "qbit", "rn", "rm"
461b8021494Sopenharmony_ci    ],
462b8021494Sopenharmony_ci    "operand-filter": "rn != rm'",
463b8021494Sopenharmony_ci    "operand-limit": 1
464b8021494Sopenharmony_ci  },
465b8021494Sopenharmony_ci  // Generate 10 random instructions with all different registers but use the
466b8021494Sopenharmony_ci  // default condition.
467b8021494Sopenharmony_ci  // For example:
468b8021494Sopenharmony_ci  //   __ Xxx(al, r5, r1, r0);
469b8021494Sopenharmony_ci  //   __ Xxx(al, r8, r9, r7);
470b8021494Sopenharmony_ci  //   __ Xxx(al, r9, r1, r2);
471b8021494Sopenharmony_ci  //   __ Xxx(al, r0, r6, r2);
472b8021494Sopenharmony_ci  //   __ Xxx(al, r11, r9, r11);
473b8021494Sopenharmony_ci  //   __ Xxx(al, r14, r2, r11);
474b8021494Sopenharmony_ci  //   __ Xxx(al, r8, r2, r5);
475b8021494Sopenharmony_ci  //   __ Xxx(al, r10, r0, r1);
476b8021494Sopenharmony_ci  //   __ Xxx(al, r11, r2, r7);
477b8021494Sopenharmony_ci  //   __ Xxx(al, r2, r6, r1);
478b8021494Sopenharmony_ci  //
479b8021494Sopenharmony_ci  // For each instruction, feed it 200 different combination of values in the
480b8021494Sopenharmony_ci  // three registers.
481b8021494Sopenharmony_ci  {
482b8021494Sopenharmony_ci    "name": "RegisterSimulatorTest",
483b8021494Sopenharmony_ci    "operands": [
484b8021494Sopenharmony_ci      "rd", "rn", "rm"
485b8021494Sopenharmony_ci    ],
486b8021494Sopenharmony_ci    "inputs": [
487b8021494Sopenharmony_ci      "rd", "rn", "rm"
488b8021494Sopenharmony_ci    ],
489b8021494Sopenharmony_ci    "operand-limit": 10,
490b8021494Sopenharmony_ci    "input-limit": 200
491b8021494Sopenharmony_ci  }
492b8021494Sopenharmony_ci]
493b8021494Sopenharmony_ci~~~
494b8021494Sopenharmony_ci
495b8021494Sopenharmony_ciAssembler test cases are much simpler, here are some examples:
496b8021494Sopenharmony_ci~~~
497b8021494Sopenharmony_ci// Generate 2000 random instructions out of all possible operand combinations.
498b8021494Sopenharmony_ci{
499b8021494Sopenharmony_ci  "name": "LotsOfRandomInstructions",
500b8021494Sopenharmony_ci  "operands": [
501b8021494Sopenharmony_ci    "cond", "rd", "rn", "rm"
502b8021494Sopenharmony_ci  ],
503b8021494Sopenharmony_ci  "operand-limit": 2000
504b8021494Sopenharmony_ci},
505b8021494Sopenharmony_ci// Same as above but limit the test to 200 instructions where rd == rn.
506b8021494Sopenharmony_ci{
507b8021494Sopenharmony_ci  "name": "RdIsRn",
508b8021494Sopenharmony_ci  "operands": [
509b8021494Sopenharmony_ci    "cond", "rd", "rn", "rm"
510b8021494Sopenharmony_ci  ],
511b8021494Sopenharmony_ci  "operand-filter": "rd == rn",
512b8021494Sopenharmony_ci  "operand-limit": 200
513b8021494Sopenharmony_ci}
514b8021494Sopenharmony_ci~~~
515b8021494Sopenharmony_ci
516b8021494Sopenharmony_ciAs can be expected, assembler test do not have the notion of "inputs".
517b8021494Sopenharmony_ci
518b8021494Sopenharmony_ciHere are details about each field. Note that all of them except for "name" are
519b8021494Sopenharmony_cioptional.
520b8021494Sopenharmony_ci
521b8021494Sopenharmony_ci  * "name":
522b8021494Sopenharmony_ci
523b8021494Sopenharmony_ci    A unique name should be given to the test case, it will be used to give the
524b8021494Sopenharmony_ci    generated C++ `const Input[]` array a name.
525b8021494Sopenharmony_ci
526b8021494Sopenharmony_ci  * "operands":
527b8021494Sopenharmony_ci
528b8021494Sopenharmony_ci    List of operand names that we are interested in testing. The generator will
529b8021494Sopenharmony_ci    lookup the list of variants for each operand and build the product of all of
530b8021494Sopenharmony_ci    them. It will then choose the default variant for the operands not specified
531b8021494Sopenharmony_ci    here.
532b8021494Sopenharmony_ci
533b8021494Sopenharmony_ci  * "operand-filter":
534b8021494Sopenharmony_ci
535b8021494Sopenharmony_ci    As you would expect, the product of all operand variants may be huge. To
536b8021494Sopenharmony_ci    prevent this, you may specify a Python expression to filter the list.
537b8021494Sopenharmony_ci
538b8021494Sopenharmony_ci  * "operand-limit":
539b8021494Sopenharmony_ci
540b8021494Sopenharmony_ci    We can potentially obtain a *massive* set of variants of instructions, as we
541b8021494Sopenharmony_ci    are computing a product of operand variants in "operands". This field allows
542b8021494Sopenharmony_ci    us to limit this by choosing a random sample from the computed variants.
543b8021494Sopenharmony_ci    Note that this is a seeded pseudo-random sample, and the seed corresponds to
544b8021494Sopenharmony_ci    the test case description. The same test case description will always
545b8021494Sopenharmony_ci    generate the same code.
546b8021494Sopenharmony_ci
547b8021494Sopenharmony_ci  * "inputs":
548b8021494Sopenharmony_ci
549b8021494Sopenharmony_ci    This is exactly the same as "operands" but for inputs.
550b8021494Sopenharmony_ci
551b8021494Sopenharmony_ci  * "input-filter":
552b8021494Sopenharmony_ci
553b8021494Sopenharmony_ci    Ditto.
554b8021494Sopenharmony_ci
555b8021494Sopenharmony_ci  * "input-limit":
556b8021494Sopenharmony_ci
557b8021494Sopenharmony_ci    Ditto.
558b8021494Sopenharmony_ci
559b8021494Sopenharmony_ciHere is an example of the C++ code that will be generated for a given test case.
560b8021494Sopenharmony_ciFor simplicity, let's generate tests for an instruction with only `NZCV` and two
561b8021494Sopenharmony_ciregisters as inputs.
562b8021494Sopenharmony_ci
563b8021494Sopenharmony_ciFor the following test case, which will target encodings where `rd` and `rn` are
564b8021494Sopenharmony_cithe same registers:
565b8021494Sopenharmony_ci
566b8021494Sopenharmony_ci~~~
567b8021494Sopenharmony_ci{
568b8021494Sopenharmony_ci  "name": "RdIsRn",
569b8021494Sopenharmony_ci  "operands": [
570b8021494Sopenharmony_ci    "rd", "rn"
571b8021494Sopenharmony_ci  ],
572b8021494Sopenharmony_ci  "operand-filter": "rd == rn",
573b8021494Sopenharmony_ci  "inputs": [
574b8021494Sopenharmony_ci    "rd", "rn"
575b8021494Sopenharmony_ci  ],
576b8021494Sopenharmony_ci  "input-filter": "rd == rn"
577b8021494Sopenharmony_ci},
578b8021494Sopenharmony_ci~~~
579b8021494Sopenharmony_ci
580b8021494Sopenharmony_ciIt will generate the following input array.
581b8021494Sopenharmony_ci
582b8021494Sopenharmony_ci~~~
583b8021494Sopenharmony_ci//                                apsr,        rd,         rn
584b8021494Sopenharmony_cistatic const Inputs kRdIsRn[] = {{NoFlag, 0x00000000, 0x00000000},
585b8021494Sopenharmony_ci                                 {NoFlag, 0xffffffff, 0xffffffff},
586b8021494Sopenharmony_ci                                 {NoFlag, 0xabababab, 0xabababab},
587b8021494Sopenharmony_ci                                 {NoFlag, 0x5a5a5a5a, 0x5a5a5a5a}};
588b8021494Sopenharmony_ci~~~
589b8021494Sopenharmony_ci
590b8021494Sopenharmony_ciWe can see that the default apsr value was chosen (NoFlag), as apsr is not in
591b8021494Sopenharmony_cithe list of "inputs".
592b8021494Sopenharmony_ci
593b8021494Sopenharmony_ciIt will also generate a list of instructions to test:
594b8021494Sopenharmony_ci
595b8021494Sopenharmony_ci~~~
596b8021494Sopenharmony_cistatic const TestLoopData kTests[] = {
597b8021494Sopenharmony_ci    {{al, r1, r1, 0x000000ab}, ARRAY_SIZE(kRdIsRn), kRdIsRn, "RdIsRn"},
598b8021494Sopenharmony_ci    {{al, r2, r2, 0x000000ab}, ARRAY_SIZE(kRdIsRn), kRdIsRn, "RdIsRn"},
599b8021494Sopenharmony_ci    {{al, r8, r8, 0x000000ab}, ARRAY_SIZE(kRdIsRn), kRdIsRn, "RdIsRn"},
600b8021494Sopenharmony_ci    {{al, r9, r9, 0x000000ab}, ARRAY_SIZE(kRdIsRn), kRdIsRn, "RdIsRn"},
601b8021494Sopenharmony_ci};
602b8021494Sopenharmony_ci~~~
603b8021494Sopenharmony_ci
604b8021494Sopenharmony_ciAs a result, the new test we will assemble each instructions in "mnemonics" with
605b8021494Sopenharmony_ciall of the operands described in `kTests` above. And each instruction will be
606b8021494Sopenharmony_ciexecuted and passed all inputs in `kRdIsRn`.
607b8021494Sopenharmony_ci"""
608b8021494Sopenharmony_ci
609b8021494Sopenharmony_ciimport subprocess
610b8021494Sopenharmony_ciimport argparse
611b8021494Sopenharmony_ciimport string
612b8021494Sopenharmony_ciimport re
613b8021494Sopenharmony_ciimport multiprocessing
614b8021494Sopenharmony_ciimport functools
615b8021494Sopenharmony_ci
616b8021494Sopenharmony_ciimport test_generator.parser
617b8021494Sopenharmony_ci
618b8021494Sopenharmony_ci
619b8021494Sopenharmony_cidefault_config_files = [
620b8021494Sopenharmony_ci    # A32 and T32 tests
621b8021494Sopenharmony_ci    'test/aarch32/config/rd-rn-rm.json',
622b8021494Sopenharmony_ci    'test/aarch32/config/cond-dt-drt-drd-drn-drm-float.json',
623b8021494Sopenharmony_ci
624b8021494Sopenharmony_ci    # A32 specific tests
625b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-operand-const-a32.json',
626b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-operand-rm-a32.json',
627b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-operand-rm-shift-amount-1to31-a32.json',
628b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-operand-rm-shift-amount-1to32-a32.json',
629b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-operand-rm-shift-rs-a32.json',
630b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-operand-rm-ror-amount-a32.json',
631b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-a32.json',
632b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-pc-a32.json',
633b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-rm-a32.json',
634b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-operand-const-a32.json',
635b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-operand-rn-a32.json',
636b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-operand-rn-shift-amount-1to31-a32.json',
637b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-operand-rn-shift-amount-1to32-a32.json',
638b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-operand-rn-shift-rs-a32.json',
639b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-operand-rn-ror-amount-a32.json',
640b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-memop-immediate-512-a32.json',
641b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-memop-immediate-8192-a32.json',
642b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-memop-rs-a32.json',
643b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-memop-rs-shift-amount-1to31-a32.json',
644b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-memop-rs-shift-amount-1to32-a32.json',
645b8021494Sopenharmony_ci
646b8021494Sopenharmony_ci    # T32 specific tests
647b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-t32.json',
648b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-rm-t32.json',
649b8021494Sopenharmony_ci    'test/aarch32/config/cond-rdlow-rnlow-rmlow-t32.json',
650b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-operand-const-t32.json',
651b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-pc-operand-imm12-t32.json',
652b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-operand-imm12-t32.json',
653b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-pc-operand-imm8-t32.json',
654b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-sp-operand-imm8-t32.json',
655b8021494Sopenharmony_ci    'test/aarch32/config/cond-rdlow-rnlow-operand-immediate-t32.json',
656b8021494Sopenharmony_ci    'test/aarch32/config/cond-sp-sp-operand-imm7-t32.json',
657b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-operand-rm-t32.json',
658b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-operand-rm-shift-amount-1to31-t32.json',
659b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-operand-rm-shift-amount-1to32-t32.json',
660b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-rn-operand-rm-ror-amount-t32.json',
661b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-operand-const-t32.json',
662b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-operand-imm16-t32.json',
663b8021494Sopenharmony_ci    'test/aarch32/config/cond-rdlow-operand-imm8-t32.json',
664b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-operand-rn-shift-amount-1to31-t32.json',
665b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-operand-rn-shift-amount-1to32-t32.json',
666b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-operand-rn-shift-rs-t32.json',
667b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-operand-rn-ror-amount-t32.json',
668b8021494Sopenharmony_ci    'test/aarch32/config/cond-rd-operand-rn-t32.json',
669b8021494Sopenharmony_ci]
670b8021494Sopenharmony_ci
671b8021494Sopenharmony_ci
672b8021494Sopenharmony_ci# Link a test type with a template file.
673b8021494Sopenharmony_citemplate_files = {
674b8021494Sopenharmony_ci    'simulator': "test/aarch32/config/template-simulator-aarch32.cc.in",
675b8021494Sopenharmony_ci    'assembler': "test/aarch32/config/template-assembler-aarch32.cc.in",
676b8021494Sopenharmony_ci    'macro-assembler': "test/aarch32/config/template-macro-assembler-aarch32.cc.in",
677b8021494Sopenharmony_ci    'assembler-negative': "test/aarch32/config/template-assembler-negative-aarch32.cc.in",
678b8021494Sopenharmony_ci}
679b8021494Sopenharmony_ci
680b8021494Sopenharmony_ci
681b8021494Sopenharmony_cidef BuildOptions():
682b8021494Sopenharmony_ci  result = argparse.ArgumentParser(
683b8021494Sopenharmony_ci      description = 'Test generator for AArch32.',
684b8021494Sopenharmony_ci      formatter_class=argparse.ArgumentDefaultsHelpFormatter)
685b8021494Sopenharmony_ci  result.add_argument('--config-files', nargs='+',
686b8021494Sopenharmony_ci                      default=default_config_files,
687b8021494Sopenharmony_ci                      metavar='FILE',
688b8021494Sopenharmony_ci                      help='Configuration files, each will generate a test file.')
689b8021494Sopenharmony_ci  result.add_argument('--clang-format',
690b8021494Sopenharmony_ci                      default='clang-format-4.0', help='Path to clang-format.')
691b8021494Sopenharmony_ci  result.add_argument('--jobs', '-j', type=int, metavar='N',
692b8021494Sopenharmony_ci                      default=multiprocessing.cpu_count(),
693b8021494Sopenharmony_ci                      help='Allow N jobs at once')
694b8021494Sopenharmony_ci  result.add_argument('--skip-traces', action='store_true',
695b8021494Sopenharmony_ci                      help='Skip generation of placeholder traces.')
696b8021494Sopenharmony_ci  return result.parse_args()
697b8021494Sopenharmony_ci
698b8021494Sopenharmony_ci
699b8021494Sopenharmony_cidef DoNotEditComment(template_file):
700b8021494Sopenharmony_ci  # We rely on `clang-format` to wrap this comment to 80 characters.
701b8021494Sopenharmony_ci  return """
702b8021494Sopenharmony_ci// -----------------------------------------------------------------------------
703b8021494Sopenharmony_ci// This file is auto generated from the {} template file using tools/generate_tests.py.
704b8021494Sopenharmony_ci//
705b8021494Sopenharmony_ci// PLEASE DO NOT EDIT.
706b8021494Sopenharmony_ci// -----------------------------------------------------------------------------
707b8021494Sopenharmony_ci    """.format(template_file)
708b8021494Sopenharmony_ci
709b8021494Sopenharmony_cidef GenerateTest(generator, clang_format, skip_traces):
710b8021494Sopenharmony_ci  template_file = template_files[generator.test_type]
711b8021494Sopenharmony_ci  generated_file = ""
712b8021494Sopenharmony_ci  with open(template_file, "r") as f:
713b8021494Sopenharmony_ci    # Strip out comments starting with three forward slashes before creating the
714b8021494Sopenharmony_ci    # string.Template object.
715b8021494Sopenharmony_ci    template = string.Template(re.sub("\/\/\/.*", "", f.read()))
716b8021494Sopenharmony_ci
717b8021494Sopenharmony_ci    # The `generator` object has methods generating strings to fill the template.
718b8021494Sopenharmony_ci    generated_file = template.substitute({
719b8021494Sopenharmony_ci      # Add a top comment stating this file is auto-generated.
720b8021494Sopenharmony_ci      'do_not_edit_comment': DoNotEditComment(template_file),
721b8021494Sopenharmony_ci
722b8021494Sopenharmony_ci      # List of mnemonics.
723b8021494Sopenharmony_ci      'instruction_list_declaration': generator.InstructionListDeclaration(),
724b8021494Sopenharmony_ci
725b8021494Sopenharmony_ci      # Declarations.
726b8021494Sopenharmony_ci      'operand_list_declaration': generator.OperandDeclarations(),
727b8021494Sopenharmony_ci      'input_declarations': generator.InputDeclarations(),
728b8021494Sopenharmony_ci
729b8021494Sopenharmony_ci      # Definitions.
730b8021494Sopenharmony_ci      'input_definitions': generator.InputDefinitions(),
731b8021494Sopenharmony_ci      'test_case_definitions': generator.TestCaseDefinitions(),
732b8021494Sopenharmony_ci
733b8021494Sopenharmony_ci      # Include traces.
734b8021494Sopenharmony_ci      'include_trace_files': generator.IncludeTraceFiles(),
735b8021494Sopenharmony_ci
736b8021494Sopenharmony_ci      # Define a typedef for the MacroAssembler method.
737b8021494Sopenharmony_ci      'macroassembler_method_args': generator.MacroAssemblerMethodArgs(),
738b8021494Sopenharmony_ci
739b8021494Sopenharmony_ci      # Generate code to switch instruction set.
740b8021494Sopenharmony_ci      'macroassembler_set_isa': generator.MacroAssemblerSetISA(),
741b8021494Sopenharmony_ci
742b8021494Sopenharmony_ci      # Generate code to emit instructions.
743b8021494Sopenharmony_ci      'code_instantiate_operands': generator.CodeInstantiateOperands(),
744b8021494Sopenharmony_ci      'code_prologue': generator.CodePrologue(),
745b8021494Sopenharmony_ci      'code_epilogue': generator.CodeEpilogue(),
746b8021494Sopenharmony_ci      'code_parameter_list': generator.CodeParameterList(),
747b8021494Sopenharmony_ci
748b8021494Sopenharmony_ci      # Generate code to trace the execution and print C++.
749b8021494Sopenharmony_ci      'trace_print_outputs': generator.TracePrintOutputs(),
750b8021494Sopenharmony_ci
751b8021494Sopenharmony_ci      # Generate code to compare the results against a trace.
752b8021494Sopenharmony_ci      'check_instantiate_results': generator.CheckInstantiateResults(),
753b8021494Sopenharmony_ci      'check_instantiate_inputs': generator.CheckInstantiateInputs(),
754b8021494Sopenharmony_ci      'check_instantiate_references': generator.CheckInstantiateReferences(),
755b8021494Sopenharmony_ci      'check_results_against_references':
756b8021494Sopenharmony_ci          generator.CheckResultsAgainstReferences(),
757b8021494Sopenharmony_ci      'check_print_input': generator.CheckPrintInput(),
758b8021494Sopenharmony_ci      'check_print_expected': generator.CheckPrintExpected(),
759b8021494Sopenharmony_ci      'check_print_found': generator.CheckPrintFound(),
760b8021494Sopenharmony_ci
761b8021494Sopenharmony_ci      'test_isa': generator.TestISA(),
762b8021494Sopenharmony_ci      'test_name': generator.TestName(),
763b8021494Sopenharmony_ci      'isa_guard': generator.GetIsaGuard()
764b8021494Sopenharmony_ci    })
765b8021494Sopenharmony_ci  # Create the test case and pipe it through `clang-format` before writing it.
766b8021494Sopenharmony_ci  with open(
767b8021494Sopenharmony_ci      "test/aarch32/test-{}-{}-{}.cc".format(generator.test_type,
768b8021494Sopenharmony_ci                                             generator.test_name,
769b8021494Sopenharmony_ci                                             generator.test_isa),
770b8021494Sopenharmony_ci      "w") as f:
771b8021494Sopenharmony_ci    proc = subprocess.Popen([clang_format], stdin=subprocess.PIPE,
772b8021494Sopenharmony_ci                            stdout=subprocess.PIPE)
773b8021494Sopenharmony_ci    out, _ = proc.communicate(generated_file.encode())
774b8021494Sopenharmony_ci    f.write(out.decode())
775b8021494Sopenharmony_ci  if not skip_traces:
776b8021494Sopenharmony_ci    # Write placeholder trace files into 'test/aarch32/traces/'.
777b8021494Sopenharmony_ci    generator.WriteEmptyTraces("test/aarch32/traces/")
778b8021494Sopenharmony_ci  print("Generated {} {} test for \"{}\".".format(generator.test_isa.upper(),
779b8021494Sopenharmony_ci                                                  generator.test_type,
780b8021494Sopenharmony_ci                                                  generator.test_name))
781b8021494Sopenharmony_ci
782b8021494Sopenharmony_ciif __name__ == '__main__':
783b8021494Sopenharmony_ci  args = BuildOptions()
784b8021494Sopenharmony_ci
785b8021494Sopenharmony_ci  # Each file in `args.config_files` populates a `Generator` object.
786b8021494Sopenharmony_ci  generators = test_generator.parser.Parse('test/aarch32/config/data-types.json',
787b8021494Sopenharmony_ci                                           args.config_files)
788b8021494Sopenharmony_ci
789b8021494Sopenharmony_ci  # Call the `GenerateTest` function for each generator object in parallel. This
790b8021494Sopenharmony_ci  # will use as many processes as defined by `-jN`, which defaults to 1.
791b8021494Sopenharmony_ci  with multiprocessing.Pool(processes=args.jobs) as pool:
792b8021494Sopenharmony_ci    pool.map(functools.partial(GenerateTest, clang_format=args.clang_format,
793b8021494Sopenharmony_ci                                             skip_traces=args.skip_traces),
794b8021494Sopenharmony_ci             generators)
795