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((void*)base, (void*)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], regs[i]); 498 return; 499 } 500 } 501 502 if(test.checkRd == 1 && (uint64_t)regs[Rd] != test.postRdValue) 503 { 504 printf("Test %x failed, Expected(%"PRIx64"), Actual(%"PRIx64")\n", 505 test.id, test.postRdValue, regs[Rd]); 506 } 507 else if(test.checkFlag == 1 && flags[test.postFlag] == 0) 508 { 509 printf("Test %x failed Flag(%s) NOT set\n", 510 test.id,cc_code[test.postFlag]); 511 } 512 else 513 { 514 printf("Test %x passed\n", test.id); 515 } 516 } 517 518 519 void dataTransferTest(dataTransferTest_t test, ARMAssemblerInterface *a64asm, 520 uint32_t Rd = 0, uint32_t Rn = 1,uint32_t Rm = 2) 521 { 522 int64_t regs[NUM_REGS] = {0}; 523 int64_t savedRegs[NUM_REGS] = {0}; 524 int32_t flags[NUM_FLAGS] = {0}; 525 uint32_t i; 526 for(i = 0; i < NUM_REGS; ++i) 527 { 528 regs[i] = i; 529 } 530 531 uint32_t op2; 532 533 regs[Rd] = test.RdValue; 534 regs[Rn] = (uint64_t)(&dataMem[test.RnValue]); 535 regs[Rm] = test.RmValue; 536 flags[test.preFlag] = 1; 537 538 if(test.setMem == true) 539 { 540 unsigned char *mem = (unsigned char *)&dataMem[test.memOffset]; 541 uint64_t value = test.memValue; 542 for(int j = 0; j < 8; ++j) 543 { 544 mem[j] = value & 0x00FF; 545 value >>= 8; 546 } 547 } 548 a64asm->reset(); 549 a64asm->prolog(); 550 if(test.offsetType == REG_SCALE_OFFSET) 551 { 552 op2 = a64asm->reg_scale_pre(Rm); 553 } 554 else if(test.offsetType == REG_OFFSET) 555 { 556 op2 = a64asm->reg_pre(Rm); 557 } 558 else if(test.offsetType == IMM12_OFFSET && test.preIndex == true) 559 { 560 op2 = a64asm->immed12_pre(test.immValue, test.writeBack); 561 } 562 else if(test.offsetType == IMM12_OFFSET && test.postIndex == true) 563 { 564 op2 = a64asm->immed12_post(test.immValue); 565 } 566 else if(test.offsetType == IMM8_OFFSET && test.preIndex == true) 567 { 568 op2 = a64asm->immed8_pre(test.immValue, test.writeBack); 569 } 570 else if(test.offsetType == IMM8_OFFSET && test.postIndex == true) 571 { 572 op2 = a64asm->immed8_post(test.immValue); 573 } 574 else if(test.offsetType == NO_OFFSET) 575 { 576 op2 = a64asm->__immed12_pre(0); 577 } 578 else 579 { 580 printf("Error - Unknown offset\n"); return; 581 } 582 583 switch(test.op) 584 { 585 case INSTR_LDR: a64asm->LDR(test.cond, Rd,Rn,op2); break; 586 case INSTR_LDRB: a64asm->LDRB(test.cond, Rd,Rn,op2); break; 587 case INSTR_LDRH: a64asm->LDRH(test.cond, Rd,Rn,op2); break; 588 case INSTR_ADDR_LDR: a64asm->ADDR_LDR(test.cond, Rd,Rn,op2); break; 589 case INSTR_STR: a64asm->STR(test.cond, Rd,Rn,op2); break; 590 case INSTR_STRB: a64asm->STRB(test.cond, Rd,Rn,op2); break; 591 case INSTR_STRH: a64asm->STRH(test.cond, Rd,Rn,op2); break; 592 case INSTR_ADDR_STR: a64asm->ADDR_STR(test.cond, Rd,Rn,op2); break; 593 default: printf("Error"); return; 594 } 595 a64asm->epilog(0); 596 flushcache(); 597 598 asm_function_t asm_function = (asm_function_t)(instrMem); 599 600 for(i = 0; i < NUM_REGS; ++i) 601 savedRegs[i] = regs[i]; 602 603 604 asm_test_jacket(asm_function, regs, flags); 605 606 /* Check if all regs except Rd/Rn are same */ 607 for(i = 0; i < NUM_REGS; ++i) 608 { 609 if(i == Rd || i == Rn) continue; 610 if(regs[i] != savedRegs[i]) 611 { 612 printf("Test %x failed Reg(%d) tampered" 613 " Expected(0x%"PRIx64"), Actual(0x%"PRIx64") t\n", 614 test.id, i, savedRegs[i], regs[i]); 615 return; 616 } 617 } 618 619 if((uint64_t)regs[Rd] != test.postRdValue) 620 { 621 printf("Test %x failed, " 622 "Expected in Rd(0x%"PRIx64"), Actual(0x%"PRIx64")\n", 623 test.id, test.postRdValue, regs[Rd]); 624 } 625 else if((uint64_t)regs[Rn] != (uint64_t)(&dataMem[test.postRnValue])) 626 { 627 printf("Test %x failed, " 628 "Expected in Rn(0x%"PRIx64"), Actual(0x%"PRIx64")\n", 629 test.id, test.postRnValue, regs[Rn] - (uint64_t)dataMem); 630 } 631 else if(test.checkMem == true) 632 { 633 unsigned char *addr = (unsigned char *)&dataMem[test.postMemOffset]; 634 uint64_t value; 635 value = 0; 636 for(uint32_t j = 0; j < test.postMemLength; ++j) 637 value = (value << 8) | addr[test.postMemLength-j-1]; 638 if(value != test.postMemValue) 639 { 640 printf("Test %x failed, " 641 "Expected in Mem(0x%"PRIx64"), Actual(0x%"PRIx64")\n", 642 test.id, test.postMemValue, value); 643 } 644 else 645 { 646 printf("Test %x passed\n", test.id); 647 } 648 } 649 else 650 { 651 printf("Test %x passed\n", test.id); 652 } 653 } 654 655 void dataTransferLDMSTM(ARMAssemblerInterface *a64asm) 656 { 657 int64_t regs[NUM_REGS] = {0}; 658 int32_t flags[NUM_FLAGS] = {0}; 659 const uint32_t numArmv7Regs = 16; 660 661 uint32_t Rn = ARMAssemblerInterface::SP; 662 663 uint32_t patterns[] = 664 { 665 0x5A03, 666 0x4CF0, 667 0x1EA6, 668 0x0DBF, 669 }; 670 671 uint32_t i, j; 672 for(i = 0; i < sizeof(patterns)/sizeof(uint32_t); ++i) 673 { 674 for(j = 0; j < NUM_REGS; ++j) 675 { 676 regs[j] = j; 677 } 678 a64asm->reset(); 679 a64asm->prolog(); 680 a64asm->STM(AL,ARMAssemblerInterface::DB,Rn,1,patterns[i]); 681 for(j = 0; j < numArmv7Regs; ++j) 682 { 683 uint32_t op2 = a64asm->imm(0x31); 684 a64asm->MOV(AL, 0,j,op2); 685 } 686 a64asm->LDM(AL,ARMAssemblerInterface::IA,Rn,1,patterns[i]); 687 a64asm->epilog(0); 688 flushcache(); 689 690 asm_function_t asm_function = (asm_function_t)(instrMem); 691 asm_test_jacket(asm_function, regs, flags); 692 693 for(j = 0; j < numArmv7Regs; ++j) 694 { 695 if((1 << j) & patterns[i]) 696 { 697 if(regs[j] != j) 698 { 699 printf("LDM/STM Test %x failed " 700 "Reg%d expected(0x%x) Actual(0x%"PRIx64") \n", 701 patterns[i],j,j,regs[j]); 702 break; 703 } 704 } 705 } 706 if(j == numArmv7Regs) 707 printf("LDM/STM Test %x passed\n", patterns[i]); 708 } 709 } 710 711 int main(void) 712 { 713 uint32_t i; 714 715 /* Allocate memory to store instructions generated by ArmToArm64Assembler */ 716 { 717 int fd = ashmem_create_region("code cache", instrMemSize); 718 if(fd < 0) 719 printf("Creating code cache, ashmem_create_region " 720 "failed with error '%s'", strerror(errno)); 721 instrMem = mmap(NULL, instrMemSize, 722 PROT_READ | PROT_WRITE | PROT_EXEC, 723 MAP_PRIVATE, fd, 0); 724 } 725 726 ArmToArm64Assembler a64asm(instrMem); 727 728 if(TESTS_DATAOP_ENABLE) 729 { 730 printf("Running data processing tests\n"); 731 for(i = 0; i < sizeof(dataOpTests)/sizeof(dataOpTest_t); ++i) 732 dataOpTest(dataOpTests[i], &a64asm); 733 } 734 735 if(TESTS_DATATRANSFER_ENABLE) 736 { 737 printf("Running data transfer tests\n"); 738 for(i = 0; i < sizeof(dataTransferTests)/sizeof(dataTransferTest_t); ++i) 739 dataTransferTest(dataTransferTests[i], &a64asm); 740 } 741 742 if(TESTS_LDMSTM_ENABLE) 743 { 744 printf("Running LDM/STM tests\n"); 745 dataTransferLDMSTM(&a64asm); 746 } 747 748 749 if(TESTS_REG_CORRUPTION_ENABLE) 750 { 751 uint32_t reg_list[] = {0,1,12,14}; 752 uint32_t Rd, Rm, Rs, Rn; 753 uint32_t i; 754 uint32_t numRegs = sizeof(reg_list)/sizeof(uint32_t); 755 756 printf("Running Register corruption tests\n"); 757 for(i = 0; i < sizeof(dataOpTests)/sizeof(dataOpTest_t); ++i) 758 { 759 for(Rd = 0; Rd < numRegs; ++Rd) 760 { 761 for(Rn = 0; Rn < numRegs; ++Rn) 762 { 763 for(Rm = 0; Rm < numRegs; ++Rm) 764 { 765 for(Rs = 0; Rs < numRegs;++Rs) 766 { 767 if(Rd == Rn || Rd == Rm || Rd == Rs) continue; 768 if(Rn == Rm || Rn == Rs) continue; 769 if(Rm == Rs) continue; 770 printf("Testing combination Rd(%d), Rn(%d)," 771 " Rm(%d), Rs(%d): ", 772 reg_list[Rd], reg_list[Rn], reg_list[Rm], reg_list[Rs]); 773 dataOpTest(dataOpTests[i], &a64asm, reg_list[Rd], 774 reg_list[Rn], reg_list[Rm], reg_list[Rs]); 775 } 776 } 777 } 778 } 779 } 780 } 781 return 0; 782 } 783