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