Home | History | Annotate | Download | only in aarch32
      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 
     47 namespace vixl {
     48 namespace aarch32 {
     49 
     50 // List of instruction mnemonics.
     51 #define FOREACH_INSTRUCTION(M) M(add)
     52 
     53 
     54 // The following definitions are defined again in each generated test, therefore
     55 // we need to place them in an anomymous 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
     61 namespace {
     62 
     63 // Values to be passed to the assembler to produce the instruction under test.
     64 struct Operands {
     65   Condition cond;
     66   Register rd;
     67   Register rn;
     68   Register rm;
     69 };
     70 
     71 // This structure contains all data needed to test one specific
     72 // instruction.
     73 struct TestData {
     74   // The `operands` field represents what to pass to the assembler to
     75   // produce the instruction.
     76   Operands operands;
     77   // True if we need to generate an IT instruction for this test to be valid.
     78   bool in_it_block;
     79   // The condition to give the IT instruction, this will be set to "al" by
     80   // default.
     81   Condition it_condition;
     82   // Description of the operands, used for error reporting.
     83   const char* operands_description;
     84   // Unique identifier, used for generating traces.
     85   const char* identifier;
     86 };
     87 
     88 struct TestResult {
     89   size_t size;
     90   const byte* encoding;
     91 };
     92 
     93 // Each element of this array produce one instruction encoding.
     94 const TestData kTests[] =
     95     {{{eq, r0, r13, r0}, true, eq, "eq r0 r13 r0", "eq_r0_r13_r0"},
     96      {{eq, r1, r13, r1}, true, eq, "eq r1 r13 r1", "eq_r1_r13_r1"},
     97      {{eq, r2, r13, r2}, true, eq, "eq r2 r13 r2", "eq_r2_r13_r2"},
     98      {{eq, r3, r13, r3}, true, eq, "eq r3 r13 r3", "eq_r3_r13_r3"},
     99      {{eq, r4, r13, r4}, true, eq, "eq r4 r13 r4", "eq_r4_r13_r4"},
    100      {{eq, r5, r13, r5}, true, eq, "eq r5 r13 r5", "eq_r5_r13_r5"},
    101      {{eq, r6, r13, r6}, true, eq, "eq r6 r13 r6", "eq_r6_r13_r6"},
    102      {{eq, r7, r13, r7}, true, eq, "eq r7 r13 r7", "eq_r7_r13_r7"},
    103      {{ne, r0, r13, r0}, true, ne, "ne r0 r13 r0", "ne_r0_r13_r0"},
    104      {{ne, r1, r13, r1}, true, ne, "ne r1 r13 r1", "ne_r1_r13_r1"},
    105      {{ne, r2, r13, r2}, true, ne, "ne r2 r13 r2", "ne_r2_r13_r2"},
    106      {{ne, r3, r13, r3}, true, ne, "ne r3 r13 r3", "ne_r3_r13_r3"},
    107      {{ne, r4, r13, r4}, true, ne, "ne r4 r13 r4", "ne_r4_r13_r4"},
    108      {{ne, r5, r13, r5}, true, ne, "ne r5 r13 r5", "ne_r5_r13_r5"},
    109      {{ne, r6, r13, r6}, true, ne, "ne r6 r13 r6", "ne_r6_r13_r6"},
    110      {{ne, r7, r13, r7}, true, ne, "ne r7 r13 r7", "ne_r7_r13_r7"},
    111      {{cs, r0, r13, r0}, true, cs, "cs r0 r13 r0", "cs_r0_r13_r0"},
    112      {{cs, r1, r13, r1}, true, cs, "cs r1 r13 r1", "cs_r1_r13_r1"},
    113      {{cs, r2, r13, r2}, true, cs, "cs r2 r13 r2", "cs_r2_r13_r2"},
    114      {{cs, r3, r13, r3}, true, cs, "cs r3 r13 r3", "cs_r3_r13_r3"},
    115      {{cs, r4, r13, r4}, true, cs, "cs r4 r13 r4", "cs_r4_r13_r4"},
    116      {{cs, r5, r13, r5}, true, cs, "cs r5 r13 r5", "cs_r5_r13_r5"},
    117      {{cs, r6, r13, r6}, true, cs, "cs r6 r13 r6", "cs_r6_r13_r6"},
    118      {{cs, r7, r13, r7}, true, cs, "cs r7 r13 r7", "cs_r7_r13_r7"},
    119      {{cc, r0, r13, r0}, true, cc, "cc r0 r13 r0", "cc_r0_r13_r0"},
    120      {{cc, r1, r13, r1}, true, cc, "cc r1 r13 r1", "cc_r1_r13_r1"},
    121      {{cc, r2, r13, r2}, true, cc, "cc r2 r13 r2", "cc_r2_r13_r2"},
    122      {{cc, r3, r13, r3}, true, cc, "cc r3 r13 r3", "cc_r3_r13_r3"},
    123      {{cc, r4, r13, r4}, true, cc, "cc r4 r13 r4", "cc_r4_r13_r4"},
    124      {{cc, r5, r13, r5}, true, cc, "cc r5 r13 r5", "cc_r5_r13_r5"},
    125      {{cc, r6, r13, r6}, true, cc, "cc r6 r13 r6", "cc_r6_r13_r6"},
    126      {{cc, r7, r13, r7}, true, cc, "cc r7 r13 r7", "cc_r7_r13_r7"},
    127      {{mi, r0, r13, r0}, true, mi, "mi r0 r13 r0", "mi_r0_r13_r0"},
    128      {{mi, r1, r13, r1}, true, mi, "mi r1 r13 r1", "mi_r1_r13_r1"},
    129      {{mi, r2, r13, r2}, true, mi, "mi r2 r13 r2", "mi_r2_r13_r2"},
    130      {{mi, r3, r13, r3}, true, mi, "mi r3 r13 r3", "mi_r3_r13_r3"},
    131      {{mi, r4, r13, r4}, true, mi, "mi r4 r13 r4", "mi_r4_r13_r4"},
    132      {{mi, r5, r13, r5}, true, mi, "mi r5 r13 r5", "mi_r5_r13_r5"},
    133      {{mi, r6, r13, r6}, true, mi, "mi r6 r13 r6", "mi_r6_r13_r6"},
    134      {{mi, r7, r13, r7}, true, mi, "mi r7 r13 r7", "mi_r7_r13_r7"},
    135      {{pl, r0, r13, r0}, true, pl, "pl r0 r13 r0", "pl_r0_r13_r0"},
    136      {{pl, r1, r13, r1}, true, pl, "pl r1 r13 r1", "pl_r1_r13_r1"},
    137      {{pl, r2, r13, r2}, true, pl, "pl r2 r13 r2", "pl_r2_r13_r2"},
    138      {{pl, r3, r13, r3}, true, pl, "pl r3 r13 r3", "pl_r3_r13_r3"},
    139      {{pl, r4, r13, r4}, true, pl, "pl r4 r13 r4", "pl_r4_r13_r4"},
    140      {{pl, r5, r13, r5}, true, pl, "pl r5 r13 r5", "pl_r5_r13_r5"},
    141      {{pl, r6, r13, r6}, true, pl, "pl r6 r13 r6", "pl_r6_r13_r6"},
    142      {{pl, r7, r13, r7}, true, pl, "pl r7 r13 r7", "pl_r7_r13_r7"},
    143      {{vs, r0, r13, r0}, true, vs, "vs r0 r13 r0", "vs_r0_r13_r0"},
    144      {{vs, r1, r13, r1}, true, vs, "vs r1 r13 r1", "vs_r1_r13_r1"},
    145      {{vs, r2, r13, r2}, true, vs, "vs r2 r13 r2", "vs_r2_r13_r2"},
    146      {{vs, r3, r13, r3}, true, vs, "vs r3 r13 r3", "vs_r3_r13_r3"},
    147      {{vs, r4, r13, r4}, true, vs, "vs r4 r13 r4", "vs_r4_r13_r4"},
    148      {{vs, r5, r13, r5}, true, vs, "vs r5 r13 r5", "vs_r5_r13_r5"},
    149      {{vs, r6, r13, r6}, true, vs, "vs r6 r13 r6", "vs_r6_r13_r6"},
    150      {{vs, r7, r13, r7}, true, vs, "vs r7 r13 r7", "vs_r7_r13_r7"},
    151      {{vc, r0, r13, r0}, true, vc, "vc r0 r13 r0", "vc_r0_r13_r0"},
    152      {{vc, r1, r13, r1}, true, vc, "vc r1 r13 r1", "vc_r1_r13_r1"},
    153      {{vc, r2, r13, r2}, true, vc, "vc r2 r13 r2", "vc_r2_r13_r2"},
    154      {{vc, r3, r13, r3}, true, vc, "vc r3 r13 r3", "vc_r3_r13_r3"},
    155      {{vc, r4, r13, r4}, true, vc, "vc r4 r13 r4", "vc_r4_r13_r4"},
    156      {{vc, r5, r13, r5}, true, vc, "vc r5 r13 r5", "vc_r5_r13_r5"},
    157      {{vc, r6, r13, r6}, true, vc, "vc r6 r13 r6", "vc_r6_r13_r6"},
    158      {{vc, r7, r13, r7}, true, vc, "vc r7 r13 r7", "vc_r7_r13_r7"},
    159      {{hi, r0, r13, r0}, true, hi, "hi r0 r13 r0", "hi_r0_r13_r0"},
    160      {{hi, r1, r13, r1}, true, hi, "hi r1 r13 r1", "hi_r1_r13_r1"},
    161      {{hi, r2, r13, r2}, true, hi, "hi r2 r13 r2", "hi_r2_r13_r2"},
    162      {{hi, r3, r13, r3}, true, hi, "hi r3 r13 r3", "hi_r3_r13_r3"},
    163      {{hi, r4, r13, r4}, true, hi, "hi r4 r13 r4", "hi_r4_r13_r4"},
    164      {{hi, r5, r13, r5}, true, hi, "hi r5 r13 r5", "hi_r5_r13_r5"},
    165      {{hi, r6, r13, r6}, true, hi, "hi r6 r13 r6", "hi_r6_r13_r6"},
    166      {{hi, r7, r13, r7}, true, hi, "hi r7 r13 r7", "hi_r7_r13_r7"},
    167      {{ls, r0, r13, r0}, true, ls, "ls r0 r13 r0", "ls_r0_r13_r0"},
    168      {{ls, r1, r13, r1}, true, ls, "ls r1 r13 r1", "ls_r1_r13_r1"},
    169      {{ls, r2, r13, r2}, true, ls, "ls r2 r13 r2", "ls_r2_r13_r2"},
    170      {{ls, r3, r13, r3}, true, ls, "ls r3 r13 r3", "ls_r3_r13_r3"},
    171      {{ls, r4, r13, r4}, true, ls, "ls r4 r13 r4", "ls_r4_r13_r4"},
    172      {{ls, r5, r13, r5}, true, ls, "ls r5 r13 r5", "ls_r5_r13_r5"},
    173      {{ls, r6, r13, r6}, true, ls, "ls r6 r13 r6", "ls_r6_r13_r6"},
    174      {{ls, r7, r13, r7}, true, ls, "ls r7 r13 r7", "ls_r7_r13_r7"},
    175      {{ge, r0, r13, r0}, true, ge, "ge r0 r13 r0", "ge_r0_r13_r0"},
    176      {{ge, r1, r13, r1}, true, ge, "ge r1 r13 r1", "ge_r1_r13_r1"},
    177      {{ge, r2, r13, r2}, true, ge, "ge r2 r13 r2", "ge_r2_r13_r2"},
    178      {{ge, r3, r13, r3}, true, ge, "ge r3 r13 r3", "ge_r3_r13_r3"},
    179      {{ge, r4, r13, r4}, true, ge, "ge r4 r13 r4", "ge_r4_r13_r4"},
    180      {{ge, r5, r13, r5}, true, ge, "ge r5 r13 r5", "ge_r5_r13_r5"},
    181      {{ge, r6, r13, r6}, true, ge, "ge r6 r13 r6", "ge_r6_r13_r6"},
    182      {{ge, r7, r13, r7}, true, ge, "ge r7 r13 r7", "ge_r7_r13_r7"},
    183      {{lt, r0, r13, r0}, true, lt, "lt r0 r13 r0", "lt_r0_r13_r0"},
    184      {{lt, r1, r13, r1}, true, lt, "lt r1 r13 r1", "lt_r1_r13_r1"},
    185      {{lt, r2, r13, r2}, true, lt, "lt r2 r13 r2", "lt_r2_r13_r2"},
    186      {{lt, r3, r13, r3}, true, lt, "lt r3 r13 r3", "lt_r3_r13_r3"},
    187      {{lt, r4, r13, r4}, true, lt, "lt r4 r13 r4", "lt_r4_r13_r4"},
    188      {{lt, r5, r13, r5}, true, lt, "lt r5 r13 r5", "lt_r5_r13_r5"},
    189      {{lt, r6, r13, r6}, true, lt, "lt r6 r13 r6", "lt_r6_r13_r6"},
    190      {{lt, r7, r13, r7}, true, lt, "lt r7 r13 r7", "lt_r7_r13_r7"},
    191      {{gt, r0, r13, r0}, true, gt, "gt r0 r13 r0", "gt_r0_r13_r0"},
    192      {{gt, r1, r13, r1}, true, gt, "gt r1 r13 r1", "gt_r1_r13_r1"},
    193      {{gt, r2, r13, r2}, true, gt, "gt r2 r13 r2", "gt_r2_r13_r2"},
    194      {{gt, r3, r13, r3}, true, gt, "gt r3 r13 r3", "gt_r3_r13_r3"},
    195      {{gt, r4, r13, r4}, true, gt, "gt r4 r13 r4", "gt_r4_r13_r4"},
    196      {{gt, r5, r13, r5}, true, gt, "gt r5 r13 r5", "gt_r5_r13_r5"},
    197      {{gt, r6, r13, r6}, true, gt, "gt r6 r13 r6", "gt_r6_r13_r6"},
    198      {{gt, r7, r13, r7}, true, gt, "gt r7 r13 r7", "gt_r7_r13_r7"},
    199      {{le, r0, r13, r0}, true, le, "le r0 r13 r0", "le_r0_r13_r0"},
    200      {{le, r1, r13, r1}, true, le, "le r1 r13 r1", "le_r1_r13_r1"},
    201      {{le, r2, r13, r2}, true, le, "le r2 r13 r2", "le_r2_r13_r2"},
    202      {{le, r3, r13, r3}, true, le, "le r3 r13 r3", "le_r3_r13_r3"},
    203      {{le, r4, r13, r4}, true, le, "le r4 r13 r4", "le_r4_r13_r4"},
    204      {{le, r5, r13, r5}, true, le, "le r5 r13 r5", "le_r5_r13_r5"},
    205      {{le, r6, r13, r6}, true, le, "le r6 r13 r6", "le_r6_r13_r6"},
    206      {{le, r7, r13, r7}, true, le, "le r7 r13 r7", "le_r7_r13_r7"}};
    207 
    208 // These headers each contain an array of `TestResult` with the reference output
    209 // values. The reference arrays are names `kReference{mnemonic}`.
    210 #include "aarch32/traces/assembler-cond-rd-rn-operand-rm-rn-is-sp-in-it-block-add-t32.h"
    211 
    212 
    213 // The maximum number of errors to report in detail for each test.
    214 const unsigned kErrorReportLimit = 8;
    215 
    216 typedef void (MacroAssembler::*Fn)(Condition cond,
    217                                    Register rd,
    218                                    Register rn,
    219                                    const Operand& op);
    220 
    221 void TestHelper(Fn instruction,
    222                 const char* mnemonic,
    223                 const TestResult reference[]) {
    224   unsigned total_error_count = 0;
    225   MacroAssembler masm(BUF_SIZE);
    226 
    227   masm.UseT32();
    228 
    229   for (unsigned i = 0; i < ARRAY_SIZE(kTests); i++) {
    230     // Values to pass to the macro-assembler.
    231     Condition cond = kTests[i].operands.cond;
    232     Register rd = kTests[i].operands.rd;
    233     Register rn = kTests[i].operands.rn;
    234     Register rm = kTests[i].operands.rm;
    235     Operand op(rm);
    236 
    237     int32_t start = masm.GetCursorOffset();
    238     {
    239       // We never generate more that 4 bytes, as IT instructions are only
    240       // allowed for narrow encodings.
    241       ExactAssemblyScope scope(&masm, 4, ExactAssemblyScope::kMaximumSize);
    242       if (kTests[i].in_it_block) {
    243         masm.it(kTests[i].it_condition);
    244       }
    245       (masm.*instruction)(cond, rd, rn, op);
    246     }
    247     int32_t end = masm.GetCursorOffset();
    248 
    249     const byte* result_ptr =
    250         masm.GetBuffer()->GetOffsetAddress<const byte*>(start);
    251     VIXL_ASSERT(start < end);
    252     uint32_t result_size = end - start;
    253 
    254     if (Test::generate_test_trace()) {
    255       // Print the result bytes.
    256       printf("const byte kInstruction_%s_%s[] = {\n",
    257              mnemonic,
    258              kTests[i].identifier);
    259       for (uint32_t j = 0; j < result_size; j++) {
    260         if (j == 0) {
    261           printf("  0x%02" PRIx8, result_ptr[j]);
    262         } else {
    263           printf(", 0x%02" PRIx8, result_ptr[j]);
    264         }
    265       }
    266       // This comment is meant to be used by external tools to validate
    267       // the encoding. We can parse the comment to figure out what
    268       // instruction this corresponds to.
    269       if (kTests[i].in_it_block) {
    270         printf(" // It %s; %s %s\n};\n",
    271                kTests[i].it_condition.GetName(),
    272                mnemonic,
    273                kTests[i].operands_description);
    274       } else {
    275         printf(" // %s %s\n};\n", mnemonic, kTests[i].operands_description);
    276       }
    277     } else {
    278       // Check we've emitted the exact same encoding as present in the
    279       // trace file. Only print up to `kErrorReportLimit` errors.
    280       if (((result_size != reference[i].size) ||
    281            (memcmp(result_ptr, reference[i].encoding, reference[i].size) !=
    282             0)) &&
    283           (++total_error_count <= kErrorReportLimit)) {
    284         printf("Error when testing \"%s\" with operands \"%s\":\n",
    285                mnemonic,
    286                kTests[i].operands_description);
    287         printf("  Expected: ");
    288         for (uint32_t j = 0; j < reference[i].size; j++) {
    289           if (j == 0) {
    290             printf("0x%02" PRIx8, reference[i].encoding[j]);
    291           } else {
    292             printf(", 0x%02" PRIx8, reference[i].encoding[j]);
    293           }
    294         }
    295         printf("\n");
    296         printf("  Found:    ");
    297         for (uint32_t j = 0; j < result_size; j++) {
    298           if (j == 0) {
    299             printf("0x%02" PRIx8, result_ptr[j]);
    300           } else {
    301             printf(", 0x%02" PRIx8, result_ptr[j]);
    302           }
    303         }
    304         printf("\n");
    305       }
    306     }
    307   }
    308 
    309   masm.FinalizeCode();
    310 
    311   if (Test::generate_test_trace()) {
    312     // Finalize the trace file by writing the final `TestResult` array
    313     // which links all generated instruction encodings.
    314     printf("const TestResult kReference%s[] = {\n", mnemonic);
    315     for (unsigned i = 0; i < ARRAY_SIZE(kTests); i++) {
    316       printf("  {\n");
    317       printf("    ARRAY_SIZE(kInstruction_%s_%s),\n",
    318              mnemonic,
    319              kTests[i].identifier);
    320       printf("    kInstruction_%s_%s,\n", mnemonic, kTests[i].identifier);
    321       printf("  },\n");
    322     }
    323     printf("};\n");
    324   } else {
    325     if (total_error_count > kErrorReportLimit) {
    326       printf("%u other errors follow.\n",
    327              total_error_count - kErrorReportLimit);
    328     }
    329     // Crash if the test failed.
    330     VIXL_CHECK(total_error_count == 0);
    331   }
    332 }
    333 
    334 // Instantiate tests for each instruction in the list.
    335 #define TEST(mnemonic)                                                      \
    336   void Test_##mnemonic() {                                                  \
    337     TestHelper(&MacroAssembler::mnemonic, #mnemonic, kReference##mnemonic); \
    338   }                                                                         \
    339   Test test_##mnemonic(                                                     \
    340       "AARCH32_ASSEMBLER_COND_RD_RN_OPERAND_RM_RN_IS_SP_IN_IT_"             \
    341       "BLOCK_" #mnemonic "_T32",                                            \
    342       &Test_##mnemonic);
    343 FOREACH_INSTRUCTION(TEST)
    344 #undef TEST
    345 
    346 }  // namespace
    347 #endif
    348 
    349 }  // namespace aarch32
    350 }  // namespace vixl
    351