arm64_assembler_test.cpp revision fd1c060eaa640d6801b6d42e714a66bb2e6afac8
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"
44using 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
51void *instrMem;
52uint32_t  instrMemSize = 128 * 1024;
53char     dataMem[8192];
54
55typedef void (*asm_function_t)();
56extern "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)
60const uint32_t NA = 0;
61const uint32_t NUM_REGS = 32;
62const uint32_t NUM_FLAGS = 16;
63
64enum 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
100enum shift_t
101{
102    SHIFT_LSL,
103    SHIFT_LSR,
104    SHIFT_ASR,
105    SHIFT_ROR,
106    SHIFT_NONE
107};
108
109enum offset_t
110{
111    REG_SCALE_OFFSET,
112    REG_OFFSET,
113    IMM8_OFFSET,
114    IMM12_OFFSET,
115    NO_OFFSET
116};
117
118enum 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
125const 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
132struct 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
153struct 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
179dataOpTest_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
363dataTransferTest_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
408void flushcache()
409{
410    const long base = long(instrMem);
411    const long curr = base + long(instrMemSize);
412    __builtin___clear_cache((char*)base, (char*)curr);
413}
414void 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
520void 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
656void 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
712int 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