test-simulator-cond-rd-operand-rn-ror-amount-a32.cc revision 9a9331faeba996d6c85e6e2a6355ccfc22c6cab6
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 113namespace vixl { 114namespace aarch32 { 115 116// List of instruction encodings: 117#define FOREACH_INSTRUCTION(M) \ 118 M(Sxtb) \ 119 M(Sxtb16) \ 120 M(Sxth) \ 121 M(Uxtb) \ 122 M(Uxtb16) \ 123 M(Uxth) 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_A32 134namespace { 135 136// Values to be passed to the assembler to produce the instruction under test. 137struct Operands { 138 Condition cond; 139 Register rd; 140 Register rn; 141 ShiftType ror; 142 uint32_t amount; 143}; 144 145// Input data to feed to the instruction. 146struct Inputs { 147 uint32_t apsr; 148 uint32_t rd; 149 uint32_t rn; 150}; 151 152// This structure contains all input data needed to test one specific encoding. 153// It used to generate a loop over an instruction. 154struct TestLoopData { 155 // The `operands` fields represents the values to pass to the assembler to 156 // produce the instruction. 157 Operands operands; 158 // Description of the operands, used for error reporting. 159 const char* operands_description; 160 // Unique identifier, used for generating traces. 161 const char* identifier; 162 // Array of values to be fed to the instruction. 163 size_t input_size; 164 const Inputs* inputs; 165}; 166 167static const Inputs kCondition[] = {{NFlag, 0xabababab, 0xabababab}, 168 {ZFlag, 0xabababab, 0xabababab}, 169 {CFlag, 0xabababab, 0xabababab}, 170 {VFlag, 0xabababab, 0xabababab}, 171 {NZFlag, 0xabababab, 0xabababab}, 172 {NCFlag, 0xabababab, 0xabababab}, 173 {NVFlag, 0xabababab, 0xabababab}, 174 {ZCFlag, 0xabababab, 0xabababab}, 175 {ZVFlag, 0xabababab, 0xabababab}, 176 {CVFlag, 0xabababab, 0xabababab}, 177 {NZCFlag, 0xabababab, 0xabababab}, 178 {NZVFlag, 0xabababab, 0xabababab}, 179 {NCVFlag, 0xabababab, 0xabababab}, 180 {ZCVFlag, 0xabababab, 0xabababab}, 181 {NZCVFlag, 0xabababab, 0xabababab}}; 182 183static const Inputs kRdIsRn[] = {{NoFlag, 0x00000000, 0x00000000}, 184 {NoFlag, 0x00000001, 0x00000001}, 185 {NoFlag, 0x00000002, 0x00000002}, 186 {NoFlag, 0x00000020, 0x00000020}, 187 {NoFlag, 0x0000007d, 0x0000007d}, 188 {NoFlag, 0x0000007e, 0x0000007e}, 189 {NoFlag, 0x0000007f, 0x0000007f}, 190 {NoFlag, 0x00007ffd, 0x00007ffd}, 191 {NoFlag, 0x00007ffe, 0x00007ffe}, 192 {NoFlag, 0x00007fff, 0x00007fff}, 193 {NoFlag, 0x33333333, 0x33333333}, 194 {NoFlag, 0x55555555, 0x55555555}, 195 {NoFlag, 0x7ffffffd, 0x7ffffffd}, 196 {NoFlag, 0x7ffffffe, 0x7ffffffe}, 197 {NoFlag, 0x7fffffff, 0x7fffffff}, 198 {NoFlag, 0x80000000, 0x80000000}, 199 {NoFlag, 0x80000001, 0x80000001}, 200 {NoFlag, 0xaaaaaaaa, 0xaaaaaaaa}, 201 {NoFlag, 0xcccccccc, 0xcccccccc}, 202 {NoFlag, 0xffff8000, 0xffff8000}, 203 {NoFlag, 0xffff8001, 0xffff8001}, 204 {NoFlag, 0xffff8002, 0xffff8002}, 205 {NoFlag, 0xffff8003, 0xffff8003}, 206 {NoFlag, 0xffffff80, 0xffffff80}, 207 {NoFlag, 0xffffff81, 0xffffff81}, 208 {NoFlag, 0xffffff82, 0xffffff82}, 209 {NoFlag, 0xffffff83, 0xffffff83}, 210 {NoFlag, 0xffffffe0, 0xffffffe0}, 211 {NoFlag, 0xfffffffd, 0xfffffffd}, 212 {NoFlag, 0xfffffffe, 0xfffffffe}, 213 {NoFlag, 0xffffffff, 0xffffffff}}; 214 215static const Inputs kRdIsNotRn[] = {{NoFlag, 0x00000002, 0xcccccccc}, 216 {NoFlag, 0x7ffffffd, 0x00007ffe}, 217 {NoFlag, 0xffffff80, 0x00000020}, 218 {NoFlag, 0xaaaaaaaa, 0xaaaaaaaa}, 219 {NoFlag, 0x33333333, 0xffffff82}, 220 {NoFlag, 0xffff8001, 0x7ffffffe}, 221 {NoFlag, 0xfffffffd, 0x00007ffe}, 222 {NoFlag, 0xffffff80, 0x80000000}, 223 {NoFlag, 0x00000001, 0x33333333}, 224 {NoFlag, 0xcccccccc, 0x7ffffffe}, 225 {NoFlag, 0x00000000, 0xcccccccc}, 226 {NoFlag, 0x00000000, 0x55555555}, 227 {NoFlag, 0xffffffff, 0xffffffff}, 228 {NoFlag, 0x0000007e, 0xffff8002}, 229 {NoFlag, 0x80000000, 0x7ffffffd}, 230 {NoFlag, 0xffffff81, 0x0000007e}, 231 {NoFlag, 0x0000007f, 0xffff8001}, 232 {NoFlag, 0xffffffe0, 0x00007ffd}, 233 {NoFlag, 0xffff8003, 0x00000002}, 234 {NoFlag, 0xffffff83, 0x55555555}, 235 {NoFlag, 0xffffff83, 0xffffff80}, 236 {NoFlag, 0xffffff81, 0xffff8000}, 237 {NoFlag, 0x00000020, 0x7ffffffe}, 238 {NoFlag, 0xffffffe0, 0x00000000}, 239 {NoFlag, 0x7fffffff, 0x0000007e}, 240 {NoFlag, 0x80000001, 0xffffffff}, 241 {NoFlag, 0x00000001, 0x80000001}, 242 {NoFlag, 0x00000002, 0x0000007f}, 243 {NoFlag, 0x7fffffff, 0xcccccccc}, 244 {NoFlag, 0x80000001, 0x00007ffe}, 245 {NoFlag, 0xffff8002, 0x0000007e}, 246 {NoFlag, 0x00007ffe, 0xcccccccc}, 247 {NoFlag, 0x80000000, 0xffff8002}, 248 {NoFlag, 0xffffff83, 0x7ffffffe}, 249 {NoFlag, 0xffff8001, 0x00000001}, 250 {NoFlag, 0xffffff81, 0x00000020}, 251 {NoFlag, 0xfffffffe, 0xffff8001}, 252 {NoFlag, 0xffffffff, 0xfffffffe}, 253 {NoFlag, 0xcccccccc, 0x55555555}, 254 {NoFlag, 0x00000020, 0xffffff83}, 255 {NoFlag, 0xffffff83, 0xffff8001}, 256 {NoFlag, 0xffffff83, 0xffff8000}, 257 {NoFlag, 0x00007fff, 0x00000002}, 258 {NoFlag, 0x55555555, 0xffff8000}, 259 {NoFlag, 0x80000001, 0xffffff81}, 260 {NoFlag, 0x00000002, 0x00000000}, 261 {NoFlag, 0x33333333, 0xffffff81}, 262 {NoFlag, 0xffff8001, 0xffffff82}, 263 {NoFlag, 0xcccccccc, 0xffff8003}, 264 {NoFlag, 0xffff8003, 0x7ffffffd}, 265 {NoFlag, 0x0000007d, 0x00007ffe}, 266 {NoFlag, 0xffffff80, 0x0000007d}, 267 {NoFlag, 0xaaaaaaaa, 0x00007ffd}, 268 {NoFlag, 0x80000000, 0xffffff82}, 269 {NoFlag, 0x00000002, 0x7ffffffe}, 270 {NoFlag, 0x00000002, 0xffffff83}, 271 {NoFlag, 0x55555555, 0x00000002}, 272 {NoFlag, 0xffffffff, 0xffffff82}, 273 {NoFlag, 0xaaaaaaaa, 0x00000020}, 274 {NoFlag, 0x00000001, 0xffffff82}, 275 {NoFlag, 0x0000007f, 0xffffff82}, 276 {NoFlag, 0x7ffffffd, 0xaaaaaaaa}, 277 {NoFlag, 0x00007ffe, 0x00000001}, 278 {NoFlag, 0xfffffffd, 0xffffffe0}, 279 {NoFlag, 0xffffff81, 0xffffff83}, 280 {NoFlag, 0x0000007d, 0x00000000}, 281 {NoFlag, 0x0000007d, 0xffff8000}, 282 {NoFlag, 0xffffff81, 0x7fffffff}, 283 {NoFlag, 0xffffffff, 0x80000000}, 284 {NoFlag, 0x00000000, 0x00000001}, 285 {NoFlag, 0x55555555, 0xffffff82}, 286 {NoFlag, 0x00007ffe, 0x00007ffe}, 287 {NoFlag, 0x80000001, 0xfffffffd}, 288 {NoFlag, 0x00007fff, 0x33333333}, 289 {NoFlag, 0x00007fff, 0x80000000}, 290 {NoFlag, 0xcccccccc, 0x00007fff}, 291 {NoFlag, 0xfffffffe, 0xffffffe0}, 292 {NoFlag, 0x7ffffffe, 0x0000007f}, 293 {NoFlag, 0x00007ffd, 0xffff8001}, 294 {NoFlag, 0x00000002, 0x00000001}, 295 {NoFlag, 0x80000000, 0xffffffff}, 296 {NoFlag, 0xffffff83, 0xcccccccc}, 297 {NoFlag, 0xffff8002, 0x7ffffffe}, 298 {NoFlag, 0xaaaaaaaa, 0x00000000}, 299 {NoFlag, 0xffffff80, 0xcccccccc}, 300 {NoFlag, 0x33333333, 0xffffff83}, 301 {NoFlag, 0x0000007e, 0xffffffe0}, 302 {NoFlag, 0x0000007e, 0x00007fff}, 303 {NoFlag, 0x0000007f, 0x00000002}, 304 {NoFlag, 0x7ffffffe, 0xcccccccc}, 305 {NoFlag, 0x0000007d, 0xffffff80}, 306 {NoFlag, 0x00007fff, 0x00000020}, 307 {NoFlag, 0x7ffffffe, 0xfffffffe}, 308 {NoFlag, 0xfffffffe, 0xffffff81}, 309 {NoFlag, 0xffffffff, 0x0000007f}, 310 {NoFlag, 0xffff8002, 0x7ffffffd}, 311 {NoFlag, 0xffff8001, 0xfffffffe}, 312 {NoFlag, 0x33333333, 0xffff8002}, 313 {NoFlag, 0x00000000, 0xffffffff}, 314 {NoFlag, 0x33333333, 0xffffff80}, 315 {NoFlag, 0x0000007f, 0x00007fff}, 316 {NoFlag, 0xffffffff, 0xffff8001}, 317 {NoFlag, 0x7fffffff, 0xffff8002}, 318 {NoFlag, 0x7ffffffd, 0xffffff83}, 319 {NoFlag, 0x7fffffff, 0x0000007f}, 320 {NoFlag, 0xffffff83, 0xfffffffe}, 321 {NoFlag, 0x7ffffffe, 0xffff8003}, 322 {NoFlag, 0xffff8002, 0xffff8002}, 323 {NoFlag, 0x80000001, 0x0000007f}, 324 {NoFlag, 0x00000020, 0x00000002}, 325 {NoFlag, 0xffffff82, 0xffff8001}, 326 {NoFlag, 0xffffffff, 0x00000001}, 327 {NoFlag, 0xffffff80, 0xffff8002}, 328 {NoFlag, 0xffff8003, 0x7fffffff}, 329 {NoFlag, 0xffffffff, 0xffff8000}, 330 {NoFlag, 0xffff8002, 0x00007ffd}, 331 {NoFlag, 0x00000020, 0xffffff81}, 332 {NoFlag, 0x00000001, 0x55555555}, 333 {NoFlag, 0x7ffffffe, 0x00000020}, 334 {NoFlag, 0x80000000, 0x00000001}, 335 {NoFlag, 0x00007ffd, 0xffff8002}, 336 {NoFlag, 0x7fffffff, 0xfffffffe}, 337 {NoFlag, 0xcccccccc, 0x00007ffd}, 338 {NoFlag, 0x00000000, 0xfffffffd}, 339 {NoFlag, 0xffff8003, 0xffffff80}, 340 {NoFlag, 0x80000001, 0xffffff80}, 341 {NoFlag, 0xffffffff, 0xffff8002}, 342 {NoFlag, 0x00007ffe, 0xffff8002}, 343 {NoFlag, 0xffffff80, 0x00007ffe}, 344 {NoFlag, 0x80000001, 0xffff8001}, 345 {NoFlag, 0x0000007f, 0xffffff80}, 346 {NoFlag, 0xffffff81, 0x80000000}, 347 {NoFlag, 0x00007fff, 0x00007ffe}, 348 {NoFlag, 0x33333333, 0xffff8000}, 349 {NoFlag, 0x33333333, 0x00007fff}, 350 {NoFlag, 0x00000000, 0x0000007d}, 351 {NoFlag, 0x80000001, 0x00000000}, 352 {NoFlag, 0xffffffff, 0x55555555}, 353 {NoFlag, 0x80000001, 0x80000000}, 354 {NoFlag, 0xffffffff, 0xffffff80}, 355 {NoFlag, 0xffffff81, 0xffff8003}, 356 {NoFlag, 0x55555555, 0x80000001}, 357 {NoFlag, 0x7fffffff, 0xffff8001}, 358 {NoFlag, 0xffffff83, 0x00000002}, 359 {NoFlag, 0x0000007e, 0xffffff81}, 360 {NoFlag, 0x80000000, 0xffff8001}, 361 {NoFlag, 0xffffff80, 0xfffffffe}, 362 {NoFlag, 0x0000007e, 0xfffffffd}, 363 {NoFlag, 0xffffffe0, 0xffffffff}, 364 {NoFlag, 0x55555555, 0x80000000}, 365 {NoFlag, 0x0000007d, 0x80000001}, 366 {NoFlag, 0xffffffe0, 0x7ffffffd}, 367 {NoFlag, 0x00000000, 0x00000000}, 368 {NoFlag, 0x55555555, 0x00000001}, 369 {NoFlag, 0x00007ffd, 0x7fffffff}, 370 {NoFlag, 0x55555555, 0xffffffff}, 371 {NoFlag, 0xffff8003, 0x00007fff}, 372 {NoFlag, 0xffffff82, 0x00007fff}, 373 {NoFlag, 0x33333333, 0x55555555}, 374 {NoFlag, 0x00000020, 0x33333333}, 375 {NoFlag, 0x7ffffffe, 0xfffffffd}, 376 {NoFlag, 0x7ffffffe, 0x00000001}, 377 {NoFlag, 0xffffff83, 0xffffffe0}, 378 {NoFlag, 0xfffffffe, 0xaaaaaaaa}, 379 {NoFlag, 0xffff8002, 0x33333333}, 380 {NoFlag, 0xffff8002, 0xffff8003}, 381 {NoFlag, 0x33333333, 0x7fffffff}, 382 {NoFlag, 0xfffffffd, 0xffffff83}, 383 {NoFlag, 0x00000000, 0xffff8000}, 384 {NoFlag, 0xffffff82, 0x55555555}, 385 {NoFlag, 0xffffff82, 0xffffff81}, 386 {NoFlag, 0xcccccccc, 0xfffffffe}, 387 {NoFlag, 0xfffffffd, 0x7fffffff}, 388 {NoFlag, 0x00007fff, 0x7fffffff}, 389 {NoFlag, 0xffffff83, 0xffff8003}, 390 {NoFlag, 0xfffffffe, 0xffffffff}, 391 {NoFlag, 0x7ffffffd, 0x00007ffd}, 392 {NoFlag, 0x7ffffffd, 0x00007fff}, 393 {NoFlag, 0x00007ffd, 0xffffffff}, 394 {NoFlag, 0x00000001, 0xffff8003}, 395 {NoFlag, 0xffffff80, 0xfffffffd}, 396 {NoFlag, 0x33333333, 0x80000000}, 397 {NoFlag, 0xffff8001, 0x00000020}, 398 {NoFlag, 0xcccccccc, 0x00000002}, 399 {NoFlag, 0x00000000, 0x00000002}, 400 {NoFlag, 0x0000007d, 0x00007fff}, 401 {NoFlag, 0xcccccccc, 0x00000001}, 402 {NoFlag, 0xffffff83, 0x00007fff}, 403 {NoFlag, 0x80000001, 0x00000020}, 404 {NoFlag, 0xffff8003, 0xffffffe0}, 405 {NoFlag, 0x00007ffd, 0xaaaaaaaa}, 406 {NoFlag, 0x33333333, 0xffff8001}, 407 {NoFlag, 0xffffff83, 0x80000001}, 408 {NoFlag, 0xffff8000, 0xffff8000}, 409 {NoFlag, 0x00007ffe, 0xffff8001}, 410 {NoFlag, 0x7ffffffd, 0x00000000}, 411 {NoFlag, 0x00007ffe, 0x33333333}, 412 {NoFlag, 0xffff8001, 0xffffff80}, 413 {NoFlag, 0xfffffffe, 0x55555555}, 414 {NoFlag, 0xffffff82, 0xffffffff}}; 415 416static const Inputs kRotations[] = {{NoFlag, 0xabababab, 0x00000000}, 417 {NoFlag, 0xabababab, 0x00000001}, 418 {NoFlag, 0xabababab, 0x00000002}, 419 {NoFlag, 0xabababab, 0x00000020}, 420 {NoFlag, 0xabababab, 0x0000007d}, 421 {NoFlag, 0xabababab, 0x0000007e}, 422 {NoFlag, 0xabababab, 0x0000007f}, 423 {NoFlag, 0xabababab, 0x00007ffd}, 424 {NoFlag, 0xabababab, 0x00007ffe}, 425 {NoFlag, 0xabababab, 0x00007fff}, 426 {NoFlag, 0xabababab, 0x33333333}, 427 {NoFlag, 0xabababab, 0x55555555}, 428 {NoFlag, 0xabababab, 0x7ffffffd}, 429 {NoFlag, 0xabababab, 0x7ffffffe}, 430 {NoFlag, 0xabababab, 0x7fffffff}, 431 {NoFlag, 0xabababab, 0x80000000}, 432 {NoFlag, 0xabababab, 0x80000001}, 433 {NoFlag, 0xabababab, 0xaaaaaaaa}, 434 {NoFlag, 0xabababab, 0xcccccccc}, 435 {NoFlag, 0xabababab, 0xffff8000}, 436 {NoFlag, 0xabababab, 0xffff8001}, 437 {NoFlag, 0xabababab, 0xffff8002}, 438 {NoFlag, 0xabababab, 0xffff8003}, 439 {NoFlag, 0xabababab, 0xffffff80}, 440 {NoFlag, 0xabababab, 0xffffff81}, 441 {NoFlag, 0xabababab, 0xffffff82}, 442 {NoFlag, 0xabababab, 0xffffff83}, 443 {NoFlag, 0xabababab, 0xffffffe0}, 444 {NoFlag, 0xabababab, 0xfffffffd}, 445 {NoFlag, 0xabababab, 0xfffffffe}, 446 {NoFlag, 0xabababab, 0xffffffff}}; 447 448 449// A loop will be generated for each element of this array. 450const TestLoopData kTests[] = {{{eq, r0, r0, ROR, 0}, 451 "eq r0 r0 ROR 0", 452 "Condition_eq_r0_r0_ROR_0", 453 ARRAY_SIZE(kCondition), 454 kCondition}, 455 {{ne, r0, r0, ROR, 0}, 456 "ne r0 r0 ROR 0", 457 "Condition_ne_r0_r0_ROR_0", 458 ARRAY_SIZE(kCondition), 459 kCondition}, 460 {{cs, r0, r0, ROR, 0}, 461 "cs r0 r0 ROR 0", 462 "Condition_cs_r0_r0_ROR_0", 463 ARRAY_SIZE(kCondition), 464 kCondition}, 465 {{cc, r0, r0, ROR, 0}, 466 "cc r0 r0 ROR 0", 467 "Condition_cc_r0_r0_ROR_0", 468 ARRAY_SIZE(kCondition), 469 kCondition}, 470 {{mi, r0, r0, ROR, 0}, 471 "mi r0 r0 ROR 0", 472 "Condition_mi_r0_r0_ROR_0", 473 ARRAY_SIZE(kCondition), 474 kCondition}, 475 {{pl, r0, r0, ROR, 0}, 476 "pl r0 r0 ROR 0", 477 "Condition_pl_r0_r0_ROR_0", 478 ARRAY_SIZE(kCondition), 479 kCondition}, 480 {{vs, r0, r0, ROR, 0}, 481 "vs r0 r0 ROR 0", 482 "Condition_vs_r0_r0_ROR_0", 483 ARRAY_SIZE(kCondition), 484 kCondition}, 485 {{vc, r0, r0, ROR, 0}, 486 "vc r0 r0 ROR 0", 487 "Condition_vc_r0_r0_ROR_0", 488 ARRAY_SIZE(kCondition), 489 kCondition}, 490 {{hi, r0, r0, ROR, 0}, 491 "hi r0 r0 ROR 0", 492 "Condition_hi_r0_r0_ROR_0", 493 ARRAY_SIZE(kCondition), 494 kCondition}, 495 {{ls, r0, r0, ROR, 0}, 496 "ls r0 r0 ROR 0", 497 "Condition_ls_r0_r0_ROR_0", 498 ARRAY_SIZE(kCondition), 499 kCondition}, 500 {{ge, r0, r0, ROR, 0}, 501 "ge r0 r0 ROR 0", 502 "Condition_ge_r0_r0_ROR_0", 503 ARRAY_SIZE(kCondition), 504 kCondition}, 505 {{lt, r0, r0, ROR, 0}, 506 "lt r0 r0 ROR 0", 507 "Condition_lt_r0_r0_ROR_0", 508 ARRAY_SIZE(kCondition), 509 kCondition}, 510 {{gt, r0, r0, ROR, 0}, 511 "gt r0 r0 ROR 0", 512 "Condition_gt_r0_r0_ROR_0", 513 ARRAY_SIZE(kCondition), 514 kCondition}, 515 {{le, r0, r0, ROR, 0}, 516 "le r0 r0 ROR 0", 517 "Condition_le_r0_r0_ROR_0", 518 ARRAY_SIZE(kCondition), 519 kCondition}, 520 {{al, r0, r0, ROR, 0}, 521 "al r0 r0 ROR 0", 522 "Condition_al_r0_r0_ROR_0", 523 ARRAY_SIZE(kCondition), 524 kCondition}, 525 {{al, r0, r0, ROR, 0}, 526 "al r0 r0 ROR 0", 527 "RdIsRn_al_r0_r0_ROR_0", 528 ARRAY_SIZE(kRdIsRn), 529 kRdIsRn}, 530 {{al, r1, r1, ROR, 0}, 531 "al r1 r1 ROR 0", 532 "RdIsRn_al_r1_r1_ROR_0", 533 ARRAY_SIZE(kRdIsRn), 534 kRdIsRn}, 535 {{al, r2, r2, ROR, 0}, 536 "al r2 r2 ROR 0", 537 "RdIsRn_al_r2_r2_ROR_0", 538 ARRAY_SIZE(kRdIsRn), 539 kRdIsRn}, 540 {{al, r3, r3, ROR, 0}, 541 "al r3 r3 ROR 0", 542 "RdIsRn_al_r3_r3_ROR_0", 543 ARRAY_SIZE(kRdIsRn), 544 kRdIsRn}, 545 {{al, r4, r4, ROR, 0}, 546 "al r4 r4 ROR 0", 547 "RdIsRn_al_r4_r4_ROR_0", 548 ARRAY_SIZE(kRdIsRn), 549 kRdIsRn}, 550 {{al, r5, r5, ROR, 0}, 551 "al r5 r5 ROR 0", 552 "RdIsRn_al_r5_r5_ROR_0", 553 ARRAY_SIZE(kRdIsRn), 554 kRdIsRn}, 555 {{al, r6, r6, ROR, 0}, 556 "al r6 r6 ROR 0", 557 "RdIsRn_al_r6_r6_ROR_0", 558 ARRAY_SIZE(kRdIsRn), 559 kRdIsRn}, 560 {{al, r7, r7, ROR, 0}, 561 "al r7 r7 ROR 0", 562 "RdIsRn_al_r7_r7_ROR_0", 563 ARRAY_SIZE(kRdIsRn), 564 kRdIsRn}, 565 {{al, r8, r8, ROR, 0}, 566 "al r8 r8 ROR 0", 567 "RdIsRn_al_r8_r8_ROR_0", 568 ARRAY_SIZE(kRdIsRn), 569 kRdIsRn}, 570 {{al, r9, r9, ROR, 0}, 571 "al r9 r9 ROR 0", 572 "RdIsRn_al_r9_r9_ROR_0", 573 ARRAY_SIZE(kRdIsRn), 574 kRdIsRn}, 575 {{al, r10, r10, ROR, 0}, 576 "al r10 r10 ROR 0", 577 "RdIsRn_al_r10_r10_ROR_0", 578 ARRAY_SIZE(kRdIsRn), 579 kRdIsRn}, 580 {{al, r11, r11, ROR, 0}, 581 "al r11 r11 ROR 0", 582 "RdIsRn_al_r11_r11_ROR_0", 583 ARRAY_SIZE(kRdIsRn), 584 kRdIsRn}, 585 {{al, r12, r12, ROR, 0}, 586 "al r12 r12 ROR 0", 587 "RdIsRn_al_r12_r12_ROR_0", 588 ARRAY_SIZE(kRdIsRn), 589 kRdIsRn}, 590 {{al, r14, r14, ROR, 0}, 591 "al r14 r14 ROR 0", 592 "RdIsRn_al_r14_r14_ROR_0", 593 ARRAY_SIZE(kRdIsRn), 594 kRdIsRn}, 595 {{al, r1, r8, ROR, 0}, 596 "al r1 r8 ROR 0", 597 "RdIsNotRn_al_r1_r8_ROR_0", 598 ARRAY_SIZE(kRdIsNotRn), 599 kRdIsNotRn}, 600 {{al, r7, r4, ROR, 0}, 601 "al r7 r4 ROR 0", 602 "RdIsNotRn_al_r7_r4_ROR_0", 603 ARRAY_SIZE(kRdIsNotRn), 604 kRdIsNotRn}, 605 {{al, r14, r10, ROR, 0}, 606 "al r14 r10 ROR 0", 607 "RdIsNotRn_al_r14_r10_ROR_0", 608 ARRAY_SIZE(kRdIsNotRn), 609 kRdIsNotRn}, 610 {{al, r10, r6, ROR, 0}, 611 "al r10 r6 ROR 0", 612 "RdIsNotRn_al_r10_r6_ROR_0", 613 ARRAY_SIZE(kRdIsNotRn), 614 kRdIsNotRn}, 615 {{al, r6, r5, ROR, 0}, 616 "al r6 r5 ROR 0", 617 "RdIsNotRn_al_r6_r5_ROR_0", 618 ARRAY_SIZE(kRdIsNotRn), 619 kRdIsNotRn}, 620 {{al, r12, r2, ROR, 0}, 621 "al r12 r2 ROR 0", 622 "RdIsNotRn_al_r12_r2_ROR_0", 623 ARRAY_SIZE(kRdIsNotRn), 624 kRdIsNotRn}, 625 {{al, r0, r11, ROR, 0}, 626 "al r0 r11 ROR 0", 627 "RdIsNotRn_al_r0_r11_ROR_0", 628 ARRAY_SIZE(kRdIsNotRn), 629 kRdIsNotRn}, 630 {{al, r10, r14, ROR, 0}, 631 "al r10 r14 ROR 0", 632 "RdIsNotRn_al_r10_r14_ROR_0", 633 ARRAY_SIZE(kRdIsNotRn), 634 kRdIsNotRn}, 635 {{al, r0, r5, ROR, 0}, 636 "al r0 r5 ROR 0", 637 "RdIsNotRn_al_r0_r5_ROR_0", 638 ARRAY_SIZE(kRdIsNotRn), 639 kRdIsNotRn}, 640 {{al, r0, r3, ROR, 0}, 641 "al r0 r3 ROR 0", 642 "RdIsNotRn_al_r0_r3_ROR_0", 643 ARRAY_SIZE(kRdIsNotRn), 644 kRdIsNotRn}, 645 {{al, r0, r1, ROR, 0}, 646 "al r0 r1 ROR 0", 647 "Rotations_al_r0_r1_ROR_0", 648 ARRAY_SIZE(kRotations), 649 kRotations}, 650 {{al, r0, r1, ROR, 8}, 651 "al r0 r1 ROR 8", 652 "Rotations_al_r0_r1_ROR_8", 653 ARRAY_SIZE(kRotations), 654 kRotations}, 655 {{al, r0, r1, ROR, 16}, 656 "al r0 r1 ROR 16", 657 "Rotations_al_r0_r1_ROR_16", 658 ARRAY_SIZE(kRotations), 659 kRotations}, 660 {{al, r0, r1, ROR, 24}, 661 "al r0 r1 ROR 24", 662 "Rotations_al_r0_r1_ROR_24", 663 ARRAY_SIZE(kRotations), 664 kRotations}}; 665 666// We record all inputs to the instructions as outputs. This way, we also check 667// that what shouldn't change didn't change. 668struct TestResult { 669 size_t output_size; 670 const Inputs* outputs; 671}; 672 673// These headers each contain an array of `TestResult` with the reference output 674// values. The reference arrays are names `kReference{mnemonic}`. 675#include "aarch32/traces/simulator-cond-rd-operand-rn-ror-amount-a32-sxtb.h" 676#include "aarch32/traces/simulator-cond-rd-operand-rn-ror-amount-a32-sxtb16.h" 677#include "aarch32/traces/simulator-cond-rd-operand-rn-ror-amount-a32-sxth.h" 678#include "aarch32/traces/simulator-cond-rd-operand-rn-ror-amount-a32-uxtb.h" 679#include "aarch32/traces/simulator-cond-rd-operand-rn-ror-amount-a32-uxtb16.h" 680#include "aarch32/traces/simulator-cond-rd-operand-rn-ror-amount-a32-uxth.h" 681 682 683// The maximum number of errors to report in detail for each test. 684const unsigned kErrorReportLimit = 8; 685 686typedef void (MacroAssembler::*Fn)(Condition cond, 687 Register rd, 688 const Operand& op); 689 690void TestHelper(Fn instruction, 691 const char* mnemonic, 692 const TestResult reference[]) { 693 SETUP(); 694 masm.UseA32(); 695 START(); 696 697 // Data to compare to `reference`. 698 TestResult* results[ARRAY_SIZE(kTests)]; 699 700 // Test cases for memory bound instructions may allocate a buffer and save its 701 // address in this array. 702 byte* scratch_memory_buffers[ARRAY_SIZE(kTests)]; 703 704 // Generate a loop for each element in `kTests`. Each loop tests one specific 705 // instruction. 706 for (unsigned i = 0; i < ARRAY_SIZE(kTests); i++) { 707 // Allocate results on the heap for this test. 708 results[i] = new TestResult; 709 results[i]->outputs = new Inputs[kTests[i].input_size]; 710 results[i]->output_size = kTests[i].input_size; 711 712 size_t input_stride = sizeof(kTests[i].inputs[0]) * kTests[i].input_size; 713 VIXL_ASSERT(IsUint32(input_stride)); 714 715 scratch_memory_buffers[i] = NULL; 716 717 Label loop; 718 UseScratchRegisterScope scratch_registers(&masm); 719 // Include all registers from r0 ro r12. 720 scratch_registers.Include(RegisterList(0x1fff)); 721 722 // Values to pass to the macro-assembler. 723 Condition cond = kTests[i].operands.cond; 724 Register rd = kTests[i].operands.rd; 725 Register rn = kTests[i].operands.rn; 726 ShiftType ror = kTests[i].operands.ror; 727 uint32_t amount = kTests[i].operands.amount; 728 Operand op(rn, ror, amount); 729 scratch_registers.Exclude(rd); 730 scratch_registers.Exclude(rn); 731 732 // Allocate reserved registers for our own use. 733 Register input_ptr = scratch_registers.Acquire(); 734 Register input_end = scratch_registers.Acquire(); 735 Register result_ptr = scratch_registers.Acquire(); 736 737 // Initialize `input_ptr` to the first element and `input_end` the address 738 // after the array. 739 __ Mov(input_ptr, Operand::From(kTests[i].inputs)); 740 __ Add(input_end, input_ptr, static_cast<uint32_t>(input_stride)); 741 __ Mov(result_ptr, Operand::From(results[i]->outputs)); 742 __ Bind(&loop); 743 744 { 745 UseScratchRegisterScope temp_registers(&masm); 746 Register nzcv_bits = temp_registers.Acquire(); 747 Register saved_q_bit = temp_registers.Acquire(); 748 // Save the `Q` bit flag. 749 __ Mrs(saved_q_bit, APSR); 750 __ And(saved_q_bit, saved_q_bit, QFlag); 751 // Set the `NZCV` and `Q` flags together. 752 __ Ldr(nzcv_bits, MemOperand(input_ptr, offsetof(Inputs, apsr))); 753 __ Orr(nzcv_bits, nzcv_bits, saved_q_bit); 754 __ Msr(APSR_nzcvq, nzcv_bits); 755 } 756 __ Ldr(rd, MemOperand(input_ptr, offsetof(Inputs, rd))); 757 __ Ldr(rn, MemOperand(input_ptr, offsetof(Inputs, rn))); 758 759 (masm.*instruction)(cond, rd, op); 760 761 { 762 UseScratchRegisterScope temp_registers(&masm); 763 Register nzcv_bits = temp_registers.Acquire(); 764 __ Mrs(nzcv_bits, APSR); 765 // Only record the NZCV bits. 766 __ And(nzcv_bits, nzcv_bits, NZCVFlag); 767 __ Str(nzcv_bits, MemOperand(result_ptr, offsetof(Inputs, apsr))); 768 } 769 __ Str(rd, MemOperand(result_ptr, offsetof(Inputs, rd))); 770 __ Str(rn, MemOperand(result_ptr, offsetof(Inputs, rn))); 771 772 // Advance the result pointer. 773 __ Add(result_ptr, result_ptr, Operand::From(sizeof(kTests[i].inputs[0]))); 774 // Loop back until `input_ptr` is lower than `input_base`. 775 __ Add(input_ptr, input_ptr, Operand::From(sizeof(kTests[i].inputs[0]))); 776 __ Cmp(input_ptr, input_end); 777 __ B(ne, &loop); 778 } 779 780 END(); 781 782 RUN(); 783 784 if (Test::generate_test_trace()) { 785 // Print the results. 786 for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) { 787 printf("const Inputs kOutputs_%s_%s[] = {\n", 788 mnemonic, 789 kTests[i].identifier); 790 for (size_t j = 0; j < results[i]->output_size; j++) { 791 printf(" { "); 792 printf("0x%08" PRIx32, results[i]->outputs[j].apsr); 793 printf(", "); 794 printf("0x%08" PRIx32, results[i]->outputs[j].rd); 795 printf(", "); 796 printf("0x%08" PRIx32, results[i]->outputs[j].rn); 797 printf(" },\n"); 798 } 799 printf("};\n"); 800 } 801 printf("const TestResult kReference%s[] = {\n", mnemonic); 802 for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) { 803 printf(" {\n"); 804 printf(" ARRAY_SIZE(kOutputs_%s_%s),\n", 805 mnemonic, 806 kTests[i].identifier); 807 printf(" kOutputs_%s_%s,\n", mnemonic, kTests[i].identifier); 808 printf(" },\n"); 809 } 810 printf("};\n"); 811 } else if (kCheckSimulatorTestResults) { 812 // Check the results. 813 unsigned total_error_count = 0; 814 for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) { 815 bool instruction_has_errors = false; 816 for (size_t j = 0; j < kTests[i].input_size; j++) { 817 uint32_t apsr = results[i]->outputs[j].apsr; 818 uint32_t rd = results[i]->outputs[j].rd; 819 uint32_t rn = results[i]->outputs[j].rn; 820 uint32_t apsr_input = kTests[i].inputs[j].apsr; 821 uint32_t rd_input = kTests[i].inputs[j].rd; 822 uint32_t rn_input = kTests[i].inputs[j].rn; 823 uint32_t apsr_ref = reference[i].outputs[j].apsr; 824 uint32_t rd_ref = reference[i].outputs[j].rd; 825 uint32_t rn_ref = reference[i].outputs[j].rn; 826 827 if (((apsr != apsr_ref) || (rd != rd_ref) || (rn != rn_ref)) && 828 (++total_error_count <= kErrorReportLimit)) { 829 // Print the instruction once even if it triggered multiple failures. 830 if (!instruction_has_errors) { 831 printf("Error(s) when testing \"%s %s\":\n", 832 mnemonic, 833 kTests[i].operands_description); 834 instruction_has_errors = true; 835 } 836 // Print subsequent errors. 837 printf(" Input: "); 838 printf("0x%08" PRIx32, apsr_input); 839 printf(", "); 840 printf("0x%08" PRIx32, rd_input); 841 printf(", "); 842 printf("0x%08" PRIx32, rn_input); 843 printf("\n"); 844 printf(" Expected: "); 845 printf("0x%08" PRIx32, apsr_ref); 846 printf(", "); 847 printf("0x%08" PRIx32, rd_ref); 848 printf(", "); 849 printf("0x%08" PRIx32, rn_ref); 850 printf("\n"); 851 printf(" Found: "); 852 printf("0x%08" PRIx32, apsr); 853 printf(", "); 854 printf("0x%08" PRIx32, rd); 855 printf(", "); 856 printf("0x%08" PRIx32, rn); 857 printf("\n\n"); 858 } 859 } 860 } 861 862 if (total_error_count > kErrorReportLimit) { 863 printf("%u other errors follow.\n", 864 total_error_count - kErrorReportLimit); 865 } 866 VIXL_CHECK(total_error_count == 0); 867 } else { 868 VIXL_WARNING("Assembled the code, but did not run anything.\n"); 869 } 870 871 for (size_t i = 0; i < ARRAY_SIZE(kTests); i++) { 872 delete[] results[i]->outputs; 873 delete results[i]; 874 delete[] scratch_memory_buffers[i]; 875 } 876 877 TEARDOWN(); 878} 879 880// Instantiate tests for each instruction in the list. 881// TODO: Remove this limitation by having a sandboxing mechanism. 882#if defined(VIXL_HOST_POINTER_32) 883#define TEST(mnemonic) \ 884 void Test_##mnemonic() { \ 885 TestHelper(&MacroAssembler::mnemonic, #mnemonic, kReference##mnemonic); \ 886 } \ 887 Test test_##mnemonic( \ 888 "AARCH32_SIMULATOR_COND_RD_OPERAND_RN_ROR_AMOUNT_A32_" #mnemonic, \ 889 &Test_##mnemonic); 890#else 891#define TEST(mnemonic) \ 892 void Test_##mnemonic() { \ 893 VIXL_WARNING("This test can only run on a 32-bit host.\n"); \ 894 USE(TestHelper); \ 895 } \ 896 Test test_##mnemonic( \ 897 "AARCH32_SIMULATOR_COND_RD_OPERAND_RN_ROR_AMOUNT_A32_" #mnemonic, \ 898 &Test_##mnemonic); 899#endif 900 901FOREACH_INSTRUCTION(TEST) 902#undef TEST 903 904} // namespace 905#endif 906 907} // namespace aarch32 908} // namespace vixl 909