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-simulator-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#include "aarch32/disasm-aarch32.h"
45
46#define __ masm.
47#define BUF_SIZE (4096)
48
49#ifdef VIXL_INCLUDE_SIMULATOR_AARCH32
50// Run tests with the simulator.
51
52#define SETUP() MacroAssembler masm(BUF_SIZE)
53
54#define START() masm.GetBuffer()->Reset()
55
56#define END() \
57  __ Hlt(0);  \
58  __ FinalizeCode();
59
60// TODO: Run the tests in the simulator.
61#define RUN()
62
63#define TEARDOWN()
64
65#else  // ifdef VIXL_INCLUDE_SIMULATOR_AARCH32.
66
67#define SETUP()                                   \
68  MacroAssembler masm(BUF_SIZE);                  \
69  UseScratchRegisterScope harness_scratch(&masm); \
70  harness_scratch.ExcludeAll();
71
72#define START()              \
73  masm.GetBuffer()->Reset(); \
74  __ Push(r4);               \
75  __ Push(r5);               \
76  __ Push(r6);               \
77  __ Push(r7);               \
78  __ Push(r8);               \
79  __ Push(r9);               \
80  __ Push(r10);              \
81  __ Push(r11);              \
82  __ Push(lr);               \
83  harness_scratch.Include(ip);
84
85#define END()                  \
86  harness_scratch.Exclude(ip); \
87  __ Pop(lr);                  \
88  __ Pop(r11);                 \
89  __ Pop(r10);                 \
90  __ Pop(r9);                  \
91  __ Pop(r8);                  \
92  __ Pop(r7);                  \
93  __ Pop(r6);                  \
94  __ Pop(r5);                  \
95  __ Pop(r4);                  \
96  __ Bx(lr);                   \
97  __ FinalizeCode();
98
99#define RUN()                                                 \
100  {                                                           \
101    int pcs_offset = masm.IsUsingT32() ? 1 : 0;               \
102    masm.GetBuffer()->SetExecutable();                        \
103    ExecuteMemory(masm.GetBuffer()->GetStartAddress<byte*>(), \
104                  masm.GetSizeOfCodeGenerated(),              \
105                  pcs_offset);                                \
106    masm.GetBuffer()->SetWritable();                          \
107  }
108
109#define TEARDOWN() harness_scratch.Close();
110
111#endif  // ifdef VIXL_INCLUDE_SIMULATOR_AARCH32
112
113namespace vixl {
114namespace aarch32 {
115
116// List of instruction encodings:
117#define FOREACH_INSTRUCTION(M) \
118  M(Cmn)                       \
119  M(Cmp)                       \
120  M(Mov)                       \
121  M(Movs)                      \
122  M(Mvn)                       \
123  M(Mvns)                      \
124  M(Teq)                       \
125  M(Tst)
126
127
128// The following definitions are defined again in each generated test, therefore
129// we need to place them in an anomymous namespace. It expresses that they are
130// local to this file only, and the compiler is not allowed to share these types
131// across test files during template instantiation. Specifically, `Operands` and
132// `Inputs` have various layouts across generated tests so they absolutely
133// cannot be shared.
134
135#ifdef VIXL_INCLUDE_TARGET_T32
136namespace {
137
138// Values to be passed to the assembler to produce the instruction under test.
139struct Operands {
140  Condition cond;
141  Register rd;
142  uint32_t immediate;
143};
144
145// Input data to feed to the instruction.
146struct Inputs {
147  uint32_t apsr;
148  uint32_t rd;
149};
150
151// This structure contains all input data needed to test one specific encoding.
152// It used to generate a loop over an instruction.
153struct TestLoopData {
154  // The `operands` fields represents the values to pass to the assembler to
155  // produce the instruction.
156  Operands operands;
157  // Description of the operands, used for error reporting.
158  const char* operands_description;
159  // Unique identifier, used for generating traces.
160  const char* identifier;
161  // Array of values to be fed to the instruction.
162  size_t input_size;
163  const Inputs* inputs;
164};
165
166static const Inputs kCondition[] = {{NFlag, 0xabababab},
167                                    {ZFlag, 0xabababab},
168                                    {CFlag, 0xabababab},
169                                    {VFlag, 0xabababab},
170                                    {NZFlag, 0xabababab},
171                                    {NCFlag, 0xabababab},
172                                    {NVFlag, 0xabababab},
173                                    {ZCFlag, 0xabababab},
174                                    {ZVFlag, 0xabababab},
175                                    {CVFlag, 0xabababab},
176                                    {NZCFlag, 0xabababab},
177                                    {NZVFlag, 0xabababab},
178                                    {NCVFlag, 0xabababab},
179                                    {ZCVFlag, 0xabababab},
180                                    {NZCVFlag, 0xabababab}};
181
182static const Inputs kModifiedImmediate[] = {{NoFlag, 0x00000000},
183                                            {NoFlag, 0x00000001},
184                                            {NoFlag, 0x00000002},
185                                            {NoFlag, 0x00000020},
186                                            {NoFlag, 0x0000007d},
187                                            {NoFlag, 0x0000007e},
188                                            {NoFlag, 0x0000007f},
189                                            {NoFlag, 0x00007ffd},
190                                            {NoFlag, 0x00007ffe},
191                                            {NoFlag, 0x00007fff},
192                                            {NoFlag, 0x33333333},
193                                            {NoFlag, 0x55555555},
194                                            {NoFlag, 0x7ffffffd},
195                                            {NoFlag, 0x7ffffffe},
196                                            {NoFlag, 0x7fffffff},
197                                            {NoFlag, 0x80000000},
198                                            {NoFlag, 0x80000001},
199                                            {NoFlag, 0xaaaaaaaa},
200                                            {NoFlag, 0xcccccccc},
201                                            {NoFlag, 0xffff8000},
202                                            {NoFlag, 0xffff8001},
203                                            {NoFlag, 0xffff8002},
204                                            {NoFlag, 0xffff8003},
205                                            {NoFlag, 0xffffff80},
206                                            {NoFlag, 0xffffff81},
207                                            {NoFlag, 0xffffff82},
208                                            {NoFlag, 0xffffff83},
209                                            {NoFlag, 0xffffffe0},
210                                            {NoFlag, 0xfffffffd},
211                                            {NoFlag, 0xfffffffe},
212                                            {NoFlag, 0xffffffff}};
213
214
215// A loop will be generated for each element of this array.
216const TestLoopData kTests[] = {{{eq, r0, 0xabababab},
217                                "eq r0 0xabababab",
218                                "Condition_eq_r0_0xabababab",
219                                ARRAY_SIZE(kCondition),
220                                kCondition},
221                               {{ne, r0, 0xabababab},
222                                "ne r0 0xabababab",
223                                "Condition_ne_r0_0xabababab",
224                                ARRAY_SIZE(kCondition),
225                                kCondition},
226                               {{cs, r0, 0xabababab},
227                                "cs r0 0xabababab",
228                                "Condition_cs_r0_0xabababab",
229                                ARRAY_SIZE(kCondition),
230                                kCondition},
231                               {{cc, r0, 0xabababab},
232                                "cc r0 0xabababab",
233                                "Condition_cc_r0_0xabababab",
234                                ARRAY_SIZE(kCondition),
235                                kCondition},
236                               {{mi, r0, 0xabababab},
237                                "mi r0 0xabababab",
238                                "Condition_mi_r0_0xabababab",
239                                ARRAY_SIZE(kCondition),
240                                kCondition},
241                               {{pl, r0, 0xabababab},
242                                "pl r0 0xabababab",
243                                "Condition_pl_r0_0xabababab",
244                                ARRAY_SIZE(kCondition),
245                                kCondition},
246                               {{vs, r0, 0xabababab},
247                                "vs r0 0xabababab",
248                                "Condition_vs_r0_0xabababab",
249                                ARRAY_SIZE(kCondition),
250                                kCondition},
251                               {{vc, r0, 0xabababab},
252                                "vc r0 0xabababab",
253                                "Condition_vc_r0_0xabababab",
254                                ARRAY_SIZE(kCondition),
255                                kCondition},
256                               {{hi, r0, 0xabababab},
257                                "hi r0 0xabababab",
258                                "Condition_hi_r0_0xabababab",
259                                ARRAY_SIZE(kCondition),
260                                kCondition},
261                               {{ls, r0, 0xabababab},
262                                "ls r0 0xabababab",
263                                "Condition_ls_r0_0xabababab",
264                                ARRAY_SIZE(kCondition),
265                                kCondition},
266                               {{ge, r0, 0xabababab},
267                                "ge r0 0xabababab",
268                                "Condition_ge_r0_0xabababab",
269                                ARRAY_SIZE(kCondition),
270                                kCondition},
271                               {{lt, r0, 0xabababab},
272                                "lt r0 0xabababab",
273                                "Condition_lt_r0_0xabababab",
274                                ARRAY_SIZE(kCondition),
275                                kCondition},
276                               {{gt, r0, 0xabababab},
277                                "gt r0 0xabababab",
278                                "Condition_gt_r0_0xabababab",
279                                ARRAY_SIZE(kCondition),
280                                kCondition},
281                               {{le, r0, 0xabababab},
282                                "le r0 0xabababab",
283                                "Condition_le_r0_0xabababab",
284                                ARRAY_SIZE(kCondition),
285                                kCondition},
286                               {{al, r0, 0xabababab},
287                                "al r0 0xabababab",
288                                "Condition_al_r0_0xabababab",
289                                ARRAY_SIZE(kCondition),
290                                kCondition},
291                               {{al, r0, 0x000001fe},
292                                "al r0 0x000001fe",
293                                "ModifiedImmediate_al_r0_0x000001fe",
294                                ARRAY_SIZE(kModifiedImmediate),
295                                kModifiedImmediate},
296                               {{al, r0, 0x000003fc},
297                                "al r0 0x000003fc",
298                                "ModifiedImmediate_al_r0_0x000003fc",
299                                ARRAY_SIZE(kModifiedImmediate),
300                                kModifiedImmediate},
301                               {{al, r0, 0x000007f8},
302                                "al r0 0x000007f8",
303                                "ModifiedImmediate_al_r0_0x000007f8",
304                                ARRAY_SIZE(kModifiedImmediate),
305                                kModifiedImmediate},
306                               {{al, r0, 0x00000ff0},
307                                "al r0 0x00000ff0",
308                                "ModifiedImmediate_al_r0_0x00000ff0",
309                                ARRAY_SIZE(kModifiedImmediate),
310                                kModifiedImmediate},
311                               {{al, r0, 0x00001fe0},
312                                "al r0 0x00001fe0",
313                                "ModifiedImmediate_al_r0_0x00001fe0",
314                                ARRAY_SIZE(kModifiedImmediate),
315                                kModifiedImmediate},
316                               {{al, r0, 0x00003fc0},
317                                "al r0 0x00003fc0",
318                                "ModifiedImmediate_al_r0_0x00003fc0",
319                                ARRAY_SIZE(kModifiedImmediate),
320                                kModifiedImmediate},
321                               {{al, r0, 0x00007f80},
322                                "al r0 0x00007f80",
323                                "ModifiedImmediate_al_r0_0x00007f80",
324                                ARRAY_SIZE(kModifiedImmediate),
325                                kModifiedImmediate},
326                               {{al, r0, 0x0000ff00},
327                                "al r0 0x0000ff00",
328                                "ModifiedImmediate_al_r0_0x0000ff00",
329                                ARRAY_SIZE(kModifiedImmediate),
330                                kModifiedImmediate},
331                               {{al, r0, 0x0001fe00},
332                                "al r0 0x0001fe00",
333                                "ModifiedImmediate_al_r0_0x0001fe00",
334                                ARRAY_SIZE(kModifiedImmediate),
335                                kModifiedImmediate},
336                               {{al, r0, 0x0003fc00},
337                                "al r0 0x0003fc00",
338                                "ModifiedImmediate_al_r0_0x0003fc00",
339                                ARRAY_SIZE(kModifiedImmediate),
340                                kModifiedImmediate},
341                               {{al, r0, 0x0007f800},
342                                "al r0 0x0007f800",
343                                "ModifiedImmediate_al_r0_0x0007f800",
344                                ARRAY_SIZE(kModifiedImmediate),
345                                kModifiedImmediate},
346                               {{al, r0, 0x000ff000},
347                                "al r0 0x000ff000",
348                                "ModifiedImmediate_al_r0_0x000ff000",
349                                ARRAY_SIZE(kModifiedImmediate),
350                                kModifiedImmediate},
351                               {{al, r0, 0x001fe000},
352                                "al r0 0x001fe000",
353                                "ModifiedImmediate_al_r0_0x001fe000",
354                                ARRAY_SIZE(kModifiedImmediate),
355                                kModifiedImmediate},
356                               {{al, r0, 0x003fc000},
357                                "al r0 0x003fc000",
358                                "ModifiedImmediate_al_r0_0x003fc000",
359                                ARRAY_SIZE(kModifiedImmediate),
360                                kModifiedImmediate},
361                               {{al, r0, 0x007f8000},
362                                "al r0 0x007f8000",
363                                "ModifiedImmediate_al_r0_0x007f8000",
364                                ARRAY_SIZE(kModifiedImmediate),
365                                kModifiedImmediate},
366                               {{al, r0, 0x00ff0000},
367                                "al r0 0x00ff0000",
368                                "ModifiedImmediate_al_r0_0x00ff0000",
369                                ARRAY_SIZE(kModifiedImmediate),
370                                kModifiedImmediate},
371                               {{al, r0, 0x01fe0000},
372                                "al r0 0x01fe0000",
373                                "ModifiedImmediate_al_r0_0x01fe0000",
374                                ARRAY_SIZE(kModifiedImmediate),
375                                kModifiedImmediate},
376                               {{al, r0, 0x03fc0000},
377                                "al r0 0x03fc0000",
378                                "ModifiedImmediate_al_r0_0x03fc0000",
379                                ARRAY_SIZE(kModifiedImmediate),
380                                kModifiedImmediate},
381                               {{al, r0, 0x07f80000},
382                                "al r0 0x07f80000",
383                                "ModifiedImmediate_al_r0_0x07f80000",
384                                ARRAY_SIZE(kModifiedImmediate),
385                                kModifiedImmediate},
386                               {{al, r0, 0x0ff00000},
387                                "al r0 0x0ff00000",
388                                "ModifiedImmediate_al_r0_0x0ff00000",
389                                ARRAY_SIZE(kModifiedImmediate),
390                                kModifiedImmediate},
391                               {{al, r0, 0x1fe00000},
392                                "al r0 0x1fe00000",
393                                "ModifiedImmediate_al_r0_0x1fe00000",
394                                ARRAY_SIZE(kModifiedImmediate),
395                                kModifiedImmediate},
396                               {{al, r0, 0x3fc00000},
397                                "al r0 0x3fc00000",
398                                "ModifiedImmediate_al_r0_0x3fc00000",
399                                ARRAY_SIZE(kModifiedImmediate),
400                                kModifiedImmediate},
401                               {{al, r0, 0x7f800000},
402                                "al r0 0x7f800000",
403                                "ModifiedImmediate_al_r0_0x7f800000",
404                                ARRAY_SIZE(kModifiedImmediate),
405                                kModifiedImmediate},
406                               {{al, r0, 0xff000000},
407                                "al r0 0xff000000",
408                                "ModifiedImmediate_al_r0_0xff000000",
409                                ARRAY_SIZE(kModifiedImmediate),
410                                kModifiedImmediate},
411                               {{al, r0, 0x000000ff},
412                                "al r0 0x000000ff",
413                                "ModifiedImmediate_al_r0_0x000000ff",
414                                ARRAY_SIZE(kModifiedImmediate),
415                                kModifiedImmediate},
416                               {{al, r0, 0x00ff00ff},
417                                "al r0 0x00ff00ff",
418                                "ModifiedImmediate_al_r0_0x00ff00ff",
419                                ARRAY_SIZE(kModifiedImmediate),
420                                kModifiedImmediate},
421                               {{al, r0, 0xff00ff00},
422                                "al r0 0xff00ff00",
423                                "ModifiedImmediate_al_r0_0xff00ff00",
424                                ARRAY_SIZE(kModifiedImmediate),
425                                kModifiedImmediate},
426                               {{al, r0, 0xffffffff},
427                                "al r0 0xffffffff",
428                                "ModifiedImmediate_al_r0_0xffffffff",
429                                ARRAY_SIZE(kModifiedImmediate),
430                                kModifiedImmediate},
431                               {{al, r0, 0x00000156},
432                                "al r0 0x00000156",
433                                "ModifiedImmediate_al_r0_0x00000156",
434                                ARRAY_SIZE(kModifiedImmediate),
435                                kModifiedImmediate},
436                               {{al, r0, 0x000002ac},
437                                "al r0 0x000002ac",
438                                "ModifiedImmediate_al_r0_0x000002ac",
439                                ARRAY_SIZE(kModifiedImmediate),
440                                kModifiedImmediate},
441                               {{al, r0, 0x00000558},
442                                "al r0 0x00000558",
443                                "ModifiedImmediate_al_r0_0x00000558",
444                                ARRAY_SIZE(kModifiedImmediate),
445                                kModifiedImmediate},
446                               {{al, r0, 0x00000ab0},
447                                "al r0 0x00000ab0",
448                                "ModifiedImmediate_al_r0_0x00000ab0",
449                                ARRAY_SIZE(kModifiedImmediate),
450                                kModifiedImmediate},
451                               {{al, r0, 0x00001560},
452                                "al r0 0x00001560",
453                                "ModifiedImmediate_al_r0_0x00001560",
454                                ARRAY_SIZE(kModifiedImmediate),
455                                kModifiedImmediate},
456                               {{al, r0, 0x00002ac0},
457                                "al r0 0x00002ac0",
458                                "ModifiedImmediate_al_r0_0x00002ac0",
459                                ARRAY_SIZE(kModifiedImmediate),
460                                kModifiedImmediate},
461                               {{al, r0, 0x00005580},
462                                "al r0 0x00005580",
463                                "ModifiedImmediate_al_r0_0x00005580",
464                                ARRAY_SIZE(kModifiedImmediate),
465                                kModifiedImmediate},
466                               {{al, r0, 0x0000ab00},
467                                "al r0 0x0000ab00",
468                                "ModifiedImmediate_al_r0_0x0000ab00",
469                                ARRAY_SIZE(kModifiedImmediate),
470                                kModifiedImmediate},
471                               {{al, r0, 0x00015600},
472                                "al r0 0x00015600",
473                                "ModifiedImmediate_al_r0_0x00015600",
474                                ARRAY_SIZE(kModifiedImmediate),
475                                kModifiedImmediate},
476                               {{al, r0, 0x0002ac00},
477                                "al r0 0x0002ac00",
478                                "ModifiedImmediate_al_r0_0x0002ac00",
479                                ARRAY_SIZE(kModifiedImmediate),
480                                kModifiedImmediate},
481                               {{al, r0, 0x00055800},
482                                "al r0 0x00055800",
483                                "ModifiedImmediate_al_r0_0x00055800",
484                                ARRAY_SIZE(kModifiedImmediate),
485                                kModifiedImmediate},
486                               {{al, r0, 0x000ab000},
487                                "al r0 0x000ab000",
488                                "ModifiedImmediate_al_r0_0x000ab000",
489                                ARRAY_SIZE(kModifiedImmediate),
490                                kModifiedImmediate},
491                               {{al, r0, 0x00156000},
492                                "al r0 0x00156000",
493                                "ModifiedImmediate_al_r0_0x00156000",
494                                ARRAY_SIZE(kModifiedImmediate),
495                                kModifiedImmediate},
496                               {{al, r0, 0x002ac000},
497                                "al r0 0x002ac000",
498                                "ModifiedImmediate_al_r0_0x002ac000",
499                                ARRAY_SIZE(kModifiedImmediate),
500                                kModifiedImmediate},
501                               {{al, r0, 0x00558000},
502                                "al r0 0x00558000",
503                                "ModifiedImmediate_al_r0_0x00558000",
504                                ARRAY_SIZE(kModifiedImmediate),
505                                kModifiedImmediate},
506                               {{al, r0, 0x00ab0000},
507                                "al r0 0x00ab0000",
508                                "ModifiedImmediate_al_r0_0x00ab0000",
509                                ARRAY_SIZE(kModifiedImmediate),
510                                kModifiedImmediate},
511                               {{al, r0, 0x01560000},
512                                "al r0 0x01560000",
513                                "ModifiedImmediate_al_r0_0x01560000",
514                                ARRAY_SIZE(kModifiedImmediate),
515                                kModifiedImmediate},
516                               {{al, r0, 0x02ac0000},
517                                "al r0 0x02ac0000",
518                                "ModifiedImmediate_al_r0_0x02ac0000",
519                                ARRAY_SIZE(kModifiedImmediate),
520                                kModifiedImmediate},
521                               {{al, r0, 0x05580000},
522                                "al r0 0x05580000",
523                                "ModifiedImmediate_al_r0_0x05580000",
524                                ARRAY_SIZE(kModifiedImmediate),
525                                kModifiedImmediate},
526                               {{al, r0, 0x0ab00000},
527                                "al r0 0x0ab00000",
528                                "ModifiedImmediate_al_r0_0x0ab00000",
529                                ARRAY_SIZE(kModifiedImmediate),
530                                kModifiedImmediate},
531                               {{al, r0, 0x15600000},
532                                "al r0 0x15600000",
533                                "ModifiedImmediate_al_r0_0x15600000",
534                                ARRAY_SIZE(kModifiedImmediate),
535                                kModifiedImmediate},
536                               {{al, r0, 0x2ac00000},
537                                "al r0 0x2ac00000",
538                                "ModifiedImmediate_al_r0_0x2ac00000",
539                                ARRAY_SIZE(kModifiedImmediate),
540                                kModifiedImmediate},
541                               {{al, r0, 0x55800000},
542                                "al r0 0x55800000",
543                                "ModifiedImmediate_al_r0_0x55800000",
544                                ARRAY_SIZE(kModifiedImmediate),
545                                kModifiedImmediate},
546                               {{al, r0, 0xab000000},
547                                "al r0 0xab000000",
548                                "ModifiedImmediate_al_r0_0xab000000",
549                                ARRAY_SIZE(kModifiedImmediate),
550                                kModifiedImmediate},
551                               {{al, r0, 0x000000ab},
552                                "al r0 0x000000ab",
553                                "ModifiedImmediate_al_r0_0x000000ab",
554                                ARRAY_SIZE(kModifiedImmediate),
555                                kModifiedImmediate},
556                               {{al, r0, 0x00ab00ab},
557                                "al r0 0x00ab00ab",
558                                "ModifiedImmediate_al_r0_0x00ab00ab",
559                                ARRAY_SIZE(kModifiedImmediate),
560                                kModifiedImmediate},
561                               {{al, r0, 0xab00ab00},
562                                "al r0 0xab00ab00",
563                                "ModifiedImmediate_al_r0_0xab00ab00",
564                                ARRAY_SIZE(kModifiedImmediate),
565                                kModifiedImmediate},
566                               {{al, r0, 0xabababab},
567                                "al r0 0xabababab",
568                                "ModifiedImmediate_al_r0_0xabababab",
569                                ARRAY_SIZE(kModifiedImmediate),
570                                kModifiedImmediate}};
571
572// We record all inputs to the instructions as outputs. This way, we also check
573// that what shouldn't change didn't change.
574struct TestResult {
575  size_t output_size;
576  const Inputs* outputs;
577};
578
579// These headers each contain an array of `TestResult` with the reference output
580// values. The reference arrays are names `kReference{mnemonic}`.
581#include "aarch32/traces/simulator-cond-rd-operand-const-t32-cmn.h"
582#include "aarch32/traces/simulator-cond-rd-operand-const-t32-cmp.h"
583#include "aarch32/traces/simulator-cond-rd-operand-const-t32-mov.h"
584#include "aarch32/traces/simulator-cond-rd-operand-const-t32-movs.h"
585#include "aarch32/traces/simulator-cond-rd-operand-const-t32-mvn.h"
586#include "aarch32/traces/simulator-cond-rd-operand-const-t32-mvns.h"
587#include "aarch32/traces/simulator-cond-rd-operand-const-t32-teq.h"
588#include "aarch32/traces/simulator-cond-rd-operand-const-t32-tst.h"
589
590
591// The maximum number of errors to report in detail for each test.
592const unsigned kErrorReportLimit = 8;
593
594typedef void (MacroAssembler::*Fn)(Condition cond,
595                                   Register rd,
596                                   const Operand& op);
597
598void TestHelper(Fn instruction,
599                const char* mnemonic,
600                const TestResult reference[]) {
601  SETUP();
602  masm.UseT32();
603  START();
604
605  // Data to compare to `reference`.
606  TestResult* results[ARRAY_SIZE(kTests)];
607
608  // Test cases for memory bound instructions may allocate a buffer and save its
609  // address in this array.
610  byte* scratch_memory_buffers[ARRAY_SIZE(kTests)];
611
612  // Generate a loop for each element in `kTests`. Each loop tests one specific
613  // instruction.
614  for (unsigned i = 0; i < ARRAY_SIZE(kTests); i++) {
615    // Allocate results on the heap for this test.
616    results[i] = new TestResult;
617    results[i]->outputs = new Inputs[kTests[i].input_size];
618    results[i]->output_size = kTests[i].input_size;
619
620    size_t input_stride = sizeof(kTests[i].inputs[0]) * kTests[i].input_size;
621    VIXL_ASSERT(IsUint32(input_stride));
622
623    scratch_memory_buffers[i] = NULL;
624
625    Label loop;
626    UseScratchRegisterScope scratch_registers(&masm);
627    // Include all registers from r0 ro r12.
628    scratch_registers.Include(RegisterList(0x1fff));
629
630    // Values to pass to the macro-assembler.
631    Condition cond = kTests[i].operands.cond;
632    Register rd = kTests[i].operands.rd;
633    uint32_t immediate = kTests[i].operands.immediate;
634    Operand op(immediate);
635    scratch_registers.Exclude(rd);
636
637    // Allocate reserved registers for our own use.
638    Register input_ptr = scratch_registers.Acquire();
639    Register input_end = scratch_registers.Acquire();
640    Register result_ptr = scratch_registers.Acquire();
641
642    // Initialize `input_ptr` to the first element and `input_end` the address
643    // after the array.
644    __ Mov(input_ptr, Operand::From(kTests[i].inputs));
645    __ Add(input_end, input_ptr, static_cast<uint32_t>(input_stride));
646    __ Mov(result_ptr, Operand::From(results[i]->outputs));
647    __ Bind(&loop);
648
649    {
650      UseScratchRegisterScope temp_registers(&masm);
651      Register nzcv_bits = temp_registers.Acquire();
652      Register saved_q_bit = temp_registers.Acquire();
653      // Save the `Q` bit flag.
654      __ Mrs(saved_q_bit, APSR);
655      __ And(saved_q_bit, saved_q_bit, QFlag);
656      // Set the `NZCV` and `Q` flags together.
657      __ Ldr(nzcv_bits, MemOperand(input_ptr, offsetof(Inputs, apsr)));
658      __ Orr(nzcv_bits, nzcv_bits, saved_q_bit);
659      __ Msr(APSR_nzcvq, nzcv_bits);
660    }
661    __ Ldr(rd, MemOperand(input_ptr, offsetof(Inputs, rd)));
662
663    (masm.*instruction)(cond, rd, op);
664
665    {
666      UseScratchRegisterScope temp_registers(&masm);
667      Register nzcv_bits = temp_registers.Acquire();
668      __ Mrs(nzcv_bits, APSR);
669      // Only record the NZCV bits.
670      __ And(nzcv_bits, nzcv_bits, NZCVFlag);
671      __ Str(nzcv_bits, MemOperand(result_ptr, offsetof(Inputs, apsr)));
672    }
673    __ Str(rd, MemOperand(result_ptr, offsetof(Inputs, rd)));
674
675    // Advance the result pointer.
676    __ Add(result_ptr, result_ptr, Operand::From(sizeof(kTests[i].inputs[0])));
677    // Loop back until `input_ptr` is lower than `input_base`.
678    __ Add(input_ptr, input_ptr, Operand::From(sizeof(kTests[i].inputs[0])));
679    __ Cmp(input_ptr, input_end);
680    __ B(ne, &loop);
681  }
682
683  END();
684
685  RUN();
686
687  if (Test::generate_test_trace()) {
688    // Print the results.
689    for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) {
690      printf("const Inputs kOutputs_%s_%s[] = {\n",
691             mnemonic,
692             kTests[i].identifier);
693      for (size_t j = 0; j < results[i]->output_size; j++) {
694        printf("  { ");
695        printf("0x%08" PRIx32, results[i]->outputs[j].apsr);
696        printf(", ");
697        printf("0x%08" PRIx32, results[i]->outputs[j].rd);
698        printf(" },\n");
699      }
700      printf("};\n");
701    }
702    printf("const TestResult kReference%s[] = {\n", mnemonic);
703    for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) {
704      printf("  {\n");
705      printf("    ARRAY_SIZE(kOutputs_%s_%s),\n",
706             mnemonic,
707             kTests[i].identifier);
708      printf("    kOutputs_%s_%s,\n", mnemonic, kTests[i].identifier);
709      printf("  },\n");
710    }
711    printf("};\n");
712  } else if (kCheckSimulatorTestResults) {
713    // Check the results.
714    unsigned total_error_count = 0;
715    for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) {
716      bool instruction_has_errors = false;
717      for (size_t j = 0; j < kTests[i].input_size; j++) {
718        uint32_t apsr = results[i]->outputs[j].apsr;
719        uint32_t rd = results[i]->outputs[j].rd;
720        uint32_t apsr_input = kTests[i].inputs[j].apsr;
721        uint32_t rd_input = kTests[i].inputs[j].rd;
722        uint32_t apsr_ref = reference[i].outputs[j].apsr;
723        uint32_t rd_ref = reference[i].outputs[j].rd;
724
725        if (((apsr != apsr_ref) || (rd != rd_ref)) &&
726            (++total_error_count <= kErrorReportLimit)) {
727          // Print the instruction once even if it triggered multiple failures.
728          if (!instruction_has_errors) {
729            printf("Error(s) when testing \"%s %s\":\n",
730                   mnemonic,
731                   kTests[i].operands_description);
732            instruction_has_errors = true;
733          }
734          // Print subsequent errors.
735          printf("  Input:    ");
736          printf("0x%08" PRIx32, apsr_input);
737          printf(", ");
738          printf("0x%08" PRIx32, rd_input);
739          printf("\n");
740          printf("  Expected: ");
741          printf("0x%08" PRIx32, apsr_ref);
742          printf(", ");
743          printf("0x%08" PRIx32, rd_ref);
744          printf("\n");
745          printf("  Found:    ");
746          printf("0x%08" PRIx32, apsr);
747          printf(", ");
748          printf("0x%08" PRIx32, rd);
749          printf("\n\n");
750        }
751      }
752    }
753
754    if (total_error_count > kErrorReportLimit) {
755      printf("%u other errors follow.\n",
756             total_error_count - kErrorReportLimit);
757    }
758    VIXL_CHECK(total_error_count == 0);
759  } else {
760    VIXL_WARNING("Assembled the code, but did not run anything.\n");
761  }
762
763  for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) {
764    delete[] results[i]->outputs;
765    delete results[i];
766    delete[] scratch_memory_buffers[i];
767  }
768
769  TEARDOWN();
770}
771
772// Instantiate tests for each instruction in the list.
773// TODO: Remove this limitation by having a sandboxing mechanism.
774#if defined(VIXL_HOST_POINTER_32)
775#define TEST(mnemonic)                                                      \
776  void Test_##mnemonic() {                                                  \
777    TestHelper(&MacroAssembler::mnemonic, #mnemonic, kReference##mnemonic); \
778  }                                                                         \
779  Test test_##mnemonic(                                                     \
780      "AARCH32_SIMULATOR_COND_RD_OPERAND_CONST_T32_" #mnemonic,             \
781      &Test_##mnemonic);
782#else
783#define TEST(mnemonic)                                          \
784  void Test_##mnemonic() {                                      \
785    VIXL_WARNING("This test can only run on a 32-bit host.\n"); \
786    USE(TestHelper);                                            \
787  }                                                             \
788  Test test_##mnemonic(                                         \
789      "AARCH32_SIMULATOR_COND_RD_OPERAND_CONST_T32_" #mnemonic, \
790      &Test_##mnemonic);
791#endif
792
793FOREACH_INSTRUCTION(TEST)
794#undef TEST
795
796}  // namespace
797#endif
798
799}  // namespace aarch32
800}  // namespace vixl
801