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(mvn)
     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 };
     69 
     70 // This structure contains all data needed to test one specific
     71 // instruction.
     72 struct TestData {
     73   // The `operands` field represents what to pass to the assembler to
     74   // produce the instruction.
     75   Operands operands;
     76   // True if we need to generate an IT instruction for this test to be valid.
     77   bool in_it_block;
     78   // The condition to give the IT instruction, this will be set to "al" by
     79   // default.
     80   Condition it_condition;
     81   // Description of the operands, used for error reporting.
     82   const char* operands_description;
     83   // Unique identifier, used for generating traces.
     84   const char* identifier;
     85 };
     86 
     87 struct TestResult {
     88   size_t size;
     89   const byte* encoding;
     90 };
     91 
     92 // Each element of this array produce one instruction encoding.
     93 const TestData kTests[] = {{{eq, r0, r0}, true, eq, "eq r0 r0", "eq_r0_r0"},
     94                            {{eq, r1, r1}, true, eq, "eq r1 r1", "eq_r1_r1"},
     95                            {{eq, r2, r2}, true, eq, "eq r2 r2", "eq_r2_r2"},
     96                            {{eq, r3, r3}, true, eq, "eq r3 r3", "eq_r3_r3"},
     97                            {{eq, r4, r4}, true, eq, "eq r4 r4", "eq_r4_r4"},
     98                            {{eq, r5, r5}, true, eq, "eq r5 r5", "eq_r5_r5"},
     99                            {{eq, r6, r6}, true, eq, "eq r6 r6", "eq_r6_r6"},
    100                            {{eq, r7, r7}, true, eq, "eq r7 r7", "eq_r7_r7"},
    101                            {{ne, r0, r0}, true, ne, "ne r0 r0", "ne_r0_r0"},
    102                            {{ne, r1, r1}, true, ne, "ne r1 r1", "ne_r1_r1"},
    103                            {{ne, r2, r2}, true, ne, "ne r2 r2", "ne_r2_r2"},
    104                            {{ne, r3, r3}, true, ne, "ne r3 r3", "ne_r3_r3"},
    105                            {{ne, r4, r4}, true, ne, "ne r4 r4", "ne_r4_r4"},
    106                            {{ne, r5, r5}, true, ne, "ne r5 r5", "ne_r5_r5"},
    107                            {{ne, r6, r6}, true, ne, "ne r6 r6", "ne_r6_r6"},
    108                            {{ne, r7, r7}, true, ne, "ne r7 r7", "ne_r7_r7"},
    109                            {{cs, r0, r0}, true, cs, "cs r0 r0", "cs_r0_r0"},
    110                            {{cs, r1, r1}, true, cs, "cs r1 r1", "cs_r1_r1"},
    111                            {{cs, r2, r2}, true, cs, "cs r2 r2", "cs_r2_r2"},
    112                            {{cs, r3, r3}, true, cs, "cs r3 r3", "cs_r3_r3"},
    113                            {{cs, r4, r4}, true, cs, "cs r4 r4", "cs_r4_r4"},
    114                            {{cs, r5, r5}, true, cs, "cs r5 r5", "cs_r5_r5"},
    115                            {{cs, r6, r6}, true, cs, "cs r6 r6", "cs_r6_r6"},
    116                            {{cs, r7, r7}, true, cs, "cs r7 r7", "cs_r7_r7"},
    117                            {{cc, r0, r0}, true, cc, "cc r0 r0", "cc_r0_r0"},
    118                            {{cc, r1, r1}, true, cc, "cc r1 r1", "cc_r1_r1"},
    119                            {{cc, r2, r2}, true, cc, "cc r2 r2", "cc_r2_r2"},
    120                            {{cc, r3, r3}, true, cc, "cc r3 r3", "cc_r3_r3"},
    121                            {{cc, r4, r4}, true, cc, "cc r4 r4", "cc_r4_r4"},
    122                            {{cc, r5, r5}, true, cc, "cc r5 r5", "cc_r5_r5"},
    123                            {{cc, r6, r6}, true, cc, "cc r6 r6", "cc_r6_r6"},
    124                            {{cc, r7, r7}, true, cc, "cc r7 r7", "cc_r7_r7"},
    125                            {{mi, r0, r0}, true, mi, "mi r0 r0", "mi_r0_r0"},
    126                            {{mi, r1, r1}, true, mi, "mi r1 r1", "mi_r1_r1"},
    127                            {{mi, r2, r2}, true, mi, "mi r2 r2", "mi_r2_r2"},
    128                            {{mi, r3, r3}, true, mi, "mi r3 r3", "mi_r3_r3"},
    129                            {{mi, r4, r4}, true, mi, "mi r4 r4", "mi_r4_r4"},
    130                            {{mi, r5, r5}, true, mi, "mi r5 r5", "mi_r5_r5"},
    131                            {{mi, r6, r6}, true, mi, "mi r6 r6", "mi_r6_r6"},
    132                            {{mi, r7, r7}, true, mi, "mi r7 r7", "mi_r7_r7"},
    133                            {{pl, r0, r0}, true, pl, "pl r0 r0", "pl_r0_r0"},
    134                            {{pl, r1, r1}, true, pl, "pl r1 r1", "pl_r1_r1"},
    135                            {{pl, r2, r2}, true, pl, "pl r2 r2", "pl_r2_r2"},
    136                            {{pl, r3, r3}, true, pl, "pl r3 r3", "pl_r3_r3"},
    137                            {{pl, r4, r4}, true, pl, "pl r4 r4", "pl_r4_r4"},
    138                            {{pl, r5, r5}, true, pl, "pl r5 r5", "pl_r5_r5"},
    139                            {{pl, r6, r6}, true, pl, "pl r6 r6", "pl_r6_r6"},
    140                            {{pl, r7, r7}, true, pl, "pl r7 r7", "pl_r7_r7"},
    141                            {{vs, r0, r0}, true, vs, "vs r0 r0", "vs_r0_r0"},
    142                            {{vs, r1, r1}, true, vs, "vs r1 r1", "vs_r1_r1"},
    143                            {{vs, r2, r2}, true, vs, "vs r2 r2", "vs_r2_r2"},
    144                            {{vs, r3, r3}, true, vs, "vs r3 r3", "vs_r3_r3"},
    145                            {{vs, r4, r4}, true, vs, "vs r4 r4", "vs_r4_r4"},
    146                            {{vs, r5, r5}, true, vs, "vs r5 r5", "vs_r5_r5"},
    147                            {{vs, r6, r6}, true, vs, "vs r6 r6", "vs_r6_r6"},
    148                            {{vs, r7, r7}, true, vs, "vs r7 r7", "vs_r7_r7"},
    149                            {{vc, r0, r0}, true, vc, "vc r0 r0", "vc_r0_r0"},
    150                            {{vc, r1, r1}, true, vc, "vc r1 r1", "vc_r1_r1"},
    151                            {{vc, r2, r2}, true, vc, "vc r2 r2", "vc_r2_r2"},
    152                            {{vc, r3, r3}, true, vc, "vc r3 r3", "vc_r3_r3"},
    153                            {{vc, r4, r4}, true, vc, "vc r4 r4", "vc_r4_r4"},
    154                            {{vc, r5, r5}, true, vc, "vc r5 r5", "vc_r5_r5"},
    155                            {{vc, r6, r6}, true, vc, "vc r6 r6", "vc_r6_r6"},
    156                            {{vc, r7, r7}, true, vc, "vc r7 r7", "vc_r7_r7"},
    157                            {{hi, r0, r0}, true, hi, "hi r0 r0", "hi_r0_r0"},
    158                            {{hi, r1, r1}, true, hi, "hi r1 r1", "hi_r1_r1"},
    159                            {{hi, r2, r2}, true, hi, "hi r2 r2", "hi_r2_r2"},
    160                            {{hi, r3, r3}, true, hi, "hi r3 r3", "hi_r3_r3"},
    161                            {{hi, r4, r4}, true, hi, "hi r4 r4", "hi_r4_r4"},
    162                            {{hi, r5, r5}, true, hi, "hi r5 r5", "hi_r5_r5"},
    163                            {{hi, r6, r6}, true, hi, "hi r6 r6", "hi_r6_r6"},
    164                            {{hi, r7, r7}, true, hi, "hi r7 r7", "hi_r7_r7"},
    165                            {{ls, r0, r0}, true, ls, "ls r0 r0", "ls_r0_r0"},
    166                            {{ls, r1, r1}, true, ls, "ls r1 r1", "ls_r1_r1"},
    167                            {{ls, r2, r2}, true, ls, "ls r2 r2", "ls_r2_r2"},
    168                            {{ls, r3, r3}, true, ls, "ls r3 r3", "ls_r3_r3"},
    169                            {{ls, r4, r4}, true, ls, "ls r4 r4", "ls_r4_r4"},
    170                            {{ls, r5, r5}, true, ls, "ls r5 r5", "ls_r5_r5"},
    171                            {{ls, r6, r6}, true, ls, "ls r6 r6", "ls_r6_r6"},
    172                            {{ls, r7, r7}, true, ls, "ls r7 r7", "ls_r7_r7"},
    173                            {{ge, r0, r0}, true, ge, "ge r0 r0", "ge_r0_r0"},
    174                            {{ge, r1, r1}, true, ge, "ge r1 r1", "ge_r1_r1"},
    175                            {{ge, r2, r2}, true, ge, "ge r2 r2", "ge_r2_r2"},
    176                            {{ge, r3, r3}, true, ge, "ge r3 r3", "ge_r3_r3"},
    177                            {{ge, r4, r4}, true, ge, "ge r4 r4", "ge_r4_r4"},
    178                            {{ge, r5, r5}, true, ge, "ge r5 r5", "ge_r5_r5"},
    179                            {{ge, r6, r6}, true, ge, "ge r6 r6", "ge_r6_r6"},
    180                            {{ge, r7, r7}, true, ge, "ge r7 r7", "ge_r7_r7"},
    181                            {{lt, r0, r0}, true, lt, "lt r0 r0", "lt_r0_r0"},
    182                            {{lt, r1, r1}, true, lt, "lt r1 r1", "lt_r1_r1"},
    183                            {{lt, r2, r2}, true, lt, "lt r2 r2", "lt_r2_r2"},
    184                            {{lt, r3, r3}, true, lt, "lt r3 r3", "lt_r3_r3"},
    185                            {{lt, r4, r4}, true, lt, "lt r4 r4", "lt_r4_r4"},
    186                            {{lt, r5, r5}, true, lt, "lt r5 r5", "lt_r5_r5"},
    187                            {{lt, r6, r6}, true, lt, "lt r6 r6", "lt_r6_r6"},
    188                            {{lt, r7, r7}, true, lt, "lt r7 r7", "lt_r7_r7"},
    189                            {{gt, r0, r0}, true, gt, "gt r0 r0", "gt_r0_r0"},
    190                            {{gt, r1, r1}, true, gt, "gt r1 r1", "gt_r1_r1"},
    191                            {{gt, r2, r2}, true, gt, "gt r2 r2", "gt_r2_r2"},
    192                            {{gt, r3, r3}, true, gt, "gt r3 r3", "gt_r3_r3"},
    193                            {{gt, r4, r4}, true, gt, "gt r4 r4", "gt_r4_r4"},
    194                            {{gt, r5, r5}, true, gt, "gt r5 r5", "gt_r5_r5"},
    195                            {{gt, r6, r6}, true, gt, "gt r6 r6", "gt_r6_r6"},
    196                            {{gt, r7, r7}, true, gt, "gt r7 r7", "gt_r7_r7"},
    197                            {{le, r0, r0}, true, le, "le r0 r0", "le_r0_r0"},
    198                            {{le, r1, r1}, true, le, "le r1 r1", "le_r1_r1"},
    199                            {{le, r2, r2}, true, le, "le r2 r2", "le_r2_r2"},
    200                            {{le, r3, r3}, true, le, "le r3 r3", "le_r3_r3"},
    201                            {{le, r4, r4}, true, le, "le r4 r4", "le_r4_r4"},
    202                            {{le, r5, r5}, true, le, "le r5 r5", "le_r5_r5"},
    203                            {{le, r6, r6}, true, le, "le r6 r6", "le_r6_r6"},
    204                            {{le, r7, r7}, true, le, "le r7 r7", "le_r7_r7"}};
    205 
    206 // These headers each contain an array of `TestResult` with the reference output
    207 // values. The reference arrays are names `kReference{mnemonic}`.
    208 #include "aarch32/traces/assembler-cond-rd-operand-rn-identical-low-registers-in-it-block-mvn-t32.h"
    209 
    210 
    211 // The maximum number of errors to report in detail for each test.
    212 const unsigned kErrorReportLimit = 8;
    213 
    214 typedef void (MacroAssembler::*Fn)(Condition cond,
    215                                    Register rd,
    216                                    const Operand& op);
    217 
    218 void TestHelper(Fn instruction,
    219                 const char* mnemonic,
    220                 const TestResult reference[]) {
    221   unsigned total_error_count = 0;
    222   MacroAssembler masm(BUF_SIZE);
    223 
    224   masm.UseT32();
    225 
    226   for (unsigned i = 0; i < ARRAY_SIZE(kTests); i++) {
    227     // Values to pass to the macro-assembler.
    228     Condition cond = kTests[i].operands.cond;
    229     Register rd = kTests[i].operands.rd;
    230     Register rn = kTests[i].operands.rn;
    231     Operand op(rn);
    232 
    233     int32_t start = masm.GetCursorOffset();
    234     {
    235       // We never generate more that 4 bytes, as IT instructions are only
    236       // allowed for narrow encodings.
    237       ExactAssemblyScope scope(&masm, 4, ExactAssemblyScope::kMaximumSize);
    238       if (kTests[i].in_it_block) {
    239         masm.it(kTests[i].it_condition);
    240       }
    241       (masm.*instruction)(cond, rd, op);
    242     }
    243     int32_t end = masm.GetCursorOffset();
    244 
    245     const byte* result_ptr =
    246         masm.GetBuffer()->GetOffsetAddress<const byte*>(start);
    247     VIXL_ASSERT(start < end);
    248     uint32_t result_size = end - start;
    249 
    250     if (Test::generate_test_trace()) {
    251       // Print the result bytes.
    252       printf("const byte kInstruction_%s_%s[] = {\n",
    253              mnemonic,
    254              kTests[i].identifier);
    255       for (uint32_t j = 0; j < result_size; j++) {
    256         if (j == 0) {
    257           printf("  0x%02" PRIx8, result_ptr[j]);
    258         } else {
    259           printf(", 0x%02" PRIx8, result_ptr[j]);
    260         }
    261       }
    262       // This comment is meant to be used by external tools to validate
    263       // the encoding. We can parse the comment to figure out what
    264       // instruction this corresponds to.
    265       if (kTests[i].in_it_block) {
    266         printf(" // It %s; %s %s\n};\n",
    267                kTests[i].it_condition.GetName(),
    268                mnemonic,
    269                kTests[i].operands_description);
    270       } else {
    271         printf(" // %s %s\n};\n", mnemonic, kTests[i].operands_description);
    272       }
    273     } else {
    274       // Check we've emitted the exact same encoding as present in the
    275       // trace file. Only print up to `kErrorReportLimit` errors.
    276       if (((result_size != reference[i].size) ||
    277            (memcmp(result_ptr, reference[i].encoding, reference[i].size) !=
    278             0)) &&
    279           (++total_error_count <= kErrorReportLimit)) {
    280         printf("Error when testing \"%s\" with operands \"%s\":\n",
    281                mnemonic,
    282                kTests[i].operands_description);
    283         printf("  Expected: ");
    284         for (uint32_t j = 0; j < reference[i].size; j++) {
    285           if (j == 0) {
    286             printf("0x%02" PRIx8, reference[i].encoding[j]);
    287           } else {
    288             printf(", 0x%02" PRIx8, reference[i].encoding[j]);
    289           }
    290         }
    291         printf("\n");
    292         printf("  Found:    ");
    293         for (uint32_t j = 0; j < result_size; j++) {
    294           if (j == 0) {
    295             printf("0x%02" PRIx8, result_ptr[j]);
    296           } else {
    297             printf(", 0x%02" PRIx8, result_ptr[j]);
    298           }
    299         }
    300         printf("\n");
    301       }
    302     }
    303   }
    304 
    305   masm.FinalizeCode();
    306 
    307   if (Test::generate_test_trace()) {
    308     // Finalize the trace file by writing the final `TestResult` array
    309     // which links all generated instruction encodings.
    310     printf("const TestResult kReference%s[] = {\n", mnemonic);
    311     for (unsigned i = 0; i < ARRAY_SIZE(kTests); i++) {
    312       printf("  {\n");
    313       printf("    ARRAY_SIZE(kInstruction_%s_%s),\n",
    314              mnemonic,
    315              kTests[i].identifier);
    316       printf("    kInstruction_%s_%s,\n", mnemonic, kTests[i].identifier);
    317       printf("  },\n");
    318     }
    319     printf("};\n");
    320   } else {
    321     if (total_error_count > kErrorReportLimit) {
    322       printf("%u other errors follow.\n",
    323              total_error_count - kErrorReportLimit);
    324     }
    325     // Crash if the test failed.
    326     VIXL_CHECK(total_error_count == 0);
    327   }
    328 }
    329 
    330 // Instantiate tests for each instruction in the list.
    331 #define TEST(mnemonic)                                                      \
    332   void Test_##mnemonic() {                                                  \
    333     TestHelper(&MacroAssembler::mnemonic, #mnemonic, kReference##mnemonic); \
    334   }                                                                         \
    335   Test test_##mnemonic(                                                     \
    336       "AARCH32_ASSEMBLER_COND_RD_OPERAND_RN_IDENTICAL_LOW_REGISTERS_IN_IT_" \
    337       "BLOCK_" #mnemonic "_T32",                                            \
    338       &Test_##mnemonic);
    339 FOREACH_INSTRUCTION(TEST)
    340 #undef TEST
    341 
    342 }  // namespace
    343 #endif
    344 
    345 }  // namespace aarch32
    346 }  // namespace vixl
    347