1// Copyright 2016, VIXL authors 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are met: 6// 7// * Redistributions of source code must retain the above copyright notice, 8// this list of conditions and the following disclaimer. 9// * Redistributions in binary form must reproduce the above copyright notice, 10// this list of conditions and the following disclaimer in the documentation 11// and/or other materials provided with the distribution. 12// * Neither the name of ARM Limited nor the names of its contributors may be 13// used to endorse or promote products derived from this software without 14// specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27 28// ----------------------------------------------------------------------------- 29// This file is auto generated from the 30// test/aarch32/config/template-simulator-aarch32.cc.in template file using 31// tools/generate_tests.py. 32// 33// PLEASE DO NOT EDIT. 34// ----------------------------------------------------------------------------- 35 36 37#include "test-runner.h" 38 39#include "test-utils.h" 40#include "test-utils-aarch32.h" 41 42#include "aarch32/assembler-aarch32.h" 43#include "aarch32/disasm-aarch32.h" 44#include "aarch32/macro-assembler-aarch32.h" 45 46#define __ masm. 47#define BUF_SIZE (4096) 48 49#ifdef VIXL_INCLUDE_SIMULATOR_AARCH32 50// Run tests with the simulator. 51 52#define SETUP() MacroAssembler masm(BUF_SIZE) 53 54#define START() masm.GetBuffer()->Reset() 55 56#define END() \ 57 __ Hlt(0); \ 58 __ FinalizeCode(); 59 60// TODO: Run the tests in the simulator. 61#define RUN() 62 63#else // ifdef VIXL_INCLUDE_SIMULATOR_AARCH32. 64 65#define SETUP() \ 66 MacroAssembler masm(BUF_SIZE); \ 67 UseScratchRegisterScope harness_scratch; 68 69#define START() \ 70 harness_scratch.Open(&masm); \ 71 harness_scratch.ExcludeAll(); \ 72 masm.GetBuffer()->Reset(); \ 73 __ Push(r4); \ 74 __ Push(r5); \ 75 __ Push(r6); \ 76 __ Push(r7); \ 77 __ Push(r8); \ 78 __ Push(r9); \ 79 __ Push(r10); \ 80 __ Push(r11); \ 81 __ Push(lr); \ 82 harness_scratch.Include(ip); 83 84#define END() \ 85 harness_scratch.Exclude(ip); \ 86 __ Pop(lr); \ 87 __ Pop(r11); \ 88 __ Pop(r10); \ 89 __ Pop(r9); \ 90 __ Pop(r8); \ 91 __ Pop(r7); \ 92 __ Pop(r6); \ 93 __ Pop(r5); \ 94 __ Pop(r4); \ 95 __ Bx(lr); \ 96 __ FinalizeCode(); \ 97 harness_scratch.Close(); 98 99#define RUN() \ 100 { \ 101 int pcs_offset = masm.IsUsingT32() ? 1 : 0; \ 102 masm.GetBuffer()->SetExecutable(); \ 103 ExecuteMemory(masm.GetBuffer()->GetStartAddress<byte*>(), \ 104 masm.GetSizeOfCodeGenerated(), \ 105 pcs_offset); \ 106 masm.GetBuffer()->SetWritable(); \ 107 } 108 109#endif // ifdef VIXL_INCLUDE_SIMULATOR_AARCH32 110 111namespace vixl { 112namespace aarch32 { 113 114// List of instruction encodings: 115#define FOREACH_INSTRUCTION(M) \ 116 M(Cmn) \ 117 M(Cmp) \ 118 M(Mov) \ 119 M(Movs) \ 120 M(Mvn) \ 121 M(Mvns) \ 122 M(Teq) \ 123 M(Tst) \ 124 M(Sxtb) \ 125 M(Sxtb16) \ 126 M(Sxth) \ 127 M(Uxtb) \ 128 M(Uxtb16) \ 129 M(Uxth) 130 131 132// The following definitions are defined again in each generated test, therefore 133// we need to place them in an anomymous namespace. It expresses that they are 134// local to this file only, and the compiler is not allowed to share these types 135// across test files during template instantiation. Specifically, `Operands` and 136// `Inputs` have various layouts across generated tests so they absolutely 137// cannot be shared. 138 139#ifdef VIXL_INCLUDE_TARGET_A32 140namespace { 141 142// Values to be passed to the assembler to produce the instruction under test. 143struct Operands { 144 Condition cond; 145 Register rd; 146 Register rn; 147}; 148 149// Input data to feed to the instruction. 150struct Inputs { 151 uint32_t apsr; 152 uint32_t rd; 153 uint32_t rn; 154}; 155 156// This structure contains all input data needed to test one specific encoding. 157// It used to generate a loop over an instruction. 158struct TestLoopData { 159 // The `operands` fields represents the values to pass to the assembler to 160 // produce the instruction. 161 Operands operands; 162 // Description of the operands, used for error reporting. 163 const char* operands_description; 164 // Unique identifier, used for generating traces. 165 const char* identifier; 166 // Array of values to be fed to the instruction. 167 size_t input_size; 168 const Inputs* inputs; 169}; 170 171static const Inputs kCondition[] = {{NFlag, 0xabababab, 0xabababab}, 172 {ZFlag, 0xabababab, 0xabababab}, 173 {CFlag, 0xabababab, 0xabababab}, 174 {VFlag, 0xabababab, 0xabababab}, 175 {NZFlag, 0xabababab, 0xabababab}, 176 {NCFlag, 0xabababab, 0xabababab}, 177 {NVFlag, 0xabababab, 0xabababab}, 178 {ZCFlag, 0xabababab, 0xabababab}, 179 {ZVFlag, 0xabababab, 0xabababab}, 180 {CVFlag, 0xabababab, 0xabababab}, 181 {NZCFlag, 0xabababab, 0xabababab}, 182 {NZVFlag, 0xabababab, 0xabababab}, 183 {NCVFlag, 0xabababab, 0xabababab}, 184 {ZCVFlag, 0xabababab, 0xabababab}, 185 {NZCVFlag, 0xabababab, 0xabababab}}; 186 187static const Inputs kRdIsRn[] = 188 {{NoFlag, 0x00000000, 0x00000000}, {NoFlag, 0x00000001, 0x00000001}, 189 {NoFlag, 0x00000002, 0x00000002}, {NoFlag, 0x00000020, 0x00000020}, 190 {NoFlag, 0x0000007d, 0x0000007d}, {NoFlag, 0x0000007e, 0x0000007e}, 191 {NoFlag, 0x0000007f, 0x0000007f}, {NoFlag, 0x00007ffd, 0x00007ffd}, 192 {NoFlag, 0x00007ffe, 0x00007ffe}, {NoFlag, 0x00007fff, 0x00007fff}, 193 {NoFlag, 0x33333333, 0x33333333}, {NoFlag, 0x55555555, 0x55555555}, 194 {NoFlag, 0x7ffffffd, 0x7ffffffd}, {NoFlag, 0x7ffffffe, 0x7ffffffe}, 195 {NoFlag, 0x7fffffff, 0x7fffffff}, {NoFlag, 0x80000000, 0x80000000}, 196 {NoFlag, 0x80000001, 0x80000001}, {NoFlag, 0xaaaaaaaa, 0xaaaaaaaa}, 197 {NoFlag, 0xcccccccc, 0xcccccccc}, {NoFlag, 0xffff8000, 0xffff8000}, 198 {NoFlag, 0xffff8001, 0xffff8001}, {NoFlag, 0xffff8002, 0xffff8002}, 199 {NoFlag, 0xffff8003, 0xffff8003}, {NoFlag, 0xffffff80, 0xffffff80}, 200 {NoFlag, 0xffffff81, 0xffffff81}, {NoFlag, 0xffffff82, 0xffffff82}, 201 {NoFlag, 0xffffff83, 0xffffff83}, {NoFlag, 0xffffffe0, 0xffffffe0}, 202 {NoFlag, 0xfffffffd, 0xfffffffd}, {NoFlag, 0xfffffffe, 0xfffffffe}, 203 {NoFlag, 0xffffffff, 0xffffffff}}; 204 205static const Inputs kRdIsNotRn[] = 206 {{NoFlag, 0x00000002, 0xcccccccc}, {NoFlag, 0x7ffffffd, 0x00007ffe}, 207 {NoFlag, 0xffffff80, 0x00000020}, {NoFlag, 0xaaaaaaaa, 0xaaaaaaaa}, 208 {NoFlag, 0x33333333, 0xffffff82}, {NoFlag, 0xffff8001, 0x7ffffffe}, 209 {NoFlag, 0xfffffffd, 0x00007ffe}, {NoFlag, 0xffffff80, 0x80000000}, 210 {NoFlag, 0x00000001, 0x33333333}, {NoFlag, 0xcccccccc, 0x7ffffffe}, 211 {NoFlag, 0x00000000, 0xcccccccc}, {NoFlag, 0x00000000, 0x55555555}, 212 {NoFlag, 0xffffffff, 0xffffffff}, {NoFlag, 0x0000007e, 0xffff8002}, 213 {NoFlag, 0x80000000, 0x7ffffffd}, {NoFlag, 0xffffff81, 0x0000007e}, 214 {NoFlag, 0x0000007f, 0xffff8001}, {NoFlag, 0xffffffe0, 0x00007ffd}, 215 {NoFlag, 0xffff8003, 0x00000002}, {NoFlag, 0xffffff83, 0x55555555}, 216 {NoFlag, 0xffffff83, 0xffffff80}, {NoFlag, 0xffffff81, 0xffff8000}, 217 {NoFlag, 0x00000020, 0x7ffffffe}, {NoFlag, 0xffffffe0, 0x00000000}, 218 {NoFlag, 0x7fffffff, 0x0000007e}, {NoFlag, 0x80000001, 0xffffffff}, 219 {NoFlag, 0x00000001, 0x80000001}, {NoFlag, 0x00000002, 0x0000007f}, 220 {NoFlag, 0x7fffffff, 0xcccccccc}, {NoFlag, 0x80000001, 0x00007ffe}, 221 {NoFlag, 0xffff8002, 0x0000007e}, {NoFlag, 0x00007ffe, 0xcccccccc}, 222 {NoFlag, 0x80000000, 0xffff8002}, {NoFlag, 0xffffff83, 0x7ffffffe}, 223 {NoFlag, 0xffff8001, 0x00000001}, {NoFlag, 0xffffff81, 0x00000020}, 224 {NoFlag, 0xfffffffe, 0xffff8001}, {NoFlag, 0xffffffff, 0xfffffffe}, 225 {NoFlag, 0xcccccccc, 0x55555555}, {NoFlag, 0x00000020, 0xffffff83}, 226 {NoFlag, 0xffffff83, 0xffff8001}, {NoFlag, 0xffffff83, 0xffff8000}, 227 {NoFlag, 0x00007fff, 0x00000002}, {NoFlag, 0x55555555, 0xffff8000}, 228 {NoFlag, 0x80000001, 0xffffff81}, {NoFlag, 0x00000002, 0x00000000}, 229 {NoFlag, 0x33333333, 0xffffff81}, {NoFlag, 0xffff8001, 0xffffff82}, 230 {NoFlag, 0xcccccccc, 0xffff8003}, {NoFlag, 0xffff8003, 0x7ffffffd}, 231 {NoFlag, 0x0000007d, 0x00007ffe}, {NoFlag, 0xffffff80, 0x0000007d}, 232 {NoFlag, 0xaaaaaaaa, 0x00007ffd}, {NoFlag, 0x80000000, 0xffffff82}, 233 {NoFlag, 0x00000002, 0x7ffffffe}, {NoFlag, 0x00000002, 0xffffff83}, 234 {NoFlag, 0x55555555, 0x00000002}, {NoFlag, 0xffffffff, 0xffffff82}, 235 {NoFlag, 0xaaaaaaaa, 0x00000020}, {NoFlag, 0x00000001, 0xffffff82}, 236 {NoFlag, 0x0000007f, 0xffffff82}, {NoFlag, 0x7ffffffd, 0xaaaaaaaa}, 237 {NoFlag, 0x00007ffe, 0x00000001}, {NoFlag, 0xfffffffd, 0xffffffe0}, 238 {NoFlag, 0xffffff81, 0xffffff83}, {NoFlag, 0x0000007d, 0x00000000}, 239 {NoFlag, 0x0000007d, 0xffff8000}, {NoFlag, 0xffffff81, 0x7fffffff}, 240 {NoFlag, 0xffffffff, 0x80000000}, {NoFlag, 0x00000000, 0x00000001}, 241 {NoFlag, 0x55555555, 0xffffff82}, {NoFlag, 0x00007ffe, 0x00007ffe}, 242 {NoFlag, 0x80000001, 0xfffffffd}, {NoFlag, 0x00007fff, 0x33333333}, 243 {NoFlag, 0x00007fff, 0x80000000}, {NoFlag, 0xcccccccc, 0x00007fff}, 244 {NoFlag, 0xfffffffe, 0xffffffe0}, {NoFlag, 0x7ffffffe, 0x0000007f}, 245 {NoFlag, 0x00007ffd, 0xffff8001}, {NoFlag, 0x00000002, 0x00000001}, 246 {NoFlag, 0x80000000, 0xffffffff}, {NoFlag, 0xffffff83, 0xcccccccc}, 247 {NoFlag, 0xffff8002, 0x7ffffffe}, {NoFlag, 0xaaaaaaaa, 0x00000000}, 248 {NoFlag, 0xffffff80, 0xcccccccc}, {NoFlag, 0x33333333, 0xffffff83}, 249 {NoFlag, 0x0000007e, 0xffffffe0}, {NoFlag, 0x0000007e, 0x00007fff}, 250 {NoFlag, 0x0000007f, 0x00000002}, {NoFlag, 0x7ffffffe, 0xcccccccc}, 251 {NoFlag, 0x0000007d, 0xffffff80}, {NoFlag, 0x00007fff, 0x00000020}, 252 {NoFlag, 0x7ffffffe, 0xfffffffe}, {NoFlag, 0xfffffffe, 0xffffff81}, 253 {NoFlag, 0xffffffff, 0x0000007f}, {NoFlag, 0xffff8002, 0x7ffffffd}, 254 {NoFlag, 0xffff8001, 0xfffffffe}, {NoFlag, 0x33333333, 0xffff8002}, 255 {NoFlag, 0x00000000, 0xffffffff}, {NoFlag, 0x33333333, 0xffffff80}, 256 {NoFlag, 0x0000007f, 0x00007fff}, {NoFlag, 0xffffffff, 0xffff8001}, 257 {NoFlag, 0x7fffffff, 0xffff8002}, {NoFlag, 0x7ffffffd, 0xffffff83}, 258 {NoFlag, 0x7fffffff, 0x0000007f}, {NoFlag, 0xffffff83, 0xfffffffe}, 259 {NoFlag, 0x7ffffffe, 0xffff8003}, {NoFlag, 0xffff8002, 0xffff8002}, 260 {NoFlag, 0x80000001, 0x0000007f}, {NoFlag, 0x00000020, 0x00000002}, 261 {NoFlag, 0xffffff82, 0xffff8001}, {NoFlag, 0xffffffff, 0x00000001}, 262 {NoFlag, 0xffffff80, 0xffff8002}, {NoFlag, 0xffff8003, 0x7fffffff}, 263 {NoFlag, 0xffffffff, 0xffff8000}, {NoFlag, 0xffff8002, 0x00007ffd}, 264 {NoFlag, 0x00000020, 0xffffff81}, {NoFlag, 0x00000001, 0x55555555}, 265 {NoFlag, 0x7ffffffe, 0x00000020}, {NoFlag, 0x80000000, 0x00000001}, 266 {NoFlag, 0x00007ffd, 0xffff8002}, {NoFlag, 0x7fffffff, 0xfffffffe}, 267 {NoFlag, 0xcccccccc, 0x00007ffd}, {NoFlag, 0x00000000, 0xfffffffd}, 268 {NoFlag, 0xffff8003, 0xffffff80}, {NoFlag, 0x80000001, 0xffffff80}, 269 {NoFlag, 0xffffffff, 0xffff8002}, {NoFlag, 0x00007ffe, 0xffff8002}, 270 {NoFlag, 0xffffff80, 0x00007ffe}, {NoFlag, 0x80000001, 0xffff8001}, 271 {NoFlag, 0x0000007f, 0xffffff80}, {NoFlag, 0xffffff81, 0x80000000}, 272 {NoFlag, 0x00007fff, 0x00007ffe}, {NoFlag, 0x33333333, 0xffff8000}, 273 {NoFlag, 0x33333333, 0x00007fff}, {NoFlag, 0x00000000, 0x0000007d}, 274 {NoFlag, 0x80000001, 0x00000000}, {NoFlag, 0xffffffff, 0x55555555}, 275 {NoFlag, 0x80000001, 0x80000000}, {NoFlag, 0xffffffff, 0xffffff80}, 276 {NoFlag, 0xffffff81, 0xffff8003}, {NoFlag, 0x55555555, 0x80000001}, 277 {NoFlag, 0x7fffffff, 0xffff8001}, {NoFlag, 0xffffff83, 0x00000002}, 278 {NoFlag, 0x0000007e, 0xffffff81}, {NoFlag, 0x80000000, 0xffff8001}, 279 {NoFlag, 0xffffff80, 0xfffffffe}, {NoFlag, 0x0000007e, 0xfffffffd}, 280 {NoFlag, 0xffffffe0, 0xffffffff}, {NoFlag, 0x55555555, 0x80000000}, 281 {NoFlag, 0x0000007d, 0x80000001}, {NoFlag, 0xffffffe0, 0x7ffffffd}, 282 {NoFlag, 0x00000000, 0x00000000}, {NoFlag, 0x55555555, 0x00000001}, 283 {NoFlag, 0x00007ffd, 0x7fffffff}, {NoFlag, 0x55555555, 0xffffffff}, 284 {NoFlag, 0xffff8003, 0x00007fff}, {NoFlag, 0xffffff82, 0x00007fff}, 285 {NoFlag, 0x33333333, 0x55555555}, {NoFlag, 0x00000020, 0x33333333}, 286 {NoFlag, 0x7ffffffe, 0xfffffffd}, {NoFlag, 0x7ffffffe, 0x00000001}, 287 {NoFlag, 0xffffff83, 0xffffffe0}, {NoFlag, 0xfffffffe, 0xaaaaaaaa}, 288 {NoFlag, 0xffff8002, 0x33333333}, {NoFlag, 0xffff8002, 0xffff8003}, 289 {NoFlag, 0x33333333, 0x7fffffff}, {NoFlag, 0xfffffffd, 0xffffff83}, 290 {NoFlag, 0x00000000, 0xffff8000}, {NoFlag, 0xffffff82, 0x55555555}, 291 {NoFlag, 0xffffff82, 0xffffff81}, {NoFlag, 0xcccccccc, 0xfffffffe}, 292 {NoFlag, 0xfffffffd, 0x7fffffff}, {NoFlag, 0x00007fff, 0x7fffffff}, 293 {NoFlag, 0xffffff83, 0xffff8003}, {NoFlag, 0xfffffffe, 0xffffffff}, 294 {NoFlag, 0x7ffffffd, 0x00007ffd}, {NoFlag, 0x7ffffffd, 0x00007fff}, 295 {NoFlag, 0x00007ffd, 0xffffffff}, {NoFlag, 0x00000001, 0xffff8003}, 296 {NoFlag, 0xffffff80, 0xfffffffd}, {NoFlag, 0x33333333, 0x80000000}, 297 {NoFlag, 0xffff8001, 0x00000020}, {NoFlag, 0xcccccccc, 0x00000002}, 298 {NoFlag, 0x00000000, 0x00000002}, {NoFlag, 0x0000007d, 0x00007fff}, 299 {NoFlag, 0xcccccccc, 0x00000001}, {NoFlag, 0xffffff83, 0x00007fff}, 300 {NoFlag, 0x80000001, 0x00000020}, {NoFlag, 0xffff8003, 0xffffffe0}, 301 {NoFlag, 0x00007ffd, 0xaaaaaaaa}, {NoFlag, 0x33333333, 0xffff8001}, 302 {NoFlag, 0xffffff83, 0x80000001}, {NoFlag, 0xffff8000, 0xffff8000}, 303 {NoFlag, 0x00007ffe, 0xffff8001}, {NoFlag, 0x7ffffffd, 0x00000000}, 304 {NoFlag, 0x00007ffe, 0x33333333}, {NoFlag, 0xffff8001, 0xffffff80}, 305 {NoFlag, 0xfffffffe, 0x55555555}, {NoFlag, 0xffffff82, 0xffffffff}}; 306 307 308// A loop will be generated for each element of this array. 309const TestLoopData kTests[] = { 310 {{eq, r0, r0}, 311 "eq r0 r0", 312 "Condition_eq_r0_r0", 313 ARRAY_SIZE(kCondition), 314 kCondition}, 315 {{ne, r0, r0}, 316 "ne r0 r0", 317 "Condition_ne_r0_r0", 318 ARRAY_SIZE(kCondition), 319 kCondition}, 320 {{cs, r0, r0}, 321 "cs r0 r0", 322 "Condition_cs_r0_r0", 323 ARRAY_SIZE(kCondition), 324 kCondition}, 325 {{cc, r0, r0}, 326 "cc r0 r0", 327 "Condition_cc_r0_r0", 328 ARRAY_SIZE(kCondition), 329 kCondition}, 330 {{mi, r0, r0}, 331 "mi r0 r0", 332 "Condition_mi_r0_r0", 333 ARRAY_SIZE(kCondition), 334 kCondition}, 335 {{pl, r0, r0}, 336 "pl r0 r0", 337 "Condition_pl_r0_r0", 338 ARRAY_SIZE(kCondition), 339 kCondition}, 340 {{vs, r0, r0}, 341 "vs r0 r0", 342 "Condition_vs_r0_r0", 343 ARRAY_SIZE(kCondition), 344 kCondition}, 345 {{vc, r0, r0}, 346 "vc r0 r0", 347 "Condition_vc_r0_r0", 348 ARRAY_SIZE(kCondition), 349 kCondition}, 350 {{hi, r0, r0}, 351 "hi r0 r0", 352 "Condition_hi_r0_r0", 353 ARRAY_SIZE(kCondition), 354 kCondition}, 355 {{ls, r0, r0}, 356 "ls r0 r0", 357 "Condition_ls_r0_r0", 358 ARRAY_SIZE(kCondition), 359 kCondition}, 360 {{ge, r0, r0}, 361 "ge r0 r0", 362 "Condition_ge_r0_r0", 363 ARRAY_SIZE(kCondition), 364 kCondition}, 365 {{lt, r0, r0}, 366 "lt r0 r0", 367 "Condition_lt_r0_r0", 368 ARRAY_SIZE(kCondition), 369 kCondition}, 370 {{gt, r0, r0}, 371 "gt r0 r0", 372 "Condition_gt_r0_r0", 373 ARRAY_SIZE(kCondition), 374 kCondition}, 375 {{le, r0, r0}, 376 "le r0 r0", 377 "Condition_le_r0_r0", 378 ARRAY_SIZE(kCondition), 379 kCondition}, 380 {{al, r0, r0}, 381 "al r0 r0", 382 "Condition_al_r0_r0", 383 ARRAY_SIZE(kCondition), 384 kCondition}, 385 {{al, r0, r0}, "al r0 r0", "RdIsRn_al_r0_r0", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 386 {{al, r1, r1}, "al r1 r1", "RdIsRn_al_r1_r1", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 387 {{al, r2, r2}, "al r2 r2", "RdIsRn_al_r2_r2", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 388 {{al, r3, r3}, "al r3 r3", "RdIsRn_al_r3_r3", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 389 {{al, r4, r4}, "al r4 r4", "RdIsRn_al_r4_r4", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 390 {{al, r5, r5}, "al r5 r5", "RdIsRn_al_r5_r5", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 391 {{al, r6, r6}, "al r6 r6", "RdIsRn_al_r6_r6", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 392 {{al, r7, r7}, "al r7 r7", "RdIsRn_al_r7_r7", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 393 {{al, r8, r8}, "al r8 r8", "RdIsRn_al_r8_r8", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 394 {{al, r9, r9}, "al r9 r9", "RdIsRn_al_r9_r9", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 395 {{al, r10, r10}, 396 "al r10 r10", 397 "RdIsRn_al_r10_r10", 398 ARRAY_SIZE(kRdIsRn), 399 kRdIsRn}, 400 {{al, r11, r11}, 401 "al r11 r11", 402 "RdIsRn_al_r11_r11", 403 ARRAY_SIZE(kRdIsRn), 404 kRdIsRn}, 405 {{al, r12, r12}, 406 "al r12 r12", 407 "RdIsRn_al_r12_r12", 408 ARRAY_SIZE(kRdIsRn), 409 kRdIsRn}, 410 {{al, r14, r14}, 411 "al r14 r14", 412 "RdIsRn_al_r14_r14", 413 ARRAY_SIZE(kRdIsRn), 414 kRdIsRn}, 415 {{al, r1, r8}, 416 "al r1 r8", 417 "RdIsNotRn_al_r1_r8", 418 ARRAY_SIZE(kRdIsNotRn), 419 kRdIsNotRn}, 420 {{al, r7, r4}, 421 "al r7 r4", 422 "RdIsNotRn_al_r7_r4", 423 ARRAY_SIZE(kRdIsNotRn), 424 kRdIsNotRn}, 425 {{al, r14, r10}, 426 "al r14 r10", 427 "RdIsNotRn_al_r14_r10", 428 ARRAY_SIZE(kRdIsNotRn), 429 kRdIsNotRn}, 430 {{al, r10, r6}, 431 "al r10 r6", 432 "RdIsNotRn_al_r10_r6", 433 ARRAY_SIZE(kRdIsNotRn), 434 kRdIsNotRn}, 435 {{al, r6, r5}, 436 "al r6 r5", 437 "RdIsNotRn_al_r6_r5", 438 ARRAY_SIZE(kRdIsNotRn), 439 kRdIsNotRn}, 440 {{al, r12, r2}, 441 "al r12 r2", 442 "RdIsNotRn_al_r12_r2", 443 ARRAY_SIZE(kRdIsNotRn), 444 kRdIsNotRn}, 445 {{al, r0, r11}, 446 "al r0 r11", 447 "RdIsNotRn_al_r0_r11", 448 ARRAY_SIZE(kRdIsNotRn), 449 kRdIsNotRn}, 450 {{al, r10, r14}, 451 "al r10 r14", 452 "RdIsNotRn_al_r10_r14", 453 ARRAY_SIZE(kRdIsNotRn), 454 kRdIsNotRn}, 455 {{al, r0, r5}, 456 "al r0 r5", 457 "RdIsNotRn_al_r0_r5", 458 ARRAY_SIZE(kRdIsNotRn), 459 kRdIsNotRn}, 460 {{al, r0, r3}, 461 "al r0 r3", 462 "RdIsNotRn_al_r0_r3", 463 ARRAY_SIZE(kRdIsNotRn), 464 kRdIsNotRn}}; 465 466// We record all inputs to the instructions as outputs. This way, we also check 467// that what shouldn't change didn't change. 468struct TestResult { 469 size_t output_size; 470 const Inputs* outputs; 471}; 472 473// These headers each contain an array of `TestResult` with the reference output 474// values. The reference arrays are names `kReference{mnemonic}`. 475#include "aarch32/traces/simulator-cond-rd-operand-rn-cmn-a32.h" 476#include "aarch32/traces/simulator-cond-rd-operand-rn-cmp-a32.h" 477#include "aarch32/traces/simulator-cond-rd-operand-rn-mov-a32.h" 478#include "aarch32/traces/simulator-cond-rd-operand-rn-movs-a32.h" 479#include "aarch32/traces/simulator-cond-rd-operand-rn-mvn-a32.h" 480#include "aarch32/traces/simulator-cond-rd-operand-rn-mvns-a32.h" 481#include "aarch32/traces/simulator-cond-rd-operand-rn-sxtb-a32.h" 482#include "aarch32/traces/simulator-cond-rd-operand-rn-sxtb16-a32.h" 483#include "aarch32/traces/simulator-cond-rd-operand-rn-sxth-a32.h" 484#include "aarch32/traces/simulator-cond-rd-operand-rn-teq-a32.h" 485#include "aarch32/traces/simulator-cond-rd-operand-rn-tst-a32.h" 486#include "aarch32/traces/simulator-cond-rd-operand-rn-uxtb-a32.h" 487#include "aarch32/traces/simulator-cond-rd-operand-rn-uxtb16-a32.h" 488#include "aarch32/traces/simulator-cond-rd-operand-rn-uxth-a32.h" 489 490 491// The maximum number of errors to report in detail for each test. 492const unsigned kErrorReportLimit = 8; 493 494typedef void (MacroAssembler::*Fn)(Condition cond, 495 Register rd, 496 const Operand& op); 497 498void TestHelper(Fn instruction, 499 const char* mnemonic, 500 const TestResult reference[]) { 501 SETUP(); 502 masm.UseA32(); 503 START(); 504 505 // Data to compare to `reference`. 506 TestResult* results[ARRAY_SIZE(kTests)]; 507 508 // Test cases for memory bound instructions may allocate a buffer and save its 509 // address in this array. 510 byte* scratch_memory_buffers[ARRAY_SIZE(kTests)]; 511 512 // Generate a loop for each element in `kTests`. Each loop tests one specific 513 // instruction. 514 for (unsigned i = 0; i < ARRAY_SIZE(kTests); i++) { 515 // Allocate results on the heap for this test. 516 results[i] = new TestResult; 517 results[i]->outputs = new Inputs[kTests[i].input_size]; 518 results[i]->output_size = kTests[i].input_size; 519 520 size_t input_stride = sizeof(kTests[i].inputs[0]) * kTests[i].input_size; 521 VIXL_ASSERT(IsUint32(input_stride)); 522 523 scratch_memory_buffers[i] = NULL; 524 525 Label loop; 526 UseScratchRegisterScope scratch_registers(&masm); 527 // Include all registers from r0 ro r12. 528 scratch_registers.Include(RegisterList(0x1fff)); 529 530 // Values to pass to the macro-assembler. 531 Condition cond = kTests[i].operands.cond; 532 Register rd = kTests[i].operands.rd; 533 Register rn = kTests[i].operands.rn; 534 Operand op(rn); 535 scratch_registers.Exclude(rd); 536 scratch_registers.Exclude(rn); 537 538 // Allocate reserved registers for our own use. 539 Register input_ptr = scratch_registers.Acquire(); 540 Register input_end = scratch_registers.Acquire(); 541 Register result_ptr = scratch_registers.Acquire(); 542 543 // Initialize `input_ptr` to the first element and `input_end` the address 544 // after the array. 545 __ Mov(input_ptr, Operand::From(kTests[i].inputs)); 546 __ Add(input_end, input_ptr, static_cast<uint32_t>(input_stride)); 547 __ Mov(result_ptr, Operand::From(results[i]->outputs)); 548 __ Bind(&loop); 549 550 { 551 UseScratchRegisterScope temp_registers(&masm); 552 Register nzcv_bits = temp_registers.Acquire(); 553 Register saved_q_bit = temp_registers.Acquire(); 554 // Save the `Q` bit flag. 555 __ Mrs(saved_q_bit, APSR); 556 __ And(saved_q_bit, saved_q_bit, QFlag); 557 // Set the `NZCV` and `Q` flags together. 558 __ Ldr(nzcv_bits, MemOperand(input_ptr, offsetof(Inputs, apsr))); 559 __ Orr(nzcv_bits, nzcv_bits, saved_q_bit); 560 __ Msr(APSR_nzcvq, nzcv_bits); 561 } 562 __ Ldr(rd, MemOperand(input_ptr, offsetof(Inputs, rd))); 563 __ Ldr(rn, MemOperand(input_ptr, offsetof(Inputs, rn))); 564 565 (masm.*instruction)(cond, rd, op); 566 567 { 568 UseScratchRegisterScope temp_registers(&masm); 569 Register nzcv_bits = temp_registers.Acquire(); 570 __ Mrs(nzcv_bits, APSR); 571 // Only record the NZCV bits. 572 __ And(nzcv_bits, nzcv_bits, NZCVFlag); 573 __ Str(nzcv_bits, MemOperand(result_ptr, offsetof(Inputs, apsr))); 574 } 575 __ Str(rd, MemOperand(result_ptr, offsetof(Inputs, rd))); 576 __ Str(rn, MemOperand(result_ptr, offsetof(Inputs, rn))); 577 578 // Advance the result pointer. 579 __ Add(result_ptr, result_ptr, Operand::From(sizeof(kTests[i].inputs[0]))); 580 // Loop back until `input_ptr` is lower than `input_base`. 581 __ Add(input_ptr, input_ptr, Operand::From(sizeof(kTests[i].inputs[0]))); 582 __ Cmp(input_ptr, input_end); 583 __ B(ne, &loop); 584 } 585 586 END(); 587 588 RUN(); 589 590 if (Test::generate_test_trace()) { 591 // Print the results. 592 for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) { 593 printf("const Inputs kOutputs_%s_%s[] = {\n", 594 mnemonic, 595 kTests[i].identifier); 596 for (size_t j = 0; j < results[i]->output_size; j++) { 597 printf(" { "); 598 printf("0x%08" PRIx32, results[i]->outputs[j].apsr); 599 printf(", "); 600 printf("0x%08" PRIx32, results[i]->outputs[j].rd); 601 printf(", "); 602 printf("0x%08" PRIx32, results[i]->outputs[j].rn); 603 printf(" },\n"); 604 } 605 printf("};\n"); 606 } 607 printf("const TestResult kReference%s[] = {\n", mnemonic); 608 for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) { 609 printf(" {\n"); 610 printf(" ARRAY_SIZE(kOutputs_%s_%s),\n", 611 mnemonic, 612 kTests[i].identifier); 613 printf(" kOutputs_%s_%s,\n", mnemonic, kTests[i].identifier); 614 printf(" },\n"); 615 } 616 printf("};\n"); 617 } else if (kCheckSimulatorTestResults) { 618 // Check the results. 619 unsigned total_error_count = 0; 620 for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) { 621 bool instruction_has_errors = false; 622 for (size_t j = 0; j < kTests[i].input_size; j++) { 623 uint32_t apsr = results[i]->outputs[j].apsr; 624 uint32_t rd = results[i]->outputs[j].rd; 625 uint32_t rn = results[i]->outputs[j].rn; 626 uint32_t apsr_input = kTests[i].inputs[j].apsr; 627 uint32_t rd_input = kTests[i].inputs[j].rd; 628 uint32_t rn_input = kTests[i].inputs[j].rn; 629 uint32_t apsr_ref = reference[i].outputs[j].apsr; 630 uint32_t rd_ref = reference[i].outputs[j].rd; 631 uint32_t rn_ref = reference[i].outputs[j].rn; 632 633 if (((apsr != apsr_ref) || (rd != rd_ref) || (rn != rn_ref)) && 634 (++total_error_count <= kErrorReportLimit)) { 635 // Print the instruction once even if it triggered multiple failures. 636 if (!instruction_has_errors) { 637 printf("Error(s) when testing \"%s %s\":\n", 638 mnemonic, 639 kTests[i].operands_description); 640 instruction_has_errors = true; 641 } 642 // Print subsequent errors. 643 printf(" Input: "); 644 printf("0x%08" PRIx32, apsr_input); 645 printf(", "); 646 printf("0x%08" PRIx32, rd_input); 647 printf(", "); 648 printf("0x%08" PRIx32, rn_input); 649 printf("\n"); 650 printf(" Expected: "); 651 printf("0x%08" PRIx32, apsr_ref); 652 printf(", "); 653 printf("0x%08" PRIx32, rd_ref); 654 printf(", "); 655 printf("0x%08" PRIx32, rn_ref); 656 printf("\n"); 657 printf(" Found: "); 658 printf("0x%08" PRIx32, apsr); 659 printf(", "); 660 printf("0x%08" PRIx32, rd); 661 printf(", "); 662 printf("0x%08" PRIx32, rn); 663 printf("\n\n"); 664 } 665 } 666 } 667 668 if (total_error_count > kErrorReportLimit) { 669 printf("%u other errors follow.\n", 670 total_error_count - kErrorReportLimit); 671 } 672 VIXL_CHECK(total_error_count == 0); 673 } else { 674 VIXL_WARNING("Assembled the code, but did not run anything.\n"); 675 } 676 677 for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) { 678 delete[] results[i]->outputs; 679 delete results[i]; 680 delete[] scratch_memory_buffers[i]; 681 } 682} 683 684// Instantiate tests for each instruction in the list. 685// TODO: Remove this limitation by having a sandboxing mechanism. 686#if defined(VIXL_HOST_POINTER_32) 687#define TEST(mnemonic) \ 688 void Test_##mnemonic() { \ 689 TestHelper(&MacroAssembler::mnemonic, #mnemonic, kReference##mnemonic); \ 690 } \ 691 Test test_##mnemonic("AARCH32_SIMULATOR_COND_RD_OPERAND_RN_" #mnemonic \ 692 "_A32", \ 693 &Test_##mnemonic); 694#else 695#define TEST(mnemonic) \ 696 void Test_##mnemonic() { \ 697 VIXL_WARNING("This test can only run on a 32-bit host.\n"); \ 698 USE(TestHelper); \ 699 } \ 700 Test test_##mnemonic("AARCH32_SIMULATOR_COND_RD_OPERAND_RN_" #mnemonic \ 701 "_A32", \ 702 &Test_##mnemonic); 703#endif 704 705FOREACH_INSTRUCTION(TEST) 706#undef TEST 707 708} // namespace 709#endif 710 711} // namespace aarch32 712} // namespace vixl 713