1// Copyright 2016, VIXL authors
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6//
7//   * Redistributions of source code must retain the above copyright notice,
8//     this list of conditions and the following disclaimer.
9//   * Redistributions in binary form must reproduce the above copyright notice,
10//     this list of conditions and the following disclaimer in the documentation
11//     and/or other materials provided with the distribution.
12//   * Neither the name of ARM Limited nor the names of its contributors may be
13//     used to endorse or promote products derived from this software without
14//     specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27
28// -----------------------------------------------------------------------------
29// This file is auto generated from the
30// test/aarch32/config/template-assembler-aarch32.cc.in template file using
31// tools/generate_tests.py.
32//
33// PLEASE DO NOT EDIT.
34// -----------------------------------------------------------------------------
35
36
37#include "test-runner.h"
38
39#include "test-utils.h"
40#include "test-utils-aarch32.h"
41
42#include "aarch32/assembler-aarch32.h"
43#include "aarch32/macro-assembler-aarch32.h"
44
45#define BUF_SIZE (4096)
46
47namespace vixl {
48namespace aarch32 {
49
50// List of instruction mnemonics.
51#define FOREACH_INSTRUCTION(M) M(movs)
52
53
54// The following definitions are defined again in each generated test, therefore
55// we need to place them in an anonymous namespace. It expresses that they are
56// local to this file only, and the compiler is not allowed to share these types
57// across test files during template instantiation. Specifically, `Operands` has
58// various layouts across generated tests so it absolutely cannot be shared.
59
60#ifdef VIXL_INCLUDE_TARGET_T32
61namespace {
62
63// Values to be passed to the assembler to produce the instruction under test.
64struct Operands {
65  Condition cond;
66  Register rd;
67  Register rn;
68  ShiftType shift;
69  Register rs;
70};
71
72// This structure contains all data needed to test one specific
73// instruction.
74struct TestData {
75  // The `operands` field represents what to pass to the assembler to
76  // produce the instruction.
77  Operands operands;
78  // True if we need to generate an IT instruction for this test to be valid.
79  bool in_it_block;
80  // The condition to give the IT instruction, this will be set to "al" by
81  // default.
82  Condition it_condition;
83  // Description of the operands, used for error reporting.
84  const char* operands_description;
85  // Unique identifier, used for generating traces.
86  const char* identifier;
87};
88
89struct TestResult {
90  size_t size;
91  const byte* encoding;
92};
93
94// Each element of this array produce one instruction encoding.
95const TestData kTests[] =
96    {{{al, r0, r0, LSL, r0}, false, al, "al r0 r0 LSL r0", "al_r0_r0_LSL_r0"},
97     {{al, r0, r0, LSL, r1}, false, al, "al r0 r0 LSL r1", "al_r0_r0_LSL_r1"},
98     {{al, r0, r0, LSL, r2}, false, al, "al r0 r0 LSL r2", "al_r0_r0_LSL_r2"},
99     {{al, r0, r0, LSL, r3}, false, al, "al r0 r0 LSL r3", "al_r0_r0_LSL_r3"},
100     {{al, r0, r0, LSL, r4}, false, al, "al r0 r0 LSL r4", "al_r0_r0_LSL_r4"},
101     {{al, r0, r0, LSL, r5}, false, al, "al r0 r0 LSL r5", "al_r0_r0_LSL_r5"},
102     {{al, r0, r0, LSL, r6}, false, al, "al r0 r0 LSL r6", "al_r0_r0_LSL_r6"},
103     {{al, r0, r0, LSL, r7}, false, al, "al r0 r0 LSL r7", "al_r0_r0_LSL_r7"},
104     {{al, r0, r0, LSR, r0}, false, al, "al r0 r0 LSR r0", "al_r0_r0_LSR_r0"},
105     {{al, r0, r0, LSR, r1}, false, al, "al r0 r0 LSR r1", "al_r0_r0_LSR_r1"},
106     {{al, r0, r0, LSR, r2}, false, al, "al r0 r0 LSR r2", "al_r0_r0_LSR_r2"},
107     {{al, r0, r0, LSR, r3}, false, al, "al r0 r0 LSR r3", "al_r0_r0_LSR_r3"},
108     {{al, r0, r0, LSR, r4}, false, al, "al r0 r0 LSR r4", "al_r0_r0_LSR_r4"},
109     {{al, r0, r0, LSR, r5}, false, al, "al r0 r0 LSR r5", "al_r0_r0_LSR_r5"},
110     {{al, r0, r0, LSR, r6}, false, al, "al r0 r0 LSR r6", "al_r0_r0_LSR_r6"},
111     {{al, r0, r0, LSR, r7}, false, al, "al r0 r0 LSR r7", "al_r0_r0_LSR_r7"},
112     {{al, r0, r0, ASR, r0}, false, al, "al r0 r0 ASR r0", "al_r0_r0_ASR_r0"},
113     {{al, r0, r0, ASR, r1}, false, al, "al r0 r0 ASR r1", "al_r0_r0_ASR_r1"},
114     {{al, r0, r0, ASR, r2}, false, al, "al r0 r0 ASR r2", "al_r0_r0_ASR_r2"},
115     {{al, r0, r0, ASR, r3}, false, al, "al r0 r0 ASR r3", "al_r0_r0_ASR_r3"},
116     {{al, r0, r0, ASR, r4}, false, al, "al r0 r0 ASR r4", "al_r0_r0_ASR_r4"},
117     {{al, r0, r0, ASR, r5}, false, al, "al r0 r0 ASR r5", "al_r0_r0_ASR_r5"},
118     {{al, r0, r0, ASR, r6}, false, al, "al r0 r0 ASR r6", "al_r0_r0_ASR_r6"},
119     {{al, r0, r0, ASR, r7}, false, al, "al r0 r0 ASR r7", "al_r0_r0_ASR_r7"},
120     {{al, r0, r0, ROR, r0}, false, al, "al r0 r0 ROR r0", "al_r0_r0_ROR_r0"},
121     {{al, r0, r0, ROR, r1}, false, al, "al r0 r0 ROR r1", "al_r0_r0_ROR_r1"},
122     {{al, r0, r0, ROR, r2}, false, al, "al r0 r0 ROR r2", "al_r0_r0_ROR_r2"},
123     {{al, r0, r0, ROR, r3}, false, al, "al r0 r0 ROR r3", "al_r0_r0_ROR_r3"},
124     {{al, r0, r0, ROR, r4}, false, al, "al r0 r0 ROR r4", "al_r0_r0_ROR_r4"},
125     {{al, r0, r0, ROR, r5}, false, al, "al r0 r0 ROR r5", "al_r0_r0_ROR_r5"},
126     {{al, r0, r0, ROR, r6}, false, al, "al r0 r0 ROR r6", "al_r0_r0_ROR_r6"},
127     {{al, r0, r0, ROR, r7}, false, al, "al r0 r0 ROR r7", "al_r0_r0_ROR_r7"},
128     {{al, r1, r1, LSL, r0}, false, al, "al r1 r1 LSL r0", "al_r1_r1_LSL_r0"},
129     {{al, r1, r1, LSL, r1}, false, al, "al r1 r1 LSL r1", "al_r1_r1_LSL_r1"},
130     {{al, r1, r1, LSL, r2}, false, al, "al r1 r1 LSL r2", "al_r1_r1_LSL_r2"},
131     {{al, r1, r1, LSL, r3}, false, al, "al r1 r1 LSL r3", "al_r1_r1_LSL_r3"},
132     {{al, r1, r1, LSL, r4}, false, al, "al r1 r1 LSL r4", "al_r1_r1_LSL_r4"},
133     {{al, r1, r1, LSL, r5}, false, al, "al r1 r1 LSL r5", "al_r1_r1_LSL_r5"},
134     {{al, r1, r1, LSL, r6}, false, al, "al r1 r1 LSL r6", "al_r1_r1_LSL_r6"},
135     {{al, r1, r1, LSL, r7}, false, al, "al r1 r1 LSL r7", "al_r1_r1_LSL_r7"},
136     {{al, r1, r1, LSR, r0}, false, al, "al r1 r1 LSR r0", "al_r1_r1_LSR_r0"},
137     {{al, r1, r1, LSR, r1}, false, al, "al r1 r1 LSR r1", "al_r1_r1_LSR_r1"},
138     {{al, r1, r1, LSR, r2}, false, al, "al r1 r1 LSR r2", "al_r1_r1_LSR_r2"},
139     {{al, r1, r1, LSR, r3}, false, al, "al r1 r1 LSR r3", "al_r1_r1_LSR_r3"},
140     {{al, r1, r1, LSR, r4}, false, al, "al r1 r1 LSR r4", "al_r1_r1_LSR_r4"},
141     {{al, r1, r1, LSR, r5}, false, al, "al r1 r1 LSR r5", "al_r1_r1_LSR_r5"},
142     {{al, r1, r1, LSR, r6}, false, al, "al r1 r1 LSR r6", "al_r1_r1_LSR_r6"},
143     {{al, r1, r1, LSR, r7}, false, al, "al r1 r1 LSR r7", "al_r1_r1_LSR_r7"},
144     {{al, r1, r1, ASR, r0}, false, al, "al r1 r1 ASR r0", "al_r1_r1_ASR_r0"},
145     {{al, r1, r1, ASR, r1}, false, al, "al r1 r1 ASR r1", "al_r1_r1_ASR_r1"},
146     {{al, r1, r1, ASR, r2}, false, al, "al r1 r1 ASR r2", "al_r1_r1_ASR_r2"},
147     {{al, r1, r1, ASR, r3}, false, al, "al r1 r1 ASR r3", "al_r1_r1_ASR_r3"},
148     {{al, r1, r1, ASR, r4}, false, al, "al r1 r1 ASR r4", "al_r1_r1_ASR_r4"},
149     {{al, r1, r1, ASR, r5}, false, al, "al r1 r1 ASR r5", "al_r1_r1_ASR_r5"},
150     {{al, r1, r1, ASR, r6}, false, al, "al r1 r1 ASR r6", "al_r1_r1_ASR_r6"},
151     {{al, r1, r1, ASR, r7}, false, al, "al r1 r1 ASR r7", "al_r1_r1_ASR_r7"},
152     {{al, r1, r1, ROR, r0}, false, al, "al r1 r1 ROR r0", "al_r1_r1_ROR_r0"},
153     {{al, r1, r1, ROR, r1}, false, al, "al r1 r1 ROR r1", "al_r1_r1_ROR_r1"},
154     {{al, r1, r1, ROR, r2}, false, al, "al r1 r1 ROR r2", "al_r1_r1_ROR_r2"},
155     {{al, r1, r1, ROR, r3}, false, al, "al r1 r1 ROR r3", "al_r1_r1_ROR_r3"},
156     {{al, r1, r1, ROR, r4}, false, al, "al r1 r1 ROR r4", "al_r1_r1_ROR_r4"},
157     {{al, r1, r1, ROR, r5}, false, al, "al r1 r1 ROR r5", "al_r1_r1_ROR_r5"},
158     {{al, r1, r1, ROR, r6}, false, al, "al r1 r1 ROR r6", "al_r1_r1_ROR_r6"},
159     {{al, r1, r1, ROR, r7}, false, al, "al r1 r1 ROR r7", "al_r1_r1_ROR_r7"},
160     {{al, r2, r2, LSL, r0}, false, al, "al r2 r2 LSL r0", "al_r2_r2_LSL_r0"},
161     {{al, r2, r2, LSL, r1}, false, al, "al r2 r2 LSL r1", "al_r2_r2_LSL_r1"},
162     {{al, r2, r2, LSL, r2}, false, al, "al r2 r2 LSL r2", "al_r2_r2_LSL_r2"},
163     {{al, r2, r2, LSL, r3}, false, al, "al r2 r2 LSL r3", "al_r2_r2_LSL_r3"},
164     {{al, r2, r2, LSL, r4}, false, al, "al r2 r2 LSL r4", "al_r2_r2_LSL_r4"},
165     {{al, r2, r2, LSL, r5}, false, al, "al r2 r2 LSL r5", "al_r2_r2_LSL_r5"},
166     {{al, r2, r2, LSL, r6}, false, al, "al r2 r2 LSL r6", "al_r2_r2_LSL_r6"},
167     {{al, r2, r2, LSL, r7}, false, al, "al r2 r2 LSL r7", "al_r2_r2_LSL_r7"},
168     {{al, r2, r2, LSR, r0}, false, al, "al r2 r2 LSR r0", "al_r2_r2_LSR_r0"},
169     {{al, r2, r2, LSR, r1}, false, al, "al r2 r2 LSR r1", "al_r2_r2_LSR_r1"},
170     {{al, r2, r2, LSR, r2}, false, al, "al r2 r2 LSR r2", "al_r2_r2_LSR_r2"},
171     {{al, r2, r2, LSR, r3}, false, al, "al r2 r2 LSR r3", "al_r2_r2_LSR_r3"},
172     {{al, r2, r2, LSR, r4}, false, al, "al r2 r2 LSR r4", "al_r2_r2_LSR_r4"},
173     {{al, r2, r2, LSR, r5}, false, al, "al r2 r2 LSR r5", "al_r2_r2_LSR_r5"},
174     {{al, r2, r2, LSR, r6}, false, al, "al r2 r2 LSR r6", "al_r2_r2_LSR_r6"},
175     {{al, r2, r2, LSR, r7}, false, al, "al r2 r2 LSR r7", "al_r2_r2_LSR_r7"},
176     {{al, r2, r2, ASR, r0}, false, al, "al r2 r2 ASR r0", "al_r2_r2_ASR_r0"},
177     {{al, r2, r2, ASR, r1}, false, al, "al r2 r2 ASR r1", "al_r2_r2_ASR_r1"},
178     {{al, r2, r2, ASR, r2}, false, al, "al r2 r2 ASR r2", "al_r2_r2_ASR_r2"},
179     {{al, r2, r2, ASR, r3}, false, al, "al r2 r2 ASR r3", "al_r2_r2_ASR_r3"},
180     {{al, r2, r2, ASR, r4}, false, al, "al r2 r2 ASR r4", "al_r2_r2_ASR_r4"},
181     {{al, r2, r2, ASR, r5}, false, al, "al r2 r2 ASR r5", "al_r2_r2_ASR_r5"},
182     {{al, r2, r2, ASR, r6}, false, al, "al r2 r2 ASR r6", "al_r2_r2_ASR_r6"},
183     {{al, r2, r2, ASR, r7}, false, al, "al r2 r2 ASR r7", "al_r2_r2_ASR_r7"},
184     {{al, r2, r2, ROR, r0}, false, al, "al r2 r2 ROR r0", "al_r2_r2_ROR_r0"},
185     {{al, r2, r2, ROR, r1}, false, al, "al r2 r2 ROR r1", "al_r2_r2_ROR_r1"},
186     {{al, r2, r2, ROR, r2}, false, al, "al r2 r2 ROR r2", "al_r2_r2_ROR_r2"},
187     {{al, r2, r2, ROR, r3}, false, al, "al r2 r2 ROR r3", "al_r2_r2_ROR_r3"},
188     {{al, r2, r2, ROR, r4}, false, al, "al r2 r2 ROR r4", "al_r2_r2_ROR_r4"},
189     {{al, r2, r2, ROR, r5}, false, al, "al r2 r2 ROR r5", "al_r2_r2_ROR_r5"},
190     {{al, r2, r2, ROR, r6}, false, al, "al r2 r2 ROR r6", "al_r2_r2_ROR_r6"},
191     {{al, r2, r2, ROR, r7}, false, al, "al r2 r2 ROR r7", "al_r2_r2_ROR_r7"},
192     {{al, r3, r3, LSL, r0}, false, al, "al r3 r3 LSL r0", "al_r3_r3_LSL_r0"},
193     {{al, r3, r3, LSL, r1}, false, al, "al r3 r3 LSL r1", "al_r3_r3_LSL_r1"},
194     {{al, r3, r3, LSL, r2}, false, al, "al r3 r3 LSL r2", "al_r3_r3_LSL_r2"},
195     {{al, r3, r3, LSL, r3}, false, al, "al r3 r3 LSL r3", "al_r3_r3_LSL_r3"},
196     {{al, r3, r3, LSL, r4}, false, al, "al r3 r3 LSL r4", "al_r3_r3_LSL_r4"},
197     {{al, r3, r3, LSL, r5}, false, al, "al r3 r3 LSL r5", "al_r3_r3_LSL_r5"},
198     {{al, r3, r3, LSL, r6}, false, al, "al r3 r3 LSL r6", "al_r3_r3_LSL_r6"},
199     {{al, r3, r3, LSL, r7}, false, al, "al r3 r3 LSL r7", "al_r3_r3_LSL_r7"},
200     {{al, r3, r3, LSR, r0}, false, al, "al r3 r3 LSR r0", "al_r3_r3_LSR_r0"},
201     {{al, r3, r3, LSR, r1}, false, al, "al r3 r3 LSR r1", "al_r3_r3_LSR_r1"},
202     {{al, r3, r3, LSR, r2}, false, al, "al r3 r3 LSR r2", "al_r3_r3_LSR_r2"},
203     {{al, r3, r3, LSR, r3}, false, al, "al r3 r3 LSR r3", "al_r3_r3_LSR_r3"},
204     {{al, r3, r3, LSR, r4}, false, al, "al r3 r3 LSR r4", "al_r3_r3_LSR_r4"},
205     {{al, r3, r3, LSR, r5}, false, al, "al r3 r3 LSR r5", "al_r3_r3_LSR_r5"},
206     {{al, r3, r3, LSR, r6}, false, al, "al r3 r3 LSR r6", "al_r3_r3_LSR_r6"},
207     {{al, r3, r3, LSR, r7}, false, al, "al r3 r3 LSR r7", "al_r3_r3_LSR_r7"},
208     {{al, r3, r3, ASR, r0}, false, al, "al r3 r3 ASR r0", "al_r3_r3_ASR_r0"},
209     {{al, r3, r3, ASR, r1}, false, al, "al r3 r3 ASR r1", "al_r3_r3_ASR_r1"},
210     {{al, r3, r3, ASR, r2}, false, al, "al r3 r3 ASR r2", "al_r3_r3_ASR_r2"},
211     {{al, r3, r3, ASR, r3}, false, al, "al r3 r3 ASR r3", "al_r3_r3_ASR_r3"},
212     {{al, r3, r3, ASR, r4}, false, al, "al r3 r3 ASR r4", "al_r3_r3_ASR_r4"},
213     {{al, r3, r3, ASR, r5}, false, al, "al r3 r3 ASR r5", "al_r3_r3_ASR_r5"},
214     {{al, r3, r3, ASR, r6}, false, al, "al r3 r3 ASR r6", "al_r3_r3_ASR_r6"},
215     {{al, r3, r3, ASR, r7}, false, al, "al r3 r3 ASR r7", "al_r3_r3_ASR_r7"},
216     {{al, r3, r3, ROR, r0}, false, al, "al r3 r3 ROR r0", "al_r3_r3_ROR_r0"},
217     {{al, r3, r3, ROR, r1}, false, al, "al r3 r3 ROR r1", "al_r3_r3_ROR_r1"},
218     {{al, r3, r3, ROR, r2}, false, al, "al r3 r3 ROR r2", "al_r3_r3_ROR_r2"},
219     {{al, r3, r3, ROR, r3}, false, al, "al r3 r3 ROR r3", "al_r3_r3_ROR_r3"},
220     {{al, r3, r3, ROR, r4}, false, al, "al r3 r3 ROR r4", "al_r3_r3_ROR_r4"},
221     {{al, r3, r3, ROR, r5}, false, al, "al r3 r3 ROR r5", "al_r3_r3_ROR_r5"},
222     {{al, r3, r3, ROR, r6}, false, al, "al r3 r3 ROR r6", "al_r3_r3_ROR_r6"},
223     {{al, r3, r3, ROR, r7}, false, al, "al r3 r3 ROR r7", "al_r3_r3_ROR_r7"},
224     {{al, r4, r4, LSL, r0}, false, al, "al r4 r4 LSL r0", "al_r4_r4_LSL_r0"},
225     {{al, r4, r4, LSL, r1}, false, al, "al r4 r4 LSL r1", "al_r4_r4_LSL_r1"},
226     {{al, r4, r4, LSL, r2}, false, al, "al r4 r4 LSL r2", "al_r4_r4_LSL_r2"},
227     {{al, r4, r4, LSL, r3}, false, al, "al r4 r4 LSL r3", "al_r4_r4_LSL_r3"},
228     {{al, r4, r4, LSL, r4}, false, al, "al r4 r4 LSL r4", "al_r4_r4_LSL_r4"},
229     {{al, r4, r4, LSL, r5}, false, al, "al r4 r4 LSL r5", "al_r4_r4_LSL_r5"},
230     {{al, r4, r4, LSL, r6}, false, al, "al r4 r4 LSL r6", "al_r4_r4_LSL_r6"},
231     {{al, r4, r4, LSL, r7}, false, al, "al r4 r4 LSL r7", "al_r4_r4_LSL_r7"},
232     {{al, r4, r4, LSR, r0}, false, al, "al r4 r4 LSR r0", "al_r4_r4_LSR_r0"},
233     {{al, r4, r4, LSR, r1}, false, al, "al r4 r4 LSR r1", "al_r4_r4_LSR_r1"},
234     {{al, r4, r4, LSR, r2}, false, al, "al r4 r4 LSR r2", "al_r4_r4_LSR_r2"},
235     {{al, r4, r4, LSR, r3}, false, al, "al r4 r4 LSR r3", "al_r4_r4_LSR_r3"},
236     {{al, r4, r4, LSR, r4}, false, al, "al r4 r4 LSR r4", "al_r4_r4_LSR_r4"},
237     {{al, r4, r4, LSR, r5}, false, al, "al r4 r4 LSR r5", "al_r4_r4_LSR_r5"},
238     {{al, r4, r4, LSR, r6}, false, al, "al r4 r4 LSR r6", "al_r4_r4_LSR_r6"},
239     {{al, r4, r4, LSR, r7}, false, al, "al r4 r4 LSR r7", "al_r4_r4_LSR_r7"},
240     {{al, r4, r4, ASR, r0}, false, al, "al r4 r4 ASR r0", "al_r4_r4_ASR_r0"},
241     {{al, r4, r4, ASR, r1}, false, al, "al r4 r4 ASR r1", "al_r4_r4_ASR_r1"},
242     {{al, r4, r4, ASR, r2}, false, al, "al r4 r4 ASR r2", "al_r4_r4_ASR_r2"},
243     {{al, r4, r4, ASR, r3}, false, al, "al r4 r4 ASR r3", "al_r4_r4_ASR_r3"},
244     {{al, r4, r4, ASR, r4}, false, al, "al r4 r4 ASR r4", "al_r4_r4_ASR_r4"},
245     {{al, r4, r4, ASR, r5}, false, al, "al r4 r4 ASR r5", "al_r4_r4_ASR_r5"},
246     {{al, r4, r4, ASR, r6}, false, al, "al r4 r4 ASR r6", "al_r4_r4_ASR_r6"},
247     {{al, r4, r4, ASR, r7}, false, al, "al r4 r4 ASR r7", "al_r4_r4_ASR_r7"},
248     {{al, r4, r4, ROR, r0}, false, al, "al r4 r4 ROR r0", "al_r4_r4_ROR_r0"},
249     {{al, r4, r4, ROR, r1}, false, al, "al r4 r4 ROR r1", "al_r4_r4_ROR_r1"},
250     {{al, r4, r4, ROR, r2}, false, al, "al r4 r4 ROR r2", "al_r4_r4_ROR_r2"},
251     {{al, r4, r4, ROR, r3}, false, al, "al r4 r4 ROR r3", "al_r4_r4_ROR_r3"},
252     {{al, r4, r4, ROR, r4}, false, al, "al r4 r4 ROR r4", "al_r4_r4_ROR_r4"},
253     {{al, r4, r4, ROR, r5}, false, al, "al r4 r4 ROR r5", "al_r4_r4_ROR_r5"},
254     {{al, r4, r4, ROR, r6}, false, al, "al r4 r4 ROR r6", "al_r4_r4_ROR_r6"},
255     {{al, r4, r4, ROR, r7}, false, al, "al r4 r4 ROR r7", "al_r4_r4_ROR_r7"},
256     {{al, r5, r5, LSL, r0}, false, al, "al r5 r5 LSL r0", "al_r5_r5_LSL_r0"},
257     {{al, r5, r5, LSL, r1}, false, al, "al r5 r5 LSL r1", "al_r5_r5_LSL_r1"},
258     {{al, r5, r5, LSL, r2}, false, al, "al r5 r5 LSL r2", "al_r5_r5_LSL_r2"},
259     {{al, r5, r5, LSL, r3}, false, al, "al r5 r5 LSL r3", "al_r5_r5_LSL_r3"},
260     {{al, r5, r5, LSL, r4}, false, al, "al r5 r5 LSL r4", "al_r5_r5_LSL_r4"},
261     {{al, r5, r5, LSL, r5}, false, al, "al r5 r5 LSL r5", "al_r5_r5_LSL_r5"},
262     {{al, r5, r5, LSL, r6}, false, al, "al r5 r5 LSL r6", "al_r5_r5_LSL_r6"},
263     {{al, r5, r5, LSL, r7}, false, al, "al r5 r5 LSL r7", "al_r5_r5_LSL_r7"},
264     {{al, r5, r5, LSR, r0}, false, al, "al r5 r5 LSR r0", "al_r5_r5_LSR_r0"},
265     {{al, r5, r5, LSR, r1}, false, al, "al r5 r5 LSR r1", "al_r5_r5_LSR_r1"},
266     {{al, r5, r5, LSR, r2}, false, al, "al r5 r5 LSR r2", "al_r5_r5_LSR_r2"},
267     {{al, r5, r5, LSR, r3}, false, al, "al r5 r5 LSR r3", "al_r5_r5_LSR_r3"},
268     {{al, r5, r5, LSR, r4}, false, al, "al r5 r5 LSR r4", "al_r5_r5_LSR_r4"},
269     {{al, r5, r5, LSR, r5}, false, al, "al r5 r5 LSR r5", "al_r5_r5_LSR_r5"},
270     {{al, r5, r5, LSR, r6}, false, al, "al r5 r5 LSR r6", "al_r5_r5_LSR_r6"},
271     {{al, r5, r5, LSR, r7}, false, al, "al r5 r5 LSR r7", "al_r5_r5_LSR_r7"},
272     {{al, r5, r5, ASR, r0}, false, al, "al r5 r5 ASR r0", "al_r5_r5_ASR_r0"},
273     {{al, r5, r5, ASR, r1}, false, al, "al r5 r5 ASR r1", "al_r5_r5_ASR_r1"},
274     {{al, r5, r5, ASR, r2}, false, al, "al r5 r5 ASR r2", "al_r5_r5_ASR_r2"},
275     {{al, r5, r5, ASR, r3}, false, al, "al r5 r5 ASR r3", "al_r5_r5_ASR_r3"},
276     {{al, r5, r5, ASR, r4}, false, al, "al r5 r5 ASR r4", "al_r5_r5_ASR_r4"},
277     {{al, r5, r5, ASR, r5}, false, al, "al r5 r5 ASR r5", "al_r5_r5_ASR_r5"},
278     {{al, r5, r5, ASR, r6}, false, al, "al r5 r5 ASR r6", "al_r5_r5_ASR_r6"},
279     {{al, r5, r5, ASR, r7}, false, al, "al r5 r5 ASR r7", "al_r5_r5_ASR_r7"},
280     {{al, r5, r5, ROR, r0}, false, al, "al r5 r5 ROR r0", "al_r5_r5_ROR_r0"},
281     {{al, r5, r5, ROR, r1}, false, al, "al r5 r5 ROR r1", "al_r5_r5_ROR_r1"},
282     {{al, r5, r5, ROR, r2}, false, al, "al r5 r5 ROR r2", "al_r5_r5_ROR_r2"},
283     {{al, r5, r5, ROR, r3}, false, al, "al r5 r5 ROR r3", "al_r5_r5_ROR_r3"},
284     {{al, r5, r5, ROR, r4}, false, al, "al r5 r5 ROR r4", "al_r5_r5_ROR_r4"},
285     {{al, r5, r5, ROR, r5}, false, al, "al r5 r5 ROR r5", "al_r5_r5_ROR_r5"},
286     {{al, r5, r5, ROR, r6}, false, al, "al r5 r5 ROR r6", "al_r5_r5_ROR_r6"},
287     {{al, r5, r5, ROR, r7}, false, al, "al r5 r5 ROR r7", "al_r5_r5_ROR_r7"},
288     {{al, r6, r6, LSL, r0}, false, al, "al r6 r6 LSL r0", "al_r6_r6_LSL_r0"},
289     {{al, r6, r6, LSL, r1}, false, al, "al r6 r6 LSL r1", "al_r6_r6_LSL_r1"},
290     {{al, r6, r6, LSL, r2}, false, al, "al r6 r6 LSL r2", "al_r6_r6_LSL_r2"},
291     {{al, r6, r6, LSL, r3}, false, al, "al r6 r6 LSL r3", "al_r6_r6_LSL_r3"},
292     {{al, r6, r6, LSL, r4}, false, al, "al r6 r6 LSL r4", "al_r6_r6_LSL_r4"},
293     {{al, r6, r6, LSL, r5}, false, al, "al r6 r6 LSL r5", "al_r6_r6_LSL_r5"},
294     {{al, r6, r6, LSL, r6}, false, al, "al r6 r6 LSL r6", "al_r6_r6_LSL_r6"},
295     {{al, r6, r6, LSL, r7}, false, al, "al r6 r6 LSL r7", "al_r6_r6_LSL_r7"},
296     {{al, r6, r6, LSR, r0}, false, al, "al r6 r6 LSR r0", "al_r6_r6_LSR_r0"},
297     {{al, r6, r6, LSR, r1}, false, al, "al r6 r6 LSR r1", "al_r6_r6_LSR_r1"},
298     {{al, r6, r6, LSR, r2}, false, al, "al r6 r6 LSR r2", "al_r6_r6_LSR_r2"},
299     {{al, r6, r6, LSR, r3}, false, al, "al r6 r6 LSR r3", "al_r6_r6_LSR_r3"},
300     {{al, r6, r6, LSR, r4}, false, al, "al r6 r6 LSR r4", "al_r6_r6_LSR_r4"},
301     {{al, r6, r6, LSR, r5}, false, al, "al r6 r6 LSR r5", "al_r6_r6_LSR_r5"},
302     {{al, r6, r6, LSR, r6}, false, al, "al r6 r6 LSR r6", "al_r6_r6_LSR_r6"},
303     {{al, r6, r6, LSR, r7}, false, al, "al r6 r6 LSR r7", "al_r6_r6_LSR_r7"},
304     {{al, r6, r6, ASR, r0}, false, al, "al r6 r6 ASR r0", "al_r6_r6_ASR_r0"},
305     {{al, r6, r6, ASR, r1}, false, al, "al r6 r6 ASR r1", "al_r6_r6_ASR_r1"},
306     {{al, r6, r6, ASR, r2}, false, al, "al r6 r6 ASR r2", "al_r6_r6_ASR_r2"},
307     {{al, r6, r6, ASR, r3}, false, al, "al r6 r6 ASR r3", "al_r6_r6_ASR_r3"},
308     {{al, r6, r6, ASR, r4}, false, al, "al r6 r6 ASR r4", "al_r6_r6_ASR_r4"},
309     {{al, r6, r6, ASR, r5}, false, al, "al r6 r6 ASR r5", "al_r6_r6_ASR_r5"},
310     {{al, r6, r6, ASR, r6}, false, al, "al r6 r6 ASR r6", "al_r6_r6_ASR_r6"},
311     {{al, r6, r6, ASR, r7}, false, al, "al r6 r6 ASR r7", "al_r6_r6_ASR_r7"},
312     {{al, r6, r6, ROR, r0}, false, al, "al r6 r6 ROR r0", "al_r6_r6_ROR_r0"},
313     {{al, r6, r6, ROR, r1}, false, al, "al r6 r6 ROR r1", "al_r6_r6_ROR_r1"},
314     {{al, r6, r6, ROR, r2}, false, al, "al r6 r6 ROR r2", "al_r6_r6_ROR_r2"},
315     {{al, r6, r6, ROR, r3}, false, al, "al r6 r6 ROR r3", "al_r6_r6_ROR_r3"},
316     {{al, r6, r6, ROR, r4}, false, al, "al r6 r6 ROR r4", "al_r6_r6_ROR_r4"},
317     {{al, r6, r6, ROR, r5}, false, al, "al r6 r6 ROR r5", "al_r6_r6_ROR_r5"},
318     {{al, r6, r6, ROR, r6}, false, al, "al r6 r6 ROR r6", "al_r6_r6_ROR_r6"},
319     {{al, r6, r6, ROR, r7}, false, al, "al r6 r6 ROR r7", "al_r6_r6_ROR_r7"},
320     {{al, r7, r7, LSL, r0}, false, al, "al r7 r7 LSL r0", "al_r7_r7_LSL_r0"},
321     {{al, r7, r7, LSL, r1}, false, al, "al r7 r7 LSL r1", "al_r7_r7_LSL_r1"},
322     {{al, r7, r7, LSL, r2}, false, al, "al r7 r7 LSL r2", "al_r7_r7_LSL_r2"},
323     {{al, r7, r7, LSL, r3}, false, al, "al r7 r7 LSL r3", "al_r7_r7_LSL_r3"},
324     {{al, r7, r7, LSL, r4}, false, al, "al r7 r7 LSL r4", "al_r7_r7_LSL_r4"},
325     {{al, r7, r7, LSL, r5}, false, al, "al r7 r7 LSL r5", "al_r7_r7_LSL_r5"},
326     {{al, r7, r7, LSL, r6}, false, al, "al r7 r7 LSL r6", "al_r7_r7_LSL_r6"},
327     {{al, r7, r7, LSL, r7}, false, al, "al r7 r7 LSL r7", "al_r7_r7_LSL_r7"},
328     {{al, r7, r7, LSR, r0}, false, al, "al r7 r7 LSR r0", "al_r7_r7_LSR_r0"},
329     {{al, r7, r7, LSR, r1}, false, al, "al r7 r7 LSR r1", "al_r7_r7_LSR_r1"},
330     {{al, r7, r7, LSR, r2}, false, al, "al r7 r7 LSR r2", "al_r7_r7_LSR_r2"},
331     {{al, r7, r7, LSR, r3}, false, al, "al r7 r7 LSR r3", "al_r7_r7_LSR_r3"},
332     {{al, r7, r7, LSR, r4}, false, al, "al r7 r7 LSR r4", "al_r7_r7_LSR_r4"},
333     {{al, r7, r7, LSR, r5}, false, al, "al r7 r7 LSR r5", "al_r7_r7_LSR_r5"},
334     {{al, r7, r7, LSR, r6}, false, al, "al r7 r7 LSR r6", "al_r7_r7_LSR_r6"},
335     {{al, r7, r7, LSR, r7}, false, al, "al r7 r7 LSR r7", "al_r7_r7_LSR_r7"},
336     {{al, r7, r7, ASR, r0}, false, al, "al r7 r7 ASR r0", "al_r7_r7_ASR_r0"},
337     {{al, r7, r7, ASR, r1}, false, al, "al r7 r7 ASR r1", "al_r7_r7_ASR_r1"},
338     {{al, r7, r7, ASR, r2}, false, al, "al r7 r7 ASR r2", "al_r7_r7_ASR_r2"},
339     {{al, r7, r7, ASR, r3}, false, al, "al r7 r7 ASR r3", "al_r7_r7_ASR_r3"},
340     {{al, r7, r7, ASR, r4}, false, al, "al r7 r7 ASR r4", "al_r7_r7_ASR_r4"},
341     {{al, r7, r7, ASR, r5}, false, al, "al r7 r7 ASR r5", "al_r7_r7_ASR_r5"},
342     {{al, r7, r7, ASR, r6}, false, al, "al r7 r7 ASR r6", "al_r7_r7_ASR_r6"},
343     {{al, r7, r7, ASR, r7}, false, al, "al r7 r7 ASR r7", "al_r7_r7_ASR_r7"},
344     {{al, r7, r7, ROR, r0}, false, al, "al r7 r7 ROR r0", "al_r7_r7_ROR_r0"},
345     {{al, r7, r7, ROR, r1}, false, al, "al r7 r7 ROR r1", "al_r7_r7_ROR_r1"},
346     {{al, r7, r7, ROR, r2}, false, al, "al r7 r7 ROR r2", "al_r7_r7_ROR_r2"},
347     {{al, r7, r7, ROR, r3}, false, al, "al r7 r7 ROR r3", "al_r7_r7_ROR_r3"},
348     {{al, r7, r7, ROR, r4}, false, al, "al r7 r7 ROR r4", "al_r7_r7_ROR_r4"},
349     {{al, r7, r7, ROR, r5}, false, al, "al r7 r7 ROR r5", "al_r7_r7_ROR_r5"},
350     {{al, r7, r7, ROR, r6}, false, al, "al r7 r7 ROR r6", "al_r7_r7_ROR_r6"},
351     {{al, r7, r7, ROR, r7}, false, al, "al r7 r7 ROR r7", "al_r7_r7_ROR_r7"}};
352
353// These headers each contain an array of `TestResult` with the reference output
354// values. The reference arrays are names `kReference{mnemonic}`.
355#include "aarch32/traces/assembler-cond-rd-operand-rn-shift-rs-narrow-out-it-block-movs-t32.h"
356
357
358// The maximum number of errors to report in detail for each test.
359const unsigned kErrorReportLimit = 8;
360
361typedef void (MacroAssembler::*Fn)(Condition cond,
362                                   Register rd,
363                                   const Operand& op);
364
365void TestHelper(Fn instruction,
366                const char* mnemonic,
367                const TestResult reference[]) {
368  unsigned total_error_count = 0;
369  MacroAssembler masm(BUF_SIZE);
370
371  masm.UseT32();
372
373  for (unsigned i = 0; i < ARRAY_SIZE(kTests); i++) {
374    // Values to pass to the macro-assembler.
375    Condition cond = kTests[i].operands.cond;
376    Register rd = kTests[i].operands.rd;
377    Register rn = kTests[i].operands.rn;
378    ShiftType shift = kTests[i].operands.shift;
379    Register rs = kTests[i].operands.rs;
380    Operand op(rn, shift, rs);
381
382    int32_t start = masm.GetCursorOffset();
383    {
384      // We never generate more that 4 bytes, as IT instructions are only
385      // allowed for narrow encodings.
386      ExactAssemblyScope scope(&masm, 4, ExactAssemblyScope::kMaximumSize);
387      if (kTests[i].in_it_block) {
388        masm.it(kTests[i].it_condition);
389      }
390      (masm.*instruction)(cond, rd, op);
391    }
392    int32_t end = masm.GetCursorOffset();
393
394    const byte* result_ptr =
395        masm.GetBuffer()->GetOffsetAddress<const byte*>(start);
396    VIXL_ASSERT(start < end);
397    uint32_t result_size = end - start;
398
399    if (Test::generate_test_trace()) {
400      // Print the result bytes.
401      printf("const byte kInstruction_%s_%s[] = {\n",
402             mnemonic,
403             kTests[i].identifier);
404      for (uint32_t j = 0; j < result_size; j++) {
405        if (j == 0) {
406          printf("  0x%02" PRIx8, result_ptr[j]);
407        } else {
408          printf(", 0x%02" PRIx8, result_ptr[j]);
409        }
410      }
411      // This comment is meant to be used by external tools to validate
412      // the encoding. We can parse the comment to figure out what
413      // instruction this corresponds to.
414      if (kTests[i].in_it_block) {
415        printf(" // It %s; %s %s\n};\n",
416               kTests[i].it_condition.GetName(),
417               mnemonic,
418               kTests[i].operands_description);
419      } else {
420        printf(" // %s %s\n};\n", mnemonic, kTests[i].operands_description);
421      }
422    } else {
423      // Check we've emitted the exact same encoding as present in the
424      // trace file. Only print up to `kErrorReportLimit` errors.
425      if (((result_size != reference[i].size) ||
426           (memcmp(result_ptr, reference[i].encoding, reference[i].size) !=
427            0)) &&
428          (++total_error_count <= kErrorReportLimit)) {
429        printf("Error when testing \"%s\" with operands \"%s\":\n",
430               mnemonic,
431               kTests[i].operands_description);
432        printf("  Expected: ");
433        for (uint32_t j = 0; j < reference[i].size; j++) {
434          if (j == 0) {
435            printf("0x%02" PRIx8, reference[i].encoding[j]);
436          } else {
437            printf(", 0x%02" PRIx8, reference[i].encoding[j]);
438          }
439        }
440        printf("\n");
441        printf("  Found:    ");
442        for (uint32_t j = 0; j < result_size; j++) {
443          if (j == 0) {
444            printf("0x%02" PRIx8, result_ptr[j]);
445          } else {
446            printf(", 0x%02" PRIx8, result_ptr[j]);
447          }
448        }
449        printf("\n");
450      }
451    }
452  }
453
454  masm.FinalizeCode();
455
456  if (Test::generate_test_trace()) {
457    // Finalize the trace file by writing the final `TestResult` array
458    // which links all generated instruction encodings.
459    printf("const TestResult kReference%s[] = {\n", mnemonic);
460    for (unsigned i = 0; i < ARRAY_SIZE(kTests); i++) {
461      printf("  {\n");
462      printf("    ARRAY_SIZE(kInstruction_%s_%s),\n",
463             mnemonic,
464             kTests[i].identifier);
465      printf("    kInstruction_%s_%s,\n", mnemonic, kTests[i].identifier);
466      printf("  },\n");
467    }
468    printf("};\n");
469  } else {
470    if (total_error_count > kErrorReportLimit) {
471      printf("%u other errors follow.\n",
472             total_error_count - kErrorReportLimit);
473    }
474    // Crash if the test failed.
475    VIXL_CHECK(total_error_count == 0);
476  }
477}
478
479// Instantiate tests for each instruction in the list.
480#define TEST(mnemonic)                                                      \
481  void Test_##mnemonic() {                                                  \
482    TestHelper(&MacroAssembler::mnemonic, #mnemonic, kReference##mnemonic); \
483  }                                                                         \
484  Test test_##mnemonic(                                                     \
485      "AARCH32_ASSEMBLER_COND_RD_OPERAND_RN_SHIFT_RS_NARROW_OUT_IT_"        \
486      "BLOCK_" #mnemonic "_T32",                                            \
487      &Test_##mnemonic);
488FOREACH_INSTRUCTION(TEST)
489#undef TEST
490
491}  // namespace
492#endif
493
494}  // namespace aarch32
495}  // namespace vixl
496