Home | History | Annotate | Download | only in assembler
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <stdio.h>
     30 #include <stdlib.h>
     31 #include <string.h>
     32 #include <unistd.h>
     33 #include <errno.h>
     34 
     35 #include <sys/mman.h>
     36 #include <cutils/ashmem.h>
     37 #include <cutils/atomic.h>
     38 
     39 #define __STDC_FORMAT_MACROS
     40 #include <inttypes.h>
     41 
     42 #include "codeflinger/ARMAssemblerInterface.h"
     43 #include "codeflinger/Arm64Assembler.h"
     44 using namespace android;
     45 
     46 #define TESTS_DATAOP_ENABLE             1
     47 #define TESTS_DATATRANSFER_ENABLE       1
     48 #define TESTS_LDMSTM_ENABLE             1
     49 #define TESTS_REG_CORRUPTION_ENABLE     0
     50 
     51 void *instrMem;
     52 uint32_t  instrMemSize = 128 * 1024;
     53 char     dataMem[8192];
     54 
     55 typedef void (*asm_function_t)();
     56 extern "C" void asm_test_jacket(asm_function_t function,
     57                                 int64_t regs[], int32_t flags[]);
     58 
     59 #define MAX_32BIT (uint32_t)(((uint64_t)1 << 32) - 1)
     60 const uint32_t NA = 0;
     61 const uint32_t NUM_REGS = 32;
     62 const uint32_t NUM_FLAGS = 16;
     63 
     64 enum instr_t
     65 {
     66     INSTR_ADD,
     67     INSTR_SUB,
     68     INSTR_AND,
     69     INSTR_ORR,
     70     INSTR_RSB,
     71     INSTR_BIC,
     72     INSTR_CMP,
     73     INSTR_MOV,
     74     INSTR_MVN,
     75     INSTR_MUL,
     76     INSTR_MLA,
     77     INSTR_SMULBB,
     78     INSTR_SMULBT,
     79     INSTR_SMULTB,
     80     INSTR_SMULTT,
     81     INSTR_SMULWB,
     82     INSTR_SMULWT,
     83     INSTR_SMLABB,
     84     INSTR_UXTB16,
     85     INSTR_UBFX,
     86     INSTR_ADDR_ADD,
     87     INSTR_ADDR_SUB,
     88     INSTR_LDR,
     89     INSTR_LDRB,
     90     INSTR_LDRH,
     91     INSTR_ADDR_LDR,
     92     INSTR_LDM,
     93     INSTR_STR,
     94     INSTR_STRB,
     95     INSTR_STRH,
     96     INSTR_ADDR_STR,
     97     INSTR_STM
     98 };
     99 
    100 enum shift_t
    101 {
    102     SHIFT_LSL,
    103     SHIFT_LSR,
    104     SHIFT_ASR,
    105     SHIFT_ROR,
    106     SHIFT_NONE
    107 };
    108 
    109 enum offset_t
    110 {
    111     REG_SCALE_OFFSET,
    112     REG_OFFSET,
    113     IMM8_OFFSET,
    114     IMM12_OFFSET,
    115     NO_OFFSET
    116 };
    117 
    118 enum cond_t
    119 {
    120     EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV,
    121     HS = CS,
    122     LO = CC
    123 };
    124 
    125 const char * cc_code[] =
    126 {
    127     "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC",
    128     "HI", "LS","GE","LT", "GT", "LE", "AL", "NV"
    129 };
    130 
    131 
    132 struct dataOpTest_t
    133 {
    134     uint32_t id;
    135     instr_t  op;
    136     uint32_t preFlag;
    137     cond_t   cond;
    138     bool     setFlags;
    139     uint64_t RnValue;
    140     uint64_t RsValue;
    141     bool     immediate;
    142     uint32_t immValue;
    143     uint64_t RmValue;
    144     uint32_t shiftMode;
    145     uint32_t shiftAmount;
    146     uint64_t RdValue;
    147     bool     checkRd;
    148     uint64_t postRdValue;
    149     bool     checkFlag;
    150     uint32_t postFlag;
    151 };
    152 
    153 struct dataTransferTest_t
    154 {
    155     uint32_t id;
    156     instr_t op;
    157     uint32_t preFlag;
    158     cond_t   cond;
    159     bool     setMem;
    160     uint64_t memOffset;
    161     uint64_t memValue;
    162     uint64_t RnValue;
    163     offset_t offsetType;
    164     uint64_t RmValue;
    165     uint32_t immValue;
    166     bool     writeBack;
    167     bool     preIndex;
    168     bool     postIndex;
    169     uint64_t RdValue;
    170     uint64_t postRdValue;
    171     uint64_t postRnValue;
    172     bool     checkMem;
    173     uint64_t postMemOffset;
    174     uint32_t postMemLength;
    175     uint64_t postMemValue;
    176 };
    177 
    178 
    179 dataOpTest_t dataOpTests [] =
    180 {
    181      {0xA000,INSTR_ADD,AL,AL,0,1,NA,1,MAX_32BIT ,NA,NA,NA,NA,1,0,0,0},
    182      {0xA001,INSTR_ADD,AL,AL,0,1,NA,1,MAX_32BIT -1,NA,NA,NA,NA,1,MAX_32BIT,0,0},
    183      {0xA002,INSTR_ADD,AL,AL,0,1,NA,0,NA,MAX_32BIT ,NA,NA,NA,1,0,0,0},
    184      {0xA003,INSTR_ADD,AL,AL,0,1,NA,0,NA,MAX_32BIT -1,NA,NA,NA,1,MAX_32BIT,0,0},
    185      {0xA004,INSTR_ADD,AL,AL,0,1,NA,0,0,MAX_32BIT ,SHIFT_LSL,0,NA,1,0,0,0},
    186      {0xA005,INSTR_ADD,AL,AL,0,1,NA,0,0,MAX_32BIT ,SHIFT_LSL,31,NA,1,0x80000001,0,0},
    187      {0xA006,INSTR_ADD,AL,AL,0,1,NA,0,0,3,SHIFT_LSR,1,NA,1,2,0,0},
    188      {0xA007,INSTR_ADD,AL,AL,0,1,NA,0,0,MAX_32BIT ,SHIFT_LSR,31,NA,1,2,0,0},
    189      {0xA008,INSTR_ADD,AL,AL,0,0,NA,0,0,3,SHIFT_ASR,1,NA,1,1,0,0},
    190      {0xA009,INSTR_ADD,AL,AL,0,1,NA,0,0,MAX_32BIT ,SHIFT_ASR,31,NA,1,0,0,0},
    191      {0xA010,INSTR_AND,AL,AL,0,1,NA,1,MAX_32BIT ,0,0,0,NA,1,1,0,0},
    192      {0xA011,INSTR_AND,AL,AL,0,1,NA,1,MAX_32BIT -1,0,0,0,NA,1,0,0,0},
    193      {0xA012,INSTR_AND,AL,AL,0,1,NA,0,0,MAX_32BIT ,0,0,NA,1,1,0,0},
    194      {0xA013,INSTR_AND,AL,AL,0,1,NA,0,0,MAX_32BIT -1,0,0,NA,1,0,0,0},
    195      {0xA014,INSTR_AND,AL,AL,0,1,NA,0,0,MAX_32BIT ,SHIFT_LSL,0,NA,1,1,0,0},
    196      {0xA015,INSTR_AND,AL,AL,0,1,NA,0,0,MAX_32BIT ,SHIFT_LSL,31,NA,1,0,0,0},
    197      {0xA016,INSTR_AND,AL,AL,0,1,NA,0,0,3,SHIFT_LSR,1,NA,1,1,0,0},
    198      {0xA017,INSTR_AND,AL,AL,0,1,NA,0,0,MAX_32BIT ,SHIFT_LSR,31,NA,1,1,0,0},
    199      {0xA018,INSTR_AND,AL,AL,0,0,NA,0,0,3,SHIFT_ASR,1,NA,1,0,0,0},
    200      {0xA019,INSTR_AND,AL,AL,0,1,NA,0,0,MAX_32BIT ,SHIFT_ASR,31,NA,1,1,0,0},
    201      {0xA020,INSTR_ORR,AL,AL,0,3,NA,1,MAX_32BIT ,0,0,0,NA,1,MAX_32BIT,0,0},
    202      {0xA021,INSTR_ORR,AL,AL,0,2,NA,1,MAX_32BIT -1,0,0,0,NA,1,MAX_32BIT-1,0,0},
    203      {0xA022,INSTR_ORR,AL,AL,0,3,NA,0,0,MAX_32BIT ,0,0,NA,1,MAX_32BIT,0,0},
    204      {0xA023,INSTR_ORR,AL,AL,0,2,NA,0,0,MAX_32BIT -1,0,0,NA,1,MAX_32BIT-1,0,0},
    205      {0xA024,INSTR_ORR,AL,AL,0,1,NA,0,0,MAX_32BIT ,SHIFT_LSL,0,NA,1,MAX_32BIT,0,0},
    206      {0xA025,INSTR_ORR,AL,AL,0,1,NA,0,0,MAX_32BIT ,SHIFT_LSL,31,NA,1,0x80000001,0,0},
    207      {0xA026,INSTR_ORR,AL,AL,0,1,NA,0,0,3,SHIFT_LSR,1,NA,1,1,0,0},
    208      {0xA027,INSTR_ORR,AL,AL,0,0,NA,0,0,MAX_32BIT ,SHIFT_LSR,31,NA,1,1,0,0},
    209      {0xA028,INSTR_ORR,AL,AL,0,0,NA,0,0,3,SHIFT_ASR,1,NA,1,1,0,0},
    210      {0xA029,INSTR_ORR,AL,AL,0,1,NA,0,0,MAX_32BIT ,SHIFT_ASR,31,NA,1,MAX_32BIT ,0,0},
    211      {0xA030,INSTR_CMP,AL,AL,1,0x10000,NA,1,0x10000,0,0,0,NA,0,0,1,HS},
    212      {0xA031,INSTR_CMP,AL,AL,1,0x00000,NA,1,0x10000,0,0,0,NA,0,0,1,CC},
    213      {0xA032,INSTR_CMP,AL,AL,1,0x00000,NA,0,0,0x10000,0,0,NA,0,0,1,LT},
    214      {0xA033,INSTR_CMP,AL,AL,1,0x10000,NA,0,0,0x10000,0,0,NA,0,0,1,EQ},
    215      {0xA034,INSTR_CMP,AL,AL,1,0x00000,NA,0,0,0x10000,0,0,NA,0,0,1,LS},
    216      {0xA035,INSTR_CMP,AL,AL,1,0x10000,NA,0,0,0x10000,0,0,NA,0,0,1,LS},
    217      {0xA036,INSTR_CMP,AL,AL,1,0x10000,NA,0,0,0x00000,0,0,NA,0,0,1,HI},
    218      {0xA037,INSTR_CMP,AL,AL,1,0x10000,NA,0,0,0x10000,0,0,NA,0,0,1,HS},
    219      {0xA038,INSTR_CMP,AL,AL,1,0x10000,NA,0,0,0x00000,0,0,NA,0,0,1,HS},
    220      {0xA039,INSTR_CMP,AL,AL,1,0x10000,NA,0,0,0x00000,0,0,NA,0,0,1,NE},
    221      {0xA040,INSTR_CMP,AL,AL,1,0,NA,0,0,MAX_32BIT ,SHIFT_LSR,1,NA,0,0,1,LT},
    222      {0xA041,INSTR_CMP,AL,AL,1,1,NA,0,0,MAX_32BIT ,SHIFT_LSR,31,NA,0,0,1,EQ},
    223      {0xA042,INSTR_CMP,AL,AL,1,0,NA,0,0,0x10000,SHIFT_LSR,31,NA,0,0,1,LS},
    224      {0xA043,INSTR_CMP,AL,AL,1,0x10000,NA,0,0,0x30000,SHIFT_LSR,1,NA,0,0,1,LS},
    225      {0xA044,INSTR_CMP,AL,AL,1,0x10000,NA,0,0,0x00000,SHIFT_LSR,31,NA,0,0,1,HI},
    226      {0xA045,INSTR_CMP,AL,AL,1,1,NA,0,0,MAX_32BIT ,SHIFT_LSR,31,NA,0,0,1,HS},
    227      {0xA046,INSTR_CMP,AL,AL,1,0x10000,NA,0,0,0x2000,SHIFT_LSR,1,NA,0,0,1,HS},
    228      {0xA047,INSTR_CMP,AL,AL,1,0,NA,0,0,MAX_32BIT ,SHIFT_LSR,1,NA,0,0,1,NE},
    229      {0xA048,INSTR_CMP,AL,AL,1,0,NA,0,0,0x10000,SHIFT_ASR,2,NA,0,0,1,LT},
    230      {0xA049,INSTR_CMP,AL,AL,1,MAX_32BIT ,NA,0,0,MAX_32BIT ,SHIFT_ASR,1,NA,0,0,1,EQ},
    231      {0xA050,INSTR_CMP,AL,AL,1,MAX_32BIT ,NA,0,0,MAX_32BIT ,SHIFT_ASR,31,NA,0,0,1,LS},
    232      {0xA051,INSTR_CMP,AL,AL,1,0,NA,0,0,0x10000,SHIFT_ASR,1,NA,0,0,1,LS},
    233      {0xA052,INSTR_CMP,AL,AL,1,0x10000,NA,0,0,0x10000,SHIFT_ASR,1,NA,0,0,1,HI},
    234      {0xA053,INSTR_CMP,AL,AL,1,1,NA,0,0,0x10000,SHIFT_ASR,31,NA,0,0,1,HS},
    235      {0xA054,INSTR_CMP,AL,AL,1,1,NA,0,0,0x10000,SHIFT_ASR,16,NA,0,0,1,HS},
    236      {0xA055,INSTR_CMP,AL,AL,1,1,NA,0,0,MAX_32BIT ,SHIFT_ASR,1,NA,0,0,1,NE},
    237      {0xA056,INSTR_MUL,AL,AL,0,0,0x10000,0,0,0x10000,0,0,NA,1,0,0,0},
    238      {0xA057,INSTR_MUL,AL,AL,0,0,0x1000,0,0,0x10000,0,0,NA,1,0x10000000,0,0},
    239      {0xA058,INSTR_MUL,AL,AL,0,0,MAX_32BIT ,0,0,1,0,0,NA,1,MAX_32BIT ,0,0},
    240      {0xA059,INSTR_MLA,AL,AL,0,0x10000,0x10000,0,0,0x10000,0,0,NA,1,0x10000,0,0},
    241      {0xA060,INSTR_MLA,AL,AL,0,0x10000,0x1000,0,0,0x10000,0,0,NA,1,0x10010000,0,0},
    242      {0xA061,INSTR_MLA,AL,AL,1,1,MAX_32BIT ,0,0,1,0,0,NA,1,0,1,PL},
    243      {0xA062,INSTR_MLA,AL,AL,1,0,MAX_32BIT ,0,0,1,0,0,NA,1,MAX_32BIT ,1,MI},
    244      {0xA063,INSTR_SUB,AL,AL,1,1 << 16,NA,1,1 << 16,NA,NA,NA,NA,1,0,1,PL},
    245      {0xA064,INSTR_SUB,AL,AL,1,(1 << 16) + 1,NA,1,1 << 16,NA,NA,NA,NA,1,1,1,PL},
    246      {0xA065,INSTR_SUB,AL,AL,1,0,NA,1,1 << 16,NA,NA,NA,NA,1,(uint32_t)(0 - (1<<16)),1,MI},
    247      {0xA066,INSTR_SUB,MI,MI,0,2,NA,0,NA,1,NA,NA,2,1,1,0,NA},
    248      {0xA067,INSTR_SUB,EQ,MI,0,2,NA,0,NA,1,NA,NA,2,1,2,0,NA},
    249      {0xA068,INSTR_SUB,GT,GE,0,2,NA,1,1,NA,NA,NA,2,1,1,0,NA},
    250      {0xA069,INSTR_SUB,LT,GE,0,2,NA,1,1,NA,NA,NA,2,1,2,0,NA},
    251      {0xA070,INSTR_SUB,CS,HS,0,2,NA,1,1,NA,NA,NA,2,1,1,0,NA},
    252      {0xA071,INSTR_SUB,CC,HS,0,2,NA,1,1,NA,NA,NA,2,1,2,0,NA},
    253      {0xA072,INSTR_SUB,AL,AL,0,1,NA,1,1 << 16,0,0,0,NA,1,(uint32_t)(1 - (1 << 16)),0,NA},
    254      {0xA073,INSTR_SUB,AL,AL,0,MAX_32BIT,NA,1,1,0,0,0,NA,1,MAX_32BIT  - 1,0,NA},
    255      {0xA074,INSTR_SUB,AL,AL,0,1,NA,1,1,0,0,0,NA,1,0,0,NA},
    256      {0xA075,INSTR_SUB,AL,AL,0,1,NA,0,NA,1 << 16,0,0,NA,1,(uint32_t)(1 - (1 << 16)),0,NA},
    257      {0xA076,INSTR_SUB,AL,AL,0,MAX_32BIT,NA,0,NA,1,0,0,NA,1,MAX_32BIT  - 1,0,NA},
    258      {0xA077,INSTR_SUB,AL,AL,0,1,NA,0,NA,1,0,0,NA,1,0,0,NA},
    259      {0xA078,INSTR_SUB,AL,AL,0,1,NA,0,NA,1,SHIFT_LSL,16,NA,1,(uint32_t)(1 - (1 << 16)),0,NA},
    260      {0xA079,INSTR_SUB,AL,AL,0,0x80000001,NA,0,NA,MAX_32BIT ,SHIFT_LSL,31,NA,1,1,0,NA},
    261      {0xA080,INSTR_SUB,AL,AL,0,1,NA,0,NA,3,SHIFT_LSR,1,NA,1,0,0,NA},
    262      {0xA081,INSTR_SUB,AL,AL,0,1,NA,0,NA,MAX_32BIT ,SHIFT_LSR,31,NA,1,0,0,NA},
    263      {0xA082,INSTR_RSB,GT,GE,0,2,NA,1,0,NA,NA,NA,2,1,(uint32_t)-2,0,NA},
    264      {0xA083,INSTR_RSB,LT,GE,0,2,NA,1,0,NA,NA,NA,2,1,2,0,NA},
    265      {0xA084,INSTR_RSB,AL,AL,0,1,NA,1,1 << 16,NA,NA,NA,NA,1,(1 << 16) - 1,0,NA},
    266      {0xA085,INSTR_RSB,AL,AL,0,MAX_32BIT,NA,1,1,NA,NA,NA,NA,1,(uint32_t) (1 - MAX_32BIT),0,NA},
    267      {0xA086,INSTR_RSB,AL,AL,0,1,NA,1,1,NA,NA,NA,NA,1,0,0,NA},
    268      {0xA087,INSTR_RSB,AL,AL,0,1,NA,0,NA,1 << 16,0,0,NA,1,(1 << 16) - 1,0,NA},
    269      {0xA088,INSTR_RSB,AL,AL,0,MAX_32BIT,NA,0,NA,1,0,0,NA,1,(uint32_t) (1 - MAX_32BIT),0,NA},
    270      {0xA089,INSTR_RSB,AL,AL,0,1,NA,0,NA,1,0,0,NA,1,0,0,NA},
    271      {0xA090,INSTR_RSB,AL,AL,0,1,NA,0,NA,1,SHIFT_LSL,16,NA,1,(1 << 16) - 1,0,NA},
    272      {0xA091,INSTR_RSB,AL,AL,0,0x80000001,NA,0,NA,MAX_32BIT ,SHIFT_LSL,31,NA,1,(uint32_t)-1,0,NA},
    273      {0xA092,INSTR_RSB,AL,AL,0,1,NA,0,NA,3,SHIFT_LSR,1,NA,1,0,0,NA},
    274      {0xA093,INSTR_RSB,AL,AL,0,1,NA,0,NA,MAX_32BIT ,SHIFT_LSR,31,NA,1,0,0,NA},
    275      {0xA094,INSTR_MOV,AL,AL,0,NA,NA,1,0x80000001,NA,NA,NA,NA,1,0x80000001,0,0},
    276      {0xA095,INSTR_MOV,AL,AL,0,NA,NA,0,0,0x80000001,0,0,NA,1,0x80000001,0,0},
    277      {0xA096,INSTR_MOV,AL,AL,0,NA,NA,0,0,MAX_32BIT ,SHIFT_LSL,1,NA,1,MAX_32BIT -1,0,0},
    278      {0xA097,INSTR_MOV,AL,AL,0,NA,NA,0,0,MAX_32BIT ,SHIFT_LSL,31,NA,1,0x80000000,0,0},
    279      {0xA098,INSTR_MOV,AL,AL,0,NA,NA,0,0,3,SHIFT_LSR,1,NA,1,1,0,0},
    280      {0xA099,INSTR_MOV,AL,AL,0,NA,NA,0,0,MAX_32BIT ,SHIFT_LSR,31,NA,1,1,0,0},
    281      {0xA100,INSTR_MOV,AL,AL,0,NA,NA,0,0,3,SHIFT_ASR,1,NA,1,1,0,0},
    282      {0xA101,INSTR_MOV,AL,AL,0,NA,NA,0,0,MAX_32BIT ,SHIFT_ASR,31,NA,1,MAX_32BIT ,0,0},
    283      {0xA102,INSTR_MOV,AL,AL,0,NA,NA,0,0,3,SHIFT_ROR,1,NA,1,0x80000001,0,0},
    284      {0xA103,INSTR_MOV,AL,AL,0,NA,NA,0,0,0x80000001,SHIFT_ROR,31,NA,1,3,0,0},
    285      {0xA104,INSTR_MOV,AL,AL,1,NA,NA,0,0,MAX_32BIT -1,SHIFT_ASR,1,NA,1,MAX_32BIT,1,MI},
    286      {0xA105,INSTR_MOV,AL,AL,1,NA,NA,0,0,3,SHIFT_ASR,1,NA,1,1,1,PL},
    287      {0xA106,INSTR_MOV,PL,MI,0,NA,NA,1,0x80000001,NA,NA,NA,2,1,2,0,0},
    288      {0xA107,INSTR_MOV,MI,MI,0,NA,NA,0,0,0x80000001,0,0,2,1,0x80000001,0,0},
    289      {0xA108,INSTR_MOV,EQ,LT,0,NA,NA,1,0x80000001,NA,NA,NA,2,1,2,0,0},
    290      {0xA109,INSTR_MOV,LT,LT,0,NA,NA,1,0x80000001,NA,NA,NA,2,1,0x80000001,0,0},
    291      {0xA110,INSTR_MOV,GT,GE,0,NA,NA,0,0,MAX_32BIT ,SHIFT_LSL,1,2,1,MAX_32BIT -1,0,0},
    292      {0xA111,INSTR_MOV,EQ,GE,0,NA,NA,0,0,MAX_32BIT ,SHIFT_LSL,31,2,1,0x80000000,0,0},
    293      {0xA112,INSTR_MOV,LT,GE,0,NA,NA,0,0,MAX_32BIT ,SHIFT_LSL,31,2,1,2,0,0},
    294      {0xA113,INSTR_MOV,GT,LE,0,NA,NA,0,0,MAX_32BIT ,SHIFT_LSL,1,2,1,2,0,0},
    295      {0xA114,INSTR_MOV,EQ,LE,0,NA,NA,1,0x80000001,NA,NA,NA,2,1,0x80000001,0,0},
    296      {0xA115,INSTR_MOV,LT,LE,0,NA,NA,0,0,MAX_32BIT ,SHIFT_LSL,31,2,1,0x80000000,0,0},
    297      {0xA116,INSTR_MOV,EQ,GT,0,NA,NA,1,0x80000001,NA,NA,NA,2,1,2,0,0},
    298      {0xA117,INSTR_MOV,GT,GT,0,NA,NA,1,0x80000001,NA,NA,NA,2,1,0x80000001,0,0},
    299      {0xA118,INSTR_MOV,LE,GT,0,NA,NA,1,0x80000001,NA,NA,NA,2,1,2,0,0},
    300      {0xA119,INSTR_MOV,EQ,GT,0,NA,NA,0,0,0x80000001,0,0,2,1,2,0,0},
    301      {0xA120,INSTR_MOV,GT,GT,0,NA,NA,0,0,0x80000001,0,0,2,1,0x80000001,0,0},
    302      {0xA121,INSTR_MOV,LE,GT,0,NA,NA,0,0,0x80000001,0,0,2,1,2,0,0},
    303      {0xA122,INSTR_MOV,EQ,GT,0,NA,NA,0,0,MAX_32BIT ,SHIFT_LSL,1,2,1,2,0,0},
    304      {0xA123,INSTR_MOV,GT,GT,0,NA,NA,0,0,MAX_32BIT ,SHIFT_LSL,1,2,1,MAX_32BIT -1,0,0},
    305      {0xA124,INSTR_MOV,LE,GT,0,NA,NA,0,0,MAX_32BIT ,SHIFT_LSL,1,2,1,2,0,0},
    306      {0xA125,INSTR_MOV,LO,HS,0,NA,NA,1,0x80000001,NA,NA,NA,2,1,2,0,0},
    307      {0xA126,INSTR_MOV,HS,HS,0,NA,NA,1,0x80000001,NA,NA,NA,2,1,0x80000001,0,0},
    308      {0xA127,INSTR_MVN,LO,HS,0,NA,NA,1,MAX_32BIT -1,NA,NA,NA,2,1,2,0,0},
    309      {0xA128,INSTR_MVN,HS,HS,0,NA,NA,1,MAX_32BIT -1,NA,NA,NA,2,1,1,0,0},
    310      {0xA129,INSTR_MVN,AL,AL,0,NA,NA,1,0,NA,NA,NA,2,1,MAX_32BIT,0,NA},
    311      {0xA130,INSTR_MVN,AL,AL,0,NA,NA,0,NA,MAX_32BIT -1,NA,0,2,1,1,0,NA},
    312      {0xA131,INSTR_MVN,AL,AL,0,NA,NA,0,NA,0x80000001,NA,0,2,1,0x7FFFFFFE,0,NA},
    313      {0xA132,INSTR_BIC,AL,AL,0,1,NA,1,MAX_32BIT ,NA,NA,NA,NA,1,0,0,0},
    314      {0xA133,INSTR_BIC,AL,AL,0,1,NA,1,MAX_32BIT -1,NA,NA,NA,NA,1,1,0,0},
    315      {0xA134,INSTR_BIC,AL,AL,0,1,NA,0,0,MAX_32BIT ,0,0,NA,1,0,0,0},
    316      {0xA135,INSTR_BIC,AL,AL,0,1,NA,0,0,MAX_32BIT -1,0,0,NA,1,1,0,0},
    317      {0xA136,INSTR_BIC,AL,AL,0,0xF0,NA,0,0,3,SHIFT_ASR,1,NA,1,0xF0,0,0},
    318      {0xA137,INSTR_BIC,AL,AL,0,0xF0,NA,0,0,MAX_32BIT ,SHIFT_ASR,31,NA,1,0,0,0},
    319      {0xA138,INSTR_SMULBB,AL,AL,0,NA,0xABCDFFFF,0,NA,0xABCD0001,NA,NA,NA,1,0xFFFFFFFF,0,0},
    320      {0xA139,INSTR_SMULBB,AL,AL,0,NA,0xABCD0001,0,NA,0xABCD0FFF,NA,NA,NA,1,0x00000FFF,0,0},
    321      {0xA140,INSTR_SMULBB,AL,AL,0,NA,0xABCD0001,0,NA,0xABCDFFFF,NA,NA,NA,1,0xFFFFFFFF,0,0},
    322      {0xA141,INSTR_SMULBB,AL,AL,0,NA,0xABCDFFFF,0,NA,0xABCDFFFF,NA,NA,NA,1,1,0,0},
    323      {0xA142,INSTR_SMULBT,AL,AL,0,NA,0xFFFFABCD,0,NA,0xABCD0001,NA,NA,NA,1,0xFFFFFFFF,0,0},
    324      {0xA143,INSTR_SMULBT,AL,AL,0,NA,0x0001ABCD,0,NA,0xABCD0FFF,NA,NA,NA,1,0x00000FFF,0,0},
    325      {0xA144,INSTR_SMULBT,AL,AL,0,NA,0x0001ABCD,0,NA,0xABCDFFFF,NA,NA,NA,1,0xFFFFFFFF,0,0},
    326      {0xA145,INSTR_SMULBT,AL,AL,0,NA,0xFFFFABCD,0,NA,0xABCDFFFF,NA,NA,NA,1,1,0,0},
    327      {0xA146,INSTR_SMULTB,AL,AL,0,NA,0xABCDFFFF,0,NA,0x0001ABCD,NA,NA,NA,1,0xFFFFFFFF,0,0},
    328      {0xA147,INSTR_SMULTB,AL,AL,0,NA,0xABCD0001,0,NA,0x0FFFABCD,NA,NA,NA,1,0x00000FFF,0,0},
    329      {0xA148,INSTR_SMULTB,AL,AL,0,NA,0xABCD0001,0,NA,0xFFFFABCD,NA,NA,NA,1,0xFFFFFFFF,0,0},
    330      {0xA149,INSTR_SMULTB,AL,AL,0,NA,0xABCDFFFF,0,NA,0xFFFFABCD,NA,NA,NA,1,1,0,0},
    331      {0xA150,INSTR_SMULTT,AL,AL,0,NA,0xFFFFABCD,0,NA,0x0001ABCD,NA,NA,NA,1,0xFFFFFFFF,0,0},
    332      {0xA151,INSTR_SMULTT,AL,AL,0,NA,0x0001ABCD,0,NA,0x0FFFABCD,NA,NA,NA,1,0x00000FFF,0,0},
    333      {0xA152,INSTR_SMULTT,AL,AL,0,NA,0x0001ABCD,0,NA,0xFFFFABCD,NA,NA,NA,1,0xFFFFFFFF,0,0},
    334      {0xA153,INSTR_SMULTT,AL,AL,0,NA,0xFFFFABCD,0,NA,0xFFFFABCD,NA,NA,NA,1,1,0,0},
    335      {0xA154,INSTR_SMULWB,AL,AL,0,NA,0xABCDFFFF,0,NA,0x0001ABCD,NA,NA,NA,1,0xFFFFFFFE,0,0},
    336      {0xA155,INSTR_SMULWB,AL,AL,0,NA,0xABCD0001,0,NA,0x0FFFABCD,NA,NA,NA,1,0x00000FFF,0,0},
    337      {0xA156,INSTR_SMULWB,AL,AL,0,NA,0xABCD0001,0,NA,0xFFFFABCD,NA,NA,NA,1,0xFFFFFFFF,0,0},
    338      {0xA157,INSTR_SMULWB,AL,AL,0,NA,0xABCDFFFF,0,NA,0xFFFFABCD,NA,NA,NA,1,0,0,0},
    339      {0xA158,INSTR_SMULWT,AL,AL,0,NA,0xFFFFABCD,0,NA,0x0001ABCD,NA,NA,NA,1,0xFFFFFFFE,0,0},
    340      {0xA159,INSTR_SMULWT,AL,AL,0,NA,0x0001ABCD,0,NA,0x0FFFABCD,NA,NA,NA,1,0x00000FFF,0,0},
    341      {0xA160,INSTR_SMULWT,AL,AL,0,NA,0x0001ABCD,0,NA,0xFFFFABCD,NA,NA,NA,1,0xFFFFFFFF,0,0},
    342      {0xA161,INSTR_SMULWT,AL,AL,0,NA,0xFFFFABCD,0,NA,0xFFFFABCD,NA,NA,NA,1,0,0,0},
    343      {0xA162,INSTR_SMLABB,AL,AL,0,1,0xABCDFFFF,0,NA,0xABCD0001,NA,NA,NA,1,0,0,0},
    344      {0xA163,INSTR_SMLABB,AL,AL,0,1,0xABCD0001,0,NA,0xABCD0FFF,NA,NA,NA,1,0x00001000,0,0},
    345      {0xA164,INSTR_SMLABB,AL,AL,0,0xFFFFFFFF,0xABCD0001,0,NA,0xABCDFFFF,NA,NA,NA,1,0xFFFFFFFE,0,0},
    346      {0xA165,INSTR_SMLABB,AL,AL,0,0xFFFFFFFF,0xABCDFFFF,0,NA,0xABCDFFFF,NA,NA,NA,1,0,0,0},
    347      {0xA166,INSTR_UXTB16,AL,AL,0,NA,NA,0,NA,0xABCDEF01,SHIFT_ROR,0,NA,1,0x00CD0001,0,0},
    348      {0xA167,INSTR_UXTB16,AL,AL,0,NA,NA,0,NA,0xABCDEF01,SHIFT_ROR,1,NA,1,0x00AB00EF,0,0},
    349      {0xA168,INSTR_UXTB16,AL,AL,0,NA,NA,0,NA,0xABCDEF01,SHIFT_ROR,2,NA,1,0x000100CD,0,0},
    350      {0xA169,INSTR_UXTB16,AL,AL,0,NA,NA,0,NA,0xABCDEF01,SHIFT_ROR,3,NA,1,0x00EF00AB,0,0},
    351      {0xA170,INSTR_UBFX,AL,AL,0,0xABCDEF01,4,0,NA,24,NA,NA,NA,1,0x00BCDEF0,0,0},
    352      {0xA171,INSTR_UBFX,AL,AL,0,0xABCDEF01,1,0,NA,2,NA,NA,NA,1,0,0,0},
    353      {0xA172,INSTR_UBFX,AL,AL,0,0xABCDEF01,16,0,NA,8,NA,NA,NA,1,0xCD,0,0},
    354      {0xA173,INSTR_UBFX,AL,AL,0,0xABCDEF01,31,0,NA,1,NA,NA,NA,1,1,0,0},
    355      {0xA174,INSTR_ADDR_ADD,AL,AL,0,0xCFFFFFFFF,NA,0,NA,0x1,SHIFT_LSL,1,NA,1,0xD00000001,0,0},
    356      {0xA175,INSTR_ADDR_ADD,AL,AL,0,0x01,NA,0,NA,0x1,SHIFT_LSL,2,NA,1,0x5,0,0},
    357      {0xA176,INSTR_ADDR_ADD,AL,AL,0,0xCFFFFFFFF,NA,0,NA,0x1,NA,0,NA,1,0xD00000000,0,0},
    358      {0xA177,INSTR_ADDR_SUB,AL,AL,0,0xD00000001,NA,0,NA,0x010000,SHIFT_LSR,15,NA,1,0xCFFFFFFFF,0,0},
    359      {0xA178,INSTR_ADDR_SUB,AL,AL,0,0xCFFFFFFFF,NA,0,NA,0x020000,SHIFT_LSR,15,NA,1,0xCFFFFFFFB,0,0},
    360      {0xA179,INSTR_ADDR_SUB,AL,AL,0,3,NA,0,NA,0x010000,SHIFT_LSR,15,NA,1,1,0,0},
    361 };
    362 
    363 dataTransferTest_t dataTransferTests [] =
    364 {
    365     {0xB000,INSTR_LDR,AL,AL,1,24,0xABCDEF0123456789,0,REG_SCALE_OFFSET,24,NA,NA,NA,NA,NA,0x23456789,0,0,NA,NA,NA},
    366     {0xB001,INSTR_LDR,AL,AL,1,4064,0xABCDEF0123456789,0,IMM12_OFFSET,NA,4068,0,1,0,NA,0xABCDEF01,0,0,NA,NA,NA},
    367     {0xB002,INSTR_LDR,AL,AL,1,0,0xABCDEF0123456789,0,IMM12_OFFSET,NA,4,1,0,1,NA,0x23456789,4,0,NA,NA,NA},
    368     {0xB003,INSTR_LDR,AL,AL,1,0,0xABCDEF0123456789,0,NO_OFFSET,NA,NA,0,0,0,NA,0x23456789,0,0,NA,NA,NA},
    369     {0xB004,INSTR_LDRB,AL,AL,1,4064,0xABCDEF0123456789,0,REG_SCALE_OFFSET,4064,NA,NA,NA,NA,NA,0x89,0,0,NA,NA,NA},
    370     {0xB005,INSTR_LDRB,AL,AL,1,4064,0xABCDEF0123456789,0,IMM12_OFFSET,NA,4065,0,1,0,NA,0x67,0,0,NA,NA,NA},
    371     {0xB006,INSTR_LDRB,AL,AL,1,4064,0xABCDEF0123456789,4065,IMM12_OFFSET,NA,0,0,1,0,NA,0x67,4065,0,NA,NA,NA},
    372     {0xB007,INSTR_LDRB,AL,AL,1,4064,0xABCDEF0123456789,4065,IMM12_OFFSET,NA,1,0,1,0,NA,0x45,4065,0,NA,NA,NA},
    373     {0xB008,INSTR_LDRB,AL,AL,1,4064,0xABCDEF0123456789,4065,IMM12_OFFSET,NA,2,0,1,0,NA,0x23,4065,0,NA,NA,NA},
    374     {0xB009,INSTR_LDRB,AL,AL,1,4064,0xABCDEF0123456789,4065,IMM12_OFFSET,NA,1,1,0,1,NA,0x67,4066,0,NA,NA,NA},
    375     {0xB010,INSTR_LDRB,AL,AL,1,4064,0xABCDEF0123456789,0,NO_OFFSET,NA,NA,0,0,0,NA,0x89,0,0,NA,NA,NA},
    376     {0xB011,INSTR_LDRH,AL,AL,1,0,0xABCDEF0123456789,0,IMM8_OFFSET,NA,2,1,0,1,NA,0x6789,2,0,NA,NA,NA},
    377     {0xB012,INSTR_LDRH,AL,AL,1,4064,0xABCDEF0123456789,0,REG_OFFSET,4064,0,0,1,0,NA,0x6789,0,0,NA,NA,NA},
    378     {0xB013,INSTR_LDRH,AL,AL,1,4064,0xABCDEF0123456789,0,REG_OFFSET,4066,0,0,1,0,NA,0x2345,0,0,NA,NA,NA},
    379     {0xB014,INSTR_LDRH,AL,AL,1,0,0xABCDEF0123456789,0,NO_OFFSET,NA,0,0,0,0,NA,0x6789,0,0,NA,NA,NA},
    380     {0xB015,INSTR_LDRH,AL,AL,1,0,0xABCDEF0123456789,2,NO_OFFSET,NA,0,0,0,0,NA,0x2345,2,0,NA,NA,NA},
    381     {0xB016,INSTR_ADDR_LDR,AL,AL,1,4064,0xABCDEF0123456789,0,IMM12_OFFSET,NA,4064,0,1,0,NA,0xABCDEF0123456789,0,0,NA,NA,NA},
    382     {0xB017,INSTR_STR,AL,AL,1,2,0xDEADBEEFDEADBEEF,4,IMM12_OFFSET,NA,4,1,0,1,0xABCDEF0123456789,0xABCDEF0123456789,8,1,2,8,0xDEAD23456789BEEF},
    383     {0xB018,INSTR_STR,AL,AL,1,2,0xDEADBEEFDEADBEEF,4,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,4,1,2,8,0xDEAD23456789BEEF},
    384     {0xB019,INSTR_STR,AL,AL,1,4066,0xDEADBEEFDEADBEEF,4,IMM12_OFFSET,NA,4064,0,1,0,0xABCDEF0123456789,0xABCDEF0123456789,4,1,4066,8,0xDEAD23456789BEEF},
    385     {0xB020,INSTR_STRB,AL,AL,1,0,0xDEADBEEFDEADBEEF,1,IMM12_OFFSET,NA,0,0,1,0,0xABCDEF0123456789,0xABCDEF0123456789,1,1,0,8,0xDEADBEEFDEAD89EF},
    386     {0xB021,INSTR_STRB,AL,AL,1,0,0xDEADBEEFDEADBEEF,1,IMM12_OFFSET,NA,1,0,1,0,0xABCDEF0123456789,0xABCDEF0123456789,1,1,0,8,0xDEADBEEFDE89BEEF},
    387     {0xB022,INSTR_STRB,AL,AL,1,0,0xDEADBEEFDEADBEEF,1,IMM12_OFFSET,NA,2,0,1,0,0xABCDEF0123456789,0xABCDEF0123456789,1,1,0,8,0xDEADBEEF89ADBEEF},
    388     {0xB023,INSTR_STRB,AL,AL,1,0,0xDEADBEEFDEADBEEF,1,IMM12_OFFSET,NA,4,1,0,1,0xABCDEF0123456789,0xABCDEF0123456789,5,1,0,8,0xDEADBEEFDEAD89EF},
    389     {0xB024,INSTR_STRB,AL,AL,1,0,0xDEADBEEFDEADBEEF,1,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,1,1,0,8,0xDEADBEEFDEAD89EF},
    390     {0xB025,INSTR_STRH,AL,AL,1,4066,0xDEADBEEFDEADBEEF,4070,IMM12_OFFSET,NA,2,1,0,1,0xABCDEF0123456789,0xABCDEF0123456789,4072,1,4066,8,0xDEAD6789DEADBEEF},
    391     {0xB026,INSTR_STRH,AL,AL,1,4066,0xDEADBEEFDEADBEEF,4070,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,4070,1,4066,8,0xDEAD6789DEADBEEF},
    392     {0xB027,INSTR_STRH,EQ,NE,1,4066,0xDEADBEEFDEADBEEF,4070,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,4070,1,4066,8,0xDEADBEEFDEADBEEF},
    393     {0xB028,INSTR_STRH,NE,NE,1,4066,0xDEADBEEFDEADBEEF,4070,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,4070,1,4066,8,0xDEAD6789DEADBEEF},
    394     {0xB029,INSTR_STRH,NE,EQ,1,4066,0xDEADBEEFDEADBEEF,4070,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,4070,1,4066,8,0xDEADBEEFDEADBEEF},
    395     {0xB030,INSTR_STRH,EQ,EQ,1,4066,0xDEADBEEFDEADBEEF,4070,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,4070,1,4066,8,0xDEAD6789DEADBEEF},
    396     {0xB031,INSTR_STRH,HI,LS,1,4066,0xDEADBEEFDEADBEEF,4070,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,4070,1,4066,8,0xDEADBEEFDEADBEEF},
    397     {0xB032,INSTR_STRH,LS,LS,1,4066,0xDEADBEEFDEADBEEF,4070,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,4070,1,4066,8,0xDEAD6789DEADBEEF},
    398     {0xB033,INSTR_STRH,LS,HI,1,4066,0xDEADBEEFDEADBEEF,4070,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,4070,1,4066,8,0xDEADBEEFDEADBEEF},
    399     {0xB034,INSTR_STRH,HI,HI,1,4066,0xDEADBEEFDEADBEEF,4070,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,4070,1,4066,8,0xDEAD6789DEADBEEF},
    400     {0xB035,INSTR_STRH,CC,HS,1,4066,0xDEADBEEFDEADBEEF,4070,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,4070,1,4066,8,0xDEADBEEFDEADBEEF},
    401     {0xB036,INSTR_STRH,CS,HS,1,4066,0xDEADBEEFDEADBEEF,4070,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,4070,1,4066,8,0xDEAD6789DEADBEEF},
    402     {0xB037,INSTR_STRH,GE,LT,1,4066,0xDEADBEEFDEADBEEF,4070,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,4070,1,4066,8,0xDEADBEEFDEADBEEF},
    403     {0xB038,INSTR_STRH,LT,LT,1,4066,0xDEADBEEFDEADBEEF,4070,NO_OFFSET,NA,NA,0,0,0,0xABCDEF0123456789,0xABCDEF0123456789,4070,1,4066,8,0xDEAD6789DEADBEEF},
    404     {0xB039,INSTR_ADDR_STR,AL,AL,1,4064,0xDEADBEEFDEADBEEF,4,IMM12_OFFSET,NA,4060,0,1,0,0xABCDEF0123456789,0xABCDEF0123456789,4,1,4064,8,0xABCDEF0123456789},
    405 };
    406 
    407 
    408 void flushcache()
    409 {
    410     const long base = long(instrMem);
    411     const long curr = base + long(instrMemSize);
    412     __builtin___clear_cache((char*)base, (char*)curr);
    413 }
    414 void dataOpTest(dataOpTest_t test, ARMAssemblerInterface *a64asm, uint32_t Rd = 0,
    415                 uint32_t Rn = 1, uint32_t Rm = 2, uint32_t Rs = 3)
    416 {
    417     int64_t  regs[NUM_REGS] = {0};
    418     int32_t  flags[NUM_FLAGS] = {0};
    419     int64_t  savedRegs[NUM_REGS] = {0};
    420     uint32_t i;
    421     uint32_t op2;
    422 
    423     for(i = 0; i < NUM_REGS; ++i)
    424     {
    425         regs[i] = i;
    426     }
    427 
    428     regs[Rd] = test.RdValue;
    429     regs[Rn] = test.RnValue;
    430     regs[Rs] = test.RsValue;
    431     flags[test.preFlag] = 1;
    432     a64asm->reset();
    433     a64asm->prolog();
    434     if(test.immediate == true)
    435     {
    436         op2 = a64asm->imm(test.immValue);
    437     }
    438     else if(test.immediate == false && test.shiftAmount == 0)
    439     {
    440         op2 = Rm;
    441         regs[Rm] = test.RmValue;
    442     }
    443     else
    444     {
    445         op2 = a64asm->reg_imm(Rm, test.shiftMode, test.shiftAmount);
    446         regs[Rm] = test.RmValue;
    447     }
    448     switch(test.op)
    449     {
    450     case INSTR_ADD: a64asm->ADD(test.cond, test.setFlags, Rd,Rn,op2); break;
    451     case INSTR_SUB: a64asm->SUB(test.cond, test.setFlags, Rd,Rn,op2); break;
    452     case INSTR_RSB: a64asm->RSB(test.cond, test.setFlags, Rd,Rn,op2); break;
    453     case INSTR_AND: a64asm->AND(test.cond, test.setFlags, Rd,Rn,op2); break;
    454     case INSTR_ORR: a64asm->ORR(test.cond, test.setFlags, Rd,Rn,op2); break;
    455     case INSTR_BIC: a64asm->BIC(test.cond, test.setFlags, Rd,Rn,op2); break;
    456     case INSTR_MUL: a64asm->MUL(test.cond, test.setFlags, Rd,Rm,Rs); break;
    457     case INSTR_MLA: a64asm->MLA(test.cond, test.setFlags, Rd,Rm,Rs,Rn); break;
    458     case INSTR_CMP: a64asm->CMP(test.cond, Rn,op2); break;
    459     case INSTR_MOV: a64asm->MOV(test.cond, test.setFlags,Rd,op2); break;
    460     case INSTR_MVN: a64asm->MVN(test.cond, test.setFlags,Rd,op2); break;
    461     case INSTR_SMULBB:a64asm->SMULBB(test.cond, Rd,Rm,Rs); break;
    462     case INSTR_SMULBT:a64asm->SMULBT(test.cond, Rd,Rm,Rs); break;
    463     case INSTR_SMULTB:a64asm->SMULTB(test.cond, Rd,Rm,Rs); break;
    464     case INSTR_SMULTT:a64asm->SMULTT(test.cond, Rd,Rm,Rs); break;
    465     case INSTR_SMULWB:a64asm->SMULWB(test.cond, Rd,Rm,Rs); break;
    466     case INSTR_SMULWT:a64asm->SMULWT(test.cond, Rd,Rm,Rs); break;
    467     case INSTR_SMLABB:a64asm->SMLABB(test.cond, Rd,Rm,Rs,Rn); break;
    468     case INSTR_UXTB16:a64asm->UXTB16(test.cond, Rd,Rm,test.shiftAmount); break;
    469     case INSTR_UBFX:
    470     {
    471         int32_t lsb   = test.RsValue;
    472         int32_t width = test.RmValue;
    473         a64asm->UBFX(test.cond, Rd,Rn,lsb, width);
    474         break;
    475     }
    476     case INSTR_ADDR_ADD: a64asm->ADDR_ADD(test.cond, test.setFlags, Rd,Rn,op2); break;
    477     case INSTR_ADDR_SUB: a64asm->ADDR_SUB(test.cond, test.setFlags, Rd,Rn,op2); break;
    478     default: printf("Error"); return;
    479     }
    480     a64asm->epilog(0);
    481     flushcache();
    482 
    483     asm_function_t asm_function = (asm_function_t)(instrMem);
    484 
    485     for(i = 0; i < NUM_REGS; ++i)
    486         savedRegs[i] = regs[i];
    487 
    488     asm_test_jacket(asm_function, regs, flags);
    489 
    490     /* Check if all regs except Rd is same */
    491     for(i = 0; i < NUM_REGS; ++i)
    492     {
    493         if(i == Rd) continue;
    494         if(regs[i] != savedRegs[i])
    495         {
    496             printf("Test %x failed Reg(%d) tampered Expected(0x%" PRIx64 "),"
    497                    "Actual(0x%" PRIx64 ") t\n", test.id, i, savedRegs[i],
    498                    regs[i]);
    499             return;
    500         }
    501     }
    502 
    503     if(test.checkRd == 1 && (uint64_t)regs[Rd] != test.postRdValue)
    504     {
    505         printf("Test %x failed, Expected(%" PRIx64 "), Actual(%" PRIx64 ")\n",
    506                test.id, test.postRdValue, regs[Rd]);
    507     }
    508     else if(test.checkFlag == 1 && flags[test.postFlag] == 0)
    509     {
    510         printf("Test %x failed Flag(%s) NOT set\n",
    511                 test.id,cc_code[test.postFlag]);
    512     }
    513     else
    514     {
    515         printf("Test %x passed\n", test.id);
    516     }
    517 }
    518 
    519 
    520 void dataTransferTest(dataTransferTest_t test, ARMAssemblerInterface *a64asm,
    521                       uint32_t Rd = 0, uint32_t Rn = 1,uint32_t Rm = 2)
    522 {
    523     int64_t regs[NUM_REGS] = {0};
    524     int64_t savedRegs[NUM_REGS] = {0};
    525     int32_t flags[NUM_FLAGS] = {0};
    526     uint32_t i;
    527     for(i = 0; i < NUM_REGS; ++i)
    528     {
    529         regs[i] = i;
    530     }
    531 
    532     uint32_t op2;
    533 
    534     regs[Rd] = test.RdValue;
    535     regs[Rn] = (uint64_t)(&dataMem[test.RnValue]);
    536     regs[Rm] = test.RmValue;
    537     flags[test.preFlag] = 1;
    538 
    539     if(test.setMem == true)
    540     {
    541         unsigned char *mem = (unsigned char *)&dataMem[test.memOffset];
    542         uint64_t value = test.memValue;
    543         for(int j = 0; j < 8; ++j)
    544         {
    545             mem[j] = value & 0x00FF;
    546             value >>= 8;
    547         }
    548     }
    549     a64asm->reset();
    550     a64asm->prolog();
    551     if(test.offsetType == REG_SCALE_OFFSET)
    552     {
    553         op2 = a64asm->reg_scale_pre(Rm);
    554     }
    555     else if(test.offsetType == REG_OFFSET)
    556     {
    557         op2 = a64asm->reg_pre(Rm);
    558     }
    559     else if(test.offsetType == IMM12_OFFSET && test.preIndex == true)
    560     {
    561         op2 = a64asm->immed12_pre(test.immValue, test.writeBack);
    562     }
    563     else if(test.offsetType == IMM12_OFFSET && test.postIndex == true)
    564     {
    565         op2 = a64asm->immed12_post(test.immValue);
    566     }
    567     else if(test.offsetType == IMM8_OFFSET && test.preIndex == true)
    568     {
    569         op2 = a64asm->immed8_pre(test.immValue, test.writeBack);
    570     }
    571     else if(test.offsetType == IMM8_OFFSET && test.postIndex == true)
    572     {
    573         op2 = a64asm->immed8_post(test.immValue);
    574     }
    575     else if(test.offsetType == NO_OFFSET)
    576     {
    577         op2 = a64asm->__immed12_pre(0);
    578     }
    579     else
    580     {
    581         printf("Error - Unknown offset\n"); return;
    582     }
    583 
    584     switch(test.op)
    585     {
    586     case INSTR_LDR:  a64asm->LDR(test.cond, Rd,Rn,op2); break;
    587     case INSTR_LDRB: a64asm->LDRB(test.cond, Rd,Rn,op2); break;
    588     case INSTR_LDRH: a64asm->LDRH(test.cond, Rd,Rn,op2); break;
    589     case INSTR_ADDR_LDR: a64asm->ADDR_LDR(test.cond, Rd,Rn,op2); break;
    590     case INSTR_STR:  a64asm->STR(test.cond, Rd,Rn,op2); break;
    591     case INSTR_STRB: a64asm->STRB(test.cond, Rd,Rn,op2); break;
    592     case INSTR_STRH: a64asm->STRH(test.cond, Rd,Rn,op2); break;
    593     case INSTR_ADDR_STR: a64asm->ADDR_STR(test.cond, Rd,Rn,op2); break;
    594     default: printf("Error"); return;
    595     }
    596     a64asm->epilog(0);
    597     flushcache();
    598 
    599     asm_function_t asm_function = (asm_function_t)(instrMem);
    600 
    601     for(i = 0; i < NUM_REGS; ++i)
    602         savedRegs[i] = regs[i];
    603 
    604 
    605     asm_test_jacket(asm_function, regs, flags);
    606 
    607     /* Check if all regs except Rd/Rn are same */
    608     for(i = 0; i < NUM_REGS; ++i)
    609     {
    610         if(i == Rd || i == Rn) continue;
    611         if(regs[i] != savedRegs[i])
    612         {
    613             printf("Test %x failed Reg(%d) tampered"
    614                    " Expected(0x%" PRIx64 "), Actual(0x%" PRIx64 ") t\n",
    615                    test.id, i, savedRegs[i], regs[i]);
    616             return;
    617         }
    618     }
    619 
    620     if((uint64_t)regs[Rd] != test.postRdValue)
    621     {
    622         printf("Test %x failed, "
    623                "Expected in Rd(0x%" PRIx64 "), Actual(0x%" PRIx64 ")\n",
    624                test.id, test.postRdValue, regs[Rd]);
    625     }
    626     else if((uint64_t)regs[Rn] != (uint64_t)(&dataMem[test.postRnValue]))
    627     {
    628         printf("Test %x failed, "
    629                "Expected in Rn(0x%" PRIx64 "), Actual(0x%" PRIx64 ")\n",
    630                test.id, test.postRnValue, regs[Rn] - (uint64_t)dataMem);
    631     }
    632     else if(test.checkMem == true)
    633     {
    634         unsigned char *addr = (unsigned char *)&dataMem[test.postMemOffset];
    635         uint64_t value;
    636         value = 0;
    637         for(uint32_t j = 0; j < test.postMemLength; ++j)
    638             value = (value << 8) | addr[test.postMemLength-j-1];
    639         if(value != test.postMemValue)
    640         {
    641             printf("Test %x failed, "
    642                    "Expected in Mem(0x%" PRIx64 "), Actual(0x%" PRIx64 ")\n",
    643                    test.id, test.postMemValue, value);
    644         }
    645         else
    646         {
    647             printf("Test %x passed\n", test.id);
    648         }
    649     }
    650     else
    651     {
    652         printf("Test %x passed\n", test.id);
    653     }
    654 }
    655 
    656 void dataTransferLDMSTM(ARMAssemblerInterface *a64asm)
    657 {
    658     int64_t regs[NUM_REGS] = {0};
    659     int32_t flags[NUM_FLAGS] = {0};
    660     const uint32_t numArmv7Regs = 16;
    661 
    662     uint32_t Rn = ARMAssemblerInterface::SP;
    663 
    664     uint32_t patterns[] =
    665     {
    666         0x5A03,
    667         0x4CF0,
    668         0x1EA6,
    669         0x0DBF,
    670     };
    671 
    672     uint32_t i, j;
    673     for(i = 0; i < sizeof(patterns)/sizeof(uint32_t); ++i)
    674     {
    675         for(j = 0; j < NUM_REGS; ++j)
    676         {
    677             regs[j] = j;
    678         }
    679         a64asm->reset();
    680         a64asm->prolog();
    681         a64asm->STM(AL,ARMAssemblerInterface::DB,Rn,1,patterns[i]);
    682         for(j = 0; j < numArmv7Regs; ++j)
    683         {
    684             uint32_t op2 = a64asm->imm(0x31);
    685             a64asm->MOV(AL, 0,j,op2);
    686         }
    687         a64asm->LDM(AL,ARMAssemblerInterface::IA,Rn,1,patterns[i]);
    688         a64asm->epilog(0);
    689         flushcache();
    690 
    691         asm_function_t asm_function = (asm_function_t)(instrMem);
    692         asm_test_jacket(asm_function, regs, flags);
    693 
    694         for(j = 0; j < numArmv7Regs; ++j)
    695         {
    696             if((1 << j) & patterns[i])
    697             {
    698                 if(regs[j] != j)
    699                 {
    700                     printf("LDM/STM Test %x failed "
    701                            "Reg%d expected(0x%x) Actual(0x%" PRIx64 ") \n",
    702                            patterns[i], j, j, regs[j]);
    703                     break;
    704                 }
    705             }
    706         }
    707         if(j == numArmv7Regs)
    708             printf("LDM/STM Test %x passed\n", patterns[i]);
    709     }
    710 }
    711 
    712 int main(void)
    713 {
    714     uint32_t i;
    715 
    716     /* Allocate memory to store instructions generated by ArmToArm64Assembler */
    717     {
    718         int fd = ashmem_create_region("code cache", instrMemSize);
    719         if(fd < 0)
    720             printf("Creating code cache, ashmem_create_region "
    721                                 "failed with error '%s'", strerror(errno));
    722         instrMem = mmap(NULL, instrMemSize,
    723                                     PROT_READ | PROT_WRITE | PROT_EXEC,
    724                                 MAP_PRIVATE, fd, 0);
    725     }
    726 
    727     ArmToArm64Assembler a64asm(instrMem);
    728 
    729     if(TESTS_DATAOP_ENABLE)
    730     {
    731         printf("Running data processing tests\n");
    732         for(i = 0; i < sizeof(dataOpTests)/sizeof(dataOpTest_t); ++i)
    733             dataOpTest(dataOpTests[i], &a64asm);
    734     }
    735 
    736     if(TESTS_DATATRANSFER_ENABLE)
    737     {
    738         printf("Running data transfer tests\n");
    739         for(i = 0; i < sizeof(dataTransferTests)/sizeof(dataTransferTest_t); ++i)
    740             dataTransferTest(dataTransferTests[i], &a64asm);
    741     }
    742 
    743     if(TESTS_LDMSTM_ENABLE)
    744     {
    745         printf("Running LDM/STM tests\n");
    746         dataTransferLDMSTM(&a64asm);
    747     }
    748 
    749 
    750     if(TESTS_REG_CORRUPTION_ENABLE)
    751     {
    752         uint32_t reg_list[] = {0,1,12,14};
    753         uint32_t Rd, Rm, Rs, Rn;
    754         uint32_t i;
    755         uint32_t numRegs = sizeof(reg_list)/sizeof(uint32_t);
    756 
    757         printf("Running Register corruption tests\n");
    758         for(i = 0; i < sizeof(dataOpTests)/sizeof(dataOpTest_t); ++i)
    759         {
    760             for(Rd = 0; Rd < numRegs; ++Rd)
    761             {
    762                 for(Rn = 0; Rn < numRegs; ++Rn)
    763                 {
    764                     for(Rm = 0; Rm < numRegs; ++Rm)
    765                     {
    766                         for(Rs = 0; Rs < numRegs;++Rs)
    767                         {
    768                             if(Rd == Rn || Rd == Rm || Rd == Rs) continue;
    769                             if(Rn == Rm || Rn == Rs) continue;
    770                             if(Rm == Rs) continue;
    771                             printf("Testing combination Rd(%d), Rn(%d),"
    772                                    " Rm(%d), Rs(%d): ",
    773                                    reg_list[Rd], reg_list[Rn], reg_list[Rm], reg_list[Rs]);
    774                             dataOpTest(dataOpTests[i], &a64asm, reg_list[Rd],
    775                                        reg_list[Rn], reg_list[Rm], reg_list[Rs]);
    776                         }
    777                     }
    778                 }
    779             }
    780         }
    781     }
    782     return 0;
    783 }
    784