test-simulator-cond-rd-operand-rn-a32.cc revision d3832965c62a8ad461b9ea9eb0994ca6b0a3da2c
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// This file is auto generated from the 29// test/aarch32/config/template-simulator-aarch32.cc.in template file using 30// tools/generate_tests.py. 31// 32// PLEASE DO NOT EDIT. 33// ----------------------------------------------------------------------------- 34 35#include "test-runner.h" 36 37#include "test-utils.h" 38#include "test-utils-aarch32.h" 39 40#include "aarch32/assembler-aarch32.h" 41#include "aarch32/macro-assembler-aarch32.h" 42#include "aarch32/disasm-aarch32.h" 43 44#define __ masm. 45#define BUF_SIZE (4096) 46 47#ifdef VIXL_INCLUDE_SIMULATOR 48// Run tests with the simulator. 49 50#define SETUP() MacroAssembler masm(BUF_SIZE) 51 52#define START() masm.GetBuffer().Reset() 53 54#define END() \ 55 __ Hlt(0); \ 56 __ FinalizeCode(); 57 58// TODO: Run the tests in the simulator. 59#define RUN() 60 61#define TEARDOWN() 62 63#else // ifdef VIXL_INCLUDE_SIMULATOR. 64 65#define SETUP() MacroAssembler masm(BUF_SIZE); 66 67#define START() \ 68 masm.GetBuffer().Reset(); \ 69 __ Push(r4); \ 70 __ Push(r5); \ 71 __ Push(r6); \ 72 __ Push(r7); \ 73 __ Push(r8); \ 74 __ Push(r9); \ 75 __ Push(r10); \ 76 __ Push(r11); \ 77 __ Push(r12); \ 78 __ Push(lr) 79 80#define END() \ 81 __ Pop(lr); \ 82 __ Pop(r12); \ 83 __ Pop(r11); \ 84 __ Pop(r10); \ 85 __ Pop(r9); \ 86 __ Pop(r8); \ 87 __ Pop(r7); \ 88 __ Pop(r6); \ 89 __ Pop(r5); \ 90 __ Pop(r4); \ 91 __ Bx(lr); \ 92 __ FinalizeCode(); 93 94// Copy the generated code into a memory area garanteed to be executable before 95// executing it. 96#define RUN() \ 97 { \ 98 ExecutableMemory code(masm.GetBuffer().GetCursorOffset()); \ 99 code.Write(masm.GetBuffer().GetOffsetAddress<byte*>(0), \ 100 masm.GetBuffer().GetCursorOffset()); \ 101 int pcs_offset = masm.IsT32() ? 1 : 0; \ 102 code.Execute(pcs_offset); \ 103 } 104 105#define TEARDOWN() 106 107#endif // ifdef VIXL_INCLUDE_SIMULATOR 108 109namespace vixl { 110namespace aarch32 { 111 112// List of instruction encodings: 113#define FOREACH_INSTRUCTION(M) \ 114 M(Cmn) \ 115 M(Cmp) \ 116 M(Mov) \ 117 M(Movs) \ 118 M(Mvn) \ 119 M(Mvns) \ 120 M(Teq) \ 121 M(Tst) \ 122 M(Sxtb) \ 123 M(Sxtb16) \ 124 M(Sxth) \ 125 M(Uxtb) \ 126 M(Uxtb16) \ 127 M(Uxth) 128 129// Values to be passed to the assembler to produce the instruction under test. 130struct Operands { 131 Condition cond; 132 Register rd; 133 Register rn; 134}; 135 136// Input data to feed to the instruction. 137struct Inputs { 138 uint32_t apsr; 139 uint32_t rd; 140 uint32_t rn; 141}; 142 143// This structure contains all input data needed to test one specific encoding. 144// It used to generate a loop over an instruction. 145struct TestLoopData { 146 // The `operands` fields represents the values to pass to the assembler to 147 // produce the instruction. 148 Operands operands; 149 // Description of the operands, used for error reporting. 150 const char* operands_description; 151 // Unique identifier, used for generating traces. 152 const char* identifier; 153 // Array of values to be fed to the instruction. 154 size_t input_size; 155 const Inputs* inputs; 156}; 157 158static const Inputs kCondition[] = {{NFlag, 0xabababab, 0xabababab}, 159 {ZFlag, 0xabababab, 0xabababab}, 160 {CFlag, 0xabababab, 0xabababab}, 161 {VFlag, 0xabababab, 0xabababab}, 162 {NZFlag, 0xabababab, 0xabababab}, 163 {NCFlag, 0xabababab, 0xabababab}, 164 {NVFlag, 0xabababab, 0xabababab}, 165 {ZCFlag, 0xabababab, 0xabababab}, 166 {ZVFlag, 0xabababab, 0xabababab}, 167 {CVFlag, 0xabababab, 0xabababab}, 168 {NZCFlag, 0xabababab, 0xabababab}, 169 {NZVFlag, 0xabababab, 0xabababab}, 170 {NCVFlag, 0xabababab, 0xabababab}, 171 {ZCVFlag, 0xabababab, 0xabababab}, 172 {NZCVFlag, 0xabababab, 0xabababab}}; 173 174static const Inputs kRdIsRn[] = {{NoFlag, 0x00000000, 0x00000000}, 175 {NoFlag, 0x00000001, 0x00000001}, 176 {NoFlag, 0x00000002, 0x00000002}, 177 {NoFlag, 0x00000020, 0x00000020}, 178 {NoFlag, 0x0000007d, 0x0000007d}, 179 {NoFlag, 0x0000007e, 0x0000007e}, 180 {NoFlag, 0x0000007f, 0x0000007f}, 181 {NoFlag, 0x00007ffd, 0x00007ffd}, 182 {NoFlag, 0x00007ffe, 0x00007ffe}, 183 {NoFlag, 0x00007fff, 0x00007fff}, 184 {NoFlag, 0x33333333, 0x33333333}, 185 {NoFlag, 0x55555555, 0x55555555}, 186 {NoFlag, 0x7ffffffd, 0x7ffffffd}, 187 {NoFlag, 0x7ffffffe, 0x7ffffffe}, 188 {NoFlag, 0x7fffffff, 0x7fffffff}, 189 {NoFlag, 0x80000000, 0x80000000}, 190 {NoFlag, 0x80000001, 0x80000001}, 191 {NoFlag, 0xaaaaaaaa, 0xaaaaaaaa}, 192 {NoFlag, 0xcccccccc, 0xcccccccc}, 193 {NoFlag, 0xffff8000, 0xffff8000}, 194 {NoFlag, 0xffff8001, 0xffff8001}, 195 {NoFlag, 0xffff8002, 0xffff8002}, 196 {NoFlag, 0xffff8003, 0xffff8003}, 197 {NoFlag, 0xffffff80, 0xffffff80}, 198 {NoFlag, 0xffffff81, 0xffffff81}, 199 {NoFlag, 0xffffff82, 0xffffff82}, 200 {NoFlag, 0xffffff83, 0xffffff83}, 201 {NoFlag, 0xffffffe0, 0xffffffe0}, 202 {NoFlag, 0xfffffffd, 0xfffffffd}, 203 {NoFlag, 0xfffffffe, 0xfffffffe}, 204 {NoFlag, 0xffffffff, 0xffffffff}}; 205 206static const Inputs kRdIsNotRn[] = {{NoFlag, 0x00000002, 0xcccccccc}, 207 {NoFlag, 0x7ffffffd, 0x00007ffe}, 208 {NoFlag, 0xffffff80, 0x00000020}, 209 {NoFlag, 0xaaaaaaaa, 0xaaaaaaaa}, 210 {NoFlag, 0x33333333, 0xffffff82}, 211 {NoFlag, 0xffff8001, 0x7ffffffe}, 212 {NoFlag, 0xfffffffd, 0x00007ffe}, 213 {NoFlag, 0xffffff80, 0x80000000}, 214 {NoFlag, 0x00000001, 0x33333333}, 215 {NoFlag, 0xcccccccc, 0x7ffffffe}, 216 {NoFlag, 0x00000000, 0xcccccccc}, 217 {NoFlag, 0x00000000, 0x55555555}, 218 {NoFlag, 0xffffffff, 0xffffffff}, 219 {NoFlag, 0x0000007e, 0xffff8002}, 220 {NoFlag, 0x80000000, 0x7ffffffd}, 221 {NoFlag, 0xffffff81, 0x0000007e}, 222 {NoFlag, 0x0000007f, 0xffff8001}, 223 {NoFlag, 0xffffffe0, 0x00007ffd}, 224 {NoFlag, 0xffff8003, 0x00000002}, 225 {NoFlag, 0xffffff83, 0x55555555}, 226 {NoFlag, 0xffffff83, 0xffffff80}, 227 {NoFlag, 0xffffff81, 0xffff8000}, 228 {NoFlag, 0x00000020, 0x7ffffffe}, 229 {NoFlag, 0xffffffe0, 0x00000000}, 230 {NoFlag, 0x7fffffff, 0x0000007e}, 231 {NoFlag, 0x80000001, 0xffffffff}, 232 {NoFlag, 0x00000001, 0x80000001}, 233 {NoFlag, 0x00000002, 0x0000007f}, 234 {NoFlag, 0x7fffffff, 0xcccccccc}, 235 {NoFlag, 0x80000001, 0x00007ffe}, 236 {NoFlag, 0xffff8002, 0x0000007e}, 237 {NoFlag, 0x00007ffe, 0xcccccccc}, 238 {NoFlag, 0x80000000, 0xffff8002}, 239 {NoFlag, 0xffffff83, 0x7ffffffe}, 240 {NoFlag, 0xffff8001, 0x00000001}, 241 {NoFlag, 0xffffff81, 0x00000020}, 242 {NoFlag, 0xfffffffe, 0xffff8001}, 243 {NoFlag, 0xffffffff, 0xfffffffe}, 244 {NoFlag, 0xcccccccc, 0x55555555}, 245 {NoFlag, 0x00000020, 0xffffff83}, 246 {NoFlag, 0xffffff83, 0xffff8001}, 247 {NoFlag, 0xffffff83, 0xffff8000}, 248 {NoFlag, 0x00007fff, 0x00000002}, 249 {NoFlag, 0x55555555, 0xffff8000}, 250 {NoFlag, 0x80000001, 0xffffff81}, 251 {NoFlag, 0x00000002, 0x00000000}, 252 {NoFlag, 0x33333333, 0xffffff81}, 253 {NoFlag, 0xffff8001, 0xffffff82}, 254 {NoFlag, 0xcccccccc, 0xffff8003}, 255 {NoFlag, 0xffff8003, 0x7ffffffd}, 256 {NoFlag, 0x0000007d, 0x00007ffe}, 257 {NoFlag, 0xffffff80, 0x0000007d}, 258 {NoFlag, 0xaaaaaaaa, 0x00007ffd}, 259 {NoFlag, 0x80000000, 0xffffff82}, 260 {NoFlag, 0x00000002, 0x7ffffffe}, 261 {NoFlag, 0x00000002, 0xffffff83}, 262 {NoFlag, 0x55555555, 0x00000002}, 263 {NoFlag, 0xffffffff, 0xffffff82}, 264 {NoFlag, 0xaaaaaaaa, 0x00000020}, 265 {NoFlag, 0x00000001, 0xffffff82}, 266 {NoFlag, 0x0000007f, 0xffffff82}, 267 {NoFlag, 0x7ffffffd, 0xaaaaaaaa}, 268 {NoFlag, 0x00007ffe, 0x00000001}, 269 {NoFlag, 0xfffffffd, 0xffffffe0}, 270 {NoFlag, 0xffffff81, 0xffffff83}, 271 {NoFlag, 0x0000007d, 0x00000000}, 272 {NoFlag, 0x0000007d, 0xffff8000}, 273 {NoFlag, 0xffffff81, 0x7fffffff}, 274 {NoFlag, 0xffffffff, 0x80000000}, 275 {NoFlag, 0x00000000, 0x00000001}, 276 {NoFlag, 0x55555555, 0xffffff82}, 277 {NoFlag, 0x00007ffe, 0x00007ffe}, 278 {NoFlag, 0x80000001, 0xfffffffd}, 279 {NoFlag, 0x00007fff, 0x33333333}, 280 {NoFlag, 0x00007fff, 0x80000000}, 281 {NoFlag, 0xcccccccc, 0x00007fff}, 282 {NoFlag, 0xfffffffe, 0xffffffe0}, 283 {NoFlag, 0x7ffffffe, 0x0000007f}, 284 {NoFlag, 0x00007ffd, 0xffff8001}, 285 {NoFlag, 0x00000002, 0x00000001}, 286 {NoFlag, 0x80000000, 0xffffffff}, 287 {NoFlag, 0xffffff83, 0xcccccccc}, 288 {NoFlag, 0xffff8002, 0x7ffffffe}, 289 {NoFlag, 0xaaaaaaaa, 0x00000000}, 290 {NoFlag, 0xffffff80, 0xcccccccc}, 291 {NoFlag, 0x33333333, 0xffffff83}, 292 {NoFlag, 0x0000007e, 0xffffffe0}, 293 {NoFlag, 0x0000007e, 0x00007fff}, 294 {NoFlag, 0x0000007f, 0x00000002}, 295 {NoFlag, 0x7ffffffe, 0xcccccccc}, 296 {NoFlag, 0x0000007d, 0xffffff80}, 297 {NoFlag, 0x00007fff, 0x00000020}, 298 {NoFlag, 0x7ffffffe, 0xfffffffe}, 299 {NoFlag, 0xfffffffe, 0xffffff81}, 300 {NoFlag, 0xffffffff, 0x0000007f}, 301 {NoFlag, 0xffff8002, 0x7ffffffd}, 302 {NoFlag, 0xffff8001, 0xfffffffe}, 303 {NoFlag, 0x33333333, 0xffff8002}, 304 {NoFlag, 0x00000000, 0xffffffff}, 305 {NoFlag, 0x33333333, 0xffffff80}, 306 {NoFlag, 0x0000007f, 0x00007fff}, 307 {NoFlag, 0xffffffff, 0xffff8001}, 308 {NoFlag, 0x7fffffff, 0xffff8002}, 309 {NoFlag, 0x7ffffffd, 0xffffff83}, 310 {NoFlag, 0x7fffffff, 0x0000007f}, 311 {NoFlag, 0xffffff83, 0xfffffffe}, 312 {NoFlag, 0x7ffffffe, 0xffff8003}, 313 {NoFlag, 0xffff8002, 0xffff8002}, 314 {NoFlag, 0x80000001, 0x0000007f}, 315 {NoFlag, 0x00000020, 0x00000002}, 316 {NoFlag, 0xffffff82, 0xffff8001}, 317 {NoFlag, 0xffffffff, 0x00000001}, 318 {NoFlag, 0xffffff80, 0xffff8002}, 319 {NoFlag, 0xffff8003, 0x7fffffff}, 320 {NoFlag, 0xffffffff, 0xffff8000}, 321 {NoFlag, 0xffff8002, 0x00007ffd}, 322 {NoFlag, 0x00000020, 0xffffff81}, 323 {NoFlag, 0x00000001, 0x55555555}, 324 {NoFlag, 0x7ffffffe, 0x00000020}, 325 {NoFlag, 0x80000000, 0x00000001}, 326 {NoFlag, 0x00007ffd, 0xffff8002}, 327 {NoFlag, 0x7fffffff, 0xfffffffe}, 328 {NoFlag, 0xcccccccc, 0x00007ffd}, 329 {NoFlag, 0x00000000, 0xfffffffd}, 330 {NoFlag, 0xffff8003, 0xffffff80}, 331 {NoFlag, 0x80000001, 0xffffff80}, 332 {NoFlag, 0xffffffff, 0xffff8002}, 333 {NoFlag, 0x00007ffe, 0xffff8002}, 334 {NoFlag, 0xffffff80, 0x00007ffe}, 335 {NoFlag, 0x80000001, 0xffff8001}, 336 {NoFlag, 0x0000007f, 0xffffff80}, 337 {NoFlag, 0xffffff81, 0x80000000}, 338 {NoFlag, 0x00007fff, 0x00007ffe}, 339 {NoFlag, 0x33333333, 0xffff8000}, 340 {NoFlag, 0x33333333, 0x00007fff}, 341 {NoFlag, 0x00000000, 0x0000007d}, 342 {NoFlag, 0x80000001, 0x00000000}, 343 {NoFlag, 0xffffffff, 0x55555555}, 344 {NoFlag, 0x80000001, 0x80000000}, 345 {NoFlag, 0xffffffff, 0xffffff80}, 346 {NoFlag, 0xffffff81, 0xffff8003}, 347 {NoFlag, 0x55555555, 0x80000001}, 348 {NoFlag, 0x7fffffff, 0xffff8001}, 349 {NoFlag, 0xffffff83, 0x00000002}, 350 {NoFlag, 0x0000007e, 0xffffff81}, 351 {NoFlag, 0x80000000, 0xffff8001}, 352 {NoFlag, 0xffffff80, 0xfffffffe}, 353 {NoFlag, 0x0000007e, 0xfffffffd}, 354 {NoFlag, 0xffffffe0, 0xffffffff}, 355 {NoFlag, 0x55555555, 0x80000000}, 356 {NoFlag, 0x0000007d, 0x80000001}, 357 {NoFlag, 0xffffffe0, 0x7ffffffd}, 358 {NoFlag, 0x00000000, 0x00000000}, 359 {NoFlag, 0x55555555, 0x00000001}, 360 {NoFlag, 0x00007ffd, 0x7fffffff}, 361 {NoFlag, 0x55555555, 0xffffffff}, 362 {NoFlag, 0xffff8003, 0x00007fff}, 363 {NoFlag, 0xffffff82, 0x00007fff}, 364 {NoFlag, 0x33333333, 0x55555555}, 365 {NoFlag, 0x00000020, 0x33333333}, 366 {NoFlag, 0x7ffffffe, 0xfffffffd}, 367 {NoFlag, 0x7ffffffe, 0x00000001}, 368 {NoFlag, 0xffffff83, 0xffffffe0}, 369 {NoFlag, 0xfffffffe, 0xaaaaaaaa}, 370 {NoFlag, 0xffff8002, 0x33333333}, 371 {NoFlag, 0xffff8002, 0xffff8003}, 372 {NoFlag, 0x33333333, 0x7fffffff}, 373 {NoFlag, 0xfffffffd, 0xffffff83}, 374 {NoFlag, 0x00000000, 0xffff8000}, 375 {NoFlag, 0xffffff82, 0x55555555}, 376 {NoFlag, 0xffffff82, 0xffffff81}, 377 {NoFlag, 0xcccccccc, 0xfffffffe}, 378 {NoFlag, 0xfffffffd, 0x7fffffff}, 379 {NoFlag, 0x00007fff, 0x7fffffff}, 380 {NoFlag, 0xffffff83, 0xffff8003}, 381 {NoFlag, 0xfffffffe, 0xffffffff}, 382 {NoFlag, 0x7ffffffd, 0x00007ffd}, 383 {NoFlag, 0x7ffffffd, 0x00007fff}, 384 {NoFlag, 0x00007ffd, 0xffffffff}, 385 {NoFlag, 0x00000001, 0xffff8003}, 386 {NoFlag, 0xffffff80, 0xfffffffd}, 387 {NoFlag, 0x33333333, 0x80000000}, 388 {NoFlag, 0xffff8001, 0x00000020}, 389 {NoFlag, 0xcccccccc, 0x00000002}, 390 {NoFlag, 0x00000000, 0x00000002}, 391 {NoFlag, 0x0000007d, 0x00007fff}, 392 {NoFlag, 0xcccccccc, 0x00000001}, 393 {NoFlag, 0xffffff83, 0x00007fff}, 394 {NoFlag, 0x80000001, 0x00000020}, 395 {NoFlag, 0xffff8003, 0xffffffe0}, 396 {NoFlag, 0x00007ffd, 0xaaaaaaaa}, 397 {NoFlag, 0x33333333, 0xffff8001}, 398 {NoFlag, 0xffffff83, 0x80000001}, 399 {NoFlag, 0xffff8000, 0xffff8000}, 400 {NoFlag, 0x00007ffe, 0xffff8001}, 401 {NoFlag, 0x7ffffffd, 0x00000000}, 402 {NoFlag, 0x00007ffe, 0x33333333}, 403 {NoFlag, 0xffff8001, 0xffffff80}, 404 {NoFlag, 0xfffffffe, 0x55555555}, 405 {NoFlag, 0xffffff82, 0xffffffff}}; 406 407// A loop will be generated for each element of this array. 408static const TestLoopData kTests[] = { 409 {{eq, r0, r0}, 410 "eq r0 r0", 411 "Condition_eq_r0_r0", 412 ARRAY_SIZE(kCondition), 413 kCondition}, 414 {{ne, r0, r0}, 415 "ne r0 r0", 416 "Condition_ne_r0_r0", 417 ARRAY_SIZE(kCondition), 418 kCondition}, 419 {{cs, r0, r0}, 420 "cs r0 r0", 421 "Condition_cs_r0_r0", 422 ARRAY_SIZE(kCondition), 423 kCondition}, 424 {{cc, r0, r0}, 425 "cc r0 r0", 426 "Condition_cc_r0_r0", 427 ARRAY_SIZE(kCondition), 428 kCondition}, 429 {{mi, r0, r0}, 430 "mi r0 r0", 431 "Condition_mi_r0_r0", 432 ARRAY_SIZE(kCondition), 433 kCondition}, 434 {{pl, r0, r0}, 435 "pl r0 r0", 436 "Condition_pl_r0_r0", 437 ARRAY_SIZE(kCondition), 438 kCondition}, 439 {{vs, r0, r0}, 440 "vs r0 r0", 441 "Condition_vs_r0_r0", 442 ARRAY_SIZE(kCondition), 443 kCondition}, 444 {{vc, r0, r0}, 445 "vc r0 r0", 446 "Condition_vc_r0_r0", 447 ARRAY_SIZE(kCondition), 448 kCondition}, 449 {{hi, r0, r0}, 450 "hi r0 r0", 451 "Condition_hi_r0_r0", 452 ARRAY_SIZE(kCondition), 453 kCondition}, 454 {{ls, r0, r0}, 455 "ls r0 r0", 456 "Condition_ls_r0_r0", 457 ARRAY_SIZE(kCondition), 458 kCondition}, 459 {{ge, r0, r0}, 460 "ge r0 r0", 461 "Condition_ge_r0_r0", 462 ARRAY_SIZE(kCondition), 463 kCondition}, 464 {{lt, r0, r0}, 465 "lt r0 r0", 466 "Condition_lt_r0_r0", 467 ARRAY_SIZE(kCondition), 468 kCondition}, 469 {{gt, r0, r0}, 470 "gt r0 r0", 471 "Condition_gt_r0_r0", 472 ARRAY_SIZE(kCondition), 473 kCondition}, 474 {{le, r0, r0}, 475 "le r0 r0", 476 "Condition_le_r0_r0", 477 ARRAY_SIZE(kCondition), 478 kCondition}, 479 {{al, r0, r0}, 480 "al r0 r0", 481 "Condition_al_r0_r0", 482 ARRAY_SIZE(kCondition), 483 kCondition}, 484 {{al, r0, r0}, "al r0 r0", "RdIsRn_al_r0_r0", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 485 {{al, r1, r1}, "al r1 r1", "RdIsRn_al_r1_r1", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 486 {{al, r2, r2}, "al r2 r2", "RdIsRn_al_r2_r2", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 487 {{al, r3, r3}, "al r3 r3", "RdIsRn_al_r3_r3", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 488 {{al, r4, r4}, "al r4 r4", "RdIsRn_al_r4_r4", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 489 {{al, r5, r5}, "al r5 r5", "RdIsRn_al_r5_r5", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 490 {{al, r6, r6}, "al r6 r6", "RdIsRn_al_r6_r6", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 491 {{al, r7, r7}, "al r7 r7", "RdIsRn_al_r7_r7", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 492 {{al, r8, r8}, "al r8 r8", "RdIsRn_al_r8_r8", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 493 {{al, r9, r9}, "al r9 r9", "RdIsRn_al_r9_r9", ARRAY_SIZE(kRdIsRn), kRdIsRn}, 494 {{al, r10, r10}, 495 "al r10 r10", 496 "RdIsRn_al_r10_r10", 497 ARRAY_SIZE(kRdIsRn), 498 kRdIsRn}, 499 {{al, r11, r11}, 500 "al r11 r11", 501 "RdIsRn_al_r11_r11", 502 ARRAY_SIZE(kRdIsRn), 503 kRdIsRn}, 504 {{al, r12, r12}, 505 "al r12 r12", 506 "RdIsRn_al_r12_r12", 507 ARRAY_SIZE(kRdIsRn), 508 kRdIsRn}, 509 {{al, r14, r14}, 510 "al r14 r14", 511 "RdIsRn_al_r14_r14", 512 ARRAY_SIZE(kRdIsRn), 513 kRdIsRn}, 514 {{al, r1, r8}, 515 "al r1 r8", 516 "RdIsNotRn_al_r1_r8", 517 ARRAY_SIZE(kRdIsNotRn), 518 kRdIsNotRn}, 519 {{al, r7, r4}, 520 "al r7 r4", 521 "RdIsNotRn_al_r7_r4", 522 ARRAY_SIZE(kRdIsNotRn), 523 kRdIsNotRn}, 524 {{al, r14, r10}, 525 "al r14 r10", 526 "RdIsNotRn_al_r14_r10", 527 ARRAY_SIZE(kRdIsNotRn), 528 kRdIsNotRn}, 529 {{al, r10, r6}, 530 "al r10 r6", 531 "RdIsNotRn_al_r10_r6", 532 ARRAY_SIZE(kRdIsNotRn), 533 kRdIsNotRn}, 534 {{al, r6, r5}, 535 "al r6 r5", 536 "RdIsNotRn_al_r6_r5", 537 ARRAY_SIZE(kRdIsNotRn), 538 kRdIsNotRn}, 539 {{al, r12, r2}, 540 "al r12 r2", 541 "RdIsNotRn_al_r12_r2", 542 ARRAY_SIZE(kRdIsNotRn), 543 kRdIsNotRn}, 544 {{al, r0, r11}, 545 "al r0 r11", 546 "RdIsNotRn_al_r0_r11", 547 ARRAY_SIZE(kRdIsNotRn), 548 kRdIsNotRn}, 549 {{al, r10, r14}, 550 "al r10 r14", 551 "RdIsNotRn_al_r10_r14", 552 ARRAY_SIZE(kRdIsNotRn), 553 kRdIsNotRn}, 554 {{al, r0, r5}, 555 "al r0 r5", 556 "RdIsNotRn_al_r0_r5", 557 ARRAY_SIZE(kRdIsNotRn), 558 kRdIsNotRn}, 559 {{al, r0, r3}, 560 "al r0 r3", 561 "RdIsNotRn_al_r0_r3", 562 ARRAY_SIZE(kRdIsNotRn), 563 kRdIsNotRn}}; 564 565// We record all inputs to the instructions as outputs. This way, we also check 566// that what shouldn't change didn't change. 567struct TestResult { 568 size_t output_size; 569 const Inputs* outputs; 570}; 571 572// These headers each contain an array of `TestResult` with the reference output 573// values. The reference arrays are names `kReference{mnemonic}`. 574#include "aarch32/traces/simulator-cond-rd-operand-rn-a32-cmn.h" 575#include "aarch32/traces/simulator-cond-rd-operand-rn-a32-cmp.h" 576#include "aarch32/traces/simulator-cond-rd-operand-rn-a32-mov.h" 577#include "aarch32/traces/simulator-cond-rd-operand-rn-a32-movs.h" 578#include "aarch32/traces/simulator-cond-rd-operand-rn-a32-mvn.h" 579#include "aarch32/traces/simulator-cond-rd-operand-rn-a32-mvns.h" 580#include "aarch32/traces/simulator-cond-rd-operand-rn-a32-teq.h" 581#include "aarch32/traces/simulator-cond-rd-operand-rn-a32-tst.h" 582#include "aarch32/traces/simulator-cond-rd-operand-rn-a32-sxtb.h" 583#include "aarch32/traces/simulator-cond-rd-operand-rn-a32-sxtb16.h" 584#include "aarch32/traces/simulator-cond-rd-operand-rn-a32-sxth.h" 585#include "aarch32/traces/simulator-cond-rd-operand-rn-a32-uxtb.h" 586#include "aarch32/traces/simulator-cond-rd-operand-rn-a32-uxtb16.h" 587#include "aarch32/traces/simulator-cond-rd-operand-rn-a32-uxth.h" 588 589// The maximum number of errors to report in detail for each test. 590static const unsigned kErrorReportLimit = 8; 591 592typedef void (MacroAssembler::*Fn)(Condition cond, Register rd, 593 const Operand& op); 594 595static void TestHelper(Fn instruction, const char* mnemonic, 596 const TestResult reference[]) { 597 SETUP(); 598 masm.SetT32(false); 599 START(); 600 601 // Data to compare to `reference`. 602 TestResult* results[ARRAY_SIZE(kTests)]; 603 604 // Test cases for memory bound instructions may allocate a buffer and save its 605 // address in this array. 606 byte* scratch_memory_buffers[ARRAY_SIZE(kTests)]; 607 608 // Generate a loop for each element in `kTests`. Each loop tests one specific 609 // instruction. 610 for (unsigned i = 0; i < ARRAY_SIZE(kTests); i++) { 611 // Allocate results on the heap for this test. 612 results[i] = new TestResult; 613 results[i]->outputs = new Inputs[kTests[i].input_size]; 614 results[i]->output_size = kTests[i].input_size; 615 616 uintptr_t input_address = reinterpret_cast<uintptr_t>(kTests[i].inputs); 617 uintptr_t result_address = reinterpret_cast<uintptr_t>(results[i]->outputs); 618 619 scratch_memory_buffers[i] = NULL; 620 621 Label loop; 622 UseScratchRegisterScope scratch_registers(&masm); 623 // Include all registers from r0 ro r12. 624 scratch_registers.Include(RegisterList(0x1fff)); 625 626 // Values to pass to the macro-assembler. 627 Condition cond = kTests[i].operands.cond; 628 Register rd = kTests[i].operands.rd; 629 Register rn = kTests[i].operands.rn; 630 Operand op(rn); 631 scratch_registers.Exclude(rd); 632 scratch_registers.Exclude(rn); 633 634 // Allocate reserved registers for our own use. 635 Register input_ptr = scratch_registers.Acquire(); 636 Register input_end = scratch_registers.Acquire(); 637 Register result_ptr = scratch_registers.Acquire(); 638 639 // Initialize `input_ptr` to the first element and `input_end` the address 640 // after the array. 641 __ Mov(input_ptr, input_address); 642 __ Add(input_end, input_ptr, 643 sizeof(kTests[i].inputs[0]) * kTests[i].input_size); 644 __ Mov(result_ptr, result_address); 645 __ Bind(&loop); 646 647 { 648 UseScratchRegisterScope temp_registers(&masm); 649 Register nzcv_bits = temp_registers.Acquire(); 650 Register saved_q_bit = temp_registers.Acquire(); 651 // Save the `Q` bit flag. 652 __ Mrs(saved_q_bit, APSR); 653 __ And(saved_q_bit, saved_q_bit, QFlag); 654 // Set the `NZCV` and `Q` flags together. 655 __ Ldr(nzcv_bits, MemOperand(input_ptr, offsetof(Inputs, apsr))); 656 __ Orr(nzcv_bits, nzcv_bits, saved_q_bit); 657 __ Msr(APSR_nzcvq, nzcv_bits); 658 } 659 __ Ldr(rd, MemOperand(input_ptr, offsetof(Inputs, rd))); 660 __ Ldr(rn, MemOperand(input_ptr, offsetof(Inputs, rn))); 661 662 (masm.*instruction)(cond, rd, op); 663 664 { 665 UseScratchRegisterScope temp_registers(&masm); 666 Register nzcv_bits = temp_registers.Acquire(); 667 __ Mrs(nzcv_bits, APSR); 668 // Only record the NZCV bits. 669 __ And(nzcv_bits, nzcv_bits, NZCVFlag); 670 __ Str(nzcv_bits, MemOperand(result_ptr, offsetof(Inputs, apsr))); 671 } 672 __ Str(rd, MemOperand(result_ptr, offsetof(Inputs, rd))); 673 __ Str(rn, MemOperand(result_ptr, offsetof(Inputs, rn))); 674 675 // Advance the result pointer. 676 __ Add(result_ptr, result_ptr, sizeof(kTests[i].inputs[0])); 677 // Loop back until `input_ptr` is lower than `input_base`. 678 __ Add(input_ptr, input_ptr, 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("static const Inputs kOutputs_%s_%s[] = {\n", mnemonic, 691 kTests[i].identifier); 692 for (size_t j = 0; j < results[i]->output_size; j++) { 693 printf(" { "); 694 printf("0x%08" PRIx32, results[i]->outputs[j].apsr); 695 printf(", "); 696 printf("0x%08" PRIx32, results[i]->outputs[j].rd); 697 printf(", "); 698 printf("0x%08" PRIx32, results[i]->outputs[j].rn); 699 printf(" },\n"); 700 } 701 printf("};\n"); 702 } 703 printf("static const TestResult kReference%s[] = {\n", mnemonic); 704 for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) { 705 printf(" {\n"); 706 printf(" ARRAY_SIZE(kOutputs_%s_%s),\n", mnemonic, 707 kTests[i].identifier); 708 printf(" kOutputs_%s_%s,\n", mnemonic, kTests[i].identifier); 709 printf(" },\n"); 710 } 711 printf("};\n"); 712 } else { 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 rn = results[i]->outputs[j].rn; 721 uint32_t apsr_input = kTests[i].inputs[j].apsr; 722 uint32_t rd_input = kTests[i].inputs[j].rd; 723 uint32_t rn_input = kTests[i].inputs[j].rn; 724 uint32_t apsr_ref = reference[i].outputs[j].apsr; 725 uint32_t rd_ref = reference[i].outputs[j].rd; 726 uint32_t rn_ref = reference[i].outputs[j].rn; 727 728 if (((apsr != apsr_ref) || (rd != rd_ref) || (rn != rn_ref)) && 729 (++total_error_count <= kErrorReportLimit)) { 730 // Print the instruction once even if it triggered multiple failures. 731 if (!instruction_has_errors) { 732 printf("Error(s) when testing \"%s %s\":\n", mnemonic, 733 kTests[i].operands_description); 734 instruction_has_errors = true; 735 } 736 // Print subsequent errors. 737 printf(" Input: "); 738 printf("0x%08" PRIx32, apsr_input); 739 printf(", "); 740 printf("0x%08" PRIx32, rd_input); 741 printf(", "); 742 printf("0x%08" PRIx32, rn_input); 743 printf("\n"); 744 printf(" Expected: "); 745 printf("0x%08" PRIx32, apsr_ref); 746 printf(", "); 747 printf("0x%08" PRIx32, rd_ref); 748 printf(", "); 749 printf("0x%08" PRIx32, rn_ref); 750 printf("\n"); 751 printf(" Found: "); 752 printf("0x%08" PRIx32, apsr); 753 printf(", "); 754 printf("0x%08" PRIx32, rd); 755 printf(", "); 756 printf("0x%08" PRIx32, rn); 757 printf("\n\n"); 758 } 759 } 760 } 761 762 if (total_error_count > kErrorReportLimit) { 763 printf("%u other errors follow.\n", 764 total_error_count - kErrorReportLimit); 765 } 766// TODO: Do this check for the simulator too when it is ready. 767#ifndef VIXL_INCLUDE_SIMULATOR 768 VIXL_CHECK(total_error_count == 0); 769#endif 770 } 771 772 for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) { 773 delete[] results[i]->outputs; 774 delete results[i]; 775 delete scratch_memory_buffers[i]; 776 } 777 778 TEARDOWN(); 779} 780 781// Instantiate tests for each instruction in the list. 782#define TEST(mnemonic) \ 783 static void Test_##mnemonic() { \ 784 TestHelper(&MacroAssembler::mnemonic, #mnemonic, kReference##mnemonic); \ 785 } \ 786 static Test test_##mnemonic( \ 787 "AARCH32_SIMULATOR_COND_RD_OPERAND_RN_A32_" #mnemonic, \ 788 &Test_##mnemonic); 789FOREACH_INSTRUCTION(TEST) 790#undef TEST 791 792} // aarch32 793} // vixl 794