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 111 namespace vixl { 112 namespace 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 125 126 // The following definitions are defined again in each generated test, therefore 127 // we need to place them in an anomymous namespace. It expresses that they are 128 // local to this file only, and the compiler is not allowed to share these types 129 // across test files during template instantiation. Specifically, `Operands` and 130 // `Inputs` have various layouts across generated tests so they absolutely 131 // cannot be shared. 132 133 #ifdef VIXL_INCLUDE_TARGET_T32 134 namespace { 135 136 // Values to be passed to the assembler to produce the instruction under test. 137 struct Operands { 138 Condition cond; 139 Register rd; 140 uint32_t immediate; 141 }; 142 143 // Input data to feed to the instruction. 144 struct Inputs { 145 uint32_t apsr; 146 uint32_t rd; 147 }; 148 149 // This structure contains all input data needed to test one specific encoding. 150 // It used to generate a loop over an instruction. 151 struct TestLoopData { 152 // The `operands` fields represents the values to pass to the assembler to 153 // produce the instruction. 154 Operands operands; 155 // Description of the operands, used for error reporting. 156 const char* operands_description; 157 // Unique identifier, used for generating traces. 158 const char* identifier; 159 // Array of values to be fed to the instruction. 160 size_t input_size; 161 const Inputs* inputs; 162 }; 163 164 static const Inputs kCondition[] = {{NFlag, 0xabababab}, 165 {ZFlag, 0xabababab}, 166 {CFlag, 0xabababab}, 167 {VFlag, 0xabababab}, 168 {NZFlag, 0xabababab}, 169 {NCFlag, 0xabababab}, 170 {NVFlag, 0xabababab}, 171 {ZCFlag, 0xabababab}, 172 {ZVFlag, 0xabababab}, 173 {CVFlag, 0xabababab}, 174 {NZCFlag, 0xabababab}, 175 {NZVFlag, 0xabababab}, 176 {NCVFlag, 0xabababab}, 177 {ZCVFlag, 0xabababab}, 178 {NZCVFlag, 0xabababab}}; 179 180 static const Inputs kModifiedImmediate[] = 181 {{NoFlag, 0x00000000}, {NoFlag, 0x00000001}, {NoFlag, 0x00000002}, 182 {NoFlag, 0x00000020}, {NoFlag, 0x0000007d}, {NoFlag, 0x0000007e}, 183 {NoFlag, 0x0000007f}, {NoFlag, 0x00007ffd}, {NoFlag, 0x00007ffe}, 184 {NoFlag, 0x00007fff}, {NoFlag, 0x33333333}, {NoFlag, 0x55555555}, 185 {NoFlag, 0x7ffffffd}, {NoFlag, 0x7ffffffe}, {NoFlag, 0x7fffffff}, 186 {NoFlag, 0x80000000}, {NoFlag, 0x80000001}, {NoFlag, 0xaaaaaaaa}, 187 {NoFlag, 0xcccccccc}, {NoFlag, 0xffff8000}, {NoFlag, 0xffff8001}, 188 {NoFlag, 0xffff8002}, {NoFlag, 0xffff8003}, {NoFlag, 0xffffff80}, 189 {NoFlag, 0xffffff81}, {NoFlag, 0xffffff82}, {NoFlag, 0xffffff83}, 190 {NoFlag, 0xffffffe0}, {NoFlag, 0xfffffffd}, {NoFlag, 0xfffffffe}, 191 {NoFlag, 0xffffffff}}; 192 193 194 // A loop will be generated for each element of this array. 195 const TestLoopData kTests[] = {{{eq, r0, 0xabababab}, 196 "eq r0 0xabababab", 197 "Condition_eq_r0_0xabababab", 198 ARRAY_SIZE(kCondition), 199 kCondition}, 200 {{ne, r0, 0xabababab}, 201 "ne r0 0xabababab", 202 "Condition_ne_r0_0xabababab", 203 ARRAY_SIZE(kCondition), 204 kCondition}, 205 {{cs, r0, 0xabababab}, 206 "cs r0 0xabababab", 207 "Condition_cs_r0_0xabababab", 208 ARRAY_SIZE(kCondition), 209 kCondition}, 210 {{cc, r0, 0xabababab}, 211 "cc r0 0xabababab", 212 "Condition_cc_r0_0xabababab", 213 ARRAY_SIZE(kCondition), 214 kCondition}, 215 {{mi, r0, 0xabababab}, 216 "mi r0 0xabababab", 217 "Condition_mi_r0_0xabababab", 218 ARRAY_SIZE(kCondition), 219 kCondition}, 220 {{pl, r0, 0xabababab}, 221 "pl r0 0xabababab", 222 "Condition_pl_r0_0xabababab", 223 ARRAY_SIZE(kCondition), 224 kCondition}, 225 {{vs, r0, 0xabababab}, 226 "vs r0 0xabababab", 227 "Condition_vs_r0_0xabababab", 228 ARRAY_SIZE(kCondition), 229 kCondition}, 230 {{vc, r0, 0xabababab}, 231 "vc r0 0xabababab", 232 "Condition_vc_r0_0xabababab", 233 ARRAY_SIZE(kCondition), 234 kCondition}, 235 {{hi, r0, 0xabababab}, 236 "hi r0 0xabababab", 237 "Condition_hi_r0_0xabababab", 238 ARRAY_SIZE(kCondition), 239 kCondition}, 240 {{ls, r0, 0xabababab}, 241 "ls r0 0xabababab", 242 "Condition_ls_r0_0xabababab", 243 ARRAY_SIZE(kCondition), 244 kCondition}, 245 {{ge, r0, 0xabababab}, 246 "ge r0 0xabababab", 247 "Condition_ge_r0_0xabababab", 248 ARRAY_SIZE(kCondition), 249 kCondition}, 250 {{lt, r0, 0xabababab}, 251 "lt r0 0xabababab", 252 "Condition_lt_r0_0xabababab", 253 ARRAY_SIZE(kCondition), 254 kCondition}, 255 {{gt, r0, 0xabababab}, 256 "gt r0 0xabababab", 257 "Condition_gt_r0_0xabababab", 258 ARRAY_SIZE(kCondition), 259 kCondition}, 260 {{le, r0, 0xabababab}, 261 "le r0 0xabababab", 262 "Condition_le_r0_0xabababab", 263 ARRAY_SIZE(kCondition), 264 kCondition}, 265 {{al, r0, 0xabababab}, 266 "al r0 0xabababab", 267 "Condition_al_r0_0xabababab", 268 ARRAY_SIZE(kCondition), 269 kCondition}, 270 {{al, r0, 0x000001fe}, 271 "al r0 0x000001fe", 272 "ModifiedImmediate_al_r0_0x000001fe", 273 ARRAY_SIZE(kModifiedImmediate), 274 kModifiedImmediate}, 275 {{al, r0, 0x000003fc}, 276 "al r0 0x000003fc", 277 "ModifiedImmediate_al_r0_0x000003fc", 278 ARRAY_SIZE(kModifiedImmediate), 279 kModifiedImmediate}, 280 {{al, r0, 0x000007f8}, 281 "al r0 0x000007f8", 282 "ModifiedImmediate_al_r0_0x000007f8", 283 ARRAY_SIZE(kModifiedImmediate), 284 kModifiedImmediate}, 285 {{al, r0, 0x00000ff0}, 286 "al r0 0x00000ff0", 287 "ModifiedImmediate_al_r0_0x00000ff0", 288 ARRAY_SIZE(kModifiedImmediate), 289 kModifiedImmediate}, 290 {{al, r0, 0x00001fe0}, 291 "al r0 0x00001fe0", 292 "ModifiedImmediate_al_r0_0x00001fe0", 293 ARRAY_SIZE(kModifiedImmediate), 294 kModifiedImmediate}, 295 {{al, r0, 0x00003fc0}, 296 "al r0 0x00003fc0", 297 "ModifiedImmediate_al_r0_0x00003fc0", 298 ARRAY_SIZE(kModifiedImmediate), 299 kModifiedImmediate}, 300 {{al, r0, 0x00007f80}, 301 "al r0 0x00007f80", 302 "ModifiedImmediate_al_r0_0x00007f80", 303 ARRAY_SIZE(kModifiedImmediate), 304 kModifiedImmediate}, 305 {{al, r0, 0x0000ff00}, 306 "al r0 0x0000ff00", 307 "ModifiedImmediate_al_r0_0x0000ff00", 308 ARRAY_SIZE(kModifiedImmediate), 309 kModifiedImmediate}, 310 {{al, r0, 0x0001fe00}, 311 "al r0 0x0001fe00", 312 "ModifiedImmediate_al_r0_0x0001fe00", 313 ARRAY_SIZE(kModifiedImmediate), 314 kModifiedImmediate}, 315 {{al, r0, 0x0003fc00}, 316 "al r0 0x0003fc00", 317 "ModifiedImmediate_al_r0_0x0003fc00", 318 ARRAY_SIZE(kModifiedImmediate), 319 kModifiedImmediate}, 320 {{al, r0, 0x0007f800}, 321 "al r0 0x0007f800", 322 "ModifiedImmediate_al_r0_0x0007f800", 323 ARRAY_SIZE(kModifiedImmediate), 324 kModifiedImmediate}, 325 {{al, r0, 0x000ff000}, 326 "al r0 0x000ff000", 327 "ModifiedImmediate_al_r0_0x000ff000", 328 ARRAY_SIZE(kModifiedImmediate), 329 kModifiedImmediate}, 330 {{al, r0, 0x001fe000}, 331 "al r0 0x001fe000", 332 "ModifiedImmediate_al_r0_0x001fe000", 333 ARRAY_SIZE(kModifiedImmediate), 334 kModifiedImmediate}, 335 {{al, r0, 0x003fc000}, 336 "al r0 0x003fc000", 337 "ModifiedImmediate_al_r0_0x003fc000", 338 ARRAY_SIZE(kModifiedImmediate), 339 kModifiedImmediate}, 340 {{al, r0, 0x007f8000}, 341 "al r0 0x007f8000", 342 "ModifiedImmediate_al_r0_0x007f8000", 343 ARRAY_SIZE(kModifiedImmediate), 344 kModifiedImmediate}, 345 {{al, r0, 0x00ff0000}, 346 "al r0 0x00ff0000", 347 "ModifiedImmediate_al_r0_0x00ff0000", 348 ARRAY_SIZE(kModifiedImmediate), 349 kModifiedImmediate}, 350 {{al, r0, 0x01fe0000}, 351 "al r0 0x01fe0000", 352 "ModifiedImmediate_al_r0_0x01fe0000", 353 ARRAY_SIZE(kModifiedImmediate), 354 kModifiedImmediate}, 355 {{al, r0, 0x03fc0000}, 356 "al r0 0x03fc0000", 357 "ModifiedImmediate_al_r0_0x03fc0000", 358 ARRAY_SIZE(kModifiedImmediate), 359 kModifiedImmediate}, 360 {{al, r0, 0x07f80000}, 361 "al r0 0x07f80000", 362 "ModifiedImmediate_al_r0_0x07f80000", 363 ARRAY_SIZE(kModifiedImmediate), 364 kModifiedImmediate}, 365 {{al, r0, 0x0ff00000}, 366 "al r0 0x0ff00000", 367 "ModifiedImmediate_al_r0_0x0ff00000", 368 ARRAY_SIZE(kModifiedImmediate), 369 kModifiedImmediate}, 370 {{al, r0, 0x1fe00000}, 371 "al r0 0x1fe00000", 372 "ModifiedImmediate_al_r0_0x1fe00000", 373 ARRAY_SIZE(kModifiedImmediate), 374 kModifiedImmediate}, 375 {{al, r0, 0x3fc00000}, 376 "al r0 0x3fc00000", 377 "ModifiedImmediate_al_r0_0x3fc00000", 378 ARRAY_SIZE(kModifiedImmediate), 379 kModifiedImmediate}, 380 {{al, r0, 0x7f800000}, 381 "al r0 0x7f800000", 382 "ModifiedImmediate_al_r0_0x7f800000", 383 ARRAY_SIZE(kModifiedImmediate), 384 kModifiedImmediate}, 385 {{al, r0, 0xff000000}, 386 "al r0 0xff000000", 387 "ModifiedImmediate_al_r0_0xff000000", 388 ARRAY_SIZE(kModifiedImmediate), 389 kModifiedImmediate}, 390 {{al, r0, 0x000000ff}, 391 "al r0 0x000000ff", 392 "ModifiedImmediate_al_r0_0x000000ff", 393 ARRAY_SIZE(kModifiedImmediate), 394 kModifiedImmediate}, 395 {{al, r0, 0x00ff00ff}, 396 "al r0 0x00ff00ff", 397 "ModifiedImmediate_al_r0_0x00ff00ff", 398 ARRAY_SIZE(kModifiedImmediate), 399 kModifiedImmediate}, 400 {{al, r0, 0xff00ff00}, 401 "al r0 0xff00ff00", 402 "ModifiedImmediate_al_r0_0xff00ff00", 403 ARRAY_SIZE(kModifiedImmediate), 404 kModifiedImmediate}, 405 {{al, r0, 0xffffffff}, 406 "al r0 0xffffffff", 407 "ModifiedImmediate_al_r0_0xffffffff", 408 ARRAY_SIZE(kModifiedImmediate), 409 kModifiedImmediate}, 410 {{al, r0, 0x00000156}, 411 "al r0 0x00000156", 412 "ModifiedImmediate_al_r0_0x00000156", 413 ARRAY_SIZE(kModifiedImmediate), 414 kModifiedImmediate}, 415 {{al, r0, 0x000002ac}, 416 "al r0 0x000002ac", 417 "ModifiedImmediate_al_r0_0x000002ac", 418 ARRAY_SIZE(kModifiedImmediate), 419 kModifiedImmediate}, 420 {{al, r0, 0x00000558}, 421 "al r0 0x00000558", 422 "ModifiedImmediate_al_r0_0x00000558", 423 ARRAY_SIZE(kModifiedImmediate), 424 kModifiedImmediate}, 425 {{al, r0, 0x00000ab0}, 426 "al r0 0x00000ab0", 427 "ModifiedImmediate_al_r0_0x00000ab0", 428 ARRAY_SIZE(kModifiedImmediate), 429 kModifiedImmediate}, 430 {{al, r0, 0x00001560}, 431 "al r0 0x00001560", 432 "ModifiedImmediate_al_r0_0x00001560", 433 ARRAY_SIZE(kModifiedImmediate), 434 kModifiedImmediate}, 435 {{al, r0, 0x00002ac0}, 436 "al r0 0x00002ac0", 437 "ModifiedImmediate_al_r0_0x00002ac0", 438 ARRAY_SIZE(kModifiedImmediate), 439 kModifiedImmediate}, 440 {{al, r0, 0x00005580}, 441 "al r0 0x00005580", 442 "ModifiedImmediate_al_r0_0x00005580", 443 ARRAY_SIZE(kModifiedImmediate), 444 kModifiedImmediate}, 445 {{al, r0, 0x0000ab00}, 446 "al r0 0x0000ab00", 447 "ModifiedImmediate_al_r0_0x0000ab00", 448 ARRAY_SIZE(kModifiedImmediate), 449 kModifiedImmediate}, 450 {{al, r0, 0x00015600}, 451 "al r0 0x00015600", 452 "ModifiedImmediate_al_r0_0x00015600", 453 ARRAY_SIZE(kModifiedImmediate), 454 kModifiedImmediate}, 455 {{al, r0, 0x0002ac00}, 456 "al r0 0x0002ac00", 457 "ModifiedImmediate_al_r0_0x0002ac00", 458 ARRAY_SIZE(kModifiedImmediate), 459 kModifiedImmediate}, 460 {{al, r0, 0x00055800}, 461 "al r0 0x00055800", 462 "ModifiedImmediate_al_r0_0x00055800", 463 ARRAY_SIZE(kModifiedImmediate), 464 kModifiedImmediate}, 465 {{al, r0, 0x000ab000}, 466 "al r0 0x000ab000", 467 "ModifiedImmediate_al_r0_0x000ab000", 468 ARRAY_SIZE(kModifiedImmediate), 469 kModifiedImmediate}, 470 {{al, r0, 0x00156000}, 471 "al r0 0x00156000", 472 "ModifiedImmediate_al_r0_0x00156000", 473 ARRAY_SIZE(kModifiedImmediate), 474 kModifiedImmediate}, 475 {{al, r0, 0x002ac000}, 476 "al r0 0x002ac000", 477 "ModifiedImmediate_al_r0_0x002ac000", 478 ARRAY_SIZE(kModifiedImmediate), 479 kModifiedImmediate}, 480 {{al, r0, 0x00558000}, 481 "al r0 0x00558000", 482 "ModifiedImmediate_al_r0_0x00558000", 483 ARRAY_SIZE(kModifiedImmediate), 484 kModifiedImmediate}, 485 {{al, r0, 0x00ab0000}, 486 "al r0 0x00ab0000", 487 "ModifiedImmediate_al_r0_0x00ab0000", 488 ARRAY_SIZE(kModifiedImmediate), 489 kModifiedImmediate}, 490 {{al, r0, 0x01560000}, 491 "al r0 0x01560000", 492 "ModifiedImmediate_al_r0_0x01560000", 493 ARRAY_SIZE(kModifiedImmediate), 494 kModifiedImmediate}, 495 {{al, r0, 0x02ac0000}, 496 "al r0 0x02ac0000", 497 "ModifiedImmediate_al_r0_0x02ac0000", 498 ARRAY_SIZE(kModifiedImmediate), 499 kModifiedImmediate}, 500 {{al, r0, 0x05580000}, 501 "al r0 0x05580000", 502 "ModifiedImmediate_al_r0_0x05580000", 503 ARRAY_SIZE(kModifiedImmediate), 504 kModifiedImmediate}, 505 {{al, r0, 0x0ab00000}, 506 "al r0 0x0ab00000", 507 "ModifiedImmediate_al_r0_0x0ab00000", 508 ARRAY_SIZE(kModifiedImmediate), 509 kModifiedImmediate}, 510 {{al, r0, 0x15600000}, 511 "al r0 0x15600000", 512 "ModifiedImmediate_al_r0_0x15600000", 513 ARRAY_SIZE(kModifiedImmediate), 514 kModifiedImmediate}, 515 {{al, r0, 0x2ac00000}, 516 "al r0 0x2ac00000", 517 "ModifiedImmediate_al_r0_0x2ac00000", 518 ARRAY_SIZE(kModifiedImmediate), 519 kModifiedImmediate}, 520 {{al, r0, 0x55800000}, 521 "al r0 0x55800000", 522 "ModifiedImmediate_al_r0_0x55800000", 523 ARRAY_SIZE(kModifiedImmediate), 524 kModifiedImmediate}, 525 {{al, r0, 0xab000000}, 526 "al r0 0xab000000", 527 "ModifiedImmediate_al_r0_0xab000000", 528 ARRAY_SIZE(kModifiedImmediate), 529 kModifiedImmediate}, 530 {{al, r0, 0x000000ab}, 531 "al r0 0x000000ab", 532 "ModifiedImmediate_al_r0_0x000000ab", 533 ARRAY_SIZE(kModifiedImmediate), 534 kModifiedImmediate}, 535 {{al, r0, 0x00ab00ab}, 536 "al r0 0x00ab00ab", 537 "ModifiedImmediate_al_r0_0x00ab00ab", 538 ARRAY_SIZE(kModifiedImmediate), 539 kModifiedImmediate}, 540 {{al, r0, 0xab00ab00}, 541 "al r0 0xab00ab00", 542 "ModifiedImmediate_al_r0_0xab00ab00", 543 ARRAY_SIZE(kModifiedImmediate), 544 kModifiedImmediate}, 545 {{al, r0, 0xabababab}, 546 "al r0 0xabababab", 547 "ModifiedImmediate_al_r0_0xabababab", 548 ARRAY_SIZE(kModifiedImmediate), 549 kModifiedImmediate}}; 550 551 // We record all inputs to the instructions as outputs. This way, we also check 552 // that what shouldn't change didn't change. 553 struct TestResult { 554 size_t output_size; 555 const Inputs* outputs; 556 }; 557 558 // These headers each contain an array of `TestResult` with the reference output 559 // values. The reference arrays are names `kReference{mnemonic}`. 560 #include "aarch32/traces/simulator-cond-rd-operand-const-cmn-t32.h" 561 #include "aarch32/traces/simulator-cond-rd-operand-const-cmp-t32.h" 562 #include "aarch32/traces/simulator-cond-rd-operand-const-mov-t32.h" 563 #include "aarch32/traces/simulator-cond-rd-operand-const-movs-t32.h" 564 #include "aarch32/traces/simulator-cond-rd-operand-const-mvn-t32.h" 565 #include "aarch32/traces/simulator-cond-rd-operand-const-mvns-t32.h" 566 #include "aarch32/traces/simulator-cond-rd-operand-const-teq-t32.h" 567 #include "aarch32/traces/simulator-cond-rd-operand-const-tst-t32.h" 568 569 570 // The maximum number of errors to report in detail for each test. 571 const unsigned kErrorReportLimit = 8; 572 573 typedef void (MacroAssembler::*Fn)(Condition cond, 574 Register rd, 575 const Operand& op); 576 577 void TestHelper(Fn instruction, 578 const char* mnemonic, 579 const TestResult reference[]) { 580 SETUP(); 581 masm.UseT32(); 582 START(); 583 584 // Data to compare to `reference`. 585 TestResult* results[ARRAY_SIZE(kTests)]; 586 587 // Test cases for memory bound instructions may allocate a buffer and save its 588 // address in this array. 589 byte* scratch_memory_buffers[ARRAY_SIZE(kTests)]; 590 591 // Generate a loop for each element in `kTests`. Each loop tests one specific 592 // instruction. 593 for (unsigned i = 0; i < ARRAY_SIZE(kTests); i++) { 594 // Allocate results on the heap for this test. 595 results[i] = new TestResult; 596 results[i]->outputs = new Inputs[kTests[i].input_size]; 597 results[i]->output_size = kTests[i].input_size; 598 599 size_t input_stride = sizeof(kTests[i].inputs[0]) * kTests[i].input_size; 600 VIXL_ASSERT(IsUint32(input_stride)); 601 602 scratch_memory_buffers[i] = NULL; 603 604 Label loop; 605 UseScratchRegisterScope scratch_registers(&masm); 606 // Include all registers from r0 ro r12. 607 scratch_registers.Include(RegisterList(0x1fff)); 608 609 // Values to pass to the macro-assembler. 610 Condition cond = kTests[i].operands.cond; 611 Register rd = kTests[i].operands.rd; 612 uint32_t immediate = kTests[i].operands.immediate; 613 Operand op(immediate); 614 scratch_registers.Exclude(rd); 615 616 // Allocate reserved registers for our own use. 617 Register input_ptr = scratch_registers.Acquire(); 618 Register input_end = scratch_registers.Acquire(); 619 Register result_ptr = scratch_registers.Acquire(); 620 621 // Initialize `input_ptr` to the first element and `input_end` the address 622 // after the array. 623 __ Mov(input_ptr, Operand::From(kTests[i].inputs)); 624 __ Add(input_end, input_ptr, static_cast<uint32_t>(input_stride)); 625 __ Mov(result_ptr, Operand::From(results[i]->outputs)); 626 __ Bind(&loop); 627 628 { 629 UseScratchRegisterScope temp_registers(&masm); 630 Register nzcv_bits = temp_registers.Acquire(); 631 Register saved_q_bit = temp_registers.Acquire(); 632 // Save the `Q` bit flag. 633 __ Mrs(saved_q_bit, APSR); 634 __ And(saved_q_bit, saved_q_bit, QFlag); 635 // Set the `NZCV` and `Q` flags together. 636 __ Ldr(nzcv_bits, MemOperand(input_ptr, offsetof(Inputs, apsr))); 637 __ Orr(nzcv_bits, nzcv_bits, saved_q_bit); 638 __ Msr(APSR_nzcvq, nzcv_bits); 639 } 640 __ Ldr(rd, MemOperand(input_ptr, offsetof(Inputs, rd))); 641 642 (masm.*instruction)(cond, rd, op); 643 644 { 645 UseScratchRegisterScope temp_registers(&masm); 646 Register nzcv_bits = temp_registers.Acquire(); 647 __ Mrs(nzcv_bits, APSR); 648 // Only record the NZCV bits. 649 __ And(nzcv_bits, nzcv_bits, NZCVFlag); 650 __ Str(nzcv_bits, MemOperand(result_ptr, offsetof(Inputs, apsr))); 651 } 652 __ Str(rd, MemOperand(result_ptr, offsetof(Inputs, rd))); 653 654 // Advance the result pointer. 655 __ Add(result_ptr, result_ptr, Operand::From(sizeof(kTests[i].inputs[0]))); 656 // Loop back until `input_ptr` is lower than `input_base`. 657 __ Add(input_ptr, input_ptr, Operand::From(sizeof(kTests[i].inputs[0]))); 658 __ Cmp(input_ptr, input_end); 659 __ B(ne, &loop); 660 } 661 662 END(); 663 664 RUN(); 665 666 if (Test::generate_test_trace()) { 667 // Print the results. 668 for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) { 669 printf("const Inputs kOutputs_%s_%s[] = {\n", 670 mnemonic, 671 kTests[i].identifier); 672 for (size_t j = 0; j < results[i]->output_size; j++) { 673 printf(" { "); 674 printf("0x%08" PRIx32, results[i]->outputs[j].apsr); 675 printf(", "); 676 printf("0x%08" PRIx32, results[i]->outputs[j].rd); 677 printf(" },\n"); 678 } 679 printf("};\n"); 680 } 681 printf("const TestResult kReference%s[] = {\n", mnemonic); 682 for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) { 683 printf(" {\n"); 684 printf(" ARRAY_SIZE(kOutputs_%s_%s),\n", 685 mnemonic, 686 kTests[i].identifier); 687 printf(" kOutputs_%s_%s,\n", mnemonic, kTests[i].identifier); 688 printf(" },\n"); 689 } 690 printf("};\n"); 691 } else if (kCheckSimulatorTestResults) { 692 // Check the results. 693 unsigned total_error_count = 0; 694 for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) { 695 bool instruction_has_errors = false; 696 for (size_t j = 0; j < kTests[i].input_size; j++) { 697 uint32_t apsr = results[i]->outputs[j].apsr; 698 uint32_t rd = results[i]->outputs[j].rd; 699 uint32_t apsr_input = kTests[i].inputs[j].apsr; 700 uint32_t rd_input = kTests[i].inputs[j].rd; 701 uint32_t apsr_ref = reference[i].outputs[j].apsr; 702 uint32_t rd_ref = reference[i].outputs[j].rd; 703 704 if (((apsr != apsr_ref) || (rd != rd_ref)) && 705 (++total_error_count <= kErrorReportLimit)) { 706 // Print the instruction once even if it triggered multiple failures. 707 if (!instruction_has_errors) { 708 printf("Error(s) when testing \"%s %s\":\n", 709 mnemonic, 710 kTests[i].operands_description); 711 instruction_has_errors = true; 712 } 713 // Print subsequent errors. 714 printf(" Input: "); 715 printf("0x%08" PRIx32, apsr_input); 716 printf(", "); 717 printf("0x%08" PRIx32, rd_input); 718 printf("\n"); 719 printf(" Expected: "); 720 printf("0x%08" PRIx32, apsr_ref); 721 printf(", "); 722 printf("0x%08" PRIx32, rd_ref); 723 printf("\n"); 724 printf(" Found: "); 725 printf("0x%08" PRIx32, apsr); 726 printf(", "); 727 printf("0x%08" PRIx32, rd); 728 printf("\n\n"); 729 } 730 } 731 } 732 733 if (total_error_count > kErrorReportLimit) { 734 printf("%u other errors follow.\n", 735 total_error_count - kErrorReportLimit); 736 } 737 VIXL_CHECK(total_error_count == 0); 738 } else { 739 VIXL_WARNING("Assembled the code, but did not run anything.\n"); 740 } 741 742 for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) { 743 delete[] results[i]->outputs; 744 delete results[i]; 745 delete[] scratch_memory_buffers[i]; 746 } 747 } 748 749 // Instantiate tests for each instruction in the list. 750 // TODO: Remove this limitation by having a sandboxing mechanism. 751 #if defined(VIXL_HOST_POINTER_32) 752 #define TEST(mnemonic) \ 753 void Test_##mnemonic() { \ 754 TestHelper(&MacroAssembler::mnemonic, #mnemonic, kReference##mnemonic); \ 755 } \ 756 Test test_##mnemonic("AARCH32_SIMULATOR_COND_RD_OPERAND_CONST_" #mnemonic \ 757 "_T32", \ 758 &Test_##mnemonic); 759 #else 760 #define TEST(mnemonic) \ 761 void Test_##mnemonic() { \ 762 VIXL_WARNING("This test can only run on a 32-bit host.\n"); \ 763 USE(TestHelper); \ 764 } \ 765 Test test_##mnemonic("AARCH32_SIMULATOR_COND_RD_OPERAND_CONST_" #mnemonic \ 766 "_T32", \ 767 &Test_##mnemonic); 768 #endif 769 770 FOREACH_INSTRUCTION(TEST) 771 #undef TEST 772 773 } // namespace 774 #endif 775 776 } // namespace aarch32 777 } // namespace vixl 778