VIXL Release 1.13

Refer to the README.md and LICENCE files for details.

Change-Id: I922914f4e7da7cb939a8054cded11feb9ea51a86
This commit is contained in:
armvixl 2016-05-10 13:57:58 +01:00 committed by Jacob Bramley
parent 788c84fd2c
commit 0f35e36b7f
88 changed files with 43118 additions and 6205 deletions

39
.clang-format Normal file
View File

@ -0,0 +1,39 @@
# Copyright 2016, ARM Limited
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of ARM Limited nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
BasedOnStyle: Google
# We keep two empty lines between functions in `.cc` files.
MaxEmptyLinesToKeep: 2
# Either fit all arguments on the same line, or have one per line.
# Ideally we would like to allow grouping them when it makes sense. But
# `clang-format` cannot know what 'makes sense'.
BinPackArguments: false
BinPackParameters: false
PenaltyBreakBeforeFirstCallParameter: 500
PenaltyBreakString: 100

View File

@ -34,20 +34,6 @@ filter=+runtime/sizeof
filter=+runtime/string
filter=+runtime/virtual
filter=+runtime/vlog
filter=+whitespace/blank_line
filter=+whitespace/braces
filter=+whitespace/comma
filter=+whitespace/comments
filter=+whitespace/end_of_line
filter=+whitespace/ending_newline
filter=+whitespace/indent
filter=+whitespace/labels
filter=+whitespace/line_length
filter=+whitespace/newline
filter=+whitespace/operators
filter=+whitespace/parens
filter=+whitespace/tab
filter=+whitespace/todo
# cpplint.py enables these filters in reversed order.
filter=-
linelength=80

View File

@ -1,4 +1,4 @@
VIXL: AArch64 Runtime Code Generation Library Version 1.12
VIXL: AArch64 Runtime Code Generation Library Version 1.13
==========================================================
Contents:
@ -49,10 +49,12 @@ A 64-bit host machine is required, implementing an LP64 data model. VIXL has
been tested using GCC on AArch64 Debian, GCC and Clang on amd64 Ubuntu
systems.
To run the linter stage of the tests, the following software is also required:
To run the linter and code formatting stages of the tests, the following
software is also required:
1. Git
2. [Google's `cpplint.py`][cpplint]
3. clang-format-3.6
Refer to the 'Usage' section for details.
@ -77,6 +79,11 @@ builds and mostly works for 32-bit x86 platforms, there are a number of
floating-point operations which do not work correctly, and a number of tests
fail as a result.
VIXL may not build using Clang 3.7, due to a compiler warning. A workaround is
to disable conversion of warnings to errors, or to delete the offending
`return` statement reported and rebuild. This problem will be fixed in the next
release.
Debug Builds
------------
@ -144,27 +151,13 @@ It is possible to tell `tools/test.py` to skip the linter stage by passing
`--nolint`. This removes the dependency on `cpplint.py` and Git. The `--nolint`
option is implied if the VIXL project is a snapshot (with no `.git` directory).
Additionally, `tools/test.py` tests code formatting using `clang-format-3.6`.
If you don't have `clang-format-3.6`, disable the test using the
`--noclang-format` option.
Building and Running the Benchmarks
-----------------------------------
There are three very basic benchmarks provided with VIXL:
1. bench-dataop, emitting adds
2. bench-branch, emitting branches
3. bench-branch-link, emitting branch-links
Build these benchmarks using `scons bench-dataop`, `scons bench-branch` and
`scons bench-branch-link`. This will produce binaries called
`bench-dataop_sim`, `bench-branch_sim` and `bench-branch-link_sim`. Run these
with an iteration count argument, for example `./bench-dataop_sim 10000000`. The
benchmarks do not report a result; time them using the UNIX `time` command.
Build the benchmarks natively for execution on an AArch64 target using `scons
<benchmark name> simulator=off`. This will produce binaries called
`bench-dataop`, `bench-branch` and `bench-branch-link`. Run and time these in
the same way as the simulator versions.
Also note that the tests for the tracing features depend upon external `diff`
and `sed` tools. If these tools are not available in `PATH`, these tests will
fail.
Getting Started
---------------
@ -174,7 +167,6 @@ Example source code is provided in the [examples](examples) directory. You can
build all the examples with `scons examples` from the root directory, or use
`scons --help` to get a detailed list of available build targets.
Using VIXL
----------

View File

@ -215,13 +215,17 @@ def ConfigureEnvironmentForCompiler(env):
# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57045
# The bug does not seem to appear in GCC 4.7, or in debug builds with GCC 4.8.
if env['mode'] == 'release':
process = subprocess.Popen(env['CXX'] + ' --version | grep "g++.*4\.8"',
process = subprocess.Popen(env['CXX'] + ' --version 2>&1 | grep "g++.*4\.8"',
shell = True,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, stderr = process.communicate()
stdout, unused = process.communicate()
using_gcc48 = stdout != ''
if using_gcc48:
env.Append(CPPFLAGS = ['-Wno-maybe-uninitialized'])
# On OSX, compilers complain about `long long` being a C++11 extension when no
# standard is passed.
if 'std' not in env or env['std'] == 'c++98':
env.Append(CPPFLAGS = ['-Wno-c++11-long-long'])
def ConfigureEnvironment(env):

View File

@ -37,8 +37,12 @@ int main(int argc, char* argv[]) {
int iterations = 0;
switch (argc) {
case 1: iterations = kDefaultIterationsCount; break;
case 2: iterations = atoi(argv[1]); break;
case 1:
iterations = kDefaultIterationsCount;
break;
case 2:
iterations = atoi(argv[1]);
break;
default:
printf("Usage: %s [#iterations]\n", argv[0]);
exit(1);

View File

@ -38,8 +38,12 @@ int main(int argc, char* argv[]) {
int instructions = 0;
switch (argc) {
case 1: instructions = kDefaultInstructionCount; break;
case 2: instructions = atoi(argv[1]); break;
case 1:
instructions = kDefaultInstructionCount;
break;
case 2:
instructions = atoi(argv[1]);
break;
default:
printf("Usage: %s [#instructions]\n", argv[0]);
exit(1);
@ -48,7 +52,7 @@ int main(int argc, char* argv[]) {
MacroAssembler masm(instructions * kInstructionSize);
InstructionAccurateScope scope(&masm, instructions);
#define __ masm.
#define __ masm.
Label target;
for (int i = 0; i < instructions; i++) {

View File

@ -41,8 +41,12 @@ int main(int argc, char* argv[]) {
int iterations = 0;
switch (argc) {
case 1: iterations = kDefaultIterationCount; break;
case 2: iterations = atoi(argv[1]); break;
case 1:
iterations = kDefaultIterationCount;
break;
case 2:
iterations = atoi(argv[1]);
break;
default:
printf("Usage: %s [#iterations]\n", argv[0]);
exit(1);

View File

@ -41,8 +41,12 @@ int main(int argc, char* argv[]) {
int instructions = 0;
switch (argc) {
case 1: instructions = kDefaultInstructionCount; break;
case 2: instructions = atoi(argv[1]); break;
case 1:
instructions = kDefaultInstructionCount;
break;
case 2:
instructions = atoi(argv[1]);
break;
default:
printf("Usage: %s [#instructions]\n", argv[0]);
exit(1);
@ -52,7 +56,7 @@ int main(int argc, char* argv[]) {
const int buffer_instruction_count = buffer_size / kInstructionSize;
MacroAssembler masm(buffer_size);
#define __ masm.
#define __ masm.
// We emit a branch to the next instruction.
int rounds = instructions / buffer_instruction_count;

View File

@ -41,8 +41,12 @@ int main(int argc, char* argv[]) {
unsigned instructions = 0;
switch (argc) {
case 1: instructions = kDefaultInstructionCount; break;
case 2: instructions = atoi(argv[1]); break;
case 1:
instructions = kDefaultInstructionCount;
break;
case 2:
instructions = atoi(argv[1]);
break;
default:
printf("Usage: %s [#instructions]\n", argv[0]);
exit(1);
@ -52,7 +56,7 @@ int main(int argc, char* argv[]) {
const unsigned buffer_instruction_count = buffer_size / kInstructionSize;
MacroAssembler masm(buffer_size);
#define __ masm.
#define __ masm.
unsigned rounds = instructions / buffer_instruction_count;
for (unsigned i = 0; i < rounds; ++i) {

View File

@ -1,6 +1,12 @@
VIXL Change Log
===============
* 1.13
+ Improve code formatting and add tests using clang-format.
+ Fix bugs in disassembly of unallocated instruction encodings.
+ Fix some execution trace bugs, and add tests.
+ Other small bug fixes and improvements.
* 1.12
+ Bug fixes for toolchain compatibility.

View File

@ -49,28 +49,28 @@ Add and update status flags.
Calculate the address of a PC offset.
void adr(const Register& rd, int imm21)
void adr(const Register& xd, int imm21)
### ADR ###
Calculate the address of a label.
void adr(const Register& rd, Label* label)
void adr(const Register& xd, Label* label)
### ADRP ###
Calculate the page address of a PC offset.
void adrp(const Register& rd, int imm21)
void adrp(const Register& xd, int imm21)
### ADRP ###
Calculate the page address of a label.
void adrp(const Register& rd, Label* label)
void adrp(const Register& xd, Label* label)
### AND ###
@ -324,72 +324,72 @@ Conditional negate: rd = cond ? -rn : rn.
CRC-32 checksum from byte.
void crc32b(const Register& rd,
const Register& rn,
const Register& rm)
void crc32b(const Register& wd,
const Register& wn,
const Register& wm)
### CRC32CB ###
CRC-32 C checksum from byte.
void crc32cb(const Register& rd,
const Register& rn,
const Register& rm)
void crc32cb(const Register& wd,
const Register& wn,
const Register& wm)
### CRC32CH ###
CRC-32 C checksum from half-word.
void crc32ch(const Register& rd,
const Register& rn,
const Register& rm)
void crc32ch(const Register& wd,
const Register& wn,
const Register& wm)
### CRC32CW ###
CRC-32 C checksum from word.
void crc32cw(const Register& rd,
const Register& rn,
const Register& rm)
void crc32cw(const Register& wd,
const Register& wn,
const Register& wm)
### CRC32CX ###
CRC-32C checksum from double word.
void crc32cx(const Register& rd,
const Register& rn,
const Register& rm)
void crc32cx(const Register& wd,
const Register& wn,
const Register& xm)
### CRC32H ###
CRC-32 checksum from half-word.
void crc32h(const Register& rd,
const Register& rn,
const Register& rm)
void crc32h(const Register& wd,
const Register& wn,
const Register& wm)
### CRC32W ###
CRC-32 checksum from word.
void crc32w(const Register& rd,
const Register& rn,
const Register& rm)
void crc32w(const Register& wd,
const Register& wn,
const Register& wm)
### CRC32X ###
CRC-32 checksum from double word.
void crc32x(const Register& rd,
const Register& rn,
const Register& rm)
void crc32x(const Register& wd,
const Register& wn,
const Register& xm)
### CSEL ###
@ -588,7 +588,7 @@ Load integer or FP register pair.
Load word pair with sign extension.
void ldpsw(const Register& rt, const Register& rt2, const MemOperand& src)
void ldpsw(const Register& xt, const Register& xt2, const MemOperand& src)
### LDR ###
@ -649,21 +649,21 @@ Load half-word with sign extension.
Load word with sign extension from literal pool.
void ldrsw(const Register& rt, RawLiteral* literal)
void ldrsw(const Register& xt, RawLiteral* literal)
### LDRSW ###
Load word with sign extension from pc + imm19 << 2.
void ldrsw(const Register& rt, int imm19)
void ldrsw(const Register& xt, int imm19)
### LDRSW ###
Load word with sign extension.
void ldrsw(const Register& rt, const MemOperand& src,
void ldrsw(const Register& xt, const MemOperand& src,
LoadStoreScalingOption option = PreferScaledOffset)
@ -711,7 +711,7 @@ Load half-word with sign extension (and unscaled offset).
Load word with sign extension.
void ldursw(const Register& rt, const MemOperand& src,
void ldursw(const Register& xt, const MemOperand& src,
LoadStoreScalingOption option = PreferUnscaledOffset)
@ -820,14 +820,14 @@ Move immediate.
Move to register from system register.
void mrs(const Register& rt, SystemRegister sysreg)
void mrs(const Register& xt, SystemRegister sysreg)
### MSR ###
Move from register to system register.
void msr(SystemRegister sysreg, const Register& rt)
void msr(SystemRegister sysreg, const Register& xt)
### MSUB ###
@ -969,7 +969,7 @@ Reverse bytes in 16-bit half words.
Reverse bytes in 32-bit words.
void rev32(const Register& rd, const Register& rn)
void rev32(const Register& xd, const Register& xn)
### ROR ###
@ -1045,20 +1045,20 @@ Signed integer divide.
Signed long multiply and accumulate: 32 x 32 + 64 -> 64-bit.
void smaddl(const Register& rd,
const Register& rn,
const Register& rm,
const Register& ra)
void smaddl(const Register& xd,
const Register& wn,
const Register& wm,
const Register& xa)
### SMSUBL ###
Signed long multiply and subtract: 64 - (32 x 32) -> 64-bit.
void smsubl(const Register& rd,
const Register& rn,
const Register& rm,
const Register& ra)
void smsubl(const Register& xd,
const Register& wn,
const Register& wm,
const Register& xa)
### SMULH ###
@ -1072,7 +1072,7 @@ Signed multiply high: 64 x 64 -> 64-bit <127:64>.
Signed long multiply: 32 x 32 -> 64-bit.
void smull(const Register& rd, const Register& rn, const Register& rm)
void smull(const Register& xd, const Register& wn, const Register& wm)
### STLR ###
@ -1272,14 +1272,14 @@ Signed extend word.
System instruction with pre-encoded op (op1:crn:crm:op2).
void sys(int op, const Register& rt = xzr)
void sys(int op, const Register& xt = xzr)
### SYS ###
System instruction.
void sys(int op1, int crn, int crm, int op2, const Register& rt = xzr)
void sys(int op1, int crn, int crm, int op2, const Register& xt = xzr)
### TBNZ ###
@ -1358,20 +1358,20 @@ Unsigned integer divide.
Unsigned long multiply and accumulate: 32 x 32 + 64 -> 64-bit.
void umaddl(const Register& rd,
const Register& rn,
const Register& rm,
const Register& ra)
void umaddl(const Register& xd,
const Register& wn,
const Register& wm,
const Register& xa)
### UMSUBL ###
Unsigned long multiply and subtract: 64 - (32 x 32) -> 64-bit.
void umsubl(const Register& rd,
const Register& rn,
const Register& rm,
const Register& ra)
void umsubl(const Register& xd,
const Register& wn,
const Register& wm,
const Register& xa)
### UMULH ###
@ -1387,9 +1387,9 @@ Unsigned multiply high: 64 x 64 -> 64-bit <127:64>.
Unsigned long multiply: 32 x 32 -> 64-bit.
void umull(const Register& rd,
const Register& rn,
const Register& rm)
void umull(const Register& xd,
const Register& wn,
const Register& wm)
### UXTB ###

View File

@ -61,7 +61,7 @@ int main(void) {
int64_t input_value = -42;
simulator.set_xreg(0, input_value);
simulator.RunFrom(masm.GetLabelAddress<Instruction*>(&abs));
printf("abs(%ld) = %ld\n", input_value, simulator.xreg(0));
printf("abs(%" PRId64 ") = %" PRId64 "\n", input_value, simulator.xreg(0));
return 0;
}

View File

@ -82,7 +82,7 @@ void GenerateAdd2Vectors(MacroAssembler* masm) {
}
void PrintVector(const uint8_t *vec, unsigned num) {
void PrintVector(const uint8_t* vec, unsigned num) {
unsigned i;
printf("( ");
if (num > 0) {
@ -108,14 +108,14 @@ int main(void) {
masm.FinalizeCode();
// Initialize input data for the example function.
uint8_t vecA[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20};
uint8_t vecB[] = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31,
32, 33, 34, 35, 36};
// clang-format: off
uint8_t vecA[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
uint8_t vecB[] = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36};
// clang-format on
uint8_t vecC[ARRAY_SIZE(vecA)];
// Check whether the number of elements in both vectors match.

View File

@ -35,8 +35,8 @@ void GenerateAdd3Double(MacroAssembler* masm) {
// x -> d0
// y -> d1
// z -> d2
__ Fadd(d0, d0, d1); // d0 <- x + y
__ Fadd(d0, d0, d2); // d0 <- d0 + z
__ Fadd(d0, d0, d1); // d0 <- x + y
__ Fadd(d0, d0, d2); // d0 <- d0 + z
// The return value is already in d0.
__ Ret();

View File

@ -76,7 +76,10 @@ int main(void) {
simulator.set_xreg(1, c);
simulator.set_dreg(1, d);
simulator.RunFrom(masm.GetLabelAddress<Instruction*>(&add4_double));
printf("%ld + %f + %ld + %f = %f\n", a, b, c, d, simulator.dreg(0));
// clang-format off
printf("%" PRIu64 " + %f + %" PRIu64 " + %f = %f\n",
a, b, c, d, simulator.dreg(0));
// clang-format on
return 0;
}

View File

@ -59,16 +59,21 @@ void GenerateCheckBounds(MacroAssembler* masm) {
#ifndef TEST_EXAMPLES
#ifdef VIXL_INCLUDE_SIMULATOR
void run_function(Simulator *simulator, Instruction * function,
uint64_t value, uint64_t low, uint64_t high) {
void run_function(Simulator* simulator,
Instruction* function,
uint64_t value,
uint64_t low,
uint64_t high) {
simulator->set_xreg(0, value);
simulator->set_xreg(1, low);
simulator->set_xreg(2, high);
simulator->RunFrom(function);
printf("%ld %s between %ld and %ld\n", value,
printf("%" PRIu64 " %s between %" PRIu64 " and %" PRIu64 "\n",
value,
simulator->xreg(0) ? "is" : "is not",
low, high);
low,
high);
simulator->ResetState();
}
@ -87,7 +92,7 @@ int main(void) {
masm.FinalizeCode();
// Run the example function.
Instruction * function = masm.GetLabelAddress<Instruction*>(&check_bounds);
Instruction* function = masm.GetLabelAddress<Instruction*>(&check_bounds);
run_function(&simulator, function, 546, 50, 1000);
run_function(&simulator, function, 62, 100, 200);
run_function(&simulator, function, 200, 100, 200);

View File

@ -43,8 +43,8 @@ void GenerateCrc32(MacroAssembler* masm) {
// Move input array to temp register so we can re-use w0 as return register.
__ Mov(x2, x0);
// Initial remainder for the checksum. If length=0, then this value will
// be returned.
// Initial remainder for the checksum. If length=0, then this value will be
// returned.
__ Mov(w0, 0xffffffff);
// Loop for iterating through the array, starting at msg[0].
@ -66,7 +66,7 @@ void GenerateCrc32(MacroAssembler* masm) {
#ifndef TEST_EXAMPLES
void runExample(const char *msg) {
void runExample(const char* msg) {
// Create and initialize the assembler and the simulator.
byte assm_buf[BUF_SIZE];
MacroAssembler masm(assm_buf, BUF_SIZE);

View File

@ -33,9 +33,8 @@
// We override this method to specify how register names should be disassembled.
void CustomDisassembler::AppendRegisterNameToOutput(
const Instruction* instr,
const CPURegister& reg) {
void CustomDisassembler::AppendRegisterNameToOutput(const Instruction* instr,
const CPURegister& reg) {
USE(instr);
if (reg.IsRegister()) {
switch (reg.code()) {
@ -170,11 +169,12 @@ void TestCustomDisassembler() {
decoder.Decode(instr);
printf("\n");
printf("VIXL disasm\t %p:\t%s\n",
reinterpret_cast<void*>(instr), disasm.GetOutput());
reinterpret_cast<void*>(instr),
disasm.GetOutput());
int64_t rel_addr =
custom_disasm.CodeRelativeAddress(reinterpret_cast<void*>(instr));
char rel_addr_sign_char = rel_addr < 0 ? '-' : ' ';
rel_addr = labs(rel_addr);
rel_addr = std::abs(rel_addr);
printf("custom disasm\t%c0x%" PRIx64 ":\t%s\n",
rel_addr_sign_char,
rel_addr,

View File

@ -37,10 +37,10 @@ void TestCustomDisassembler();
// - Add comments to some add/sub instructions.
// - Use aliases for register names.
// - Add descriptions for code addresses.
class CustomDisassembler: public Disassembler {
class CustomDisassembler : public Disassembler {
public:
CustomDisassembler() : Disassembler() { }
virtual ~CustomDisassembler() { }
CustomDisassembler() : Disassembler() {}
virtual ~CustomDisassembler() {}
virtual void VisitAddSubShifted(const Instruction* instr);

View File

@ -25,7 +25,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef VIXL_EXAMPLE_EXAMPLES_H_
# define VIXL_EXAMPLE_EXAMPLES_H_
#define VIXL_EXAMPLE_EXAMPLES_H_
#include "vixl/a64/simulator-a64.h"
#include "vixl/a64/debugger-a64.h"
@ -113,7 +113,7 @@ void GenerateSwapInt32(MacroAssembler* masm);
// uint64_t demo_function(uint64_t x)
//
// This is the example used in doc/getting-started.txt
void GenerateDemoFunction(MacroAssembler *masm);
void GenerateDemoFunction(MacroAssembler* masm);
// This function generates and runs code that uses literals to sum the `a` and
// `b` inputs.

View File

@ -43,7 +43,7 @@ void GenerateFactorialRec(MacroAssembler* masm) {
__ Mov(x1, x0);
__ Sub(x0, x0, 1);
__ Push(x1, lr);
__ Bl(&entry); // Recursive call factorial_rec(n - 1).
__ Bl(&entry); // Recursive call factorial_rec(n - 1).
__ Pop(lr, x1);
__ Mul(x0, x0, x1);
__ Ret();
@ -73,7 +73,9 @@ int main(void) {
uint64_t input_val = 16;
simulator.set_xreg(0, input_val);
simulator.RunFrom(masm.GetLabelAddress<Instruction*>(&factorial_rec));
printf("factorial(%ld) = %ld\n", input_val, simulator.xreg(0));
printf("factorial(%" PRIu64 ") = %" PRId64 "\n",
input_val,
simulator.xreg(0));
return 0;
}

View File

@ -37,7 +37,7 @@ void GenerateFactorial(MacroAssembler* masm) {
Label loop, end;
__ Mov(x1, x0);
__ Mov(x0, 1); // Use x0 as the accumulator.
__ Mov(x0, 1); // Use x0 as the accumulator.
__ Cbz(x1, &end); // Nothing to do if the input is null.
@ -71,7 +71,9 @@ int main(void) {
uint64_t input_val = 16;
simulator.set_xreg(0, input_val);
simulator.RunFrom(masm.GetLabelAddress<Instruction*>(&factorial));
printf("factorial(%ld) = %ld\n", input_val, simulator.xreg(0));
printf("factorial(%" PRIu64 ") = %" PRId64 "\n",
input_val,
simulator.xreg(0));
return 0;
}

View File

@ -54,7 +54,7 @@ int main() {
masm.FinalizeCode();
simulator.set_xreg(0, 0x8899aabbccddeeff);
simulator.RunFrom(masm.GetLabelAddress<Instruction*>(&demo_function));
simulator.RunFrom(masm.GetLabelAddress<Instruction *>(&demo_function));
printf("x0 = %" PRIx64 "\n", simulator.xreg(0));
return 0;

View File

@ -70,7 +70,7 @@ int64_t LiteralExample(int64_t a, int64_t b) {
// Run the code.
simulator.RunFrom(masm.GetLabelAddress<Instruction*>(&start));
printf("111 + 222 = %ld\n", simulator.xreg(0));
printf("111 + 222 = %" PRId64 "\n", simulator.xreg(0));
// Now let's modify the values of the literals.
automatically_placed_literal.UpdateValue(a, code);

View File

@ -124,15 +124,39 @@ int main(void) {
// float mat1[kLength] = { 1.0f, 52.03f, 4.43f, ... };
// However, the following way better shows the "column-major" arrangement.
mat1[0] = 1.0f; mat1[4] = 2.0f; mat1[ 8] = 3.0f; mat1[12] = 4.0f;
mat1[1] = 52.03f; mat1[5] = 12.24f; mat1[ 9] = 53.56f; mat1[13] = 22.22f;
mat1[2] = 4.43f; mat1[6] = 5.00f; mat1[10] = 7.00f; mat1[14] = 3.11f;
mat1[3] = 43.47f; mat1[7] = 10.97f; mat1[11] = 37.78f; mat1[15] = 90.91f;
mat1[0] = 1.0f;
mat1[4] = 2.0f;
mat1[8] = 3.0f;
mat1[12] = 4.0f;
mat1[1] = 52.03f;
mat1[5] = 12.24f;
mat1[9] = 53.56f;
mat1[13] = 22.22f;
mat1[2] = 4.43f;
mat1[6] = 5.00f;
mat1[10] = 7.00f;
mat1[14] = 3.11f;
mat1[3] = 43.47f;
mat1[7] = 10.97f;
mat1[11] = 37.78f;
mat1[15] = 90.91f;
mat2[0] = 1.0f; mat2[4] = 11.24f; mat2[ 8] = 21.00f; mat2[12] = 21.31f;
mat2[1] = 2.0f; mat2[5] = 2.24f; mat2[ 9] = 8.56f; mat2[13] = 52.03f;
mat2[2] = 3.0f; mat2[6] = 51.00f; mat2[10] = 21.00f; mat2[14] = 33.11f;
mat2[3] = 4.0f; mat2[7] = 0.00f; mat2[11] = 84.00f; mat2[15] = 1.97f;
mat2[0] = 1.0f;
mat2[4] = 11.24f;
mat2[8] = 21.00f;
mat2[12] = 21.31f;
mat2[1] = 2.0f;
mat2[5] = 2.24f;
mat2[9] = 8.56f;
mat2[13] = 52.03f;
mat2[2] = 3.0f;
mat2[6] = 51.00f;
mat2[10] = 21.00f;
mat2[14] = 33.11f;
mat2[3] = 4.0f;
mat2[7] = 0.00f;
mat2[11] = 84.00f;
mat2[15] = 1.97f;
simulator.ResetState();
simulator.set_xreg(0, reinterpret_cast<uintptr_t>(output));
@ -142,20 +166,32 @@ int main(void) {
// Print the 4x4 output matrix along with both 4x4 input matrices.
for (int i = 0; i < kRowSize; i++) {
printf("| %8.2f %8.2f %8.2f %8.2f | "
"| %8.2f %8.2f %8.2f %8.2f | "
"| %8.2f %8.2f %8.2f %8.2f |\n",
mat1[i], mat1[4+i], mat1[8+i], mat1[12+i],
mat2[i], mat2[4+i], mat2[8+i], mat2[12+i],
output[i], output[4+i], output[8+i], output[12+i]);
printf(
"| %8.2f %8.2f %8.2f %8.2f | "
"| %8.2f %8.2f %8.2f %8.2f | "
"| %8.2f %8.2f %8.2f %8.2f |\n",
mat1[i],
mat1[4 + i],
mat1[8 + i],
mat1[12 + i],
mat2[i],
mat2[4 + i],
mat2[8 + i],
mat2[12 + i],
output[i],
output[4 + i],
output[8 + i],
output[12 + i]);
if (i == 0 || i == 2) {
printf("| | "
"| | "
"| |\n");
printf(
"| | "
"| | "
"| |\n");
} else if (i == 1) {
printf("| | x "
"| | = "
"| |\n");
printf(
"| | x "
"| | = "
"| |\n");
}
}

View File

@ -53,7 +53,7 @@ int64_t RunNonConstVisitorTestGeneratedCode(const Instruction* start_instr) {
simulator.set_xreg(1, b);
simulator.RunFrom(start_instr);
int64_t res = simulator.xreg(0);
printf("foo(%" PRId64", %" PRId64") = %" PRId64"\n", a, b, res);
printf("foo(%" PRId64 ", %" PRId64 ") = %" PRId64 "\n", a, b, res);
return res;
#else

View File

@ -53,76 +53,76 @@ class SwitchAddSubRegisterSources : public DecoderVisitor {
mutable_instr->SetInstructionBits(instr_bits);
}
// Define the remaining visitors to do nothing.
#define UNUSED_VISITOR_LIST(V) \
V(PCRelAddressing) \
V(AddSubImmediate) \
V(LogicalImmediate) \
V(MoveWideImmediate) \
V(Bitfield) \
V(Extract) \
V(UnconditionalBranch) \
V(UnconditionalBranchToRegister) \
V(CompareBranch) \
V(TestBranch) \
V(ConditionalBranch) \
V(System) \
V(Exception) \
V(LoadStorePairPostIndex) \
V(LoadStorePairOffset) \
V(LoadStorePairPreIndex) \
V(LoadStorePairNonTemporal) \
V(LoadLiteral) \
V(LoadStoreUnscaledOffset) \
V(LoadStorePostIndex) \
V(LoadStorePreIndex) \
V(LoadStoreRegisterOffset) \
V(LoadStoreUnsignedOffset) \
V(LoadStoreExclusive) \
V(LogicalShifted) \
V(AddSubExtended) \
V(AddSubWithCarry) \
V(ConditionalCompareRegister) \
V(ConditionalCompareImmediate) \
V(ConditionalSelect) \
V(DataProcessing1Source) \
V(DataProcessing2Source) \
V(DataProcessing3Source) \
V(FPCompare) \
V(FPConditionalCompare) \
V(FPConditionalSelect) \
V(FPImmediate) \
V(FPDataProcessing1Source) \
V(FPDataProcessing2Source) \
V(FPDataProcessing3Source) \
V(FPIntegerConvert) \
V(FPFixedPointConvert) \
V(Crypto2RegSHA) \
V(Crypto3RegSHA) \
V(CryptoAES) \
V(NEON2RegMisc) \
V(NEON3Different) \
V(NEON3Same) \
V(NEONAcrossLanes) \
V(NEONByIndexedElement) \
V(NEONCopy) \
V(NEONExtract) \
V(NEONLoadStoreMultiStruct) \
// Define the remaining visitors to do nothing.
#define UNUSED_VISITOR_LIST(V) \
V(PCRelAddressing) \
V(AddSubImmediate) \
V(LogicalImmediate) \
V(MoveWideImmediate) \
V(Bitfield) \
V(Extract) \
V(UnconditionalBranch) \
V(UnconditionalBranchToRegister) \
V(CompareBranch) \
V(TestBranch) \
V(ConditionalBranch) \
V(System) \
V(Exception) \
V(LoadStorePairPostIndex) \
V(LoadStorePairOffset) \
V(LoadStorePairPreIndex) \
V(LoadStorePairNonTemporal) \
V(LoadLiteral) \
V(LoadStoreUnscaledOffset) \
V(LoadStorePostIndex) \
V(LoadStorePreIndex) \
V(LoadStoreRegisterOffset) \
V(LoadStoreUnsignedOffset) \
V(LoadStoreExclusive) \
V(LogicalShifted) \
V(AddSubExtended) \
V(AddSubWithCarry) \
V(ConditionalCompareRegister) \
V(ConditionalCompareImmediate) \
V(ConditionalSelect) \
V(DataProcessing1Source) \
V(DataProcessing2Source) \
V(DataProcessing3Source) \
V(FPCompare) \
V(FPConditionalCompare) \
V(FPConditionalSelect) \
V(FPImmediate) \
V(FPDataProcessing1Source) \
V(FPDataProcessing2Source) \
V(FPDataProcessing3Source) \
V(FPIntegerConvert) \
V(FPFixedPointConvert) \
V(Crypto2RegSHA) \
V(Crypto3RegSHA) \
V(CryptoAES) \
V(NEON2RegMisc) \
V(NEON3Different) \
V(NEON3Same) \
V(NEONAcrossLanes) \
V(NEONByIndexedElement) \
V(NEONCopy) \
V(NEONExtract) \
V(NEONLoadStoreMultiStruct) \
V(NEONLoadStoreMultiStructPostIndex) \
V(NEONLoadStoreSingleStruct) \
V(NEONLoadStoreSingleStruct) \
V(NEONLoadStoreSingleStructPostIndex) \
V(NEONModifiedImmediate) \
V(NEONScalar2RegMisc) \
V(NEONScalar3Diff) \
V(NEONScalar3Same) \
V(NEONScalarByIndexedElement) \
V(NEONScalarCopy) \
V(NEONScalarPairwise) \
V(NEONScalarShiftImmediate) \
V(NEONShiftImmediate) \
V(NEONTable) \
V(NEONPerm) \
V(Unallocated) \
V(NEONModifiedImmediate) \
V(NEONScalar2RegMisc) \
V(NEONScalar3Diff) \
V(NEONScalar3Same) \
V(NEONScalarByIndexedElement) \
V(NEONScalarCopy) \
V(NEONScalarPairwise) \
V(NEONScalarShiftImmediate) \
V(NEONShiftImmediate) \
V(NEONTable) \
V(NEONPerm) \
V(Unallocated) \
V(Unimplemented)
#define DEFINE_UNUSED_VISITOR(Name) \
virtual void Visit##Name(const Instruction* i) { \

View File

@ -74,7 +74,7 @@ int main(void) {
masm.FinalizeCode();
// Run the example function.
uint8_t data[] = { 2, 45, 63, 7, 245, 38 };
uint8_t data[] = {2, 45, 63, 7, 245, 38};
uintptr_t data_addr = reinterpret_cast<uintptr_t>(data);
simulator.set_xreg(0, data_addr);
simulator.set_xreg(1, ARRAY_SIZE(data));

View File

@ -79,17 +79,21 @@ int main(void) {
simulator.set_wreg(0, 0x11111111);
simulator.set_wreg(1, 0x22222222);
// clang-format off
printf("Before swap_int32:\n"
"x0 = 0x%" PRIx32 "\n"
"x1 = 0x%" PRIx32 "\n",
simulator.wreg(0), simulator.wreg(1));
// clang-format on
simulator.RunFrom(masm.GetLabelAddress<Instruction*>(&swap_int32));
// clang-format off
printf("After swap_int32:\n"
"x0 = 0x%" PRIx32 "\n"
"x1 = 0x%" PRIx32 "\n",
simulator.wreg(0), simulator.wreg(1));
// clang-format on
return 0;
}

View File

@ -67,6 +67,7 @@ int main(void) {
simulator.set_xreg(2, 0x3333333333333333);
simulator.set_xreg(3, 0x4444444444444444);
// clang-format off
printf("Before swap4:\n"
"x0 = 0x%" PRIx64 "\n"
"x1 = 0x%" PRIx64 "\n"
@ -74,9 +75,11 @@ int main(void) {
"x3 = 0x%" PRIx64 "\n",
simulator.xreg(0), simulator.xreg(1),
simulator.xreg(2), simulator.xreg(3));
// clang-format on
simulator.RunFrom(masm.GetLabelAddress<Instruction*>(&swap4));
// clang-format off
printf("After swap4:\n"
"x0 = 0x%" PRIx64 "\n"
"x1 = 0x%" PRIx64 "\n"
@ -84,6 +87,7 @@ int main(void) {
"x3 = 0x%" PRIx64 "\n",
simulator.xreg(0), simulator.xreg(1),
simulator.xreg(2), simulator.xreg(3));
// clang-format on
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -39,151 +39,153 @@ const int kFirstCalleeSavedRegisterIndex = 21;
const int kNumberOfCalleeSavedFPRegisters = 8;
const int kFirstCalleeSavedFPRegisterIndex = 8;
// clang-format off
#define REGISTER_CODE_LIST(R) \
R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \
R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \
R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \
R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
// clang-format on
#define INSTRUCTION_FIELDS_LIST(V_) \
/* Register fields */ \
V_(Rd, 4, 0, Bits) /* Destination register. */ \
V_(Rn, 9, 5, Bits) /* First source register. */ \
V_(Rm, 20, 16, Bits) /* Second source register. */ \
V_(Ra, 14, 10, Bits) /* Third source register. */ \
V_(Rt, 4, 0, Bits) /* Load/store register. */ \
V_(Rt2, 14, 10, Bits) /* Load/store second register. */ \
V_(Rs, 20, 16, Bits) /* Exclusive access status. */ \
\
/* Common bits */ \
V_(SixtyFourBits, 31, 31, Bits) \
V_(FlagsUpdate, 29, 29, Bits) \
\
/* PC relative addressing */ \
V_(ImmPCRelHi, 23, 5, SignedBits) \
V_(ImmPCRelLo, 30, 29, Bits) \
\
/* Add/subtract/logical shift register */ \
V_(ShiftDP, 23, 22, Bits) \
V_(ImmDPShift, 15, 10, Bits) \
\
/* Add/subtract immediate */ \
V_(ImmAddSub, 21, 10, Bits) \
V_(ShiftAddSub, 23, 22, Bits) \
\
/* Add/substract extend */ \
V_(ImmExtendShift, 12, 10, Bits) \
V_(ExtendMode, 15, 13, Bits) \
\
/* Move wide */ \
V_(ImmMoveWide, 20, 5, Bits) \
V_(ShiftMoveWide, 22, 21, Bits) \
\
/* Logical immediate, bitfield and extract */ \
V_(BitN, 22, 22, Bits) \
V_(ImmRotate, 21, 16, Bits) \
V_(ImmSetBits, 15, 10, Bits) \
V_(ImmR, 21, 16, Bits) \
V_(ImmS, 15, 10, Bits) \
\
/* Test and branch immediate */ \
V_(ImmTestBranch, 18, 5, SignedBits) \
V_(ImmTestBranchBit40, 23, 19, Bits) \
V_(ImmTestBranchBit5, 31, 31, Bits) \
\
/* Conditionals */ \
V_(Condition, 15, 12, Bits) \
V_(ConditionBranch, 3, 0, Bits) \
V_(Nzcv, 3, 0, Bits) \
V_(ImmCondCmp, 20, 16, Bits) \
V_(ImmCondBranch, 23, 5, SignedBits) \
\
/* Floating point */ \
V_(FPType, 23, 22, Bits) \
V_(ImmFP, 20, 13, Bits) \
V_(FPScale, 15, 10, Bits) \
\
/* Load Store */ \
V_(ImmLS, 20, 12, SignedBits) \
V_(ImmLSUnsigned, 21, 10, Bits) \
V_(ImmLSPair, 21, 15, SignedBits) \
V_(ImmShiftLS, 12, 12, Bits) \
V_(LSOpc, 23, 22, Bits) \
V_(LSVector, 26, 26, Bits) \
V_(LSSize, 31, 30, Bits) \
V_(ImmPrefetchOperation, 4, 0, Bits) \
V_(PrefetchHint, 4, 3, Bits) \
V_(PrefetchTarget, 2, 1, Bits) \
V_(PrefetchStream, 0, 0, Bits) \
\
/* Other immediates */ \
V_(ImmUncondBranch, 25, 0, SignedBits) \
V_(ImmCmpBranch, 23, 5, SignedBits) \
V_(ImmLLiteral, 23, 5, SignedBits) \
V_(ImmException, 20, 5, Bits) \
V_(ImmHint, 11, 5, Bits) \
V_(ImmBarrierDomain, 11, 10, Bits) \
V_(ImmBarrierType, 9, 8, Bits) \
\
/* System (MRS, MSR, SYS) */ \
V_(ImmSystemRegister, 19, 5, Bits) \
V_(SysO0, 19, 19, Bits) \
V_(SysOp, 18, 5, Bits) \
V_(SysOp1, 18, 16, Bits) \
V_(SysOp2, 7, 5, Bits) \
V_(CRn, 15, 12, Bits) \
V_(CRm, 11, 8, Bits) \
\
/* Load-/store-exclusive */ \
V_(LdStXLoad, 22, 22, Bits) \
V_(LdStXNotExclusive, 23, 23, Bits) \
V_(LdStXAcquireRelease, 15, 15, Bits) \
V_(LdStXSizeLog2, 31, 30, Bits) \
V_(LdStXPair, 21, 21, Bits) \
\
/* NEON generic fields */ \
V_(NEONQ, 30, 30, Bits) \
V_(NEONSize, 23, 22, Bits) \
V_(NEONLSSize, 11, 10, Bits) \
V_(NEONS, 12, 12, Bits) \
V_(NEONL, 21, 21, Bits) \
V_(NEONM, 20, 20, Bits) \
V_(NEONH, 11, 11, Bits) \
V_(ImmNEONExt, 14, 11, Bits) \
V_(ImmNEON5, 20, 16, Bits) \
V_(ImmNEON4, 14, 11, Bits) \
\
/* NEON Modified Immediate fields */ \
V_(ImmNEONabc, 18, 16, Bits) \
V_(ImmNEONdefgh, 9, 5, Bits) \
V_(NEONModImmOp, 29, 29, Bits) \
V_(NEONCmode, 15, 12, Bits) \
\
/* NEON Shift Immediate fields */ \
V_(ImmNEONImmhImmb, 22, 16, Bits) \
V_(ImmNEONImmh, 22, 19, Bits) \
V_(ImmNEONImmb, 18, 16, Bits)
#define INSTRUCTION_FIELDS_LIST(V_) \
/* Register fields */ \
V_(Rd, 4, 0, Bits) /* Destination register. */ \
V_(Rn, 9, 5, Bits) /* First source register. */ \
V_(Rm, 20, 16, Bits) /* Second source register. */ \
V_(Ra, 14, 10, Bits) /* Third source register. */ \
V_(Rt, 4, 0, Bits) /* Load/store register. */ \
V_(Rt2, 14, 10, Bits) /* Load/store second register. */ \
V_(Rs, 20, 16, Bits) /* Exclusive access status. */ \
\
/* Common bits */ \
V_(SixtyFourBits, 31, 31, Bits) \
V_(FlagsUpdate, 29, 29, Bits) \
\
/* PC relative addressing */ \
V_(ImmPCRelHi, 23, 5, SignedBits) \
V_(ImmPCRelLo, 30, 29, Bits) \
\
/* Add/subtract/logical shift register */ \
V_(ShiftDP, 23, 22, Bits) \
V_(ImmDPShift, 15, 10, Bits) \
\
/* Add/subtract immediate */ \
V_(ImmAddSub, 21, 10, Bits) \
V_(ShiftAddSub, 23, 22, Bits) \
\
/* Add/substract extend */ \
V_(ImmExtendShift, 12, 10, Bits) \
V_(ExtendMode, 15, 13, Bits) \
\
/* Move wide */ \
V_(ImmMoveWide, 20, 5, Bits) \
V_(ShiftMoveWide, 22, 21, Bits) \
\
/* Logical immediate, bitfield and extract */ \
V_(BitN, 22, 22, Bits) \
V_(ImmRotate, 21, 16, Bits) \
V_(ImmSetBits, 15, 10, Bits) \
V_(ImmR, 21, 16, Bits) \
V_(ImmS, 15, 10, Bits) \
\
/* Test and branch immediate */ \
V_(ImmTestBranch, 18, 5, SignedBits) \
V_(ImmTestBranchBit40, 23, 19, Bits) \
V_(ImmTestBranchBit5, 31, 31, Bits) \
\
/* Conditionals */ \
V_(Condition, 15, 12, Bits) \
V_(ConditionBranch, 3, 0, Bits) \
V_(Nzcv, 3, 0, Bits) \
V_(ImmCondCmp, 20, 16, Bits) \
V_(ImmCondBranch, 23, 5, SignedBits) \
\
/* Floating point */ \
V_(FPType, 23, 22, Bits) \
V_(ImmFP, 20, 13, Bits) \
V_(FPScale, 15, 10, Bits) \
\
/* Load Store */ \
V_(ImmLS, 20, 12, SignedBits) \
V_(ImmLSUnsigned, 21, 10, Bits) \
V_(ImmLSPair, 21, 15, SignedBits) \
V_(ImmShiftLS, 12, 12, Bits) \
V_(LSOpc, 23, 22, Bits) \
V_(LSVector, 26, 26, Bits) \
V_(LSSize, 31, 30, Bits) \
V_(ImmPrefetchOperation, 4, 0, Bits) \
V_(PrefetchHint, 4, 3, Bits) \
V_(PrefetchTarget, 2, 1, Bits) \
V_(PrefetchStream, 0, 0, Bits) \
\
/* Other immediates */ \
V_(ImmUncondBranch, 25, 0, SignedBits) \
V_(ImmCmpBranch, 23, 5, SignedBits) \
V_(ImmLLiteral, 23, 5, SignedBits) \
V_(ImmException, 20, 5, Bits) \
V_(ImmHint, 11, 5, Bits) \
V_(ImmBarrierDomain, 11, 10, Bits) \
V_(ImmBarrierType, 9, 8, Bits) \
\
/* System (MRS, MSR, SYS) */ \
V_(ImmSystemRegister, 19, 5, Bits) \
V_(SysO0, 19, 19, Bits) \
V_(SysOp, 18, 5, Bits) \
V_(SysOp1, 18, 16, Bits) \
V_(SysOp2, 7, 5, Bits) \
V_(CRn, 15, 12, Bits) \
V_(CRm, 11, 8, Bits) \
\
/* Load-/store-exclusive */ \
V_(LdStXLoad, 22, 22, Bits) \
V_(LdStXNotExclusive, 23, 23, Bits) \
V_(LdStXAcquireRelease, 15, 15, Bits) \
V_(LdStXSizeLog2, 31, 30, Bits) \
V_(LdStXPair, 21, 21, Bits) \
\
/* NEON generic fields */ \
V_(NEONQ, 30, 30, Bits) \
V_(NEONSize, 23, 22, Bits) \
V_(NEONLSSize, 11, 10, Bits) \
V_(NEONS, 12, 12, Bits) \
V_(NEONL, 21, 21, Bits) \
V_(NEONM, 20, 20, Bits) \
V_(NEONH, 11, 11, Bits) \
V_(ImmNEONExt, 14, 11, Bits) \
V_(ImmNEON5, 20, 16, Bits) \
V_(ImmNEON4, 14, 11, Bits) \
\
/* NEON Modified Immediate fields */ \
V_(ImmNEONabc, 18, 16, Bits) \
V_(ImmNEONdefgh, 9, 5, Bits) \
V_(NEONModImmOp, 29, 29, Bits) \
V_(NEONCmode, 15, 12, Bits) \
\
/* NEON Shift Immediate fields */ \
V_(ImmNEONImmhImmb, 22, 16, Bits) \
V_(ImmNEONImmh, 22, 19, Bits) \
V_(ImmNEONImmb, 18, 16, Bits)
#define SYSTEM_REGISTER_FIELDS_LIST(V_, M_) \
/* NZCV */ \
V_(Flags, 31, 28, Bits) \
V_(N, 31, 31, Bits) \
V_(Z, 30, 30, Bits) \
V_(C, 29, 29, Bits) \
V_(V, 28, 28, Bits) \
M_(NZCV, Flags_mask) \
/* FPCR */ \
V_(AHP, 26, 26, Bits) \
V_(DN, 25, 25, Bits) \
V_(FZ, 24, 24, Bits) \
V_(RMode, 23, 22, Bits) \
M_(FPCR, AHP_mask | DN_mask | FZ_mask | RMode_mask)
#define SYSTEM_REGISTER_FIELDS_LIST(V_, M_) \
/* NZCV */ \
V_(Flags, 31, 28, Bits) \
V_(N, 31, 31, Bits) \
V_(Z, 30, 30, Bits) \
V_(C, 29, 29, Bits) \
V_(V, 28, 28, Bits) \
M_(NZCV, Flags_mask) \
/* FPCR */ \
V_(AHP, 26, 26, Bits) \
V_(DN, 25, 25, Bits) \
V_(FZ, 24, 24, Bits) \
V_(RMode, 23, 22, Bits) \
M_(FPCR, AHP_mask | DN_mask | FZ_mask | RMode_mask)
// Fields offsets.
#define DECLARE_FIELDS_OFFSETS(Name, HighBit, LowBit, X) \
const int Name##_offset = LowBit; \
const int Name##_width = HighBit - LowBit + 1; \
const uint32_t Name##_mask = ((1 << Name##_width) - 1) << LowBit;
#define DECLARE_FIELDS_OFFSETS(Name, HighBit, LowBit, X) \
const int Name##_offset = LowBit; \
const int Name##_width = HighBit - LowBit + 1; \
const uint32_t Name##_mask = ((1 << Name##_width) - 1) << LowBit;
#define NOTHING(A, B)
INSTRUCTION_FIELDS_LIST(DECLARE_FIELDS_OFFSETS)
SYSTEM_REGISTER_FIELDS_LIST(DECLARE_FIELDS_OFFSETS, NOTHING)
@ -194,6 +196,10 @@ SYSTEM_REGISTER_FIELDS_LIST(DECLARE_FIELDS_OFFSETS, NOTHING)
// from ImmPCRelLo and ImmPCRelHi.
const int ImmPCRel_mask = ImmPCRelLo_mask | ImmPCRelHi_mask;
// Disable `clang-format` for the `enum`s below. We care about the manual
// formatting that `clang-format` would destroy.
// clang-format off
// Condition codes.
enum Condition {
eq = 0, // Z set Equal.
@ -1434,8 +1440,8 @@ enum NEON2RegMiscOp {
enum NEON3SameOp {
NEON3SameFixed = 0x0E200400,
NEON3SameFMask = 0x9F200400,
NEON3SameMask = 0xBF20FC00,
NEON3SameUBit = 0x20000000,
NEON3SameMask = 0xBF20FC00,
NEON3SameUBit = 0x20000000,
NEON_ADD = NEON3SameFixed | 0x00008000,
NEON_ADDP = NEON3SameFixed | 0x0000B800,
NEON_SHADD = NEON3SameFixed | 0x00000000,
@ -1661,7 +1667,7 @@ enum NEONCopyOp {
enum NEONExtractOp {
NEONExtractFixed = 0x2E000000,
NEONExtractFMask = 0xBF208400,
NEONExtractMask = 0xBFE08400,
NEONExtractMask = 0xBFE08400,
NEON_EXT = NEONExtractFixed | 0x00000000
};
@ -1806,7 +1812,7 @@ enum NEONLoadStoreSingleStructPostIndexOp {
NEONLoadStoreSingleStructPostIndexFixed = 0x0D800000,
NEONLoadStoreSingleStructPostIndexFMask = 0xBF800000,
NEONLoadStoreSingleStructPostIndexMask = 0xBFE0E000,
NEONLoadStoreSingleStructPostIndex = 0x00800000,
NEONLoadStoreSingleStructPostIndex = 0x00800000,
NEON_LD1_b_post = NEON_LD1_b | NEONLoadStoreSingleStructPostIndex,
NEON_LD1_h_post = NEON_LD1_h | NEONLoadStoreSingleStructPostIndex,
NEON_LD1_s_post = NEON_LD1_s | NEONLoadStoreSingleStructPostIndex,
@ -2073,28 +2079,28 @@ enum NEONScalarShiftImmediateOp {
NEONScalarShiftImmediateFixed = 0x5F000400,
NEONScalarShiftImmediateFMask = 0xDF800400,
NEONScalarShiftImmediateMask = 0xFF80FC00,
NEON_SHL_scalar = NEON_Q | NEONScalar | NEON_SHL,
NEON_SLI_scalar = NEON_Q | NEONScalar | NEON_SLI,
NEON_SRI_scalar = NEON_Q | NEONScalar | NEON_SRI,
NEON_SSHR_scalar = NEON_Q | NEONScalar | NEON_SSHR,
NEON_USHR_scalar = NEON_Q | NEONScalar | NEON_USHR,
NEON_SRSHR_scalar = NEON_Q | NEONScalar | NEON_SRSHR,
NEON_URSHR_scalar = NEON_Q | NEONScalar | NEON_URSHR,
NEON_SSRA_scalar = NEON_Q | NEONScalar | NEON_SSRA,
NEON_USRA_scalar = NEON_Q | NEONScalar | NEON_USRA,
NEON_SRSRA_scalar = NEON_Q | NEONScalar | NEON_SRSRA,
NEON_URSRA_scalar = NEON_Q | NEONScalar | NEON_URSRA,
NEON_UQSHRN_scalar = NEON_Q | NEONScalar | NEON_UQSHRN,
NEON_UQRSHRN_scalar = NEON_Q | NEONScalar | NEON_UQRSHRN,
NEON_SQSHRN_scalar = NEON_Q | NEONScalar | NEON_SQSHRN,
NEON_SQRSHRN_scalar = NEON_Q | NEONScalar | NEON_SQRSHRN,
NEON_SQSHRUN_scalar = NEON_Q | NEONScalar | NEON_SQSHRUN,
NEON_SQRSHRUN_scalar = NEON_Q | NEONScalar | NEON_SQRSHRUN,
NEON_SQSHLU_scalar = NEON_Q | NEONScalar | NEON_SQSHLU,
NEON_SHL_scalar = NEON_Q | NEONScalar | NEON_SHL,
NEON_SLI_scalar = NEON_Q | NEONScalar | NEON_SLI,
NEON_SRI_scalar = NEON_Q | NEONScalar | NEON_SRI,
NEON_SSHR_scalar = NEON_Q | NEONScalar | NEON_SSHR,
NEON_USHR_scalar = NEON_Q | NEONScalar | NEON_USHR,
NEON_SRSHR_scalar = NEON_Q | NEONScalar | NEON_SRSHR,
NEON_URSHR_scalar = NEON_Q | NEONScalar | NEON_URSHR,
NEON_SSRA_scalar = NEON_Q | NEONScalar | NEON_SSRA,
NEON_USRA_scalar = NEON_Q | NEONScalar | NEON_USRA,
NEON_SRSRA_scalar = NEON_Q | NEONScalar | NEON_SRSRA,
NEON_URSRA_scalar = NEON_Q | NEONScalar | NEON_URSRA,
NEON_UQSHRN_scalar = NEON_Q | NEONScalar | NEON_UQSHRN,
NEON_UQRSHRN_scalar = NEON_Q | NEONScalar | NEON_UQRSHRN,
NEON_SQSHRN_scalar = NEON_Q | NEONScalar | NEON_SQSHRN,
NEON_SQRSHRN_scalar = NEON_Q | NEONScalar | NEON_SQRSHRN,
NEON_SQSHRUN_scalar = NEON_Q | NEONScalar | NEON_SQSHRUN,
NEON_SQRSHRUN_scalar = NEON_Q | NEONScalar | NEON_SQRSHRUN,
NEON_SQSHLU_scalar = NEON_Q | NEONScalar | NEON_SQSHLU,
NEON_SQSHL_imm_scalar = NEON_Q | NEONScalar | NEON_SQSHL_imm,
NEON_UQSHL_imm_scalar = NEON_Q | NEONScalar | NEON_UQSHL_imm,
NEON_SCVTF_imm_scalar = NEON_Q | NEONScalar | NEON_SCVTF_imm,
NEON_UCVTF_imm_scalar = NEON_Q | NEONScalar | NEON_UCVTF_imm,
NEON_SCVTF_imm_scalar = NEON_Q | NEONScalar | NEON_SCVTF_imm,
NEON_UCVTF_imm_scalar = NEON_Q | NEONScalar | NEON_UCVTF_imm,
NEON_FCVTZS_imm_scalar = NEON_Q | NEONScalar | NEON_FCVTZS_imm,
NEON_FCVTZU_imm_scalar = NEON_Q | NEONScalar | NEON_FCVTZU_imm
};
@ -2111,6 +2117,9 @@ enum UnallocatedOp {
UnallocatedFMask = 0x00000000
};
// Re-enable `clang-format` after the `enum`s.
// clang-format on
} // namespace vixl
#endif // VIXL_A64_CONSTANTS_A64_H_

View File

@ -61,8 +61,8 @@ uint32_t CPU::GetCacheType() {
#ifdef __aarch64__
uint64_t cache_type_register;
// Copy the content of the cache type register to a core register.
__asm__ __volatile__ ("mrs %[ctr], ctr_el0" // NOLINT
: [ctr] "=r" (cache_type_register));
__asm__ __volatile__("mrs %[ctr], ctr_el0" // NOLINT
: [ctr] "=r"(cache_type_register));
VIXL_ASSERT(is_uint32(cache_type_register));
return cache_type_register;
#else
@ -101,65 +101,70 @@ void CPU::EnsureIAndDCacheCoherency(void *address, size_t length) {
uintptr_t end = start + length;
do {
__asm__ __volatile__ (
// Clean each line of the D cache containing the target data.
//
// dc : Data Cache maintenance
// c : Clean
// va : by (Virtual) Address
// u : to the point of Unification
// The point of unification for a processor is the point by which the
// instruction and data caches are guaranteed to see the same copy of a
// memory location. See ARM DDI 0406B page B2-12 for more information.
" dc cvau, %[dline]\n"
:
: [dline] "r" (dline)
// This code does not write to memory, but the "memory" dependency
// prevents GCC from reordering the code.
: "memory");
__asm__ __volatile__(
// Clean each line of the D cache containing the target data.
//
// dc : Data Cache maintenance
// c : Clean
// va : by (Virtual) Address
// u : to the point of Unification
// The point of unification for a processor is the point by which the
// instruction and data caches are guaranteed to see the same copy of a
// memory location. See ARM DDI 0406B page B2-12 for more information.
" dc cvau, %[dline]\n"
:
: [dline] "r"(dline)
// This code does not write to memory, but the "memory" dependency
// prevents GCC from reordering the code.
: "memory");
dline += dsize;
} while (dline < end);
__asm__ __volatile__ (
// Make sure that the data cache operations (above) complete before the
// instruction cache operations (below).
//
// dsb : Data Synchronisation Barrier
// ish : Inner SHareable domain
//
// The point of unification for an Inner Shareable shareability domain is
// the point by which the instruction and data caches of all the processors
// in that Inner Shareable shareability domain are guaranteed to see the
// same copy of a memory location. See ARM DDI 0406B page B2-12 for more
// information.
" dsb ish\n"
: : : "memory");
__asm__ __volatile__(
// Make sure that the data cache operations (above) complete before the
// instruction cache operations (below).
//
// dsb : Data Synchronisation Barrier
// ish : Inner SHareable domain
//
// The point of unification for an Inner Shareable shareability domain is
// the point by which the instruction and data caches of all the
// processors
// in that Inner Shareable shareability domain are guaranteed to see the
// same copy of a memory location. See ARM DDI 0406B page B2-12 for more
// information.
" dsb ish\n"
:
:
: "memory");
do {
__asm__ __volatile__ (
// Invalidate each line of the I cache containing the target data.
//
// ic : Instruction Cache maintenance
// i : Invalidate
// va : by Address
// u : to the point of Unification
" ic ivau, %[iline]\n"
:
: [iline] "r" (iline)
: "memory");
__asm__ __volatile__(
// Invalidate each line of the I cache containing the target data.
//
// ic : Instruction Cache maintenance
// i : Invalidate
// va : by Address
// u : to the point of Unification
" ic ivau, %[iline]\n"
:
: [iline] "r"(iline)
: "memory");
iline += isize;
} while (iline < end);
__asm__ __volatile__ (
// Make sure that the instruction cache operations (above) take effect
// before the isb (below).
" dsb ish\n"
__asm__ __volatile__(
// Make sure that the instruction cache operations (above) take effect
// before the isb (below).
" dsb ish\n"
// Ensure that any instructions already in the pipeline are discarded and
// reloaded from the new data.
// isb : Instruction Synchronisation Barrier
" isb\n"
: : : "memory");
// Ensure that any instructions already in the pipeline are discarded and
// reloaded from the new data.
// isb : Instruction Synchronisation Barrier
" isb\n"
:
:
: "memory");
#else
// If the host isn't AArch64, we must be using the simulator, so this function
// doesn't have to do anything.

View File

@ -31,13 +31,13 @@
namespace vixl {
// List of commands supported by the debugger.
#define DEBUG_COMMAND_LIST(C) \
C(HelpCommand) \
C(ContinueCommand) \
C(StepCommand) \
C(DisasmCommand) \
C(PrintCommand) \
C(ExamineCommand)
#define DEBUG_COMMAND_LIST(C) \
C(HelpCommand) \
C(ContinueCommand) \
C(StepCommand) \
C(DisasmCommand) \
C(PrintCommand) \
C(ExamineCommand)
// Debugger command lines are broken up in token of different type to make
// processing easier later on.
@ -62,7 +62,8 @@ class Token {
};
// Tokens often hold one value.
template<typename T> class ValueToken : public Token {
template <typename T>
class ValueToken : public Token {
public:
explicit ValueToken(T value) : value_(value) {}
ValueToken() {}
@ -88,7 +89,7 @@ class RegisterToken : public ValueToken<const Register> {
virtual bool IsRegister() const { return true; }
virtual bool CanAddressMemory() const { return value().Is64Bits(); }
virtual uint8_t* ToAddress(Debugger* debugger) const;
virtual void Print(FILE* out = stdout) const ;
virtual void Print(FILE* out = stdout) const;
const char* Name() const;
static Token* Tokenize(const char* arg);
@ -111,7 +112,7 @@ class FPRegisterToken : public ValueToken<const FPRegister> {
: ValueToken<const FPRegister>(fpreg) {}
virtual bool IsFPRegister() const { return true; }
virtual void Print(FILE* out = stdout) const ;
virtual void Print(FILE* out = stdout) const;
static Token* Tokenize(const char* arg);
static FPRegisterToken* Cast(Token* tok) {
@ -153,7 +154,7 @@ class AddressToken : public ValueToken<uint8_t*> {
virtual bool IsAddress() const { return true; }
virtual bool CanAddressMemory() const { return true; }
virtual uint8_t* ToAddress(Debugger* debugger) const;
virtual void Print(FILE* out = stdout) const ;
virtual void Print(FILE* out = stdout) const;
static Token* Tokenize(const char* arg);
static AddressToken* Cast(Token* tok) {
@ -212,7 +213,8 @@ class FormatToken : public Token {
};
template<typename T> class Format : public FormatToken {
template <typename T>
class Format : public FormatToken {
public:
Format(const char* fmt, char type_code) : fmt_(fmt), type_code_(type_code) {}
@ -263,7 +265,7 @@ class DebugCommand {
const char* name() { return name_->value(); }
// Run the command on the given debugger. The command returns true if
// execution should move to the next instruction.
virtual bool Run(Debugger * debugger) = 0;
virtual bool Run(Debugger* debugger) = 0;
virtual void Print(FILE* out = stdout);
static bool Match(const char* name, const char** aliases);
@ -419,121 +421,116 @@ class InvalidCommand : public DebugCommand {
const char* cause_;
};
const char* HelpCommand::kAliases[] = { "help", NULL };
const char* HelpCommand::kAliases[] = {"help", NULL};
const char* HelpCommand::kArguments = NULL;
const char* HelpCommand::kHelp = " Print this help.";
const char* ContinueCommand::kAliases[] = { "continue", "c", NULL };
const char* ContinueCommand::kAliases[] = {"continue", "c", NULL};
const char* ContinueCommand::kArguments = NULL;
const char* ContinueCommand::kHelp = " Resume execution.";
const char* StepCommand::kAliases[] = { "stepi", "si", NULL };
const char* StepCommand::kAliases[] = {"stepi", "si", NULL};
const char* StepCommand::kArguments = "[n = 1]";
const char* StepCommand::kHelp = " Execute n next instruction(s).";
const char* DisasmCommand::kAliases[] = { "disasm", "di", NULL };
const char* DisasmCommand::kAliases[] = {"disasm", "di", NULL};
const char* DisasmCommand::kArguments = "[n = 10]";
const char* DisasmCommand::kHelp =
" Disassemble n instruction(s) at pc.\n"
" This command is equivalent to x pc.i [n = 10]."
;
" Disassemble n instruction(s) at pc.\n"
" This command is equivalent to x pc.i [n = 10].";
const char* PrintCommand::kAliases[] = { "print", "p", NULL };
const char* PrintCommand::kArguments = "<entity>[.format]";
const char* PrintCommand::kAliases[] = {"print", "p", NULL};
const char* PrintCommand::kArguments = "<entity>[.format]";
const char* PrintCommand::kHelp =
" Print the given entity according to the given format.\n"
" The format parameter only affects individual registers; it is ignored\n"
" for other entities.\n"
" <entity> can be one of the following:\n"
" * A register name (such as x0, s1, ...).\n"
" * 'regs', to print all integer (W and X) registers.\n"
" * 'fpregs' to print all floating-point (S and D) registers.\n"
" * 'sysregs' to print all system registers (including NZCV).\n"
" * 'pc' to print the current program counter.\n"
;
" Print the given entity according to the given format.\n"
" The format parameter only affects individual registers; it is ignored\n"
" for other entities.\n"
" <entity> can be one of the following:\n"
" * A register name (such as x0, s1, ...).\n"
" * 'regs', to print all integer (W and X) registers.\n"
" * 'fpregs' to print all floating-point (S and D) registers.\n"
" * 'sysregs' to print all system registers (including NZCV).\n"
" * 'pc' to print the current program counter.\n";
const char* ExamineCommand::kAliases[] = { "m", "mem", "x", NULL };
const char* ExamineCommand::kAliases[] = {"m", "mem", "x", NULL};
const char* ExamineCommand::kArguments = "<addr>[.format] [n = 10]";
const char* ExamineCommand::kHelp =
" Examine memory. Print n items of memory at address <addr> according to\n"
" the given [.format].\n"
" Addr can be an immediate address, a register name or pc.\n"
" Format is made of a type letter: 'x' (hexadecimal), 's' (signed), 'u'\n"
" (unsigned), 'f' (floating point), i (instruction) and a size in bits\n"
" when appropriate (8, 16, 32, 64)\n"
" E.g 'x sp.x64' will print 10 64-bit words from the stack in\n"
" hexadecimal format."
;
" Examine memory. Print n items of memory at address <addr> according to\n"
" the given [.format].\n"
" Addr can be an immediate address, a register name or pc.\n"
" Format is made of a type letter: 'x' (hexadecimal), 's' (signed), 'u'\n"
" (unsigned), 'f' (floating point), i (instruction) and a size in bits\n"
" when appropriate (8, 16, 32, 64)\n"
" E.g 'x sp.x64' will print 10 64-bit words from the stack in\n"
" hexadecimal format.";
const char* RegisterToken::kXAliases[kNumberOfRegisters][kMaxAliasNumber] = {
{ "x0", NULL },
{ "x1", NULL },
{ "x2", NULL },
{ "x3", NULL },
{ "x4", NULL },
{ "x5", NULL },
{ "x6", NULL },
{ "x7", NULL },
{ "x8", NULL },
{ "x9", NULL },
{ "x10", NULL },
{ "x11", NULL },
{ "x12", NULL },
{ "x13", NULL },
{ "x14", NULL },
{ "x15", NULL },
{ "ip0", "x16", NULL },
{ "ip1", "x17", NULL },
{ "x18", "pr", NULL },
{ "x19", NULL },
{ "x20", NULL },
{ "x21", NULL },
{ "x22", NULL },
{ "x23", NULL },
{ "x24", NULL },
{ "x25", NULL },
{ "x26", NULL },
{ "x27", NULL },
{ "x28", NULL },
{ "fp", "x29", NULL },
{ "lr", "x30", NULL },
{ "sp", NULL}
};
const char* RegisterToken::kXAliases[kNumberOfRegisters][kMaxAliasNumber] =
{{"x0", NULL},
{"x1", NULL},
{"x2", NULL},
{"x3", NULL},
{"x4", NULL},
{"x5", NULL},
{"x6", NULL},
{"x7", NULL},
{"x8", NULL},
{"x9", NULL},
{"x10", NULL},
{"x11", NULL},
{"x12", NULL},
{"x13", NULL},
{"x14", NULL},
{"x15", NULL},
{"ip0", "x16", NULL},
{"ip1", "x17", NULL},
{"x18", "pr", NULL},
{"x19", NULL},
{"x20", NULL},
{"x21", NULL},
{"x22", NULL},
{"x23", NULL},
{"x24", NULL},
{"x25", NULL},
{"x26", NULL},
{"x27", NULL},
{"x28", NULL},
{"fp", "x29", NULL},
{"lr", "x30", NULL},
{"sp", NULL}};
const char* RegisterToken::kWAliases[kNumberOfRegisters][kMaxAliasNumber] = {
{ "w0", NULL },
{ "w1", NULL },
{ "w2", NULL },
{ "w3", NULL },
{ "w4", NULL },
{ "w5", NULL },
{ "w6", NULL },
{ "w7", NULL },
{ "w8", NULL },
{ "w9", NULL },
{ "w10", NULL },
{ "w11", NULL },
{ "w12", NULL },
{ "w13", NULL },
{ "w14", NULL },
{ "w15", NULL },
{ "w16", NULL },
{ "w17", NULL },
{ "w18", NULL },
{ "w19", NULL },
{ "w20", NULL },
{ "w21", NULL },
{ "w22", NULL },
{ "w23", NULL },
{ "w24", NULL },
{ "w25", NULL },
{ "w26", NULL },
{ "w27", NULL },
{ "w28", NULL },
{ "w29", NULL },
{ "w30", NULL },
{ "wsp", NULL }
};
const char* RegisterToken::kWAliases[kNumberOfRegisters][kMaxAliasNumber] =
{{"w0", NULL},
{"w1", NULL},
{"w2", NULL},
{"w3", NULL},
{"w4", NULL},
{"w5", NULL},
{"w6", NULL},
{"w7", NULL},
{"w8", NULL},
{"w9", NULL},
{"w10", NULL},
{"w11", NULL},
{"w12", NULL},
{"w13", NULL},
{"w14", NULL},
{"w15", NULL},
{"w16", NULL},
{"w17", NULL},
{"w18", NULL},
{"w19", NULL},
{"w20", NULL},
{"w21", NULL},
{"w22", NULL},
{"w23", NULL},
{"w24", NULL},
{"w25", NULL},
{"w26", NULL},
{"w27", NULL},
{"w28", NULL},
{"w29", NULL},
{"w30", NULL},
{"wsp", NULL}};
Debugger::Debugger(Decoder* decoder, FILE* stream)
@ -554,11 +551,13 @@ Debugger::~Debugger() {
void Debugger::Run() {
pc_modified_ = false;
// Flush any written registers before executing anything, so that
// manually-set registers are logged _before_ the first instruction.
LogAllWrittenRegisters();
while (pc_ != kEndOfSimAddress) {
if (pending_request()) RunDebuggerShell();
ExecuteInstruction();
LogAllWrittenRegisters();
}
}
@ -575,8 +574,7 @@ void Debugger::PrintInstructions(const void* address, int64_t count) {
}
const Instruction* to = from + count * kInstructionSize;
for (const Instruction* current = from;
current < to;
for (const Instruction* current = from; current < to;
current = current->NextInstruction()) {
printer_->Decode(current);
}
@ -600,7 +598,7 @@ void Debugger::PrintMemory(const uint8_t* address,
for (const uint8_t* current = from; current < to; current += size) {
if (((current - from) % 8) == 0) {
printf("\n%p: ", current);
printf("\n%p: ", reinterpret_cast<const void*>(current));
}
uint64_t data = Memory::Read<uint64_t>(current);
@ -618,8 +616,8 @@ void Debugger::PrintRegister(const Register& target_reg,
const uint64_t format_size = format->SizeOf() * 8;
const uint64_t count = reg_size / format_size;
const uint64_t mask = 0xffffffffffffffff >> (64 - format_size);
const uint64_t reg_value = reg<uint64_t>(target_reg.code(),
Reg31IsStackPointer);
const uint64_t reg_value =
reg<uint64_t>(target_reg.code(), Reg31IsStackPointer);
VIXL_ASSERT(count > 0);
printf("%s = ", name);
@ -665,7 +663,8 @@ void Debugger::VisitException(const Instruction* instr) {
return;
case HLT:
VIXL_FALLTHROUGH();
default: Simulator::VisitException(instr);
default:
Simulator::VisitException(instr);
}
}
@ -917,7 +916,8 @@ Token* FPRegisterToken::Tokenize(const char* arg) {
case 'd':
fpreg = VRegister::DRegFromCode(static_cast<unsigned>(code));
break;
default: VIXL_UNREACHABLE();
default:
VIXL_UNREACHABLE();
}
return new FPRegisterToken(fpreg);
@ -965,7 +965,7 @@ uint8_t* AddressToken::ToAddress(Debugger* debugger) const {
void AddressToken::Print(FILE* out) const {
fprintf(out, "[Address %p]", value());
fprintf(out, "[Address %p]", reinterpret_cast<const void*>(value()));
}
@ -1011,7 +1011,8 @@ Token* FormatToken::Tokenize(const char* arg) {
case 'i':
if (length == 1) return new Format<uint32_t>("%08" PRIx32, 'i');
VIXL_FALLTHROUGH();
default: return NULL;
default:
return NULL;
}
char* endptr = NULL;
@ -1036,33 +1037,51 @@ Token* FormatToken::Tokenize(const char* arg) {
switch (arg[0]) {
case 'x':
switch (count) {
case 8: return new Format<uint8_t>("%02" PRIx8, 'x');
case 16: return new Format<uint16_t>("%04" PRIx16, 'x');
case 32: return new Format<uint32_t>("%08" PRIx32, 'x');
case 64: return new Format<uint64_t>("%016" PRIx64, 'x');
default: return NULL;
case 8:
return new Format<uint8_t>("%02" PRIx8, 'x');
case 16:
return new Format<uint16_t>("%04" PRIx16, 'x');
case 32:
return new Format<uint32_t>("%08" PRIx32, 'x');
case 64:
return new Format<uint64_t>("%016" PRIx64, 'x');
default:
return NULL;
}
case 's':
switch (count) {
case 8: return new Format<int8_t>("%4" PRId8, 's');
case 16: return new Format<int16_t>("%6" PRId16, 's');
case 32: return new Format<int32_t>("%11" PRId32, 's');
case 64: return new Format<int64_t>("%20" PRId64, 's');
default: return NULL;
case 8:
return new Format<int8_t>("%4" PRId8, 's');
case 16:
return new Format<int16_t>("%6" PRId16, 's');
case 32:
return new Format<int32_t>("%11" PRId32, 's');
case 64:
return new Format<int64_t>("%20" PRId64, 's');
default:
return NULL;
}
case 'u':
switch (count) {
case 8: return new Format<uint8_t>("%3" PRIu8, 'u');
case 16: return new Format<uint16_t>("%5" PRIu16, 'u');
case 32: return new Format<uint32_t>("%10" PRIu32, 'u');
case 64: return new Format<uint64_t>("%20" PRIu64, 'u');
default: return NULL;
case 8:
return new Format<uint8_t>("%3" PRIu8, 'u');
case 16:
return new Format<uint16_t>("%5" PRIu16, 'u');
case 32:
return new Format<uint32_t>("%10" PRIu32, 'u');
case 64:
return new Format<uint64_t>("%20" PRIu64, 'u');
default:
return NULL;
}
case 'f':
switch (count) {
case 32: return new Format<float>("%13g", 'f');
case 64: return new Format<double>("%13g", 'f');
default: return NULL;
case 32:
return new Format<float>("%13g", 'f');
case 64:
return new Format<double>("%13g", 'f');
default:
return NULL;
}
default:
VIXL_UNREACHABLE();
@ -1071,7 +1090,7 @@ Token* FormatToken::Tokenize(const char* arg) {
}
template<typename T>
template <typename T>
void Format<T>::Print(FILE* out) const {
unsigned size = sizeof(T) * 8;
fprintf(out, "[Format %c%u - %s]", type_code_, size, fmt_);
@ -1083,15 +1102,13 @@ void UnknownToken::Print(FILE* out) const {
}
void DebugCommand::Print(FILE* out) {
fprintf(out, "%s", name());
}
void DebugCommand::Print(FILE* out) { fprintf(out, "%s", name()); }
bool DebugCommand::Match(const char* name, const char** aliases) {
for (const char** current = aliases; *current != NULL; current++) {
if (strcmp(name, *current) == 0) {
return true;
return true;
}
}
@ -1102,8 +1119,7 @@ bool DebugCommand::Match(const char* name, const char** aliases) {
DebugCommand* DebugCommand::Parse(char* line) {
std::vector<Token*> args;
for (char* chunk = strtok(line, " \t");
chunk != NULL;
for (char* chunk = strtok(line, " \t"); chunk != NULL;
chunk = strtok(NULL, " \t")) {
char* dot = strchr(chunk, '.');
if (dot != NULL) {
@ -1132,12 +1148,12 @@ DebugCommand* DebugCommand::Parse(char* line) {
}
const char* name = IdentifierToken::Cast(args[0])->value();
#define RETURN_IF_MATCH(Command) \
if (Match(name, Command::kAliases)) { \
return Command::Build(args); \
#define RETURN_IF_MATCH(Command) \
if (Match(name, Command::kAliases)) { \
return Command::Build(args); \
}
DEBUG_COMMAND_LIST(RETURN_IF_MATCH);
#undef RETURN_IF_MATCH
#undef RETURN_IF_MATCH
return new UnknownCommand(args);
}
@ -1165,12 +1181,12 @@ bool HelpCommand::Run(Debugger* debugger) {
VIXL_ASSERT(debugger->IsDebuggerRunning());
USE(debugger);
#define PRINT_HELP(Command) \
DebugCommand::PrintHelp(Command::kAliases, \
Command::kArguments, \
Command::kHelp);
#define PRINT_HELP(Command) \
DebugCommand::PrintHelp(Command::kAliases, \
Command::kArguments, \
Command::kHelp);
DEBUG_COMMAND_LIST(PRINT_HELP);
#undef PRINT_HELP
#undef PRINT_HELP
printf("\n----\n\n");
return false;
@ -1331,8 +1347,7 @@ DebugCommand* PrintCommand::Build(std::vector<Token*> args) {
}
Token* target = args[1];
if (!target->IsRegister() &&
!target->IsFPRegister() &&
if (!target->IsRegister() && !target->IsFPRegister() &&
!target->IsIdentifier()) {
return new InvalidCommand(args, 1, "expects reg or identifier");
}
@ -1353,23 +1368,34 @@ DebugCommand* PrintCommand::Build(std::vector<Token*> args) {
case 2: {
if (target->IsRegister()) {
switch (target_size) {
case 4: format = new Format<uint32_t>("%08" PRIx32, 'x'); break;
case 8: format = new Format<uint64_t>("%016" PRIx64, 'x'); break;
default: VIXL_UNREACHABLE();
case 4:
format = new Format<uint32_t>("%08" PRIx32, 'x');
break;
case 8:
format = new Format<uint64_t>("%016" PRIx64, 'x');
break;
default:
VIXL_UNREACHABLE();
}
} else if (target->IsFPRegister()) {
switch (target_size) {
case 4: format = new Format<float>("%8g", 'f'); break;
case 8: format = new Format<double>("%8g", 'f'); break;
default: VIXL_UNREACHABLE();
case 4:
format = new Format<float>("%8g", 'f');
break;
case 8:
format = new Format<double>("%8g", 'f');
break;
default:
VIXL_UNREACHABLE();
}
}
break;
}
case 3: {
if (target->IsIdentifier()) {
return new InvalidCommand(args, 2,
"format is only allowed with registers");
return new InvalidCommand(args,
2,
"format is only allowed with registers");
}
Token* second = args[2];
@ -1396,7 +1422,7 @@ bool ExamineCommand::Run(Debugger* debugger) {
VIXL_ASSERT(debugger->IsDebuggerRunning());
uint8_t* address = target()->ToAddress(debugger);
int64_t amount = count()->value();
int64_t amount = count()->value();
if (format()->type_code() == 'i') {
debugger->PrintInstructions(address, amount);
} else {

View File

@ -45,7 +45,7 @@ namespace vixl {
enum DebugParameters {
DBG_INACTIVE = 0,
DBG_ACTIVE = 1 << 0, // The debugger is active.
DBG_BREAK = 1 << 1 // The debugger is at a breakpoint.
DBG_BREAK = 1 << 1 // The debugger is at a breakpoint.
};
// Forward declarations.
@ -81,9 +81,7 @@ class Debugger : public Simulator {
}
bool pending_request() const { return pending_request_; }
void update_pending_request() {
pending_request_ = IsDebuggerRunning();
}
void update_pending_request() { pending_request_ = IsDebuggerRunning(); }
void PrintInstructions(const void* address, int64_t count = 1);
void PrintMemory(const uint8_t* address,

View File

@ -30,16 +30,20 @@
namespace vixl {
void Decoder::DecodeInstruction(const Instruction *instr) {
void Decoder::DecodeInstruction(const Instruction* instr) {
if (instr->Bits(28, 27) == 0) {
VisitUnallocated(instr);
} else {
switch (instr->Bits(27, 24)) {
// 0: PC relative addressing.
case 0x0: DecodePCRelAddressing(instr); break;
case 0x0:
DecodePCRelAddressing(instr);
break;
// 1: Add/sub immediate.
case 0x1: DecodeAddSubImmediate(instr); break;
case 0x1:
DecodeAddSubImmediate(instr);
break;
// A: Logical shifted register.
// Add/sub with carry.
@ -52,15 +56,21 @@ void Decoder::DecodeInstruction(const Instruction *instr) {
// Add/sub extended register.
// Data processing 3 source.
case 0xA:
case 0xB: DecodeDataProcessing(instr); break;
case 0xB:
DecodeDataProcessing(instr);
break;
// 2: Logical immediate.
// Move wide immediate.
case 0x2: DecodeLogical(instr); break;
case 0x2:
DecodeLogical(instr);
break;
// 3: Bitfield.
// Extract.
case 0x3: DecodeBitfieldExtract(instr); break;
case 0x3:
DecodeBitfieldExtract(instr);
break;
// 4: Unconditional branch immediate.
// Exception generation.
@ -73,7 +83,9 @@ void Decoder::DecodeInstruction(const Instruction *instr) {
case 0x4:
case 0x5:
case 0x6:
case 0x7: DecodeBranchSystemException(instr); break;
case 0x7:
DecodeBranchSystemException(instr);
break;
// 8,9: Load/store register pair post-index.
// Load register literal.
@ -89,7 +101,9 @@ void Decoder::DecodeInstruction(const Instruction *instr) {
case 0x8:
case 0x9:
case 0xC:
case 0xD: DecodeLoadStore(instr); break;
case 0xD:
DecodeLoadStore(instr);
break;
// E: FP fixed point conversion.
// FP integer conversion.
@ -103,7 +117,9 @@ void Decoder::DecodeInstruction(const Instruction *instr) {
// F: FP data processing 3 source.
// Advanced SIMD.
case 0xE:
case 0xF: DecodeFP(instr); break;
case 0xF:
DecodeFP(instr);
break;
}
}
}
@ -166,10 +182,8 @@ void Decoder::DecodePCRelAddressing(const Instruction* instr) {
void Decoder::DecodeBranchSystemException(const Instruction* instr) {
VIXL_ASSERT((instr->Bits(27, 24) == 0x4) ||
(instr->Bits(27, 24) == 0x5) ||
(instr->Bits(27, 24) == 0x6) ||
(instr->Bits(27, 24) == 0x7) );
VIXL_ASSERT((instr->Bits(27, 24) == 0x4) || (instr->Bits(27, 24) == 0x5) ||
(instr->Bits(27, 24) == 0x6) || (instr->Bits(27, 24) == 0x7));
switch (instr->Bits(31, 29)) {
case 0:
@ -244,12 +258,9 @@ void Decoder::DecodeBranchSystemException(const Instruction* instr) {
}
}
} else {
if ((instr->Bit(24) == 0x1) ||
(instr->Bits(20, 16) != 0x1F) ||
(instr->Bits(15, 10) != 0) ||
(instr->Bits(4, 0) != 0) ||
(instr->Bits(24, 21) == 0x3) ||
(instr->Bits(24, 22) == 0x3)) {
if ((instr->Bit(24) == 0x1) || (instr->Bits(20, 16) != 0x1F) ||
(instr->Bits(15, 10) != 0) || (instr->Bits(4, 0) != 0) ||
(instr->Bits(24, 21) == 0x3) || (instr->Bits(24, 22) == 0x3)) {
VisitUnallocated(instr);
} else {
VisitUnconditionalBranchToRegister(instr);
@ -267,10 +278,8 @@ void Decoder::DecodeBranchSystemException(const Instruction* instr) {
void Decoder::DecodeLoadStore(const Instruction* instr) {
VIXL_ASSERT((instr->Bits(27, 24) == 0x8) ||
(instr->Bits(27, 24) == 0x9) ||
(instr->Bits(27, 24) == 0xC) ||
(instr->Bits(27, 24) == 0xD) );
VIXL_ASSERT((instr->Bits(27, 24) == 0x8) || (instr->Bits(27, 24) == 0x9) ||
(instr->Bits(27, 24) == 0xC) || (instr->Bits(27, 24) == 0xD));
// TODO(all): rearrange the tree to integrate this branch.
if ((instr->Bit(28) == 0) && (instr->Bit(29) == 0) && (instr->Bit(26) == 1)) {
DecodeNEONLoadStore(instr);
@ -444,8 +453,7 @@ void Decoder::DecodeAddSubImmediate(const Instruction* instr) {
void Decoder::DecodeDataProcessing(const Instruction* instr) {
VIXL_ASSERT((instr->Bits(27, 24) == 0xA) ||
(instr->Bits(27, 24) == 0xB));
VIXL_ASSERT((instr->Bits(27, 24) == 0xA) || (instr->Bits(27, 24) == 0xB));
if (instr->Bit(24) == 0) {
if (instr->Bit(28) == 0) {
@ -465,8 +473,7 @@ void Decoder::DecodeDataProcessing(const Instruction* instr) {
break;
}
case 2: {
if ((instr->Bit(29) == 0) ||
(instr->Mask(0x00000410) != 0)) {
if ((instr->Bit(29) == 0) || (instr->Mask(0x00000410) != 0)) {
VisitUnallocated(instr);
} else {
if (instr->Bit(11) == 0) {
@ -491,8 +498,7 @@ void Decoder::DecodeDataProcessing(const Instruction* instr) {
VIXL_FALLTHROUGH();
} else {
if (instr->Bit(30) == 0) {
if ((instr->Bit(15) == 0x1) ||
(instr->Bits(15, 11) == 0) ||
if ((instr->Bit(15) == 0x1) || (instr->Bits(15, 11) == 0) ||
(instr->Bits(15, 12) == 0x1) ||
(instr->Bits(15, 12) == 0x3) ||
(instr->Bits(15, 13) == 0x3) ||
@ -504,8 +510,7 @@ void Decoder::DecodeDataProcessing(const Instruction* instr) {
VisitDataProcessing2Source(instr);
}
} else {
if ((instr->Bit(13) == 1) ||
(instr->Bits(20, 16) != 0) ||
if ((instr->Bit(13) == 1) || (instr->Bits(20, 16) != 0) ||
(instr->Bits(15, 14) != 0) ||
(instr->Mask(0xA01FFC00) == 0x00000C00) ||
(instr->Mask(0x201FF800) == 0x00001800)) {
@ -520,12 +525,14 @@ void Decoder::DecodeDataProcessing(const Instruction* instr) {
case 1:
case 3:
case 5:
case 7: VisitUnallocated(instr); break;
case 7:
VisitUnallocated(instr);
break;
}
}
} else {
if (instr->Bit(28) == 0) {
if (instr->Bit(21) == 0) {
if (instr->Bit(21) == 0) {
if ((instr->Bits(23, 22) == 0x3) ||
(instr->Mask(0x80008000) == 0x00008000)) {
VisitUnallocated(instr);
@ -542,8 +549,7 @@ void Decoder::DecodeDataProcessing(const Instruction* instr) {
}
}
} else {
if ((instr->Bit(30) == 0x1) ||
(instr->Bits(30, 29) == 0x1) ||
if ((instr->Bit(30) == 0x1) || (instr->Bits(30, 29) == 0x1) ||
(instr->Mask(0xE0600000) == 0x00200000) ||
(instr->Mask(0xE0608000) == 0x00400000) ||
(instr->Mask(0x60608000) == 0x00408000) ||
@ -560,8 +566,7 @@ void Decoder::DecodeDataProcessing(const Instruction* instr) {
void Decoder::DecodeFP(const Instruction* instr) {
VIXL_ASSERT((instr->Bits(27, 24) == 0xE) ||
(instr->Bits(27, 24) == 0xF));
VIXL_ASSERT((instr->Bits(27, 24) == 0xE) || (instr->Bits(27, 24) == 0xF));
if (instr->Bit(28) == 0) {
DecodeNEONVectorDataProcessing(instr);
} else {
@ -573,8 +578,7 @@ void Decoder::DecodeFP(const Instruction* instr) {
if (instr->Bit(29) == 0) {
if (instr->Bit(24) == 0) {
if (instr->Bit(21) == 0) {
if ((instr->Bit(23) == 1) ||
(instr->Bit(18) == 1) ||
if ((instr->Bit(23) == 1) || (instr->Bit(18) == 1) ||
(instr->Mask(0x80008000) == 0x00000000) ||
(instr->Mask(0x000E0000) == 0x00000000) ||
(instr->Mask(0x000E0000) == 0x000A0000) ||
@ -626,8 +630,7 @@ void Decoder::DecodeFP(const Instruction* instr) {
VisitFPDataProcessing1Source(instr);
}
} else if (instr->Bits(13, 10) == 8) {
if ((instr->Bits(15, 14) != 0) ||
(instr->Bits(2, 0) != 0) ||
if ((instr->Bits(15, 14) != 0) || (instr->Bits(2, 0) != 0) ||
(instr->Mask(0x80800000) != 0x00000000)) {
VisitUnallocated(instr);
} else {
@ -663,7 +666,8 @@ void Decoder::DecodeFP(const Instruction* instr) {
VisitFPConditionalSelect(instr);
break;
}
default: VIXL_UNREACHABLE();
default:
VIXL_UNREACHABLE();
}
}
}
@ -864,13 +868,13 @@ void Decoder::DecodeNEONScalarDataProcessing(const Instruction* instr) {
}
#define DEFINE_VISITOR_CALLERS(A) \
void Decoder::Visit##A(const Instruction *instr) { \
VIXL_ASSERT(instr->Mask(A##FMask) == A##Fixed); \
std::list<DecoderVisitor*>::iterator it; \
for (it = visitors_.begin(); it != visitors_.end(); it++) { \
(*it)->Visit##A(instr); \
} \
#define DEFINE_VISITOR_CALLERS(A) \
void Decoder::Visit##A(const Instruction* instr) { \
VIXL_ASSERT(instr->Mask(A##FMask) == A##Fixed); \
std::list<DecoderVisitor*>::iterator it; \
for (it = visitors_.begin(); it != visitors_.end(); it++) { \
(*it)->Visit##A(instr); \
} \
}
VISITOR_LIST(DEFINE_VISITOR_CALLERS)
#undef DEFINE_VISITOR_CALLERS

View File

@ -35,83 +35,83 @@
// List macro containing all visitors needed by the decoder class.
#define VISITOR_LIST_THAT_RETURN(V) \
V(PCRelAddressing) \
V(AddSubImmediate) \
V(LogicalImmediate) \
V(MoveWideImmediate) \
V(Bitfield) \
V(Extract) \
V(UnconditionalBranch) \
V(UnconditionalBranchToRegister) \
V(CompareBranch) \
V(TestBranch) \
V(ConditionalBranch) \
V(System) \
V(Exception) \
V(LoadStorePairPostIndex) \
V(LoadStorePairOffset) \
V(LoadStorePairPreIndex) \
V(LoadStorePairNonTemporal) \
V(LoadLiteral) \
V(LoadStoreUnscaledOffset) \
V(LoadStorePostIndex) \
V(LoadStorePreIndex) \
V(LoadStoreRegisterOffset) \
V(LoadStoreUnsignedOffset) \
V(LoadStoreExclusive) \
V(LogicalShifted) \
V(AddSubShifted) \
V(AddSubExtended) \
V(AddSubWithCarry) \
V(ConditionalCompareRegister) \
V(ConditionalCompareImmediate) \
V(ConditionalSelect) \
V(DataProcessing1Source) \
V(DataProcessing2Source) \
V(DataProcessing3Source) \
V(FPCompare) \
V(FPConditionalCompare) \
V(FPConditionalSelect) \
V(FPImmediate) \
V(FPDataProcessing1Source) \
V(FPDataProcessing2Source) \
V(FPDataProcessing3Source) \
V(FPIntegerConvert) \
V(FPFixedPointConvert) \
V(Crypto2RegSHA) \
V(Crypto3RegSHA) \
V(CryptoAES) \
V(NEON2RegMisc) \
V(NEON3Different) \
V(NEON3Same) \
V(NEONAcrossLanes) \
V(NEONByIndexedElement) \
V(NEONCopy) \
V(NEONExtract) \
V(NEONLoadStoreMultiStruct) \
#define VISITOR_LIST_THAT_RETURN(V) \
V(PCRelAddressing) \
V(AddSubImmediate) \
V(LogicalImmediate) \
V(MoveWideImmediate) \
V(Bitfield) \
V(Extract) \
V(UnconditionalBranch) \
V(UnconditionalBranchToRegister) \
V(CompareBranch) \
V(TestBranch) \
V(ConditionalBranch) \
V(System) \
V(Exception) \
V(LoadStorePairPostIndex) \
V(LoadStorePairOffset) \
V(LoadStorePairPreIndex) \
V(LoadStorePairNonTemporal) \
V(LoadLiteral) \
V(LoadStoreUnscaledOffset) \
V(LoadStorePostIndex) \
V(LoadStorePreIndex) \
V(LoadStoreRegisterOffset) \
V(LoadStoreUnsignedOffset) \
V(LoadStoreExclusive) \
V(LogicalShifted) \
V(AddSubShifted) \
V(AddSubExtended) \
V(AddSubWithCarry) \
V(ConditionalCompareRegister) \
V(ConditionalCompareImmediate) \
V(ConditionalSelect) \
V(DataProcessing1Source) \
V(DataProcessing2Source) \
V(DataProcessing3Source) \
V(FPCompare) \
V(FPConditionalCompare) \
V(FPConditionalSelect) \
V(FPImmediate) \
V(FPDataProcessing1Source) \
V(FPDataProcessing2Source) \
V(FPDataProcessing3Source) \
V(FPIntegerConvert) \
V(FPFixedPointConvert) \
V(Crypto2RegSHA) \
V(Crypto3RegSHA) \
V(CryptoAES) \
V(NEON2RegMisc) \
V(NEON3Different) \
V(NEON3Same) \
V(NEONAcrossLanes) \
V(NEONByIndexedElement) \
V(NEONCopy) \
V(NEONExtract) \
V(NEONLoadStoreMultiStruct) \
V(NEONLoadStoreMultiStructPostIndex) \
V(NEONLoadStoreSingleStruct) \
V(NEONLoadStoreSingleStruct) \
V(NEONLoadStoreSingleStructPostIndex) \
V(NEONModifiedImmediate) \
V(NEONScalar2RegMisc) \
V(NEONScalar3Diff) \
V(NEONScalar3Same) \
V(NEONScalarByIndexedElement) \
V(NEONScalarCopy) \
V(NEONScalarPairwise) \
V(NEONScalarShiftImmediate) \
V(NEONShiftImmediate) \
V(NEONTable) \
V(NEONPerm) \
V(NEONModifiedImmediate) \
V(NEONScalar2RegMisc) \
V(NEONScalar3Diff) \
V(NEONScalar3Same) \
V(NEONScalarByIndexedElement) \
V(NEONScalarCopy) \
V(NEONScalarPairwise) \
V(NEONScalarShiftImmediate) \
V(NEONShiftImmediate) \
V(NEONTable) \
V(NEONPerm)
#define VISITOR_LIST_THAT_DONT_RETURN(V) \
V(Unallocated) \
V(Unimplemented) \
#define VISITOR_LIST_THAT_DONT_RETURN(V) \
V(Unallocated) \
V(Unimplemented)
#define VISITOR_LIST(V) \
VISITOR_LIST_THAT_RETURN(V) \
VISITOR_LIST_THAT_DONT_RETURN(V) \
#define VISITOR_LIST(V) \
VISITOR_LIST_THAT_RETURN(V) \
VISITOR_LIST_THAT_DONT_RETURN(V)
namespace vixl {
@ -119,18 +119,15 @@ namespace vixl {
// must provide implementations for all of these functions.
class DecoderVisitor {
public:
enum VisitorConstness {
kConstVisitor,
kNonConstVisitor
};
enum VisitorConstness { kConstVisitor, kNonConstVisitor };
explicit DecoderVisitor(VisitorConstness constness = kConstVisitor)
: constness_(constness) {}
virtual ~DecoderVisitor() {}
#define DECLARE(A) virtual void Visit##A(const Instruction* instr) = 0;
#define DECLARE(A) virtual void Visit##A(const Instruction* instr) = 0;
VISITOR_LIST(DECLARE)
#undef DECLARE
#undef DECLARE
bool IsConstVisitor() const { return constness_ == kConstVisitor; }
Instruction* MutableInstruction(const Instruction* instr) {
@ -198,9 +195,9 @@ class Decoder {
// of visitors stored by the decoder.
void RemoveVisitor(DecoderVisitor* visitor);
#define DECLARE(A) void Visit##A(const Instruction* instr);
#define DECLARE(A) void Visit##A(const Instruction* instr);
VISITOR_LIST(DECLARE)
#undef DECLARE
#undef DECLARE
std::list<DecoderVisitor*>* visitors() { return &visitors_; }

File diff suppressed because it is too large Load Diff

View File

@ -35,22 +35,22 @@
namespace vixl {
class Disassembler: public DecoderVisitor {
class Disassembler : public DecoderVisitor {
public:
Disassembler();
Disassembler(char* text_buffer, int buffer_size);
virtual ~Disassembler();
char* GetOutput();
// Declare all Visitor functions.
#define DECLARE(A) virtual void Visit##A(const Instruction* instr);
// Declare all Visitor functions.
#define DECLARE(A) virtual void Visit##A(const Instruction* instr);
VISITOR_LIST(DECLARE)
#undef DECLARE
#undef DECLARE
protected:
virtual void ProcessOutput(const Instruction* instr);
// Default output functions. The functions below implement a default way of
// Default output functions. The functions below implement a default way of
// printing elements in the disassembly. A sub-class can override these to
// customize the disassembly output.
@ -106,15 +106,16 @@ class Disassembler: public DecoderVisitor {
int64_t CodeRelativeAddress(const void* instr);
private:
void Format(
const Instruction* instr, const char* mnemonic, const char* format);
void Format(const Instruction* instr,
const char* mnemonic,
const char* format);
void Substitute(const Instruction* instr, const char* string);
int SubstituteField(const Instruction* instr, const char* format);
int SubstituteRegisterField(const Instruction* instr, const char* format);
int SubstituteImmediateField(const Instruction* instr, const char* format);
int SubstituteLiteralField(const Instruction* instr, const char* format);
int SubstituteBitfieldImmediateField(
const Instruction* instr, const char* format);
int SubstituteBitfieldImmediateField(const Instruction* instr,
const char* format);
int SubstituteShiftField(const Instruction* instr, const char* format);
int SubstituteExtendField(const Instruction* instr, const char* format);
int SubstituteConditionField(const Instruction* instr, const char* format);
@ -162,15 +163,15 @@ class Disassembler: public DecoderVisitor {
};
class PrintDisassembler: public Disassembler {
class PrintDisassembler : public Disassembler {
public:
explicit PrintDisassembler(FILE* stream) : stream_(stream) { }
explicit PrintDisassembler(FILE* stream) : stream_(stream) {}
protected:
virtual void ProcessOutput(const Instruction* instr);
private:
FILE *stream_;
FILE* stream_;
};
} // namespace vixl

View File

@ -52,8 +52,8 @@ static uint64_t RotateRight(uint64_t value,
unsigned int width) {
VIXL_ASSERT(width <= 64);
rotate &= 63;
return ((value & ((UINT64_C(1) << rotate) - 1)) <<
(width - rotate)) | (value >> rotate);
return ((value & ((UINT64_C(1) << rotate) - 1)) << (width - rotate)) |
(value >> rotate);
}
@ -94,8 +94,10 @@ bool Instruction::IsLoad() const {
case LDR_h:
case LDR_s:
case LDR_d:
case LDR_q: return true;
default: return false;
case LDR_q:
return true;
default:
return false;
}
}
}
@ -119,8 +121,10 @@ bool Instruction::IsStore() const {
case STR_h:
case STR_s:
case STR_d:
case STR_q: return true;
default: return false;
case STR_q:
return true;
default:
return false;
}
}
}
@ -199,9 +203,7 @@ float Instruction::Imm8ToFP32(uint32_t imm8) {
}
float Instruction::ImmFP32() const {
return Imm8ToFP32(ImmFP());
}
float Instruction::ImmFP32() const { return Imm8ToFP32(ImmFP()); }
double Instruction::Imm8ToFP64(uint32_t imm8) {
@ -219,14 +221,10 @@ double Instruction::Imm8ToFP64(uint32_t imm8) {
}
double Instruction::ImmFP64() const {
return Imm8ToFP64(ImmFP());
}
double Instruction::ImmFP64() const { return Imm8ToFP64(ImmFP()); }
float Instruction::ImmNEONFP32() const {
return Imm8ToFP32(ImmNEONabcdefgh());
}
float Instruction::ImmNEONFP32() const { return Imm8ToFP32(ImmNEONabcdefgh()); }
double Instruction::ImmNEONFP64() const {
@ -253,12 +251,15 @@ unsigned CalcLSPairDataSize(LoadStorePairOp op) {
VIXL_STATIC_ASSERT(kWRegSizeInBytes == kSRegSizeInBytes);
switch (op) {
case STP_q:
case LDP_q: return kQRegSizeInBytesLog2;
case LDP_q:
return kQRegSizeInBytesLog2;
case STP_x:
case LDP_x:
case STP_d:
case LDP_d: return kXRegSizeInBytesLog2;
default: return kWRegSizeInBytesLog2;
case LDP_d:
return kXRegSizeInBytesLog2;
default:
return kWRegSizeInBytesLog2;
}
}
@ -293,7 +294,7 @@ bool Instruction::IsValidImmPCOffset(ImmBranchType branch_type,
const Instruction* Instruction::ImmPCOffsetTarget() const {
const Instruction * base = this;
const Instruction* base = this;
ptrdiff_t offset;
if (IsPCRelAddressing()) {
// ADR and ADRP.
@ -316,11 +317,16 @@ const Instruction* Instruction::ImmPCOffsetTarget() const {
int Instruction::ImmBranch() const {
switch (BranchType()) {
case CondBranchType: return ImmCondBranch();
case UncondBranchType: return ImmUncondBranch();
case CompareBranchType: return ImmCmpBranch();
case TestBranchType: return ImmTestBranch();
default: VIXL_UNREACHABLE();
case CondBranchType:
return ImmCondBranch();
case UncondBranchType:
return ImmUncondBranch();
case CompareBranchType:
return ImmCmpBranch();
case TestBranchType:
return ImmTestBranch();
default:
VIXL_UNREACHABLE();
}
return 0;
}
@ -377,7 +383,8 @@ void Instruction::SetBranchImmTarget(const Instruction* target) {
imm_mask = ImmTestBranch_mask;
break;
}
default: VIXL_UNREACHABLE();
default:
VIXL_UNREACHABLE();
}
SetInstructionBits(Mask(~imm_mask) | branch_imm);
}
@ -397,13 +404,21 @@ VectorFormat VectorFormatHalfWidth(const VectorFormat vform) {
VIXL_ASSERT(vform == kFormat8H || vform == kFormat4S || vform == kFormat2D ||
vform == kFormatH || vform == kFormatS || vform == kFormatD);
switch (vform) {
case kFormat8H: return kFormat8B;
case kFormat4S: return kFormat4H;
case kFormat2D: return kFormat2S;
case kFormatH: return kFormatB;
case kFormatS: return kFormatH;
case kFormatD: return kFormatS;
default: VIXL_UNREACHABLE(); return kFormatUndefined;
case kFormat8H:
return kFormat8B;
case kFormat4S:
return kFormat4H;
case kFormat2D:
return kFormat2S;
case kFormatH:
return kFormatB;
case kFormatS:
return kFormatH;
case kFormatD:
return kFormatS;
default:
VIXL_UNREACHABLE();
return kFormatUndefined;
}
}
@ -412,13 +427,21 @@ VectorFormat VectorFormatDoubleWidth(const VectorFormat vform) {
VIXL_ASSERT(vform == kFormat8B || vform == kFormat4H || vform == kFormat2S ||
vform == kFormatB || vform == kFormatH || vform == kFormatS);
switch (vform) {
case kFormat8B: return kFormat8H;
case kFormat4H: return kFormat4S;
case kFormat2S: return kFormat2D;
case kFormatB: return kFormatH;
case kFormatH: return kFormatS;
case kFormatS: return kFormatD;
default: VIXL_UNREACHABLE(); return kFormatUndefined;
case kFormat8B:
return kFormat8H;
case kFormat4H:
return kFormat4S;
case kFormat2S:
return kFormat2D;
case kFormatB:
return kFormatH;
case kFormatH:
return kFormatS;
case kFormatS:
return kFormatD;
default:
VIXL_UNREACHABLE();
return kFormatUndefined;
}
}
@ -427,39 +450,58 @@ VectorFormat VectorFormatFillQ(const VectorFormat vform) {
switch (vform) {
case kFormatB:
case kFormat8B:
case kFormat16B: return kFormat16B;
case kFormat16B:
return kFormat16B;
case kFormatH:
case kFormat4H:
case kFormat8H: return kFormat8H;
case kFormat8H:
return kFormat8H;
case kFormatS:
case kFormat2S:
case kFormat4S: return kFormat4S;
case kFormat4S:
return kFormat4S;
case kFormatD:
case kFormat1D:
case kFormat2D: return kFormat2D;
default: VIXL_UNREACHABLE(); return kFormatUndefined;
case kFormat2D:
return kFormat2D;
default:
VIXL_UNREACHABLE();
return kFormatUndefined;
}
}
VectorFormat VectorFormatHalfWidthDoubleLanes(const VectorFormat vform) {
switch (vform) {
case kFormat4H: return kFormat8B;
case kFormat8H: return kFormat16B;
case kFormat2S: return kFormat4H;
case kFormat4S: return kFormat8H;
case kFormat1D: return kFormat2S;
case kFormat2D: return kFormat4S;
default: VIXL_UNREACHABLE(); return kFormatUndefined;
case kFormat4H:
return kFormat8B;
case kFormat8H:
return kFormat16B;
case kFormat2S:
return kFormat4H;
case kFormat4S:
return kFormat8H;
case kFormat1D:
return kFormat2S;
case kFormat2D:
return kFormat4S;
default:
VIXL_UNREACHABLE();
return kFormatUndefined;
}
}
VectorFormat VectorFormatDoubleLanes(const VectorFormat vform) {
VIXL_ASSERT(vform == kFormat8B || vform == kFormat4H || vform == kFormat2S);
switch (vform) {
case kFormat8B: return kFormat16B;
case kFormat4H: return kFormat8H;
case kFormat2S: return kFormat4S;
default: VIXL_UNREACHABLE(); return kFormatUndefined;
case kFormat8B:
return kFormat16B;
case kFormat4H:
return kFormat8H;
case kFormat2S:
return kFormat4S;
default:
VIXL_UNREACHABLE();
return kFormatUndefined;
}
}
@ -467,21 +509,32 @@ VectorFormat VectorFormatDoubleLanes(const VectorFormat vform) {
VectorFormat VectorFormatHalfLanes(const VectorFormat vform) {
VIXL_ASSERT(vform == kFormat16B || vform == kFormat8H || vform == kFormat4S);
switch (vform) {
case kFormat16B: return kFormat8B;
case kFormat8H: return kFormat4H;
case kFormat4S: return kFormat2S;
default: VIXL_UNREACHABLE(); return kFormatUndefined;
case kFormat16B:
return kFormat8B;
case kFormat8H:
return kFormat4H;
case kFormat4S:
return kFormat2S;
default:
VIXL_UNREACHABLE();
return kFormatUndefined;
}
}
VectorFormat ScalarFormatFromLaneSize(int laneSize) {
switch (laneSize) {
case 8: return kFormatB;
case 16: return kFormatH;
case 32: return kFormatS;
case 64: return kFormatD;
default: VIXL_UNREACHABLE(); return kFormatUndefined;
case 8:
return kFormatB;
case 16:
return kFormatH;
case 32:
return kFormatS;
case 64:
return kFormatD;
default:
VIXL_UNREACHABLE();
return kFormatUndefined;
}
}
@ -489,15 +542,21 @@ VectorFormat ScalarFormatFromLaneSize(int laneSize) {
unsigned RegisterSizeInBitsFromFormat(VectorFormat vform) {
VIXL_ASSERT(vform != kFormatUndefined);
switch (vform) {
case kFormatB: return kBRegSize;
case kFormatH: return kHRegSize;
case kFormatS: return kSRegSize;
case kFormatD: return kDRegSize;
case kFormatB:
return kBRegSize;
case kFormatH:
return kHRegSize;
case kFormatS:
return kSRegSize;
case kFormatD:
return kDRegSize;
case kFormat8B:
case kFormat4H:
case kFormat2S:
case kFormat1D: return kDRegSize;
default: return kQRegSize;
case kFormat1D:
return kDRegSize;
default:
return kQRegSize;
}
}
@ -512,17 +571,23 @@ unsigned LaneSizeInBitsFromFormat(VectorFormat vform) {
switch (vform) {
case kFormatB:
case kFormat8B:
case kFormat16B: return 8;
case kFormat16B:
return 8;
case kFormatH:
case kFormat4H:
case kFormat8H: return 16;
case kFormat8H:
return 16;
case kFormatS:
case kFormat2S:
case kFormat4S: return 32;
case kFormat4S:
return 32;
case kFormatD:
case kFormat1D:
case kFormat2D: return 64;
default: VIXL_UNREACHABLE(); return 0;
case kFormat2D:
return 64;
default:
VIXL_UNREACHABLE();
return 0;
}
}
@ -537,17 +602,23 @@ int LaneSizeInBytesLog2FromFormat(VectorFormat vform) {
switch (vform) {
case kFormatB:
case kFormat8B:
case kFormat16B: return 0;
case kFormat16B:
return 0;
case kFormatH:
case kFormat4H:
case kFormat8H: return 1;
case kFormat8H:
return 1;
case kFormatS:
case kFormat2S:
case kFormat4S: return 2;
case kFormat4S:
return 2;
case kFormatD:
case kFormat1D:
case kFormat2D: return 3;
default: VIXL_UNREACHABLE(); return 0;
case kFormat2D:
return 3;
default:
VIXL_UNREACHABLE();
return 0;
}
}
@ -555,19 +626,26 @@ int LaneSizeInBytesLog2FromFormat(VectorFormat vform) {
int LaneCountFromFormat(VectorFormat vform) {
VIXL_ASSERT(vform != kFormatUndefined);
switch (vform) {
case kFormat16B: return 16;
case kFormat16B:
return 16;
case kFormat8B:
case kFormat8H: return 8;
case kFormat8H:
return 8;
case kFormat4H:
case kFormat4S: return 4;
case kFormat4S:
return 4;
case kFormat2S:
case kFormat2D: return 2;
case kFormat2D:
return 2;
case kFormat1D:
case kFormatB:
case kFormatH:
case kFormatS:
case kFormatD: return 1;
default: VIXL_UNREACHABLE(); return 0;
case kFormatD:
return 1;
default:
VIXL_UNREACHABLE();
return 0;
}
}
@ -577,17 +655,23 @@ int MaxLaneCountFromFormat(VectorFormat vform) {
switch (vform) {
case kFormatB:
case kFormat8B:
case kFormat16B: return 16;
case kFormat16B:
return 16;
case kFormatH:
case kFormat4H:
case kFormat8H: return 8;
case kFormat8H:
return 8;
case kFormatS:
case kFormat2S:
case kFormat4S: return 4;
case kFormat4S:
return 4;
case kFormatD:
case kFormat1D:
case kFormat2D: return 2;
default: VIXL_UNREACHABLE(); return 0;
case kFormat2D:
return 2;
default:
VIXL_UNREACHABLE();
return 0;
}
}
@ -599,8 +683,10 @@ bool IsVectorFormat(VectorFormat vform) {
case kFormatB:
case kFormatH:
case kFormatS:
case kFormatD: return false;
default: return true;
case kFormatD:
return false;
default:
return true;
}
}
@ -619,4 +705,3 @@ uint64_t MaxUintFromFormat(VectorFormat vform) {
return UINT64_MAX >> (64 - LaneSizeInBitsFromFormat(vform));
}
} // namespace vixl

View File

@ -98,8 +98,8 @@ const unsigned kRegCodeMask = 0x1f;
const unsigned kAddressTagOffset = 56;
const unsigned kAddressTagWidth = 8;
const uint64_t kAddressTagMask =
((UINT64_C(1) << kAddressTagWidth) - 1) << kAddressTagOffset;
const uint64_t kAddressTagMask = ((UINT64_C(1) << kAddressTagWidth) - 1)
<< kAddressTagOffset;
VIXL_STATIC_ASSERT(kAddressTagMask == UINT64_C(0xff00000000000000));
// AArch64 floating-point specifics. These match IEEE-754.
@ -128,17 +128,13 @@ unsigned CalcLSPairDataSize(LoadStorePairOp op);
enum ImmBranchType {
UnknownBranchType = 0,
CondBranchType = 1,
UncondBranchType = 2,
CondBranchType = 1,
UncondBranchType = 2,
CompareBranchType = 3,
TestBranchType = 4
TestBranchType = 4
};
enum AddrMode {
Offset,
PreIndex,
PostIndex
};
enum AddrMode { Offset, PreIndex, PostIndex };
enum FPRounding {
// The first four values are encodable directly by FPCR<RMode>.
@ -153,10 +149,7 @@ enum FPRounding {
FPRoundOdd
};
enum Reg31Mode {
Reg31IsStackPointer,
Reg31IsZeroRegister
};
enum Reg31Mode { Reg31IsStackPointer, Reg31IsZeroRegister };
// Instructions. ---------------------------------------------------------------
@ -170,9 +163,7 @@ class Instruction {
*(reinterpret_cast<Instr*>(this)) = new_instr;
}
int Bit(int pos) const {
return (InstructionBits() >> pos) & 1;
}
int Bit(int pos) const { return (InstructionBits() >> pos) & 1; }
uint32_t Bits(int msb, int lsb) const {
return unsigned_bitextract_32(msb, lsb, InstructionBits());
@ -183,14 +174,12 @@ class Instruction {
return signed_bitextract_32(msb, lsb, bits);
}
Instr Mask(uint32_t mask) const {
return InstructionBits() & mask;
}
Instr Mask(uint32_t mask) const { return InstructionBits() & mask; }
#define DEFINE_GETTER(Name, HighBit, LowBit, Func) \
#define DEFINE_GETTER(Name, HighBit, LowBit, Func) \
int32_t Name() const { return Func(HighBit, LowBit); }
INSTRUCTION_FIELDS_LIST(DEFINE_GETTER)
#undef DEFINE_GETTER
#undef DEFINE_GETTER
// ImmPCRel is a compound field (not present in INSTRUCTION_FIELDS_LIST),
// formed from ImmPCRelLo and ImmPCRelHi.
@ -238,13 +227,9 @@ class Instruction {
return Mask(CompareBranchFMask) == CompareBranchFixed;
}
bool IsTestBranch() const {
return Mask(TestBranchFMask) == TestBranchFixed;
}
bool IsTestBranch() const { return Mask(TestBranchFMask) == TestBranchFixed; }
bool IsImmBranch() const {
return BranchType() != UnknownBranchType;
}
bool IsImmBranch() const { return BranchType() != UnknownBranchType; }
bool IsPCRelAddressing() const {
return Mask(PCRelAddressingFMask) == PCRelAddressingFixed;
@ -390,28 +375,24 @@ class Instruction {
return literal;
}
float LiteralFP32() const {
return rawbits_to_float(Literal32());
}
float LiteralFP32() const { return rawbits_to_float(Literal32()); }
double LiteralFP64() const {
return rawbits_to_double(Literal64());
}
double LiteralFP64() const { return rawbits_to_double(Literal64()); }
const Instruction* NextInstruction() const {
return this + kInstructionSize;
}
const Instruction* NextInstruction() const { return this + kInstructionSize; }
const Instruction* InstructionAtOffset(int64_t offset) const {
VIXL_ASSERT(IsWordAligned(this + offset));
return this + offset;
}
template<typename T> static Instruction* Cast(T src) {
template <typename T>
static Instruction* Cast(T src) {
return reinterpret_cast<Instruction*>(src);
}
template<typename T> static const Instruction* CastConst(T src) {
template <typename T>
static const Instruction* CastConst(T src) {
return reinterpret_cast<const Instruction*>(src);
}
@ -429,14 +410,14 @@ class Instruction {
// Functions for handling NEON vector format information.
enum VectorFormat {
kFormatUndefined = 0xffffffff,
kFormat8B = NEON_8B,
kFormat8B = NEON_8B,
kFormat16B = NEON_16B,
kFormat4H = NEON_4H,
kFormat8H = NEON_8H,
kFormat2S = NEON_2S,
kFormat4S = NEON_4S,
kFormat1D = NEON_1D,
kFormat2D = NEON_2D,
kFormat4H = NEON_4H,
kFormat8H = NEON_8H,
kFormat2S = NEON_2S,
kFormat4S = NEON_4S,
kFormat1D = NEON_1D,
kFormat2D = NEON_2D,
// Scalar formats. We add the scalar bit to distinguish between scalar and
// vector enumerations; the bit is always set in the encoding of scalar ops
@ -470,6 +451,7 @@ int64_t MinIntFromFormat(VectorFormat vform);
uint64_t MaxUintFromFormat(VectorFormat vform);
// clang-format off
enum NEONFormat {
NF_UNDEF = 0,
NF_8B = 1,
@ -485,6 +467,7 @@ enum NEONFormat {
NF_S = 11,
NF_D = 12
};
// clang-format on
static const unsigned kNEONFormatMaxBits = 6;
@ -498,10 +481,7 @@ struct NEONFormatMap {
class NEONFormatDecoder {
public:
enum SubstitutionMode {
kPlaceholder,
kFormat
};
enum SubstitutionMode { kPlaceholder, kFormat };
// Construct a format decoder with increasingly specific format maps for each
// subsitution. If no format map is specified, the default is the integer
@ -510,8 +490,7 @@ class NEONFormatDecoder {
instrbits_ = instr->InstructionBits();
SetFormatMaps(IntegerFormatMap());
}
NEONFormatDecoder(const Instruction* instr,
const NEONFormatMap* format) {
NEONFormatDecoder(const Instruction* instr, const NEONFormatMap* format) {
instrbits_ = instr->InstructionBits();
SetFormatMaps(format);
}
@ -556,7 +535,9 @@ class NEONFormatDecoder {
SubstitutionMode mode0 = kFormat,
SubstitutionMode mode1 = kFormat,
SubstitutionMode mode2 = kFormat) {
snprintf(form_buffer_, sizeof(form_buffer_), string,
snprintf(form_buffer_,
sizeof(form_buffer_),
string,
GetSubstitute(0, mode0),
GetSubstitute(1, mode1),
GetSubstitute(2, mode2));
@ -577,12 +558,19 @@ class NEONFormatDecoder {
}
VectorFormat GetVectorFormat(const NEONFormatMap* format_map) {
static const VectorFormat vform[] = {
kFormatUndefined,
kFormat8B, kFormat16B, kFormat4H, kFormat8H,
kFormat2S, kFormat4S, kFormat1D, kFormat2D,
kFormatB, kFormatH, kFormatS, kFormatD
};
static const VectorFormat vform[] = {kFormatUndefined,
kFormat8B,
kFormat16B,
kFormat4H,
kFormat8H,
kFormat2S,
kFormat4S,
kFormat1D,
kFormat2D,
kFormatB,
kFormatH,
kFormatS,
kFormatD};
VIXL_ASSERT(GetNEONFormat(format_map) < (sizeof(vform) / sizeof(vform[0])));
return vform[GetNEONFormat(format_map)];
}
@ -592,10 +580,9 @@ class NEONFormatDecoder {
// The integer format map uses three bits (Q, size<1:0>) to encode the
// "standard" set of NEON integer vector formats.
static const NEONFormatMap* IntegerFormatMap() {
static const NEONFormatMap map = {
{23, 22, 30},
{NF_8B, NF_16B, NF_4H, NF_8H, NF_2S, NF_4S, NF_UNDEF, NF_2D}
};
static const NEONFormatMap map =
{{23, 22, 30},
{NF_8B, NF_16B, NF_4H, NF_8H, NF_2S, NF_4S, NF_UNDEF, NF_2D}};
return &map;
}
@ -603,9 +590,7 @@ class NEONFormatDecoder {
// long set of NEON integer vector formats. These are used in narrow, wide
// and long operations.
static const NEONFormatMap* LongIntegerFormatMap() {
static const NEONFormatMap map = {
{23, 22}, {NF_8H, NF_4S, NF_2D}
};
static const NEONFormatMap map = {{23, 22}, {NF_8H, NF_4S, NF_2D}};
return &map;
}
@ -614,28 +599,24 @@ class NEONFormatDecoder {
static const NEONFormatMap* FPFormatMap() {
// The FP format map assumes two bits (Q, size<0>) are used to encode the
// NEON FP vector formats: NF_2S, NF_4S, NF_2D.
static const NEONFormatMap map = {
{22, 30}, {NF_2S, NF_4S, NF_UNDEF, NF_2D}
};
static const NEONFormatMap map = {{22, 30},
{NF_2S, NF_4S, NF_UNDEF, NF_2D}};
return &map;
}
// The load/store format map uses three bits (Q, 11, 10) to encode the
// set of NEON vector formats.
static const NEONFormatMap* LoadStoreFormatMap() {
static const NEONFormatMap map = {
{11, 10, 30},
{NF_8B, NF_16B, NF_4H, NF_8H, NF_2S, NF_4S, NF_1D, NF_2D}
};
static const NEONFormatMap map =
{{11, 10, 30},
{NF_8B, NF_16B, NF_4H, NF_8H, NF_2S, NF_4S, NF_1D, NF_2D}};
return &map;
}
// The logical format map uses one bit (Q) to encode the NEON vector format:
// NF_8B, NF_16B.
static const NEONFormatMap* LogicalFormatMap() {
static const NEONFormatMap map = {
{30}, {NF_8B, NF_16B}
};
static const NEONFormatMap map = {{30}, {NF_8B, NF_16B}};
return &map;
}
@ -644,40 +625,60 @@ class NEONFormatDecoder {
// xxx10->8B, xxx11->16B, xx100->4H, xx101->8H
// x1000->2S, x1001->4S, 10001->2D, all others undefined.
static const NEONFormatMap* TriangularFormatMap() {
static const NEONFormatMap map = {
{19, 18, 17, 16, 30},
{NF_UNDEF, NF_UNDEF, NF_8B, NF_16B, NF_4H, NF_8H, NF_8B, NF_16B, NF_2S,
NF_4S, NF_8B, NF_16B, NF_4H, NF_8H, NF_8B, NF_16B, NF_UNDEF, NF_2D,
NF_8B, NF_16B, NF_4H, NF_8H, NF_8B, NF_16B, NF_2S, NF_4S, NF_8B, NF_16B,
NF_4H, NF_8H, NF_8B, NF_16B}
};
static const NEONFormatMap map = {{19, 18, 17, 16, 30},
{NF_UNDEF,
NF_UNDEF,
NF_8B,
NF_16B,
NF_4H,
NF_8H,
NF_8B,
NF_16B,
NF_2S,
NF_4S,
NF_8B,
NF_16B,
NF_4H,
NF_8H,
NF_8B,
NF_16B,
NF_UNDEF,
NF_2D,
NF_8B,
NF_16B,
NF_4H,
NF_8H,
NF_8B,
NF_16B,
NF_2S,
NF_4S,
NF_8B,
NF_16B,
NF_4H,
NF_8H,
NF_8B,
NF_16B}};
return &map;
}
// The scalar format map uses two bits (size<1:0>) to encode the NEON scalar
// formats: NF_B, NF_H, NF_S, NF_D.
static const NEONFormatMap* ScalarFormatMap() {
static const NEONFormatMap map = {
{23, 22}, {NF_B, NF_H, NF_S, NF_D}
};
static const NEONFormatMap map = {{23, 22}, {NF_B, NF_H, NF_S, NF_D}};
return &map;
}
// The long scalar format map uses two bits (size<1:0>) to encode the longer
// NEON scalar formats: NF_H, NF_S, NF_D.
static const NEONFormatMap* LongScalarFormatMap() {
static const NEONFormatMap map = {
{23, 22}, {NF_H, NF_S, NF_D}
};
static const NEONFormatMap map = {{23, 22}, {NF_H, NF_S, NF_D}};
return &map;
}
// The FP scalar format map assumes one bit (size<0>) is used to encode the
// NEON FP scalar formats: NF_S, NF_D.
static const NEONFormatMap* FPScalarFormatMap() {
static const NEONFormatMap map = {
{22}, {NF_S, NF_D}
};
static const NEONFormatMap map = {{22}, {NF_S, NF_D}};
return &map;
}
@ -685,11 +686,23 @@ class NEONFormatDecoder {
// the NEON FP scalar formats:
// xxx1->B, xx10->H, x100->S, 1000->D, all others undefined.
static const NEONFormatMap* TriangularScalarFormatMap() {
static const NEONFormatMap map = {
{19, 18, 17, 16},
{NF_UNDEF, NF_B, NF_H, NF_B, NF_S, NF_B, NF_H, NF_B,
NF_D, NF_B, NF_H, NF_B, NF_S, NF_B, NF_H, NF_B}
};
static const NEONFormatMap map = {{19, 18, 17, 16},
{NF_UNDEF,
NF_B,
NF_H,
NF_B,
NF_S,
NF_B,
NF_H,
NF_B,
NF_D,
NF_B,
NF_H,
NF_B,
NF_S,
NF_B,
NF_H,
NF_B}};
return &map;
}
@ -712,26 +725,29 @@ class NEONFormatDecoder {
// Convert a NEONFormat into a string.
static const char* NEONFormatAsString(NEONFormat format) {
// clang-format off
static const char* formats[] = {
"undefined",
"8b", "16b", "4h", "8h", "2s", "4s", "1d", "2d",
"b", "h", "s", "d"
};
// clang-format on
VIXL_ASSERT(format < (sizeof(formats) / sizeof(formats[0])));
return formats[format];
}
// Convert a NEONFormat into a register placeholder string.
static const char* NEONFormatAsPlaceholder(NEONFormat format) {
VIXL_ASSERT((format == NF_B) || (format == NF_H) ||
(format == NF_S) || (format == NF_D) ||
(format == NF_UNDEF));
VIXL_ASSERT((format == NF_B) || (format == NF_H) || (format == NF_S) ||
(format == NF_D) || (format == NF_UNDEF));
// clang-format off
static const char* formats[] = {
"undefined",
"undefined", "undefined", "undefined", "undefined",
"undefined", "undefined", "undefined", "undefined",
"'B", "'H", "'S", "'D"
};
// clang-format on
return formats[format];
}

View File

@ -35,19 +35,13 @@ Counter::Counter(const char* name, CounterType type)
}
void Counter::Enable() {
enabled_ = true;
}
void Counter::Enable() { enabled_ = true; }
void Counter::Disable() {
enabled_ = false;
}
void Counter::Disable() { enabled_ = false; }
bool Counter::IsEnabled() {
return enabled_;
}
bool Counter::IsEnabled() { return enabled_; }
void Counter::Increment() {
@ -67,14 +61,10 @@ uint64_t Counter::count() {
}
const char* Counter::name() {
return name_;
}
const char* Counter::name() { return name_; }
CounterType Counter::type() {
return type_;
}
CounterType Counter::type() { return type_; }
struct CounterDescriptor {
@ -83,42 +73,40 @@ struct CounterDescriptor {
};
static const CounterDescriptor kCounterList[] = {
{"Instruction", Cumulative},
static const CounterDescriptor kCounterList[] = {{"Instruction", Cumulative},
{"Move Immediate", Gauge},
{"Add/Sub DP", Gauge},
{"Logical DP", Gauge},
{"Other Int DP", Gauge},
{"FP DP", Gauge},
{"Move Immediate", Gauge},
{"Add/Sub DP", Gauge},
{"Logical DP", Gauge},
{"Other Int DP", Gauge},
{"FP DP", Gauge},
{"Conditional Select", Gauge},
{"Conditional Compare", Gauge},
{"Conditional Select", Gauge},
{"Conditional Compare", Gauge},
{"Unconditional Branch", Gauge},
{"Compare and Branch", Gauge},
{"Test and Branch", Gauge},
{"Conditional Branch", Gauge},
{"Unconditional Branch",
Gauge},
{"Compare and Branch", Gauge},
{"Test and Branch", Gauge},
{"Conditional Branch", Gauge},
{"Load Integer", Gauge},
{"Load FP", Gauge},
{"Load Pair", Gauge},
{"Load Literal", Gauge},
{"Load Integer", Gauge},
{"Load FP", Gauge},
{"Load Pair", Gauge},
{"Load Literal", Gauge},
{"Store Integer", Gauge},
{"Store FP", Gauge},
{"Store Pair", Gauge},
{"Store Integer", Gauge},
{"Store FP", Gauge},
{"Store Pair", Gauge},
{"PC Addressing", Gauge},
{"Other", Gauge},
{"NEON", Gauge},
{"Crypto", Gauge}
};
{"PC Addressing", Gauge},
{"Other", Gauge},
{"NEON", Gauge},
{"Crypto", Gauge}};
Instrument::Instrument(const char* datafile, uint64_t sample_period)
: output_stream_(stdout), sample_period_(sample_period) {
// Set up the output stream. If datafile is non-NULL, use that file. If it
// can't be opened, or datafile is NULL, use stdout.
if (datafile != NULL) {
@ -130,7 +118,7 @@ Instrument::Instrument(const char* datafile, uint64_t sample_period)
}
static const int num_counters =
sizeof(kCounterList) / sizeof(CounterDescriptor);
sizeof(kCounterList) / sizeof(CounterDescriptor);
// Dump an instrumentation description comment at the top of the file.
fprintf(output_stream_, "# counters=%d\n", num_counters);
@ -169,8 +157,8 @@ void Instrument::Update() {
VIXL_ASSERT(counter->type() == Cumulative);
counter->Increment();
if ((sample_period_ != 0) && counter->IsEnabled()
&& (counter->count() % sample_period_) == 0) {
if ((sample_period_ != 0) && counter->IsEnabled() &&
(counter->count() % sample_period_) == 0) {
DumpCounters();
}
}
@ -202,9 +190,14 @@ void Instrument::DumpCounterNames() {
void Instrument::HandleInstrumentationEvent(unsigned event) {
switch (event) {
case InstrumentStateEnable: Enable(); break;
case InstrumentStateDisable: Disable(); break;
default: DumpEventMarker(event);
case InstrumentStateEnable:
Enable();
break;
case InstrumentStateDisable:
Disable();
break;
default:
DumpEventMarker(event);
}
}
@ -214,8 +207,11 @@ void Instrument::DumpEventMarker(unsigned marker) {
// line.
static Counter* counter = GetCounter("Instruction");
fprintf(output_stream_, "# %c%c @ %" PRId64 "\n", marker & 0xff,
(marker >> 8) & 0xff, counter->count());
fprintf(output_stream_,
"# %c%c @ %" PRId64 "\n",
marker & 0xff,
(marker >> 8) & 0xff,
counter->count());
}
@ -231,7 +227,7 @@ Counter* Instrument::GetCounter(const char* name) {
// A Counter by that name does not exist: print an error message to stderr
// and the output file, and exit.
static const char* error_message =
"# Error: Unknown counter \"%s\". Exiting.\n";
"# Error: Unknown counter \"%s\". Exiting.\n";
fprintf(stderr, error_message, name);
fprintf(output_stream_, error_message, name);
exit(1);
@ -426,10 +422,14 @@ void Instrument::InstrumentLoadStore(const Instruction* instr) {
case STRH_w:
case STR_w:
VIXL_FALLTHROUGH();
case STR_x: store_int_counter->Increment(); break;
case STR_x:
store_int_counter->Increment();
break;
case STR_s:
VIXL_FALLTHROUGH();
case STR_d: store_fp_counter->Increment(); break;
case STR_d:
store_fp_counter->Increment();
break;
case LDRB_w:
case LDRH_w:
case LDR_w:
@ -439,10 +439,14 @@ void Instrument::InstrumentLoadStore(const Instruction* instr) {
case LDRSW_x:
case LDRSB_w:
VIXL_FALLTHROUGH();
case LDRSH_w: load_int_counter->Increment(); break;
case LDRSH_w:
load_int_counter->Increment();
break;
case LDR_s:
VIXL_FALLTHROUGH();
case LDR_d: load_fp_counter->Increment(); break;
case LDR_d:
load_fp_counter->Increment();
break;
}
}

View File

@ -39,10 +39,7 @@ const int kCounterNameMaxLength = 256;
const uint64_t kDefaultInstrumentationSamplingPeriod = 1 << 22;
enum InstrumentState {
InstrumentStateDisable = 0,
InstrumentStateEnable = 1
};
enum InstrumentState { InstrumentStateDisable = 0, InstrumentStateEnable = 1 };
enum CounterType {
@ -71,19 +68,20 @@ class Counter {
};
class Instrument: public DecoderVisitor {
class Instrument : public DecoderVisitor {
public:
explicit Instrument(const char* datafile = NULL,
uint64_t sample_period = kDefaultInstrumentationSamplingPeriod);
explicit Instrument(
const char* datafile = NULL,
uint64_t sample_period = kDefaultInstrumentationSamplingPeriod);
~Instrument();
void Enable();
void Disable();
// Declare all Visitor functions.
#define DECLARE(A) void Visit##A(const Instruction* instr);
// Declare all Visitor functions.
#define DECLARE(A) void Visit##A(const Instruction* instr);
VISITOR_LIST(DECLARE)
#undef DECLARE
#undef DECLARE
private:
void Update();
@ -98,7 +96,7 @@ class Instrument: public DecoderVisitor {
std::list<Counter*> counters_;
FILE *output_stream_;
FILE* output_stream_;
// Counter information is dumped every sample_period_ instructions decoded.
// For a sample_period_ = 0 a final counter value is only produced when the

File diff suppressed because it is too large Load Diff

View File

@ -46,9 +46,10 @@ void Pool::SetNextCheckpoint(ptrdiff_t checkpoint) {
LiteralPool::LiteralPool(MacroAssembler* masm)
: Pool(masm), size_(0), first_use_(-1),
recommended_checkpoint_(kNoCheckpointRequired) {
}
: Pool(masm),
size_(0),
first_use_(-1),
recommended_checkpoint_(kNoCheckpointRequired) {}
LiteralPool::~LiteralPool() {
@ -264,6 +265,12 @@ void VeneerPool::Emit(EmitOption option, size_t amount) {
EmissionCheckScope::EmissionCheckScope(MacroAssembler* masm, size_t size)
: masm_(masm) {
if (masm_ == NULL) {
// Nothing to do.
// We may reach this point in a context of conditional code generation. See
// `MacroAssembler::MoveImmediateHelper()` for an example.
return;
}
masm_->EnsureEmitFor(size);
masm_->BlockPools();
#ifdef VIXL_DEBUG
@ -275,6 +282,10 @@ EmissionCheckScope::EmissionCheckScope(MacroAssembler* masm, size_t size)
EmissionCheckScope::~EmissionCheckScope() {
if (masm_ == NULL) {
// Nothing to do.
return;
}
#ifdef VIXL_DEBUG
masm_->ReleaseBuffer();
VIXL_ASSERT(masm_->SizeOfCodeGeneratedSince(&start_) <= size_);
@ -300,7 +311,7 @@ MacroAssembler::MacroAssembler(size_t capacity,
}
MacroAssembler::MacroAssembler(byte * buffer,
MacroAssembler::MacroAssembler(byte* buffer,
size_t capacity,
PositionIndependentCodeOption pic)
: Assembler(buffer, capacity, pic),
@ -318,8 +329,7 @@ MacroAssembler::MacroAssembler(byte * buffer,
}
MacroAssembler::~MacroAssembler() {
}
MacroAssembler::~MacroAssembler() {}
void MacroAssembler::Reset() {
@ -357,7 +367,7 @@ void MacroAssembler::CheckEmitFor(size_t amount) {
int MacroAssembler::MoveImmediateHelper(MacroAssembler* masm,
const Register &rd,
const Register& rd,
uint64_t imm) {
bool emit_code = (masm != NULL);
VIXL_ASSERT(is_uint32(imm) || is_int32(imm) || rd.Is64Bits());
@ -417,7 +427,7 @@ int MacroAssembler::MoveImmediateHelper(MacroAssembler* masm,
// halfword, and movk for subsequent halfwords.
VIXL_ASSERT((reg_size % 16) == 0);
bool first_mov_done = false;
for (unsigned i = 0; i < (temp.size() / 16); i++) {
for (unsigned i = 0; i < (reg_size / 16); i++) {
uint64_t imm16 = (imm >> (16 * i)) & 0xffff;
if (imm16 != ignored_halfword) {
if (!first_mov_done) {
@ -475,8 +485,12 @@ bool MacroAssembler::OneInstrMoveImmediateHelper(MacroAssembler* masm,
// Immediate can be represented in a logical orr instruction.
VIXL_ASSERT(!dst.IsZero());
if (emit_code) {
masm->LogicalImmediate(
dst, AppropriateZeroRegFor(dst), n, imm_s, imm_r, ORR);
masm->LogicalImmediate(dst,
AppropriateZeroRegFor(dst),
n,
imm_s,
imm_r,
ORR);
}
return true;
}
@ -491,12 +505,23 @@ void MacroAssembler::B(Label* label, BranchType type, Register reg, int bit) {
B(static_cast<Condition>(type), label);
} else {
switch (type) {
case always: B(label); break;
case never: break;
case reg_zero: Cbz(reg, label); break;
case reg_not_zero: Cbnz(reg, label); break;
case reg_bit_clear: Tbz(reg, bit, label); break;
case reg_bit_set: Tbnz(reg, bit, label); break;
case always:
B(label);
break;
case never:
break;
case reg_zero:
Cbz(reg, label);
break;
case reg_not_zero:
Cbnz(reg, label);
break;
case reg_bit_clear:
Tbz(reg, bit, label);
break;
case reg_bit_set:
Tbnz(reg, bit, label);
break;
default:
VIXL_UNREACHABLE();
}
@ -646,8 +671,7 @@ void MacroAssembler::Ands(const Register& rd,
}
void MacroAssembler::Tst(const Register& rn,
const Operand& operand) {
void MacroAssembler::Tst(const Register& rn, const Operand& operand) {
VIXL_ASSERT(allow_macro_instructions_);
Ands(AppropriateZeroRegFor(rn), rn, operand);
}
@ -795,11 +819,13 @@ void MacroAssembler::LogicalMacro(const Register& rd,
// same modes here.
VIXL_ASSERT(operand.shift_amount() <= 4);
VIXL_ASSERT(operand.reg().Is64Bits() ||
((operand.extend() != UXTX) && (operand.extend() != SXTX)));
((operand.extend() != UXTX) && (operand.extend() != SXTX)));
temps.Exclude(operand.reg());
Register temp = temps.AcquireSameSizeAs(rn);
EmitExtendShift(temp, operand.reg(), operand.extend(),
EmitExtendShift(temp,
operand.reg(),
operand.extend(),
operand.shift_amount());
Logical(rd, rn, Operand(temp), op);
} else {
@ -828,7 +854,9 @@ void MacroAssembler::Mov(const Register& rd,
} else if (operand.IsExtendedRegister()) {
// Emit an extend instruction if moving an extended register. This handles
// extend with post-shift operations, too.
EmitExtendShift(rd, operand.reg(), operand.extend(),
EmitExtendShift(rd,
operand.reg(),
operand.extend(),
operand.shift_amount());
} else {
// Otherwise, emit a register move only if the registers are distinct, or
@ -840,8 +868,8 @@ void MacroAssembler::Mov(const Register& rd,
// this case, the instruction is discarded.
//
// If the sp is an operand, add #0 is emitted, otherwise, orr #0.
if (!rd.Is(operand.reg()) || (rd.Is32Bits() &&
(discard_mode == kDontDiscardForSameWReg))) {
if (!rd.Is(operand.reg()) ||
(rd.Is32Bits() && (discard_mode == kDontDiscardForSameWReg))) {
mov(rd, operand.reg());
}
}
@ -1011,9 +1039,7 @@ void MacroAssembler::Movi(const VRegister& vd,
}
void MacroAssembler::Movi(const VRegister& vd,
uint64_t hi,
uint64_t lo) {
void MacroAssembler::Movi(const VRegister& vd, uint64_t hi, uint64_t lo) {
// TODO: Move 128-bit values in a more efficient way.
VIXL_ASSERT(vd.Is128Bits());
UseScratchRegisterScope temps(this);
@ -1039,7 +1065,9 @@ void MacroAssembler::Mvn(const Register& rd, const Operand& operand) {
// Emit two instructions for the extend case. This differs from Mov, as
// the extend and invert can't be achieved in one instruction.
Register temp = temps.AcquireSameSizeAs(rd);
EmitExtendShift(temp, operand.reg(), operand.extend(),
EmitExtendShift(temp,
operand.reg(),
operand.extend(),
operand.shift_amount());
mvn(rd, Operand(temp));
} else {
@ -1109,45 +1137,198 @@ void MacroAssembler::ConditionalCompareMacro(const Register& rn,
}
void MacroAssembler::Csel(const Register& rd,
const Register& rn,
const Operand& operand,
Condition cond) {
VIXL_ASSERT(allow_macro_instructions_);
VIXL_ASSERT(!rd.IsZero());
VIXL_ASSERT(!rn.IsZero());
VIXL_ASSERT((cond != al) && (cond != nv));
// The worst case for size is csel immediate:
// * up to 4 instructions to materialise the constant
// * 1 instruction for csel
MacroEmissionCheckScope guard(this);
void MacroAssembler::CselHelper(MacroAssembler* masm,
const Register& rd,
Operand left,
Operand right,
Condition cond,
bool* should_synthesise_left,
bool* should_synthesise_right) {
bool emit_code = (masm != NULL);
if (operand.IsImmediate()) {
// Immediate argument. Handle special cases of 0, 1 and -1 using zero
// register.
int64_t imm = operand.immediate();
Register zr = AppropriateZeroRegFor(rn);
if (imm == 0) {
csel(rd, rn, zr, cond);
} else if (imm == 1) {
csinc(rd, rn, zr, cond);
} else if (imm == -1) {
csinv(rd, rn, zr, cond);
} else {
UseScratchRegisterScope temps(this);
Register temp = temps.AcquireSameSizeAs(rn);
Mov(temp, operand.immediate());
csel(rd, rn, temp, cond);
VIXL_ASSERT(!emit_code || masm->allow_macro_instructions_);
VIXL_ASSERT((cond != al) && (cond != nv));
VIXL_ASSERT(!rd.IsZero() && !rd.IsSP());
VIXL_ASSERT(left.IsImmediate() || !left.reg().IsSP());
VIXL_ASSERT(right.IsImmediate() || !right.reg().IsSP());
if (should_synthesise_left != NULL) *should_synthesise_left = false;
if (should_synthesise_right != NULL) *should_synthesise_right = false;
// The worst case for size occurs when the inputs are two non encodable
// constants:
// * up to 4 instructions to materialise the left constant
// * up to 4 instructions to materialise the right constant
// * 1 instruction for csel
EmissionCheckScope guard(masm, 9 * kInstructionSize);
UseScratchRegisterScope temps;
if (masm != NULL) {
temps.Open(masm);
}
// Try to handle cases where both inputs are immediates.
bool left_is_immediate = left.IsImmediate() || left.IsZero();
bool right_is_immediate = right.IsImmediate() || right.IsZero();
if (left_is_immediate && right_is_immediate &&
CselSubHelperTwoImmediates(masm,
rd,
left.GetEquivalentImmediate(),
right.GetEquivalentImmediate(),
cond,
should_synthesise_left,
should_synthesise_right)) {
return;
}
// Handle cases where one of the two inputs is -1, 0, or 1.
bool left_is_small_immediate =
left_is_immediate && ((-1 <= left.GetEquivalentImmediate()) &&
(left.GetEquivalentImmediate() <= 1));
bool right_is_small_immediate =
right_is_immediate && ((-1 <= right.GetEquivalentImmediate()) &&
(right.GetEquivalentImmediate() <= 1));
if (right_is_small_immediate || left_is_small_immediate) {
bool swapped_inputs = false;
if (!right_is_small_immediate) {
std::swap(left, right);
cond = InvertCondition(cond);
swapped_inputs = true;
}
} else if (operand.IsShiftedRegister() && (operand.shift_amount() == 0)) {
// Unshifted register argument.
csel(rd, rn, operand.reg(), cond);
CselSubHelperRightSmallImmediate(masm,
&temps,
rd,
left,
right,
cond,
swapped_inputs ? should_synthesise_right
: should_synthesise_left);
return;
}
// Otherwise both inputs need to be available in registers. Synthesise them
// if necessary and emit the `csel`.
if (!left.IsPlainRegister()) {
if (emit_code) {
Register temp = temps.AcquireSameSizeAs(rd);
masm->Mov(temp, left);
left = temp;
}
if (should_synthesise_left != NULL) *should_synthesise_left = true;
}
if (!right.IsPlainRegister()) {
if (emit_code) {
Register temp = temps.AcquireSameSizeAs(rd);
masm->Mov(temp, right);
right = temp;
}
if (should_synthesise_right != NULL) *should_synthesise_right = true;
}
if (emit_code) {
VIXL_ASSERT(left.IsPlainRegister() && right.IsPlainRegister());
if (left.reg().Is(right.reg())) {
masm->Mov(rd, left.reg());
} else {
masm->csel(rd, left.reg(), right.reg(), cond);
}
}
}
bool MacroAssembler::CselSubHelperTwoImmediates(MacroAssembler* masm,
const Register& rd,
int64_t left,
int64_t right,
Condition cond,
bool* should_synthesise_left,
bool* should_synthesise_right) {
bool emit_code = (masm != NULL);
if (should_synthesise_left != NULL) *should_synthesise_left = false;
if (should_synthesise_right != NULL) *should_synthesise_right = false;
if (left == right) {
if (emit_code) masm->Mov(rd, left);
return true;
} else if (left == -right) {
if (should_synthesise_right != NULL) *should_synthesise_right = true;
if (emit_code) {
masm->Mov(rd, right);
masm->Cneg(rd, rd, cond);
}
return true;
}
if (CselSubHelperTwoOrderedImmediates(masm, rd, left, right, cond)) {
return true;
} else {
// All other arguments.
UseScratchRegisterScope temps(this);
Register temp = temps.AcquireSameSizeAs(rn);
Mov(temp, operand);
csel(rd, rn, temp, cond);
std::swap(left, right);
if (CselSubHelperTwoOrderedImmediates(masm,
rd,
left,
right,
InvertCondition(cond))) {
return true;
}
}
// TODO: Handle more situations. For example handle `csel rd, #5, #6, cond`
// with `cinc`.
return false;
}
bool MacroAssembler::CselSubHelperTwoOrderedImmediates(MacroAssembler* masm,
const Register& rd,
int64_t left,
int64_t right,
Condition cond) {
bool emit_code = (masm != NULL);
if ((left == 0) && (right == 1)) {
if (emit_code) masm->cset(rd, cond);
return true;
} else if ((left == 0) && (right == -1)) {
Register zr = AppropriateZeroRegFor(rd);
if (emit_code) masm->csinv(rd, zr, zr, InvertCondition(cond));
return true;
}
return false;
}
void MacroAssembler::CselSubHelperRightSmallImmediate(
MacroAssembler* masm,
UseScratchRegisterScope* temps,
const Register& rd,
const Operand& left,
const Operand& right,
Condition cond,
bool* should_synthesise_left) {
bool emit_code = (masm != NULL);
VIXL_ASSERT((right.IsImmediate() || right.IsZero()) &&
(-1 <= right.GetEquivalentImmediate()) &&
(right.GetEquivalentImmediate() <= 1));
Register left_register;
if (left.IsPlainRegister()) {
left_register = left.reg();
} else {
if (emit_code) {
left_register = temps->AcquireSameSizeAs(rd);
masm->Mov(left_register, left);
}
if (should_synthesise_left != NULL) *should_synthesise_left = true;
}
if (emit_code) {
int64_t imm = right.GetEquivalentImmediate();
Register zr = AppropriateZeroRegFor(rd);
if (imm == 0) {
masm->csel(rd, left_register, zr, cond);
} else if (imm == 1) {
masm->csinc(rd, left_register, zr, cond);
} else {
VIXL_ASSERT(imm == -1);
masm->csinv(rd, left_register, zr, cond);
}
}
}
@ -1206,7 +1387,8 @@ void MacroAssembler::Cmp(const Register& rn, const Operand& operand) {
}
void MacroAssembler::Fcmp(const FPRegister& fn, double value,
void MacroAssembler::Fcmp(const FPRegister& fn,
double value,
FPTrapFlags trap) {
VIXL_ASSERT(allow_macro_instructions_);
// The worst case for size is:
@ -1293,9 +1475,7 @@ void MacroAssembler::Fmov(VRegister vd, float imm) {
}
void MacroAssembler::Neg(const Register& rd,
const Operand& operand) {
void MacroAssembler::Neg(const Register& rd, const Operand& operand) {
VIXL_ASSERT(allow_macro_instructions_);
if (operand.IsImmediate()) {
Mov(rd, -operand.immediate());
@ -1305,8 +1485,7 @@ void MacroAssembler::Neg(const Register& rd,
}
void MacroAssembler::Negs(const Register& rd,
const Operand& operand) {
void MacroAssembler::Negs(const Register& rd, const Operand& operand) {
VIXL_ASSERT(allow_macro_instructions_);
Subs(rd, AppropriateZeroRegFor(rd), operand);
}
@ -1391,7 +1570,7 @@ void MacroAssembler::AddSubMacro(const Register& rd,
}
if ((operand.IsImmediate() && !IsImmAddSub(operand.immediate())) ||
(rn.IsZero() && !operand.IsShiftedRegister()) ||
(rn.IsZero() && !operand.IsShiftedRegister()) ||
(operand.IsShiftedRegister() && (operand.shift() == ROR))) {
UseScratchRegisterScope temps(this);
Register temp = temps.AcquireSameSizeAs(rn);
@ -1441,16 +1620,14 @@ void MacroAssembler::Sbcs(const Register& rd,
}
void MacroAssembler::Ngc(const Register& rd,
const Operand& operand) {
void MacroAssembler::Ngc(const Register& rd, const Operand& operand) {
VIXL_ASSERT(allow_macro_instructions_);
Register zr = AppropriateZeroRegFor(rd);
Sbc(rd, zr, operand);
}
void MacroAssembler::Ngcs(const Register& rd,
const Operand& operand) {
void MacroAssembler::Ngcs(const Register& rd, const Operand& operand) {
VIXL_ASSERT(allow_macro_instructions_);
Register zr = AppropriateZeroRegFor(rd);
Sbcs(rd, zr, operand);
@ -1480,7 +1657,7 @@ void MacroAssembler::AddSubWithCarryMacro(const Register& rd,
VIXL_ASSERT(operand.reg().size() == rd.size());
VIXL_ASSERT(operand.shift() != ROR);
VIXL_ASSERT(is_uintn(rd.size() == kXRegSize ? kXRegSizeLog2 : kWRegSizeLog2,
operand.shift_amount()));
operand.shift_amount()));
temps.Exclude(operand.reg());
Register temp = temps.AcquireSameSizeAs(rn);
EmitShift(temp, operand.reg(), operand.shift(), operand.shift_amount());
@ -1492,10 +1669,12 @@ void MacroAssembler::AddSubWithCarryMacro(const Register& rd,
// same modes.
VIXL_ASSERT(operand.shift_amount() <= 4);
VIXL_ASSERT(operand.reg().Is64Bits() ||
((operand.extend() != UXTX) && (operand.extend() != SXTX)));
((operand.extend() != UXTX) && (operand.extend() != SXTX)));
temps.Exclude(operand.reg());
Register temp = temps.AcquireSameSizeAs(rn);
EmitExtendShift(temp, operand.reg(), operand.extend(),
EmitExtendShift(temp,
operand.reg(),
operand.extend(),
operand.shift_amount());
AddSubWithCarry(rd, rn, Operand(temp), S, op);
} else {
@ -1505,11 +1684,11 @@ void MacroAssembler::AddSubWithCarryMacro(const Register& rd,
}
#define DEFINE_FUNCTION(FN, REGTYPE, REG, OP) \
void MacroAssembler::FN(const REGTYPE REG, const MemOperand& addr) { \
VIXL_ASSERT(allow_macro_instructions_); \
LoadStoreMacro(REG, addr, OP); \
}
#define DEFINE_FUNCTION(FN, REGTYPE, REG, OP) \
void MacroAssembler::FN(const REGTYPE REG, const MemOperand& addr) { \
VIXL_ASSERT(allow_macro_instructions_); \
LoadStoreMacro(REG, addr, OP); \
}
LS_MACRO_LIST(DEFINE_FUNCTION)
#undef DEFINE_FUNCTION
@ -1552,13 +1731,13 @@ void MacroAssembler::LoadStoreMacro(const CPURegister& rt,
}
#define DEFINE_FUNCTION(FN, REGTYPE, REG, REG2, OP) \
void MacroAssembler::FN(const REGTYPE REG, \
const REGTYPE REG2, \
const MemOperand& addr) { \
VIXL_ASSERT(allow_macro_instructions_); \
LoadStorePairMacro(REG, REG2, addr, OP); \
}
#define DEFINE_FUNCTION(FN, REGTYPE, REG, REG2, OP) \
void MacroAssembler::FN(const REGTYPE REG, \
const REGTYPE REG2, \
const MemOperand& addr) { \
VIXL_ASSERT(allow_macro_instructions_); \
LoadStorePairMacro(REG, REG2, addr, OP); \
}
LSPAIR_MACRO_LIST(DEFINE_FUNCTION)
#undef DEFINE_FUNCTION
@ -1628,8 +1807,10 @@ void MacroAssembler::Prfm(PrefetchOperation op, const MemOperand& addr) {
}
void MacroAssembler::Push(const CPURegister& src0, const CPURegister& src1,
const CPURegister& src2, const CPURegister& src3) {
void MacroAssembler::Push(const CPURegister& src0,
const CPURegister& src1,
const CPURegister& src2,
const CPURegister& src3) {
VIXL_ASSERT(allow_macro_instructions_);
VIXL_ASSERT(AreSameSizeAndType(src0, src1, src2, src3));
VIXL_ASSERT(src0.IsValid());
@ -1642,8 +1823,10 @@ void MacroAssembler::Push(const CPURegister& src0, const CPURegister& src1,
}
void MacroAssembler::Pop(const CPURegister& dst0, const CPURegister& dst1,
const CPURegister& dst2, const CPURegister& dst3) {
void MacroAssembler::Pop(const CPURegister& dst0,
const CPURegister& dst1,
const CPURegister& dst2,
const CPURegister& dst3) {
// It is not valid to pop into the same register more than once in one
// instruction, not even into the zero register.
VIXL_ASSERT(allow_macro_instructions_);
@ -1749,14 +1932,16 @@ void MacroAssembler::PushMultipleTimes(int count, Register src) {
}
void MacroAssembler::PushHelper(int count, int size,
void MacroAssembler::PushHelper(int count,
int size,
const CPURegister& src0,
const CPURegister& src1,
const CPURegister& src2,
const CPURegister& src3) {
// Ensure that we don't unintentionally modify scratch or debug registers.
// Worst case for size is 2 stp.
InstructionAccurateScope scope(this, 2,
InstructionAccurateScope scope(this,
2,
InstructionAccurateScope::kMaximumSize);
VIXL_ASSERT(AreSameSizeAndType(src0, src1, src2, src3));
@ -1791,14 +1976,16 @@ void MacroAssembler::PushHelper(int count, int size,
}
void MacroAssembler::PopHelper(int count, int size,
void MacroAssembler::PopHelper(int count,
int size,
const CPURegister& dst0,
const CPURegister& dst1,
const CPURegister& dst2,
const CPURegister& dst3) {
// Ensure that we don't unintentionally modify scratch or debug registers.
// Worst case for size is 2 ldp.
InstructionAccurateScope scope(this, 2,
InstructionAccurateScope scope(this,
2,
InstructionAccurateScope::kMaximumSize);
VIXL_ASSERT(AreSameSizeAndType(dst0, dst1, dst2, dst3));
@ -1990,9 +2177,7 @@ void MacroAssembler::LoadStoreCPURegListHelper(LoadStoreCPURegListAction op,
UseScratchRegisterScope temps(this);
MemOperand loc = BaseMemOperandForLoadStoreCPURegList(registers,
mem,
&temps);
MemOperand loc = BaseMemOperandForLoadStoreCPURegList(registers, mem, &temps);
while (registers.Count() >= 2) {
const CPURegister& dst0 = registers.PopLowestIndex();
@ -2057,7 +2242,7 @@ void MacroAssembler::BumpSystemStackPointer(const Operand& space) {
// This is the main Printf implementation. All callee-saved registers are
// preserved, but NZCV and the caller-saved registers may be clobbered.
void MacroAssembler::PrintfNoPreserve(const char * format,
void MacroAssembler::PrintfNoPreserve(const char* format,
const CPURegister& arg0,
const CPURegister& arg1,
const CPURegister& arg2,
@ -2167,9 +2352,9 @@ void MacroAssembler::PrintfNoPreserve(const char * format,
// strlen(format) + 1 (includes null termination)
// padding to next instruction
// unreachable
EmissionCheckScope guard(
this,
AlignUp(strlen(format) + 1, kInstructionSize) + 2 * kInstructionSize);
EmissionCheckScope guard(this,
AlignUp(strlen(format) + 1, kInstructionSize) +
2 * kInstructionSize);
Label after_data;
B(&after_data);
Bind(&format_address);
@ -2190,7 +2375,7 @@ void MacroAssembler::PrintfNoPreserve(const char * format,
if (allow_simulator_instructions_) {
InstructionAccurateScope scope(this, kPrintfLength / kInstructionSize);
hlt(kPrintfOpcode);
dc32(arg_count); // kPrintfArgCountOffset
dc32(arg_count); // kPrintfArgCountOffset
// Determine the argument pattern.
uint32_t arg_pattern_list = 0;
@ -2205,7 +2390,7 @@ void MacroAssembler::PrintfNoPreserve(const char * format,
VIXL_ASSERT(arg_pattern < (1 << kPrintfArgPatternBits));
arg_pattern_list |= (arg_pattern << (kPrintfArgPatternBits * i));
}
dc32(arg_pattern_list); // kPrintfArgPatternListOffset
dc32(arg_pattern_list); // kPrintfArgPatternListOffset
} else {
Register tmp = temps.AcquireX();
Mov(tmp, reinterpret_cast<uintptr_t>(printf));
@ -2214,7 +2399,7 @@ void MacroAssembler::PrintfNoPreserve(const char * format,
}
void MacroAssembler::Printf(const char * format,
void MacroAssembler::Printf(const char* format,
CPURegister arg0,
CPURegister arg1,
CPURegister arg2,
@ -2238,7 +2423,8 @@ void MacroAssembler::Printf(const char * format,
PushCPURegList(kCallerSaved);
PushCPURegList(kCallerSavedV);
{ UseScratchRegisterScope temps(this);
{
UseScratchRegisterScope temps(this);
// We can use caller-saved registers as scratch values (except for argN).
temps.Include(kCallerSaved);
temps.Include(kCallerSavedV);
@ -2255,7 +2441,8 @@ void MacroAssembler::Printf(const char * format,
// Allocate a register to hold the original stack pointer value, to pass
// to PrintfNoPreserve as an argument.
Register arg_sp = temps.AcquireX();
Add(arg_sp, StackPointer(),
Add(arg_sp,
StackPointer(),
kCallerSaved.TotalSizeInBytes() + kCallerSavedV.TotalSizeInBytes());
if (arg0_sp) arg0 = Register(arg_sp.code(), arg0.size());
if (arg1_sp) arg1 = Register(arg_sp.code(), arg1.size());
@ -2361,6 +2548,7 @@ void MacroAssembler::AnnotateInstrumentation(const char* marker_name) {
void UseScratchRegisterScope::Open(MacroAssembler* masm) {
VIXL_ASSERT(!initialised_);
VIXL_ASSERT(masm != NULL);
available_ = masm->TmpList();
availablefp_ = masm->FPTmpList();
old_available_ = available_->list();
@ -2397,16 +2585,16 @@ UseScratchRegisterScope::UseScratchRegisterScope(MacroAssembler* masm) {
// This allows deferred (and optional) initialisation of the scope.
UseScratchRegisterScope::UseScratchRegisterScope()
: available_(NULL), availablefp_(NULL),
old_available_(0), old_availablefp_(0) {
: available_(NULL),
availablefp_(NULL),
old_available_(0),
old_availablefp_(0) {
#ifdef VIXL_DEBUG
initialised_ = false;
#endif
}
UseScratchRegisterScope::~UseScratchRegisterScope() {
Close();
}
UseScratchRegisterScope::~UseScratchRegisterScope() { Close(); }
bool UseScratchRegisterScope::IsAvailable(const CPURegister& reg) const {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -108,22 +108,19 @@ const unsigned kTraceLength = 3 * kInstructionSize;
// Trace parameters.
enum TraceParameters {
LOG_DISASM = 1 << 0, // Log disassembly.
LOG_REGS = 1 << 1, // Log general purpose registers.
LOG_VREGS = 1 << 2, // Log NEON and floating-point registers.
LOG_SYSREGS = 1 << 3, // Log the flags and system registers.
LOG_WRITE = 1 << 4, // Log writes to memory.
LOG_DISASM = 1 << 0, // Log disassembly.
LOG_REGS = 1 << 1, // Log general purpose registers.
LOG_VREGS = 1 << 2, // Log NEON and floating-point registers.
LOG_SYSREGS = 1 << 3, // Log the flags and system registers.
LOG_WRITE = 1 << 4, // Log writes to memory.
LOG_NONE = 0,
LOG_STATE = LOG_REGS | LOG_VREGS | LOG_SYSREGS,
LOG_ALL = LOG_DISASM | LOG_STATE | LOG_WRITE
LOG_NONE = 0,
LOG_STATE = LOG_REGS | LOG_VREGS | LOG_SYSREGS,
LOG_ALL = LOG_DISASM | LOG_STATE | LOG_WRITE
};
// Trace commands.
enum TraceCommand {
TRACE_ENABLE = 1,
TRACE_DISABLE = 2
};
enum TraceCommand { TRACE_ENABLE = 1, TRACE_DISABLE = 2 };
// Log - kLogOpcode
// - parameter: TraceParameter stored as a uint32_t

View File

@ -76,7 +76,7 @@ void CodeBuffer::Align() {
const size_t padding_size = end - cursor_;
VIXL_ASSERT(RemainingBytes() >= padding_size);
VIXL_ASSERT(padding_size <= 4);
const byte padding[] = { 0, 0, 0, 0};
const byte padding[] = {0, 0, 0, 0};
dirty_ = true;
memcpy(cursor_, padding, padding_size);
cursor_ = end;

View File

@ -46,9 +46,7 @@ class CodeBuffer {
return cursor_offset - offset;
}
ptrdiff_t CursorOffset() const {
return OffsetFrom(0);
}
ptrdiff_t CursorOffset() const { return OffsetFrom(0); }
template <typename T>
T GetOffsetAddress(ptrdiff_t offset) const {
@ -110,4 +108,3 @@ class CodeBuffer {
} // namespace vixl
#endif // VIXL_CODE_BUFFER_H

View File

@ -92,12 +92,12 @@ int CountSetBitsFallBack(uint64_t value, int width) {
// \ |
// value = h+g+f+e+d+c+b+a
const uint64_t kMasks[] = {
UINT64_C(0x5555555555555555),
UINT64_C(0x3333333333333333),
UINT64_C(0x0f0f0f0f0f0f0f0f),
UINT64_C(0x00ff00ff00ff00ff),
UINT64_C(0x0000ffff0000ffff),
UINT64_C(0x00000000ffffffff),
UINT64_C(0x5555555555555555),
UINT64_C(0x3333333333333333),
UINT64_C(0x0f0f0f0f0f0f0f0f),
UINT64_C(0x00ff00ff00ff00ff),
UINT64_C(0x0000ffff0000ffff),
UINT64_C(0x00000000ffffffff),
};
for (unsigned i = 0; i < (sizeof(kMasks) / sizeof(kMasks[0])); i++) {

View File

@ -37,13 +37,13 @@ namespace vixl {
#define MAJOR 1000000
#define MINOR 1000
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
#define GCC_VERSION_OR_NEWER(major, minor, patchlevel) \
((__GNUC__ * MAJOR + __GNUC_MINOR__ * MINOR + __GNUC_PATCHLEVEL__) >= \
((major) * MAJOR + (minor) * MINOR + (patchlevel)))
#define GCC_VERSION_OR_NEWER(major, minor, patchlevel) \
((__GNUC__ * (MAJOR) + __GNUC_MINOR__ * (MINOR) + __GNUC_PATCHLEVEL__) >= \
((major) * (MAJOR) + ((minor)) * (MINOR) + (patchlevel)))
#elif defined(__GNUC__) && defined(__GNUC_MINOR__)
#define GCC_VERSION_OR_NEWER(major, minor, patchlevel) \
((__GNUC__ * MAJOR + __GNUC_MINOR__ * MINOR) >= \
((major) * MAJOR + (minor) * MINOR + (patchlevel)))
#define GCC_VERSION_OR_NEWER(major, minor, patchlevel) \
((__GNUC__ * (MAJOR) + __GNUC_MINOR__ * (MINOR)) >= \
((major) * (MAJOR) + ((minor)) * (MINOR) + (patchlevel)))
#else
#define GCC_VERSION_OR_NEWER(major, minor, patchlevel) 0
#endif
@ -51,37 +51,43 @@ namespace vixl {
#if defined(__clang__) && !defined(VIXL_NO_COMPILER_BUILTINS)
// clang-format off
#define COMPILER_HAS_BUILTIN_CLRSB (__has_builtin(__builtin_clrsb))
#define COMPILER_HAS_BUILTIN_CLZ (__has_builtin(__builtin_clz))
#define COMPILER_HAS_BUILTIN_CTZ (__has_builtin(__builtin_ctz))
#define COMPILER_HAS_BUILTIN_FFS (__has_builtin(__builtin_ffs))
#define COMPILER_HAS_BUILTIN_POPCOUNT (__has_builtin(__builtin_popcount))
// clang-format on
#elif defined(__GNUC__) && !defined(VIXL_NO_COMPILER_BUILTINS)
// The documentation for these builtins is available at:
// https://gcc.gnu.org/onlinedocs/gcc-$MAJOR.$MINOR.$PATCHLEVEL/gcc//Other-Builtins.html
// clang-format off
# define COMPILER_HAS_BUILTIN_CLRSB (GCC_VERSION_OR_NEWER(4, 7, 0))
# define COMPILER_HAS_BUILTIN_CLZ (GCC_VERSION_OR_NEWER(3, 4, 0))
# define COMPILER_HAS_BUILTIN_CTZ (GCC_VERSION_OR_NEWER(3, 4, 0))
# define COMPILER_HAS_BUILTIN_FFS (GCC_VERSION_OR_NEWER(3, 4, 0))
# define COMPILER_HAS_BUILTIN_POPCOUNT (GCC_VERSION_OR_NEWER(3, 4, 0))
// clang-format on
#else
// One can define VIXL_NO_COMPILER_BUILTINS to force using the manually
// implemented C++ methods.
// clang-format off
#define COMPILER_HAS_BUILTIN_BSWAP false
#define COMPILER_HAS_BUILTIN_CLRSB false
#define COMPILER_HAS_BUILTIN_CLZ false
#define COMPILER_HAS_BUILTIN_CTZ false
#define COMPILER_HAS_BUILTIN_FFS false
#define COMPILER_HAS_BUILTIN_POPCOUNT false
// clang-format on
#endif
template<typename V>
template <typename V>
inline bool IsPowerOf2(V value) {
return (value != 0) && ((value & (value - 1)) == 0);
}
@ -98,7 +104,7 @@ int CountTrailingZerosFallBack(uint64_t value, int width);
// TODO: The implementations could be improved for sizes different from 32bit
// and 64bit: we could mask the values and call the appropriate builtin.
template<typename V>
template <typename V>
inline int CountLeadingSignBits(V value, int width = (sizeof(V) * 8)) {
#if COMPILER_HAS_BUILTIN_CLRSB
if (width == 32) {
@ -111,7 +117,7 @@ inline int CountLeadingSignBits(V value, int width = (sizeof(V) * 8)) {
}
template<typename V>
template <typename V>
inline int CountLeadingZeros(V value, int width = (sizeof(V) * 8)) {
#if COMPILER_HAS_BUILTIN_CLZ
if (width == 32) {
@ -124,7 +130,7 @@ inline int CountLeadingZeros(V value, int width = (sizeof(V) * 8)) {
}
template<typename V>
template <typename V>
inline int CountSetBits(V value, int width = (sizeof(V) * 8)) {
#if COMPILER_HAS_BUILTIN_POPCOUNT
if (width == 32) {
@ -137,7 +143,7 @@ inline int CountSetBits(V value, int width = (sizeof(V) * 8)) {
}
template<typename V>
template <typename V>
inline int CountTrailingZeros(V value, int width = (sizeof(V) * 8)) {
#if COMPILER_HAS_BUILTIN_CTZ
if (width == 32) {
@ -152,4 +158,3 @@ inline int CountTrailingZeros(V value, int width = (sizeof(V) * 8)) {
} // namespace vixl
#endif // VIXL_COMPILER_INTRINSICS_H

View File

@ -60,30 +60,39 @@ typedef uint16_t float16;
const int KBytes = 1024;
const int MBytes = 1024 * KBytes;
#define VIXL_ABORT() \
do { printf("in %s, line %i", __FILE__, __LINE__); abort(); } while (false)
#define VIXL_ABORT() \
do { \
printf("in %s, line %i", __FILE__, __LINE__); \
abort(); \
} while (false)
#ifdef VIXL_DEBUG
#define VIXL_ASSERT(condition) assert(condition)
#define VIXL_CHECK(condition) VIXL_ASSERT(condition)
#define VIXL_UNIMPLEMENTED() \
do { fprintf(stderr, "UNIMPLEMENTED\t"); VIXL_ABORT(); } while (false)
#define VIXL_UNREACHABLE() \
do { fprintf(stderr, "UNREACHABLE\t"); VIXL_ABORT(); } while (false)
#define VIXL_ASSERT(condition) assert(condition)
#define VIXL_CHECK(condition) VIXL_ASSERT(condition)
#define VIXL_UNIMPLEMENTED() \
do { \
fprintf(stderr, "UNIMPLEMENTED\t"); \
VIXL_ABORT(); \
} while (false)
#define VIXL_UNREACHABLE() \
do { \
fprintf(stderr, "UNREACHABLE\t"); \
VIXL_ABORT(); \
} while (false)
#else
#define VIXL_ASSERT(condition) ((void) 0)
#define VIXL_CHECK(condition) assert(condition)
#define VIXL_UNIMPLEMENTED() ((void) 0)
#define VIXL_UNREACHABLE() ((void) 0)
#define VIXL_ASSERT(condition) ((void)0)
#define VIXL_CHECK(condition) assert(condition)
#define VIXL_UNIMPLEMENTED() ((void)0)
#define VIXL_UNREACHABLE() ((void)0)
#endif
// This is not as powerful as template based assertions, but it is simple.
// It assumes that the descriptions are unique. If this starts being a problem,
// we can switch to a different implemention.
#define VIXL_CONCAT(a, b) a##b
#define VIXL_STATIC_ASSERT_LINE(line, condition) \
#define VIXL_STATIC_ASSERT_LINE(line, condition) \
typedef char VIXL_CONCAT(STATIC_ASSERT_LINE_, line)[(condition) ? 1 : -1] \
__attribute__((unused))
__attribute__((unused))
#define VIXL_STATIC_ASSERT(condition) \
VIXL_STATIC_ASSERT_LINE(__LINE__, condition)
VIXL_STATIC_ASSERT_LINE(__LINE__, condition)
template <typename T1>
inline void USE(T1) {}
@ -97,55 +106,60 @@ inline void USE(T1, T2, T3) {}
template <typename T1, typename T2, typename T3, typename T4>
inline void USE(T1, T2, T3, T4) {}
#define VIXL_ALIGNMENT_EXCEPTION() \
do { fprintf(stderr, "ALIGNMENT EXCEPTION\t"); VIXL_ABORT(); } while (0)
#define VIXL_ALIGNMENT_EXCEPTION() \
do { \
fprintf(stderr, "ALIGNMENT EXCEPTION\t"); \
VIXL_ABORT(); \
} while (0)
// The clang::fallthrough attribute is used along with the Wimplicit-fallthrough
// argument to annotate intentional fall-through between switch labels.
// For more information please refer to:
// http://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough
#ifndef __has_warning
#define __has_warning(x) 0
#define __has_warning(x) 0
#endif
// Note: This option is only available for Clang. And will only be enabled for
// C++11(201103L).
#if __has_warning("-Wimplicit-fallthrough") && __cplusplus >= 201103L
#define VIXL_FALLTHROUGH() [[clang::fallthrough]] //NOLINT
#define VIXL_FALLTHROUGH() [[clang::fallthrough]] // NOLINT
#else
#define VIXL_FALLTHROUGH() do {} while (0)
#define VIXL_FALLTHROUGH() \
do { \
} while (0)
#endif
#if __cplusplus >= 201103L
#define VIXL_NO_RETURN [[noreturn]] //NOLINT
#define VIXL_NO_RETURN [[noreturn]] // NOLINT
#else
#define VIXL_NO_RETURN __attribute__((noreturn))
#define VIXL_NO_RETURN __attribute__((noreturn))
#endif
// Some functions might only be marked as "noreturn" for the DEBUG build. This
// macro should be used for such cases (for more details see what
// VIXL_UNREACHABLE expands to).
#ifdef VIXL_DEBUG
#define VIXL_DEBUG_NO_RETURN VIXL_NO_RETURN
#define VIXL_DEBUG_NO_RETURN VIXL_NO_RETURN
#else
#define VIXL_DEBUG_NO_RETURN
#define VIXL_DEBUG_NO_RETURN
#endif
#ifdef VIXL_INCLUDE_SIMULATOR
#ifndef VIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE
#define VIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE 1
#define VIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE 1
#endif
#else
#ifndef VIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE
#define VIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE 0
#define VIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE 0
#endif
#if VIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE
#warning "Generating Simulator instructions without Simulator support."
#warning "Generating Simulator instructions without Simulator support."
#endif
#endif
#ifdef USE_SIMULATOR
#error "Please see the release notes for USE_SIMULATOR."
#error "Please see the release notes for USE_SIMULATOR."
#endif
#endif // VIXL_GLOBALS_H

View File

@ -67,9 +67,10 @@ namespace vixl {
// are used, a number of elements are preallocated.
// 'ElementType' and 'KeyType' are respectively the types of the elements and
// their key. The structure only reclaims memory when safe to do so, if the
// their key. The structure only reclaims memory when safe to do so, if the
// number of elements that can be reclaimed is greater than `RECLAIM_FROM` and
// greater than `<total number of elements> / RECLAIM_FACTOR.
// clang-format off
#define TEMPLATE_INVALSET_P_DECL \
class ElementType, \
unsigned N_PREALLOCATED_ELEMENTS, \
@ -77,14 +78,17 @@ namespace vixl {
KeyType INVALID_KEY, \
size_t RECLAIM_FROM, \
unsigned RECLAIM_FACTOR
// clang-format on
#define TEMPLATE_INVALSET_P_DEF \
ElementType, N_PREALLOCATED_ELEMENTS, \
KeyType, INVALID_KEY, RECLAIM_FROM, RECLAIM_FACTOR
#define TEMPLATE_INVALSET_P_DEF \
ElementType, N_PREALLOCATED_ELEMENTS, KeyType, INVALID_KEY, RECLAIM_FROM, \
RECLAIM_FACTOR
template<class S> class InvalSetIterator; // Forward declaration.
template <class S>
class InvalSetIterator; // Forward declaration.
template<TEMPLATE_INVALSET_P_DECL> class InvalSet {
template <TEMPLATE_INVALSET_P_DECL>
class InvalSet {
public:
InvalSet();
~InvalSet();
@ -92,11 +96,17 @@ template<TEMPLATE_INVALSET_P_DECL> class InvalSet {
static const size_t kNPreallocatedElements = N_PREALLOCATED_ELEMENTS;
static const KeyType kInvalidKey = INVALID_KEY;
// C++ STL iterator interface.
typedef InvalSetIterator<InvalSet<TEMPLATE_INVALSET_P_DEF> > iterator;
iterator begin();
iterator end();
// It is illegal to insert an element already present in the set.
void insert(const ElementType& element);
// Looks for the specified element in the set and - if found - deletes it.
void erase(const ElementType& element);
// The return value is the number of elements erased: either 0 or 1.
size_t erase(const ElementType& element);
// This indicates the number of (valid) elements stored in this set.
size_t size() const;
@ -108,15 +118,18 @@ template<TEMPLATE_INVALSET_P_DECL> class InvalSet {
void clear();
const ElementType min_element();
const ElementType GetMinElement();
// This returns the key of the minimum element in the set.
KeyType min_element_key();
KeyType GetMinElementKey();
static bool IsValid(const ElementType& element);
static KeyType Key(const ElementType& element);
static KeyType GetKey(const ElementType& element);
static void SetKey(ElementType* element, KeyType key);
typedef ElementType _ElementType;
typedef KeyType _KeyType;
protected:
// Returns a pointer to the element in vector_ if it was found, or NULL
// otherwise.
@ -162,30 +175,30 @@ template<TEMPLATE_INVALSET_P_DECL> class InvalSet {
// Returns the index of the element within the backing storage. The element
// must belong to the backing storage.
size_t ElementIndex(const ElementType* element) const;
size_t GetElementIndex(const ElementType* element) const;
// Returns the element at the specified index in the backing storage.
const ElementType* ElementAt(size_t index) const;
ElementType* ElementAt(size_t index);
const ElementType* GetElementAt(size_t index) const;
ElementType* GetElementAt(size_t index);
static const ElementType* FirstValidElement(const ElementType* from,
const ElementType* end);
static const ElementType* GetFirstValidElement(const ElementType* from,
const ElementType* end);
void CacheMinElement();
const ElementType CachedMinElement() const;
const ElementType GetCachedMinElement() const;
bool ShouldReclaimMemory() const;
void ReclaimMemory();
bool IsUsingVector() const { return vector_ != NULL; }
void set_sorted(bool sorted) { sorted_ = sorted; }
void SetSorted(bool sorted) { sorted_ = sorted; }
// We cache some data commonly required by users to improve performance.
// We cannot cache pointers to elements as we do not control the backing
// storage.
bool valid_cached_min_;
size_t cached_min_index_; // Valid iff `valid_cached_min_` is true.
KeyType cached_min_key_; // Valid iff `valid_cached_min_` is true.
KeyType cached_min_key_; // Valid iff `valid_cached_min_` is true.
// Indicates whether the elements are sorted.
bool sorted_;
@ -215,27 +228,51 @@ template<TEMPLATE_INVALSET_P_DECL> class InvalSet {
}
#endif
private:
// The copy constructor and assignment operator are not used and the defaults
// are unsafe, so disable them (without an implementation).
#if __cplusplus >= 201103L
InvalSet(const InvalSet& other) = delete;
InvalSet operator=(const InvalSet& other) = delete;
#else
InvalSet(const InvalSet& other);
InvalSet operator=(const InvalSet& other);
#endif
friend class InvalSetIterator<InvalSet<TEMPLATE_INVALSET_P_DEF> >;
typedef ElementType _ElementType;
typedef KeyType _KeyType;
};
template<class S> class InvalSetIterator {
template <class S>
class InvalSetIterator : public std::iterator<std::forward_iterator_tag,
typename S::_ElementType> {
private:
// Redefine types to mirror the associated set types.
typedef typename S::_ElementType ElementType;
typedef typename S::_KeyType KeyType;
public:
explicit InvalSetIterator(S* inval_set);
~InvalSetIterator();
explicit InvalSetIterator(S* inval_set = NULL);
ElementType* Current() const;
void Advance();
// This class implements the standard copy-swap idiom.
~InvalSetIterator();
InvalSetIterator(const InvalSetIterator<S>& other);
InvalSetIterator<S>& operator=(InvalSetIterator<S> other);
#if __cplusplus >= 201103L
InvalSetIterator(InvalSetIterator<S>&& other) noexcept;
#endif
friend void swap(InvalSetIterator<S>& a, InvalSetIterator<S>& b) {
using std::swap;
swap(a.using_vector_, b.using_vector_);
swap(a.index_, b.index_);
swap(a.inval_set_, b.inval_set_);
}
// Return true if the iterator is at the end of the set.
bool Done() const;
// Mark this iterator as 'done'.
// Move this iterator to the end of the set.
void Finish();
// Delete the current element and advance the iterator to point to the next
@ -243,45 +280,77 @@ template<class S> class InvalSetIterator {
void DeleteCurrentAndAdvance();
static bool IsValid(const ElementType& element);
static KeyType Key(const ElementType& element);
static KeyType GetKey(const ElementType& element);
// Extra helpers to support the forward-iterator interface.
InvalSetIterator<S>& operator++(); // Pre-increment.
InvalSetIterator<S> operator++(int); // Post-increment.
bool operator==(const InvalSetIterator<S>& rhs) const;
bool operator!=(const InvalSetIterator<S>& rhs) const {
return !(*this == rhs);
}
ElementType& operator*() { return *Current(); }
const ElementType& operator*() const { return *Current(); }
ElementType* operator->() { return Current(); }
const ElementType* operator->() const { return Current(); }
protected:
void MoveToValidElement();
// Indicates if the iterator is looking at the vector or at the preallocated
// elements.
const bool using_vector_;
bool using_vector_;
// Used when looking at the preallocated elements, or in debug mode when using
// the vector to track how many times the iterator has advanced.
size_t index_;
typename std::vector<ElementType>::iterator iterator_;
S* inval_set_;
// TODO: These helpers are deprecated and will be removed in future versions
// of VIXL.
ElementType* Current() const;
void Advance();
};
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
InvalSet<TEMPLATE_INVALSET_P_DEF>::InvalSet()
: valid_cached_min_(false),
sorted_(true), size_(0), vector_(NULL) {
: valid_cached_min_(false), sorted_(true), size_(0), vector_(NULL) {
#ifdef VIXL_DEBUG
monitor_ = 0;
#endif
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
InvalSet<TEMPLATE_INVALSET_P_DEF>::~InvalSet() {
VIXL_ASSERT(monitor_ == 0);
delete vector_;
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
typename InvalSet<TEMPLATE_INVALSET_P_DEF>::iterator
InvalSet<TEMPLATE_INVALSET_P_DEF>::begin() {
return iterator(this);
}
template <TEMPLATE_INVALSET_P_DECL>
typename InvalSet<TEMPLATE_INVALSET_P_DEF>::iterator
InvalSet<TEMPLATE_INVALSET_P_DEF>::end() {
iterator end(this);
end.Finish();
return end;
}
template <TEMPLATE_INVALSET_P_DECL>
void InvalSet<TEMPLATE_INVALSET_P_DEF>::insert(const ElementType& element) {
VIXL_ASSERT(monitor() == 0);
VIXL_ASSERT(IsValid(element));
VIXL_ASSERT(Search(element) == NULL);
set_sorted(empty() || (sorted_ && (element > CleanBack())));
SetSorted(empty() || (sorted_ && (element > CleanBack())));
if (IsUsingVector()) {
vector_->push_back(element);
} else {
@ -289,16 +358,16 @@ void InvalSet<TEMPLATE_INVALSET_P_DEF>::insert(const ElementType& element) {
preallocated_[size_] = element;
} else {
// Transition to using the vector.
vector_ = new std::vector<ElementType>(preallocated_,
preallocated_ + size_);
vector_ =
new std::vector<ElementType>(preallocated_, preallocated_ + size_);
vector_->push_back(element);
}
}
size_++;
if (valid_cached_min_ && (element < min_element())) {
if (valid_cached_min_ && (element < GetMinElement())) {
cached_min_index_ = IsUsingVector() ? vector_->size() - 1 : size_ - 1;
cached_min_key_ = Key(element);
cached_min_key_ = GetKey(element);
valid_cached_min_ = true;
}
@ -308,18 +377,20 @@ void InvalSet<TEMPLATE_INVALSET_P_DEF>::insert(const ElementType& element) {
}
template<TEMPLATE_INVALSET_P_DECL>
void InvalSet<TEMPLATE_INVALSET_P_DEF>::erase(const ElementType& element) {
template <TEMPLATE_INVALSET_P_DECL>
size_t InvalSet<TEMPLATE_INVALSET_P_DEF>::erase(const ElementType& element) {
VIXL_ASSERT(monitor() == 0);
VIXL_ASSERT(IsValid(element));
ElementType* local_element = Search(element);
if (local_element != NULL) {
EraseInternal(local_element);
return 1;
}
return 0;
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::Search(
const ElementType& element) {
VIXL_ASSERT(monitor() == 0);
@ -335,66 +406,66 @@ ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::Search(
if (!valid_cached_min_) {
CacheMinElement();
}
return BinarySearch(element, ElementAt(cached_min_index_), StorageEnd());
return BinarySearch(element, GetElementAt(cached_min_index_), StorageEnd());
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
size_t InvalSet<TEMPLATE_INVALSET_P_DEF>::size() const {
return size_;
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
bool InvalSet<TEMPLATE_INVALSET_P_DEF>::empty() const {
return size_ == 0;
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
void InvalSet<TEMPLATE_INVALSET_P_DEF>::clear() {
VIXL_ASSERT(monitor() == 0);
size_ = 0;
if (IsUsingVector()) {
vector_->clear();
}
set_sorted(true);
SetSorted(true);
valid_cached_min_ = false;
}
template<TEMPLATE_INVALSET_P_DECL>
const ElementType InvalSet<TEMPLATE_INVALSET_P_DEF>::min_element() {
template <TEMPLATE_INVALSET_P_DECL>
const ElementType InvalSet<TEMPLATE_INVALSET_P_DEF>::GetMinElement() {
VIXL_ASSERT(monitor() == 0);
VIXL_ASSERT(!empty());
CacheMinElement();
return *ElementAt(cached_min_index_);
return *GetElementAt(cached_min_index_);
}
template<TEMPLATE_INVALSET_P_DECL>
KeyType InvalSet<TEMPLATE_INVALSET_P_DEF>::min_element_key() {
template <TEMPLATE_INVALSET_P_DECL>
KeyType InvalSet<TEMPLATE_INVALSET_P_DEF>::GetMinElementKey() {
VIXL_ASSERT(monitor() == 0);
if (valid_cached_min_) {
return cached_min_key_;
} else {
return Key(min_element());
return GetKey(GetMinElement());
}
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
bool InvalSet<TEMPLATE_INVALSET_P_DEF>::IsValid(const ElementType& element) {
return Key(element) != kInvalidKey;
return GetKey(element) != kInvalidKey;
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
void InvalSet<TEMPLATE_INVALSET_P_DEF>::EraseInternal(ElementType* element) {
// Note that this function must be safe even while an iterator has acquired
// this set.
VIXL_ASSERT(element != NULL);
size_t deleted_index = ElementIndex(element);
size_t deleted_index = GetElementIndex(element);
if (IsUsingVector()) {
VIXL_ASSERT((&(vector_->front()) <= element) &&
(element <= &(vector_->back())));
@ -408,12 +479,11 @@ void InvalSet<TEMPLATE_INVALSET_P_DEF>::EraseInternal(ElementType* element) {
}
size_--;
if (valid_cached_min_ &&
(deleted_index == cached_min_index_)) {
if (valid_cached_min_ && (deleted_index == cached_min_index_)) {
if (sorted_ && !empty()) {
const ElementType* min = FirstValidElement(element, StorageEnd());
cached_min_index_ = ElementIndex(min);
cached_min_key_ = Key(*min);
const ElementType* min = GetFirstValidElement(element, StorageEnd());
cached_min_index_ = GetElementIndex(min);
cached_min_key_ = GetKey(*min);
valid_cached_min_ = true;
} else {
valid_cached_min_ = false;
@ -422,7 +492,7 @@ void InvalSet<TEMPLATE_INVALSET_P_DEF>::EraseInternal(ElementType* element) {
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::BinarySearch(
const ElementType& element, ElementType* start, ElementType* end) const {
if (start == end) {
@ -443,12 +513,12 @@ ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::BinarySearch(
while (!IsValid(elements[high]) && (low < high)) --high;
VIXL_ASSERT(low <= high);
// Avoid overflow when computing the middle index.
size_t middle = low / 2 + high / 2 + (low & high & 1);
size_t middle = low + (high - low) / 2;
if ((middle == low) || (middle == high)) {
break;
}
while (!IsValid(elements[middle]) && (middle < high - 1)) ++middle;
while (!IsValid(elements[middle]) && (low + 1 < middle)) --middle;
while ((middle < high - 1) && !IsValid(elements[middle])) ++middle;
while ((low + 1 < middle) && !IsValid(elements[middle])) --middle;
if (!IsValid(elements[middle])) {
break;
}
@ -465,14 +535,14 @@ ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::BinarySearch(
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
void InvalSet<TEMPLATE_INVALSET_P_DEF>::Sort(SortType sort_type) {
VIXL_ASSERT(monitor() == 0);
if (sort_type == kSoftSort) {
if (sorted_) {
return;
}
}
VIXL_ASSERT(monitor() == 0);
if (empty()) {
return;
}
@ -480,14 +550,14 @@ void InvalSet<TEMPLATE_INVALSET_P_DEF>::Sort(SortType sort_type) {
Clean();
std::sort(StorageBegin(), StorageEnd());
set_sorted(true);
SetSorted(true);
cached_min_index_ = 0;
cached_min_key_ = Key(Front());
cached_min_key_ = GetKey(Front());
valid_cached_min_ = true;
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
void InvalSet<TEMPLATE_INVALSET_P_DEF>::Clean() {
VIXL_ASSERT(monitor() == 0);
if (empty() || !IsUsingVector()) {
@ -501,17 +571,17 @@ void InvalSet<TEMPLATE_INVALSET_P_DEF>::Clean() {
ElementType* first_valid;
ElementType* next_invalid;
while (c < end && IsValid(*c)) { c++; }
while ((c < end) && IsValid(*c)) c++;
first_invalid = c;
while (c < end) {
while (c < end && !IsValid(*c)) { c++; }
while ((c < end) && !IsValid(*c)) c++;
first_valid = c;
while (c < end && IsValid(*c)) { c++; }
while ((c < end) && IsValid(*c)) c++;
next_invalid = c;
ptrdiff_t n_moved_elements = (next_invalid - first_valid);
memmove(first_invalid, first_valid, n_moved_elements * sizeof(*c));
memmove(first_invalid, first_valid, n_moved_elements * sizeof(*c));
first_invalid = first_invalid + n_moved_elements;
c = next_invalid;
}
@ -523,28 +593,28 @@ void InvalSet<TEMPLATE_INVALSET_P_DEF>::Clean() {
if (sorted_) {
valid_cached_min_ = true;
cached_min_index_ = 0;
cached_min_key_ = Key(*ElementAt(0));
cached_min_key_ = GetKey(*GetElementAt(0));
} else {
valid_cached_min_ = false;
}
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
const ElementType InvalSet<TEMPLATE_INVALSET_P_DEF>::Front() const {
VIXL_ASSERT(!empty());
return IsUsingVector() ? vector_->front() : preallocated_[0];
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
const ElementType InvalSet<TEMPLATE_INVALSET_P_DEF>::Back() const {
VIXL_ASSERT(!empty());
return IsUsingVector() ? vector_->back() : preallocated_[size_ - 1];
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
const ElementType InvalSet<TEMPLATE_INVALSET_P_DEF>::CleanBack() {
VIXL_ASSERT(monitor() == 0);
if (IsUsingVector()) {
@ -559,55 +629,55 @@ const ElementType InvalSet<TEMPLATE_INVALSET_P_DEF>::CleanBack() {
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
const ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::StorageBegin() const {
return IsUsingVector() ? &(vector_->front()) : preallocated_;
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
const ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::StorageEnd() const {
return IsUsingVector() ? &(vector_->back()) + 1 : preallocated_ + size_;
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::StorageBegin() {
return IsUsingVector() ? &(vector_->front()) : preallocated_;
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::StorageEnd() {
return IsUsingVector() ? &(vector_->back()) + 1 : preallocated_ + size_;
}
template<TEMPLATE_INVALSET_P_DECL>
size_t InvalSet<TEMPLATE_INVALSET_P_DEF>::ElementIndex(
template <TEMPLATE_INVALSET_P_DECL>
size_t InvalSet<TEMPLATE_INVALSET_P_DEF>::GetElementIndex(
const ElementType* element) const {
VIXL_ASSERT((StorageBegin() <= element) && (element < StorageEnd()));
return element - StorageBegin();
}
template<TEMPLATE_INVALSET_P_DECL>
const ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::ElementAt(
template <TEMPLATE_INVALSET_P_DECL>
const ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::GetElementAt(
size_t index) const {
VIXL_ASSERT(
(IsUsingVector() && (index < vector_->size())) || (index < size_));
VIXL_ASSERT((IsUsingVector() && (index < vector_->size())) ||
(index < size_));
return StorageBegin() + index;
}
template<TEMPLATE_INVALSET_P_DECL>
ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::ElementAt(size_t index) {
VIXL_ASSERT(
(IsUsingVector() && (index < vector_->size())) || (index < size_));
template <TEMPLATE_INVALSET_P_DECL>
ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::GetElementAt(size_t index) {
VIXL_ASSERT((IsUsingVector() && (index < vector_->size())) ||
(index < size_));
return StorageBegin() + index;
}
template<TEMPLATE_INVALSET_P_DECL>
const ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::FirstValidElement(
template <TEMPLATE_INVALSET_P_DECL>
const ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::GetFirstValidElement(
const ElementType* from, const ElementType* end) {
while ((from < end) && !IsValid(*from)) {
from++;
@ -616,7 +686,7 @@ const ElementType* InvalSet<TEMPLATE_INVALSET_P_DEF>::FirstValidElement(
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
void InvalSet<TEMPLATE_INVALSET_P_DEF>::CacheMinElement() {
VIXL_ASSERT(monitor() == 0);
VIXL_ASSERT(!empty());
@ -626,9 +696,9 @@ void InvalSet<TEMPLATE_INVALSET_P_DEF>::CacheMinElement() {
}
if (sorted_) {
const ElementType* min = FirstValidElement(StorageBegin(), StorageEnd());
cached_min_index_ = ElementIndex(min);
cached_min_key_ = Key(*min);
const ElementType* min = GetFirstValidElement(StorageBegin(), StorageEnd());
cached_min_index_ = GetElementIndex(min);
cached_min_key_ = GetKey(*min);
valid_cached_min_ = true;
} else {
Sort(kHardSort);
@ -637,7 +707,7 @@ void InvalSet<TEMPLATE_INVALSET_P_DEF>::CacheMinElement() {
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
bool InvalSet<TEMPLATE_INVALSET_P_DEF>::ShouldReclaimMemory() const {
if (!IsUsingVector()) {
return false;
@ -648,14 +718,14 @@ bool InvalSet<TEMPLATE_INVALSET_P_DEF>::ShouldReclaimMemory() const {
}
template<TEMPLATE_INVALSET_P_DECL>
template <TEMPLATE_INVALSET_P_DECL>
void InvalSet<TEMPLATE_INVALSET_P_DEF>::ReclaimMemory() {
VIXL_ASSERT(monitor() == 0);
Clean();
}
template<class S>
template <class S>
InvalSetIterator<S>::InvalSetIterator(S* inval_set)
: using_vector_((inval_set != NULL) && inval_set->IsUsingVector()),
index_(0),
@ -674,17 +744,15 @@ InvalSetIterator<S>::InvalSetIterator(S* inval_set)
}
template<class S>
template <class S>
InvalSetIterator<S>::~InvalSetIterator() {
#ifdef VIXL_DEBUG
if (inval_set_ != NULL) {
inval_set_->Release();
}
if (inval_set_ != NULL) inval_set_->Release();
#endif
}
template<class S>
template <class S>
typename S::_ElementType* InvalSetIterator<S>::Current() const {
VIXL_ASSERT(!Done());
if (using_vector_) {
@ -695,22 +763,13 @@ typename S::_ElementType* InvalSetIterator<S>::Current() const {
}
template<class S>
template <class S>
void InvalSetIterator<S>::Advance() {
VIXL_ASSERT(!Done());
if (using_vector_) {
iterator_++;
#ifdef VIXL_DEBUG
index_++;
#endif
MoveToValidElement();
} else {
index_++;
}
++(*this);
}
template<class S>
template <class S>
bool InvalSetIterator<S>::Done() const {
if (using_vector_) {
bool done = (iterator_ == inval_set_->vector_->end());
@ -722,7 +781,7 @@ bool InvalSetIterator<S>::Done() const {
}
template<class S>
template <class S>
void InvalSetIterator<S>::Finish() {
VIXL_ASSERT(inval_set_->sorted_);
if (using_vector_) {
@ -732,7 +791,7 @@ void InvalSetIterator<S>::Finish() {
}
template<class S>
template <class S>
void InvalSetIterator<S>::DeleteCurrentAndAdvance() {
if (using_vector_) {
inval_set_->EraseInternal(&(*iterator_));
@ -743,19 +802,19 @@ void InvalSetIterator<S>::DeleteCurrentAndAdvance() {
}
template<class S>
template <class S>
bool InvalSetIterator<S>::IsValid(const ElementType& element) {
return S::IsValid(element);
}
template<class S>
typename S::_KeyType InvalSetIterator<S>::Key(const ElementType& element) {
return S::Key(element);
template <class S>
typename S::_KeyType InvalSetIterator<S>::GetKey(const ElementType& element) {
return S::GetKey(element);
}
template<class S>
template <class S>
void InvalSetIterator<S>::MoveToValidElement() {
if (using_vector_) {
while ((iterator_ != inval_set_->vector_->end()) && !IsValid(*iterator_)) {
@ -767,6 +826,87 @@ void InvalSetIterator<S>::MoveToValidElement() {
}
}
template <class S>
InvalSetIterator<S>::InvalSetIterator(const InvalSetIterator<S>& other)
: using_vector_(other.using_vector_),
index_(other.index_),
inval_set_(other.inval_set_) {
#ifdef VIXL_DEBUG
if (inval_set_ != NULL) inval_set_->Acquire();
#endif
}
#if __cplusplus >= 201103L
template <class S>
InvalSetIterator<S>::InvalSetIterator(InvalSetIterator<S>&& other) noexcept
: using_vector_(false),
index_(0),
inval_set_(NULL) {
swap(*this, other);
}
#endif
template <class S>
InvalSetIterator<S>& InvalSetIterator<S>::operator=(InvalSetIterator<S> other) {
swap(*this, other);
return *this;
}
template <class S>
bool InvalSetIterator<S>::operator==(const InvalSetIterator<S>& rhs) const {
bool equal = (inval_set_ == rhs.inval_set_);
// If the inval_set_ matches, using_vector_ must also match.
VIXL_ASSERT(!equal || (using_vector_ == rhs.using_vector_));
if (using_vector_) {
equal = equal && (iterator_ == rhs.iterator_);
// In debug mode, index_ is maintained even with using_vector_.
VIXL_ASSERT(!equal || (index_ == rhs.index_));
} else {
equal = equal && (index_ == rhs.index_);
#ifdef DEBUG
// If not using_vector_, iterator_ should be default-initialised.
std::vector<ElementType>::iterator default_iterator;
VIXL_ASSERT(iterator_ == default_iterator);
VIXL_ASSERT(rhs.iterator_ == default_iterator);
#endif
}
return equal;
}
template <class S>
InvalSetIterator<S>& InvalSetIterator<S>::operator++() {
// Pre-increment.
VIXL_ASSERT(!Done());
if (using_vector_) {
iterator_++;
#ifdef VIXL_DEBUG
index_++;
#endif
MoveToValidElement();
} else {
index_++;
}
return *this;
}
template <class S>
InvalSetIterator<S> InvalSetIterator<S>::operator++(int /* unused */) {
// Post-increment.
VIXL_ASSERT(!Done());
InvalSetIterator<S> old(*this);
++(*this);
return old;
}
#undef TEMPLATE_INVALSET_P_DECL
#undef TEMPLATE_INVALSET_P_DEF

View File

@ -59,6 +59,7 @@ inline uint32_t truncate_to_intn(unsigned n, int64_t x) {
return static_cast<uint32_t>(x & ((INT64_C(1) << n) - 1));
}
// clang-format off
#define INT_1_TO_63_LIST(V) \
V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8) \
V(9) V(10) V(11) V(12) V(13) V(14) V(15) V(16) \
@ -68,13 +69,14 @@ V(33) V(34) V(35) V(36) V(37) V(38) V(39) V(40) \
V(41) V(42) V(43) V(44) V(45) V(46) V(47) V(48) \
V(49) V(50) V(51) V(52) V(53) V(54) V(55) V(56) \
V(57) V(58) V(59) V(60) V(61) V(62) V(63)
// clang-format on
#define DECLARE_IS_INT_N(N) \
inline bool is_int##N(int64_t x) { return is_intn(N, x); }
#define DECLARE_IS_UINT_N(N) \
inline bool is_uint##N(int64_t x) { return is_uintn(N, x); }
#define DECLARE_TRUNCATE_TO_INT_N(N) \
inline uint32_t truncate_to_int##N(int x) { return truncate_to_intn(N, x); }
#define DECLARE_IS_INT_N(N) \
inline bool is_int##N(int64_t x) { return is_intn(N, x); }
#define DECLARE_IS_UINT_N(N) \
inline bool is_uint##N(int64_t x) { return is_uintn(N, x); }
#define DECLARE_TRUNCATE_TO_INT_N(N) \
inline uint32_t truncate_to_int##N(int x) { return truncate_to_intn(N, x); }
INT_1_TO_63_LIST(DECLARE_IS_INT_N)
INT_1_TO_63_LIST(DECLARE_IS_UINT_N)
INT_1_TO_63_LIST(DECLARE_TRUNCATE_TO_INT_N)
@ -141,8 +143,7 @@ inline bool IsSignallingNaN(float num) {
inline bool IsSignallingNaN(float16 num) {
const uint16_t kFP16QuietNaNMask = 0x0200;
return (float16classify(num) == FP_NAN) &&
((num & kFP16QuietNaNMask) == 0);
return (float16classify(num) == FP_NAN) && ((num & kFP16QuietNaNMask) == 0);
}
@ -178,19 +179,17 @@ inline float FusedMultiplyAdd(float op1, float op2, float a) {
}
inline uint64_t LowestSetBit(uint64_t value) {
return value & -value;
}
inline uint64_t LowestSetBit(uint64_t value) { return value & -value; }
template<typename T>
template <typename T>
inline int HighestSetBitPosition(T value) {
VIXL_ASSERT(value != 0);
return (sizeof(value) * 8 - 1) - CountLeadingZeros(value);
}
template<typename V>
template <typename V>
inline int WhichPowerOf2(V value) {
VIXL_ASSERT(IsPowerOf2(value));
return CountTrailingZeros(value);
@ -231,9 +230,9 @@ T ReverseBytes(T value, int block_bytes_log2) {
// permute_table[1] is used by REV32_x, REV_w
// permute_table[2] is used by REV_x
VIXL_ASSERT((0 < block_bytes_log2) && (block_bytes_log2 < 4));
static const uint8_t permute_table[3][8] = { {6, 7, 4, 5, 2, 3, 0, 1},
{4, 5, 6, 7, 0, 1, 2, 3},
{0, 1, 2, 3, 4, 5, 6, 7} };
static const uint8_t permute_table[3][8] = {{6, 7, 4, 5, 2, 3, 0, 1},
{4, 5, 6, 7, 0, 1, 2, 3},
{0, 1, 2, 3, 4, 5, 6, 7}};
T result = 0;
for (int i = 0; i < 8; i++) {
result <<= 8;
@ -245,14 +244,14 @@ T ReverseBytes(T value, int block_bytes_log2) {
// Pointer alignment
// TODO: rename/refactor to make it specific to instructions.
template<typename T>
template <typename T>
bool IsWordAligned(T pointer) {
VIXL_ASSERT(sizeof(pointer) == sizeof(intptr_t)); // NOLINT(runtime/sizeof)
return ((intptr_t)(pointer) & 3) == 0;
VIXL_ASSERT(sizeof(pointer) == sizeof(intptr_t)); // NOLINT(runtime/sizeof)
return ((intptr_t)pointer & 3) == 0;
}
// Increment a pointer (up to 64 bits) until it has the specified alignment.
template<class T>
template <class T>
T AlignUp(T pointer, size_t alignment) {
// Use C-style casts to get static_cast behaviour for integral types (T), and
// reinterpret_cast behaviour for other types.
@ -267,7 +266,7 @@ T AlignUp(T pointer, size_t alignment) {
}
// Decrement a pointer (up to 64 bits) until it has the specified alignment.
template<class T>
template <class T>
T AlignDown(T pointer, size_t alignment) {
// Use C-style casts to get static_cast behaviour for integral types (T), and
// reinterpret_cast behaviour for other types.

View File

@ -22007,4 +22007,12 @@ TEST(literal_deletion_policies) {
}
TEST(move_immediate_helpers) {
// Using these helpers to query information (without generating code) should
// not crash.
MacroAssembler::MoveImmediateHelper(NULL, x0, 0x12345678);
MacroAssembler::OneInstrMoveImmediateHelper(NULL, x1, 0xabcdef);
}
} // namespace vixl

View File

@ -26,6 +26,7 @@
#include <stdio.h>
#include <cstring>
#include <string>
#include "test-runner.h"
#include "vixl/a64/macro-assembler-a64.h"
@ -94,19 +95,44 @@
printf("%08" PRIx32 "\t%s\n", encoding, disasm->GetOutput()); \
}
#define COMPARE_MACRO(ASM, EXP) \
#define COMPARE_MACRO_BASE(ASM, EXP) \
masm->Reset(); \
masm->ASM; \
masm->FinalizeCode(); \
decoder->Decode(reinterpret_cast<Instruction*>(buf)); \
encoding = *reinterpret_cast<uint32_t*>(buf); \
if (strncmp(disasm->GetOutput(), EXP, strlen(EXP)) != 0) { \
printf("\nEncoding: %08" PRIx32 "\nExpected: %s\nFound: %s\n", \
encoding, EXP, disasm->GetOutput()); \
abort(); \
} \
if (Test::trace_sim()) { \
printf("%08" PRIx32 "\t%s\n", encoding, disasm->GetOutput()); \
std::string res; \
\
Instruction* instruction = masm->GetOffsetAddress<Instruction*>(0); \
Instruction* end = masm->GetOffsetAddress<Instruction*>( \
masm->SizeOfCodeGenerated()); \
while (instruction != end) { \
decoder->Decode(instruction); \
res.append(disasm->GetOutput()); \
if (Test::trace_sim()) { \
encoding = *reinterpret_cast<uint32_t*>(instruction); \
printf("%08" PRIx32 "\t%s\n", encoding, disasm->GetOutput()); \
} \
instruction += kInstructionSize; \
if (instruction != end) { \
res.append("\n"); \
} \
}
#define COMPARE_MACRO(ASM, EXP) \
{ \
COMPARE_MACRO_BASE(ASM, EXP) \
if (strcmp(res.c_str(), EXP) != 0) { \
printf("Expected: %s\nFound: %s\n", EXP, res.c_str()); \
abort(); \
} \
}
#define COMPARE_MACRO_PREFIX(ASM, EXP) \
{ \
COMPARE_MACRO_BASE(ASM, EXP) \
if (strncmp(res.c_str(), EXP, strlen(EXP)) != 0) { \
printf("Expected (prefix): %s\nFound: %s\n", EXP, res.c_str()); \
abort(); \
} \
}
#define CLEANUP() \
@ -2200,12 +2226,215 @@ TEST(cond_select) {
TEST(cond_select_macro) {
SETUP_MACRO();
// In the tests below we also test the `GetCselSynthesisInformation()` helper.
// These tests are here (rather than in test-assembler-a64.cc) because the
// disassembly makes it easy to see whether or not the inputs are synthesised.
bool synthesises_left = false;
bool synthesises_right = false;
COMPARE(Csel(w0, w1, -1, eq), "csinv w0, w1, wzr, eq");
MacroAssembler::GetCselSynthesisInformation(w0, w1, -1,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE(Csel(w2, w3, 0, ne), "csel w2, w3, wzr, ne");
MacroAssembler::GetCselSynthesisInformation(w2, w3, wzr,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE(Csel(w4, w5, 1, hs), "csinc w4, w5, wzr, hs");
MacroAssembler::GetCselSynthesisInformation(w4, w5, 1,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE(Csel(x6, x7, -1, lo), "csinv x6, x7, xzr, lo");
MacroAssembler::GetCselSynthesisInformation(x6, x7, xzr,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE(Csel(x8, x9, 0, mi), "csel x8, x9, xzr, mi");
MacroAssembler::GetCselSynthesisInformation(x8, x9, xzr,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE(Csel(x10, x11, 1, pl), "csinc x10, x11, xzr, pl");
MacroAssembler::GetCselSynthesisInformation(x10, x11, xzr,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE_MACRO(Csel(x12, 0, 0, eq), "mov x12, #0x0");
MacroAssembler::GetCselSynthesisInformation(x12, 0, 0,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE_MACRO(Csel(w13, 0, 1, eq), "cset w13, eq");
MacroAssembler::GetCselSynthesisInformation(w13, 0, 1,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE_MACRO(Csel(x14, 1, 0, eq), "cset x14, ne");
MacroAssembler::GetCselSynthesisInformation(x14, 1, 0,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE_MACRO(Csel(w15, 0, -1, eq), "csetm w15, eq");
MacroAssembler::GetCselSynthesisInformation(w15, 0, -1,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE_MACRO(Csel(x18, -1, 0, eq), "csetm x18, ne");
MacroAssembler::GetCselSynthesisInformation(x18, -1, 0,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE_MACRO(Csel(w19, -1, 1, eq), "mov w19, #0x1\n"
"cneg w19, w19, eq");
MacroAssembler::GetCselSynthesisInformation(w19, -1, 1,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && synthesises_right);
COMPARE_MACRO(Csel(x20, 1, -1, eq), "mov x20, #0xffffffffffffffff\n"
"cneg x20, x20, eq");
MacroAssembler::GetCselSynthesisInformation(x20, 1, -1,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && synthesises_right);
COMPARE_MACRO(Csel(w21, 0xaa, 0xbb, eq), "mov w16, #0xaa\n"
"mov w17, #0xbb\n"
"csel w21, w16, w17, eq");
MacroAssembler::GetCselSynthesisInformation(w21, 0xaa, 0xbb,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(synthesises_left && synthesises_right);
COMPARE_MACRO(Csel(x22, 0xaa, -0xbb, eq), "mov x16, #0xaa\n"
"mov x17, #0xffffffffffffff45\n"
"csel x22, x16, x17, eq");
MacroAssembler::GetCselSynthesisInformation(x22, 0xaa, -0xbb,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(synthesises_left && synthesises_right);
COMPARE_MACRO(Csel(w23, 0, 0xaa, eq), "mov w16, #0xaa\n"
"csel w23, w16, wzr, ne");
MacroAssembler::GetCselSynthesisInformation(w23, 0, 0xaa,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && synthesises_right);
COMPARE_MACRO(Csel(x24, -0xaa, 0, eq), "mov x16, #0xffffffffffffff56\n"
"csel x24, x16, xzr, eq");
MacroAssembler::GetCselSynthesisInformation(x24, -0xaa, 0,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(synthesises_left && !synthesises_right);
COMPARE_MACRO(Csel(w25, 0xcc, -0xcc, eq), "mov w25, #0xffffff34\n"
"cneg w25, w25, eq");
MacroAssembler::GetCselSynthesisInformation(w25, 0xcc, -0xcc,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && synthesises_right);
COMPARE_MACRO(Csel(x26, -0xcc, 0xcc, eq), "mov x26, #0xcc\n"
"cneg x26, x26, eq");
MacroAssembler::GetCselSynthesisInformation(w25, -0xcc, 0xcc,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && synthesises_right);
// Test with `Operand` inputs.
COMPARE_MACRO(Csel(x0, x1, Operand(x2, LSL, 3), eq), "lsl x16, x2, #3\n"
"csel x0, x1, x16, eq");
MacroAssembler::GetCselSynthesisInformation(x0, x1, Operand(x2, LSL, 3),
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && synthesises_right);
COMPARE_MACRO(Csel(x3, x4, Operand(x5, SXTH), eq), "sxth x16, w5\n"
"csel x3, x4, x16, eq");
MacroAssembler::GetCselSynthesisInformation(x3, x4, Operand(x5, SXTH),
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && synthesises_right);
COMPARE_MACRO(Csel(x6, Operand(x7, LSL, 7), x8, eq), "lsl x16, x7, #7\n"
"csel x6, x16, x8, eq");
MacroAssembler::GetCselSynthesisInformation(x6, Operand(x7, LSL, 7), x8,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(synthesises_left && !synthesises_right);
COMPARE_MACRO(Csel(x9, Operand(x10, SXTH), x11, eq), "sxth x16, w10\n"
"csel x9, x16, x11, eq");
MacroAssembler::GetCselSynthesisInformation(x9, Operand(x10, SXTH), x11,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(synthesises_left && !synthesises_right);
COMPARE_MACRO(Csel(x12, Operand(x13, LSL, 13), Operand(x14, SXTB), eq),
"lsl x16, x13, #13\n"
"sxtb x17, w14\n"
"csel x12, x16, x17, eq");
MacroAssembler::GetCselSynthesisInformation(x12,
Operand(x13, LSL, 13),
Operand(x14, SXTB),
&synthesises_left,
&synthesises_right);
VIXL_CHECK(synthesises_left && synthesises_right);
COMPARE_MACRO(Csel(x15, 0, Operand(x18, LSR, 18), eq),
"lsr x16, x18, #18\n"
"csel x15, x16, xzr, ne");
MacroAssembler::GetCselSynthesisInformation(x15, 0, Operand(x18, LSR, 18),
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && synthesises_right);
// Test with the zero register.
COMPARE_MACRO(Csel(w19, wzr, wzr, eq), "mov w19, #0x0");
MacroAssembler::GetCselSynthesisInformation(w19, wzr, wzr,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE_MACRO(Csel(x20, x21, xzr, eq), "csel x20, x21, xzr, eq");
MacroAssembler::GetCselSynthesisInformation(x20, x21, xzr,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE_MACRO(Csel(w22, wzr, w23, eq), "csel w22, w23, wzr, ne");
MacroAssembler::GetCselSynthesisInformation(w22, wzr, w23,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE_MACRO(Csel(x24, xzr, 0, eq), "mov x24, #0x0");
MacroAssembler::GetCselSynthesisInformation(x24, xzr, 0,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
COMPARE_MACRO(Csel(w25, wzr, 1, eq), "cset w25, eq");
MacroAssembler::GetCselSynthesisInformation(w25, wzr, 1,
&synthesises_left,
&synthesises_right);
VIXL_CHECK(!synthesises_left && !synthesises_right);
CLEANUP();
}
@ -2615,8 +2844,8 @@ TEST(trace) {
VIXL_ASSERT(kTraceOpcode == 0xdeb2);
// All Trace calls should produce the same instruction.
COMPARE_MACRO(Trace(LOG_ALL, TRACE_ENABLE), "hlt #0xdeb2");
COMPARE_MACRO(Trace(LOG_REGS, TRACE_DISABLE), "hlt #0xdeb2");
COMPARE_MACRO_PREFIX(Trace(LOG_ALL, TRACE_ENABLE), "hlt #0xdeb2");
COMPARE_MACRO_PREFIX(Trace(LOG_REGS, TRACE_DISABLE), "hlt #0xdeb2");
CLEANUP();
}
@ -2630,8 +2859,8 @@ TEST(log) {
VIXL_ASSERT(kLogOpcode == 0xdeb3);
// All Log calls should produce the same instruction.
COMPARE_MACRO(Log(LOG_ALL), "hlt #0xdeb3");
COMPARE_MACRO(Log(LOG_SYSREGS), "hlt #0xdeb3");
COMPARE_MACRO_PREFIX(Log(LOG_ALL), "hlt #0xdeb3");
COMPARE_MACRO_PREFIX(Log(LOG_SYSREGS), "hlt #0xdeb3");
CLEANUP();
}
@ -3033,6 +3262,71 @@ TEST(neon_load_store_vector) {
}
TEST(neon_load_store_vector_unallocated) {
SETUP();
const char* expected = "unallocated (NEONLoadStoreMultiStruct)";
// LD[1-4] (multiple structures) (no offset)
COMPARE(dci(0x0c401000), expected); // opcode = 0b0001
COMPARE(dci(0x0c403000), expected); // opcode = 0b0011
COMPARE(dci(0x0c405000), expected); // opcode = 0b0101
COMPARE(dci(0x0c409000), expected); // opcode = 0b1001
COMPARE(dci(0x0c40b000), expected); // opcode = 0b1011
COMPARE(dci(0x0c40c000), expected); // opcode = 0b1100
COMPARE(dci(0x0c40d000), expected); // opcode = 0b1101
COMPARE(dci(0x0c40e000), expected); // opcode = 0b1110
COMPARE(dci(0x0c40f000), expected); // opcode = 0b1111
COMPARE(dci(0x0c400c00), expected); // opcode = 0b0000, size:Q = 0b110
COMPARE(dci(0x0c404c00), expected); // opcode = 0b0100, size:Q = 0b110
COMPARE(dci(0x0c408c00), expected); // opcode = 0b1000, size:Q = 0b110
// ST[1-4] (multiple structures) (no offset)
COMPARE(dci(0x0c001000), expected); // opcode = 0b0001
COMPARE(dci(0x0c003000), expected); // opcode = 0b0011
COMPARE(dci(0x0c005000), expected); // opcode = 0b0101
COMPARE(dci(0x0c009000), expected); // opcode = 0b1001
COMPARE(dci(0x0c00b000), expected); // opcode = 0b1011
COMPARE(dci(0x0c00c000), expected); // opcode = 0b1100
COMPARE(dci(0x0c00d000), expected); // opcode = 0b1101
COMPARE(dci(0x0c00e000), expected); // opcode = 0b1110
COMPARE(dci(0x0c00f000), expected); // opcode = 0b1111
COMPARE(dci(0x0c000c00), expected); // opcode = 0b0000, size:Q = 0b110
COMPARE(dci(0x0c004c00), expected); // opcode = 0b0100, size:Q = 0b110
COMPARE(dci(0x0c008c00), expected); // opcode = 0b1000, size:Q = 0b110
expected = "unallocated (NEONLoadStoreMultiStructPostIndex)";
// LD[1-4] (multiple structures) (post index)
COMPARE(dci(0x0cc01000), expected); // opcode = 0b0001
COMPARE(dci(0x0cc03000), expected); // opcode = 0b0011
COMPARE(dci(0x0cc05000), expected); // opcode = 0b0101
COMPARE(dci(0x0cc09000), expected); // opcode = 0b1001
COMPARE(dci(0x0cc0b000), expected); // opcode = 0b1011
COMPARE(dci(0x0cc0c000), expected); // opcode = 0b1100
COMPARE(dci(0x0cc0d000), expected); // opcode = 0b1101
COMPARE(dci(0x0cc0e000), expected); // opcode = 0b1110
COMPARE(dci(0x0cc0f000), expected); // opcode = 0b1111
COMPARE(dci(0x0cc00c00), expected); // opcode = 0b0000, size:Q = 0b110
COMPARE(dci(0x0cc04c00), expected); // opcode = 0b0100, size:Q = 0b110
COMPARE(dci(0x0cc08c00), expected); // opcode = 0b1000, size:Q = 0b110
// ST[1-4] (multiple structures) (post index)
COMPARE(dci(0x0c801000), expected); // opcode = 0b0001
COMPARE(dci(0x0c803000), expected); // opcode = 0b0011
COMPARE(dci(0x0c805000), expected); // opcode = 0b0101
COMPARE(dci(0x0c809000), expected); // opcode = 0b1001
COMPARE(dci(0x0c80b000), expected); // opcode = 0b1011
COMPARE(dci(0x0c80c000), expected); // opcode = 0b1100
COMPARE(dci(0x0c80d000), expected); // opcode = 0b1101
COMPARE(dci(0x0c80e000), expected); // opcode = 0b1110
COMPARE(dci(0x0c80f000), expected); // opcode = 0b1111
COMPARE(dci(0x0c800c00), expected); // opcode = 0b0000, size:Q = 0b110
COMPARE(dci(0x0c804c00), expected); // opcode = 0b0100, size:Q = 0b110
COMPARE(dci(0x0c808c00), expected); // opcode = 0b1000, size:Q = 0b110
CLEANUP();
}
TEST(neon_load_store_lane) {
SETUP_MACRO();
@ -3077,8 +3371,12 @@ TEST(neon_load_store_lane) {
"ld1 {v11.s}[1], [x26], #4");
COMPARE(Ld1(v12.S(), 3, MemOperand(x27, x5, PostIndex)),
"ld1 {v12.s}[3], [x27], x5");
COMPARE(Ld1(v12.S(), 3, MemOperand(x27, 4, PostIndex)),
"ld1 {v12.s}[3], [x27], #4");
COMPARE(Ld1(v13.D(), 1, MemOperand(sp, x6, PostIndex)),
"ld1 {v13.d}[1], [sp], x6");
COMPARE(Ld1(v13.D(), 1, MemOperand(sp, 8, PostIndex)),
"ld1 {v13.d}[1], [sp], #8");
COMPARE(Ld2(v0.V8B(), v1.V8B(), 0, MemOperand(x15)),
"ld2 {v0.b, v1.b}[0], [x15]");
@ -3135,8 +3433,12 @@ TEST(neon_load_store_lane) {
"ld2 {v11.s, v12.s}[1], [x26], #8");
COMPARE(Ld2(v12.S(), v13.S(), 3, MemOperand(x27, x5, PostIndex)),
"ld2 {v12.s, v13.s}[3], [x27], x5");
COMPARE(Ld2(v11.S(), v12.S(), 3, MemOperand(x26, 8, PostIndex)),
"ld2 {v11.s, v12.s}[3], [x26], #8");
COMPARE(Ld2(v13.D(), v14.D(), 1, MemOperand(sp, x6, PostIndex)),
"ld2 {v13.d, v14.d}[1], [sp], x6");
COMPARE(Ld2(v13.D(), v14.D(), 1, MemOperand(sp, 16, PostIndex)),
"ld2 {v13.d, v14.d}[1], [sp], #16");
COMPARE(Ld3(v0.V8B(), v1.V8B(), v2.V8B(), 0, MemOperand(x15)),
"ld3 {v0.b, v1.b, v2.b}[0], [x15]");
@ -3206,9 +3508,15 @@ TEST(neon_load_store_lane) {
COMPARE(Ld3(v12.S(), v13.S(), v14.S(), 3,
MemOperand(x27, x5, PostIndex)),
"ld3 {v12.s, v13.s, v14.s}[3], [x27], x5");
COMPARE(Ld3(v12.S(), v13.S(), v14.S(), 3,
MemOperand(x27, 12, PostIndex)),
"ld3 {v12.s, v13.s, v14.s}[3], [x27], #12");
COMPARE(Ld3(v13.D(), v14.D(), v15.D(), 1,
MemOperand(sp, x6, PostIndex)),
"ld3 {v13.d, v14.d, v15.d}[1], [sp], x6");
COMPARE(Ld3(v13.D(), v14.D(), v15.D(), 1,
MemOperand(sp, 24, PostIndex)),
"ld3 {v13.d, v14.d, v15.d}[1], [sp], #24");
COMPARE(Ld4(v0.V8B(), v1.V8B(), v2.V8B(), v3.V8B(), 0,
MemOperand(x15)),
@ -3292,9 +3600,15 @@ TEST(neon_load_store_lane) {
COMPARE(Ld4(v12.S(), v13.S(), v14.S(), v15.S(), 3,
MemOperand(x27, x5, PostIndex)),
"ld4 {v12.s, v13.s, v14.s, v15.s}[3], [x27], x5");
COMPARE(Ld4(v11.S(), v12.S(), v13.S(), v14.S(), 3,
MemOperand(x26, 16, PostIndex)),
"ld4 {v11.s, v12.s, v13.s, v14.s}[3], [x26], #16");
COMPARE(Ld4(v13.D(), v14.D(), v15.D(), v16.D(), 1,
MemOperand(sp, x6, PostIndex)),
"ld4 {v13.d, v14.d, v15.d, v16.d}[1], [sp], x6");
COMPARE(Ld4(v13.D(), v14.D(), v15.D(), v16.D(), 1,
MemOperand(sp, 32, PostIndex)),
"ld4 {v13.d, v14.d, v15.d, v16.d}[1], [sp], #32");
COMPARE(St1(v0.V8B(), 0, MemOperand(x15)), "st1 {v0.b}[0], [x15]");
COMPARE(St1(v1.V16B(), 1, MemOperand(x16)), "st1 {v1.b}[1], [x16]");
@ -3429,6 +3743,81 @@ TEST(neon_load_store_lane) {
}
TEST(neon_load_store_lane_unallocated) {
SETUP();
const char* expected = "unallocated (NEONLoadStoreSingleStruct)";
// LD1 (single structure) (no offset)
COMPARE(dci(0x0d404400), expected); // .h, size<0> = 1
COMPARE(dci(0x0d408800), expected); // .s, size<1> = 1
COMPARE(dci(0x0d409400), expected); // .d, size<0> = 1, S = 1
// LD2 (single structure) (no offset)
COMPARE(dci(0x0d604400), expected); // .h, size<0> = 1
COMPARE(dci(0x0d608800), expected); // .s, size<1> = 1
COMPARE(dci(0x0d609400), expected); // .d, size<0> = 1, S = 1
// LD3 (single structure) (no offset)
COMPARE(dci(0x0d406400), expected); // .h, size<0> = 1
COMPARE(dci(0x0d40a800), expected); // .s, size<1> = 1
COMPARE(dci(0x0d40b400), expected); // .d, size<0> = 1, S = 1
// LD4 (single structure) (no offset)
COMPARE(dci(0x0d606400), expected); // .h, size<0> = 1
COMPARE(dci(0x0d60a800), expected); // .s, size<1> = 1
COMPARE(dci(0x0d60b400), expected); // .d, size<0> = 1, S = 1
// ST1 (single structure) (no offset)
COMPARE(dci(0x0d004400), expected); // .h, size<0> = 1
COMPARE(dci(0x0d008800), expected); // .s, size<1> = 1
COMPARE(dci(0x0d009400), expected); // .d, size<0> = 1, S = 1
// ST2 (single structure) (no offset)
COMPARE(dci(0x0d204400), expected); // .h, size<0> = 1
COMPARE(dci(0x0d208800), expected); // .s, size<1> = 1
COMPARE(dci(0x0d209400), expected); // .d, size<0> = 1, S = 1
// ST3 (single structure) (no offset)
COMPARE(dci(0x0d006400), expected); // .h, size<0> = 1
COMPARE(dci(0x0d00a800), expected); // .s, size<1> = 1
COMPARE(dci(0x0d00b400), expected); // .d, size<0> = 1, S = 1
// ST4 (single structure) (no offset)
COMPARE(dci(0x0d206400), expected); // .h, size<0> = 1
COMPARE(dci(0x0d20a800), expected); // .s, size<1> = 1
COMPARE(dci(0x0d20b400), expected); // .d, size<0> = 1, S = 1
expected = "unallocated (NEONLoadStoreSingleStructPostIndex)";
// LD1 (single structure) (post index)
COMPARE(dci(0x0dc04400), expected); // .h, size<0> = 1
COMPARE(dci(0x0dc08800), expected); // .s, size<1> = 1
COMPARE(dci(0x0dc09400), expected); // .d, size<0> = 1, S = 1
// LD2 (single structure) (post index)
COMPARE(dci(0x0de04400), expected); // .h, size<0> = 1
COMPARE(dci(0x0de08800), expected); // .s, size<1> = 1
COMPARE(dci(0x0de09400), expected); // .d, size<0> = 1, S = 1
// LD3 (single structure) (post index)
COMPARE(dci(0x0dc06400), expected); // .h, size<0> = 1
COMPARE(dci(0x0dc0a800), expected); // .s, size<1> = 1
COMPARE(dci(0x0dc0b400), expected); // .d, size<0> = 1, S = 1
// LD4 (single structure) (post index)
COMPARE(dci(0x0de06400), expected); // .h, size<0> = 1
COMPARE(dci(0x0de0a800), expected); // .s, size<1> = 1
COMPARE(dci(0x0de0b400), expected); // .d, size<0> = 1, S = 1
// ST1 (single structure) (post index)
COMPARE(dci(0x0d804400), expected); // .h, size<0> = 1
COMPARE(dci(0x0d808800), expected); // .s, size<1> = 1
COMPARE(dci(0x0d809400), expected); // .d, size<0> = 1, S = 1
// ST2 (single structure) (post index)
COMPARE(dci(0x0da04400), expected); // .h, size<0> = 1
COMPARE(dci(0x0da08800), expected); // .s, size<1> = 1
COMPARE(dci(0x0da09400), expected); // .d, size<0> = 1, S = 1
// ST3 (single structure) (post index)
COMPARE(dci(0x0d806400), expected); // .h, size<0> = 1
COMPARE(dci(0x0d80a800), expected); // .s, size<1> = 1
COMPARE(dci(0x0d80b400), expected); // .d, size<0> = 1, S = 1
// ST4 (single structure) (post index)
COMPARE(dci(0x0da06400), expected); // .h, size<0> = 1
COMPARE(dci(0x0da0a800), expected); // .s, size<1> = 1
COMPARE(dci(0x0da0b400), expected); // .d, size<0> = 1, S = 1
CLEANUP();
}
TEST(neon_load_all_lanes) {
SETUP_MACRO();
@ -3577,6 +3966,41 @@ TEST(neon_load_all_lanes) {
}
TEST(neon_load_all_lanes_unallocated) {
SETUP();
const char* expected = "unallocated (NEONLoadStoreSingleStruct)";
// LD1R (single structure) (no offset)
COMPARE(dci(0x0d00c000), expected); // L = 0
COMPARE(dci(0x0d40d000), expected); // S = 1
// LD2R (single structure) (no offset)
COMPARE(dci(0x0d20c000), expected); // L = 0
COMPARE(dci(0x0d60d000), expected); // S = 1
// LD3R (single structure) (no offset)
COMPARE(dci(0x0d00e000), expected); // L = 0
COMPARE(dci(0x0d40f000), expected); // S = 1
// LD4R (single structure) (no offset)
COMPARE(dci(0x0d20e000), expected); // L = 0
COMPARE(dci(0x0d60f000), expected); // S = 1
expected = "unallocated (NEONLoadStoreSingleStructPostIndex)";
// LD1R (single structure) (post index)
COMPARE(dci(0x0d80c000), expected); // L = 0
COMPARE(dci(0x0dc0d000), expected); // S = 1
// LD2R (single structure) (post index)
COMPARE(dci(0x0da0c000), expected); // L = 0
COMPARE(dci(0x0de0d000), expected); // S = 1
// LD3R (single structure) (post index)
COMPARE(dci(0x0d80e000), expected); // L = 0
COMPARE(dci(0x0dc0f000), expected); // S = 1
// LD4R (single structure) (post index)
COMPARE(dci(0x0da0e000), expected); // L = 0
COMPARE(dci(0x0de0f000), expected); // S = 1
CLEANUP();
}
TEST(neon_3same) {
SETUP_MACRO();
@ -4697,6 +5121,9 @@ TEST(neon_modimm) {
COMPARE(Fmov(v1.V2D(), 1.0), "fmov v1.2d, #0x70 (1.0000)");
COMPARE(Fmov(v29.V2D(), -13.0), "fmov v29.2d, #0xaa (-13.0000)");
// An unallocated form of fmov.
COMPARE(dci(0x2f07ffff), "unallocated (NEONModifiedImmediate)");
CLEANUP();
}
@ -4711,6 +5138,11 @@ TEST(neon_2regmisc) {
COMPARE(Shll2(v4.V4S(), v2.V8H(), 16), "shll2 v4.4s, v2.8h, #16");
COMPARE(Shll2(v6.V2D(), v4.V4S(), 32), "shll2 v6.2d, v4.4s, #32");
// An unallocated form of shll.
COMPARE(dci(0x2ee13bff), "unallocated (NEON2RegMisc)");
// An unallocated form of shll2.
COMPARE(dci(0x6ee13bff), "unallocated (NEON2RegMisc)");
#define DISASM_INST(M, S) \
COMPARE(Cmeq(v0.M, v1.M, 0), "cmeq v0." S ", v1." S ", #0");
NEON_FORMAT_LIST(DISASM_INST)

View File

@ -80,7 +80,7 @@ inline KeyType InvalSet<Obj,
KeyType,
kInvalidKey,
kReclaimFrom,
kReclaimFactor>::Key(const Obj& obj) {
kReclaimFactor>::GetKey(const Obj& obj) {
return obj.key_;
}
template<>
@ -106,10 +106,10 @@ TEST(basic_test) {
set.insert(Obj(-123, 456));
set.insert(Obj(2718, 2871828));
VIXL_CHECK(set.size() == kNPreallocatedElements + 2);
VIXL_CHECK(set.min_element() == Obj(-123, 456));
VIXL_CHECK(set.GetMinElement() == Obj(-123, 456));
set.erase(Obj(-123, 456));
VIXL_CHECK(set.min_element_key() == 0);
VIXL_CHECK(set.GetMinElementKey() == 0);
set.clear();
VIXL_CHECK(set.empty() && (set.size() == 0));
@ -168,7 +168,7 @@ TEST(erase) {
set.erase(Obj(100, -1));
VIXL_CHECK(set.size() == max_size - 1);
for (size_t i = 2; i <= max_size; i++) {
set.erase(set.min_element());
set.erase(set.GetMinElement());
VIXL_CHECK(set.size() == max_size - i);
}
@ -186,9 +186,9 @@ TEST(min) {
set.insert(Obj(-1, 0));
set.insert(Obj(0, 0));
set.insert(Obj(1, 0));
VIXL_CHECK(set.min_element() == Obj(-1, -1));
VIXL_CHECK(set.min_element_key() == -1);
VIXL_CHECK(set.min_element().key_ == set.min_element_key());
VIXL_CHECK(set.GetMinElement() == Obj(-1, -1));
VIXL_CHECK(set.GetMinElementKey() == -1);
VIXL_CHECK(set.GetMinElement().key_ == set.GetMinElementKey());
// Test with more elements.
set.clear();
@ -198,13 +198,13 @@ TEST(min) {
int sign = ((i % 2) == 0) ? -1 : 1;
set.insert(Obj(sign * i, i));
}
VIXL_CHECK(set.min_element() == Obj(-max_index, max_index));
VIXL_CHECK(set.min_element().key_ == set.min_element_key());
VIXL_CHECK(set.GetMinElement() == Obj(-max_index, max_index));
VIXL_CHECK(set.GetMinElement().key_ == set.GetMinElementKey());
set.erase(Obj(0, 0));
VIXL_CHECK(set.min_element() == Obj(-max_index, max_index));
set.erase(set.min_element());
VIXL_CHECK(set.min_element() == Obj(-(max_index - 2), max_index - 2));
VIXL_CHECK(set.GetMinElement() == Obj(-max_index, max_index));
set.erase(set.GetMinElement());
VIXL_CHECK(set.GetMinElement() == Obj(-(max_index - 2), max_index - 2));
set.clear();
VIXL_CHECK(set.empty() && (set.size() == 0));
@ -215,37 +215,191 @@ TEST(iterator) {
TestSet set;
VIXL_CHECK(set.empty() && (set.size() == 0));
// Ensure that set.begin() == set.end() for the empty set.
VIXL_CHECK(set.begin() == set.end());
// Test with only preallocated elements in the set.
size_t expected_total = 0;
for (unsigned i = 0; i < kNPreallocatedElements; i++) {
set.insert(Obj(i, i));
expected_total += i;
}
size_t size = 0;
for (InvalSetIterator<TestSet> it(&set); !it.Done(); it.Advance()) {
size_t total = 0;
for (InvalSetIterator<TestSet> it = set.begin(); it != set.end(); ++it) {
total += it->val_;
size++;
}
VIXL_CHECK(size == set.size());
VIXL_CHECK(total == expected_total);
// Test with more elements.
for (unsigned i = kNPreallocatedElements;
i < 4 * kNPreallocatedElements;
i++) {
set.insert(Obj(i, i));
expected_total += i;
}
size = 0;
for (InvalSetIterator<TestSet> it(&set); !it.Done(); it.Advance()) {
total = 0;
for (InvalSetIterator<TestSet> it = set.begin(); it != set.end(); ++it) {
total += it->val_;
size++;
}
VIXL_CHECK(size == set.size());
VIXL_CHECK(total == expected_total);
// Test after an element has been deleted.
size = 0;
set.erase(Obj(0, 0));
for (InvalSetIterator<TestSet> it(&set); !it.Done(); it.Advance()) {
size++;
// Test after elements have been deleted.
// - Select an interesting list of elements to erase.
std::vector<Obj> to_erase;
unsigned step = 0;
for (unsigned i = 0; i < set.size(); i += step, step++) {
to_erase.push_back(Obj(i, i));
}
to_erase.push_back(Obj(set.size() - 1, set.size() - 1)); // The last element.
to_erase.push_back(Obj(set.size(), set.size())); // Not in the set.
// - Erase one at a time, retesting after each one.
while (!to_erase.empty()) {
size_t erased = set.erase(to_erase.back());
if (erased > 0) {
VIXL_CHECK(erased == 1);
expected_total -= to_erase.back().val_;
} else {
}
to_erase.pop_back();
size = 0;
total = 0;
for (InvalSetIterator<TestSet> it = set.begin(); it != set.end(); ++it) {
total += it->val_;
size++;
}
VIXL_CHECK(size == set.size());
VIXL_CHECK(total == expected_total);
}
VIXL_CHECK(size == set.size());
}
#if __cplusplus >= 201103L
TEST(iterator_cxx11) {
TestSet set;
VIXL_CHECK(set.empty() && (set.size() == 0));
// Test with only preallocated elements in the set.
size_t expected_total = 0;
for (unsigned i = 0; i < kNPreallocatedElements; i++) {
set.insert(Obj(i, i));
expected_total += i;
}
size_t size = 0;
size_t total = 0;
for (auto object : set) {
total += object.val_;
size++;
}
VIXL_CHECK(size == set.size());
VIXL_CHECK(total == expected_total);
// Test with more elements.
for (unsigned i = kNPreallocatedElements;
i < 4 * kNPreallocatedElements;
i++) {
set.insert(Obj(i, i));
expected_total += i;
}
size = 0;
total = 0;
for (auto object : set) {
total += object.val_;
size++;
}
VIXL_CHECK(size == set.size());
VIXL_CHECK(total == expected_total);
// Test after elements have been deleted.
// - Select an interesting list of elements to erase.
std::vector<Obj> to_erase;
unsigned step = 0;
for (unsigned i = 0; i < set.size(); i += step, step++) {
to_erase.push_back(Obj(i, i));
}
to_erase.push_back(Obj(set.size() - 1, set.size() - 1)); // The last element.
to_erase.push_back(Obj(set.size(), set.size())); // Not in the set.
// - Erase one at a time, retesting after each one.
while (!to_erase.empty()) {
size_t erased = set.erase(to_erase.back());
if (erased > 0) {
VIXL_CHECK(erased == 1);
expected_total -= to_erase.back().val_;
} else {
}
to_erase.pop_back();
size = 0;
total = 0;
for (auto object : set) {
total += object.val_;
size++;
}
VIXL_CHECK(size == set.size());
VIXL_CHECK(total == expected_total);
}
}
#endif
TEST(stl_forward_iterator) {
{
TestSet::iterator default_it; // Default-constructible.
TestSet::iterator copy_it(default_it); // Copy-constructible.
copy_it = default_it; // Copy-assignable.
} // Destructible.
TestSet set1;
VIXL_CHECK(set1.empty() && (set1.size() == 0));
TestSet set2;
VIXL_CHECK(set2.empty() && (set2.size() == 0));
// Test with only preallocated elements in the set.
for (unsigned i = 0; i < kNPreallocatedElements; i++) {
set1.insert(Obj(i, 1));
set2.insert(Obj(i, 2));
}
TestSet::iterator it1_a = set1.begin();
TestSet::iterator it1_b = set1.begin();
// Incrementable (whilst valid).
it1_a++;
++it1_b;
// Testable for equivalence.
VIXL_CHECK(it1_a == it1_b);
VIXL_CHECK(set1.begin() != set1.end());
VIXL_CHECK(set2.begin() != set2.end());
VIXL_CHECK(set1.begin() != set2.begin());
VIXL_CHECK(set1.end() != set2.end());
// Dereferencable.
VIXL_CHECK((*it1_a++).key_ == 1);
VIXL_CHECK(((*it1_a).key_ == 2) && ((*it1_a).val_ == 1));
*it1_b = Obj(42, 1);
VIXL_CHECK((it1_b->key_ == 42) && (it1_b->val_ == 1));
#if __cplusplus >= 201103L
// Swappable.
std::swap(it1_a, it1_b);
VIXL_CHECK(it1_a->key_ == 42);
VIXL_CHECK(it1_b->key_ == 2);
#endif
}
} // namespace vixl

View File

@ -47,8 +47,8 @@ bool vixl::Test::coloured_trace_ = false;
// No instruction statistics by default.
bool vixl::Test::instruction_stats_ = false;
// Don't generate simulator test traces by default.
bool vixl::Test::sim_test_trace_ = false;
// Don't generate traces by default.
bool vixl::Test::generate_test_trace_ = false;
// Instantiate a Test and append it to the linked list.
vixl::Test::Test(const char* name, TestFunction* callback)
@ -96,18 +96,20 @@ static void NormalizeOption(char * arg) {
static void PrintHelpMessage() {
printf("Usage: ./test [options] [test names]\n"
"Run all tests specified on the command line.\n"
"--help Print this help message.\n"
"--list List all available tests.\n"
"--run_all Run all available tests.\n"
"--debugger Run in the debugger.\n"
"--trace_all Enable all trace options, plus --coloured_trace.\n"
"--trace_sim Generate a trace of simulated instructions, as\n"
" well as disassembly from the DISASM tests.\n"
"--trace_reg Generate a trace of simulated registers.\n"
"--trace_write Generate a trace of memory writes.\n"
"--coloured_trace Generate coloured trace.\n"
"--instruction_stats Log instruction statistics to vixl_stats.csv.\n"
"--sim_test_trace Print result traces for SIM_* tests.\n");
"--help Print this help message.\n"
"--list List all available tests.\n"
"--run_all Run all available tests.\n"
"--debugger Run in the debugger.\n"
"--trace_all "
"Enable all trace options, plus --coloured_trace.\n"
"--trace_sim Generate a trace of simulated instructions, as\n"
" well as disassembly from the DISASM tests.\n"
"--trace_reg Generate a trace of simulated registers.\n"
"--trace_write Generate a trace of memory writes.\n"
"--coloured_trace Generate coloured trace.\n"
"--instruction_stats Log instruction statistics to vixl_stats.csv.\n"
"--generate_test_trace "
"Print result traces for SIM_* and TRACE_* tests.\n");
}
int main(int argc, char* argv[]) {
@ -157,8 +159,8 @@ int main(int argc, char* argv[]) {
vixl::Test::set_instruction_stats(true);
}
if (IsInArgs("--sim-test-trace", argc, argv)) {
vixl::Test::set_sim_test_trace(true);
if (IsInArgs("--generate-test-trace", argc, argv)) {
vixl::Test::set_generate_test_trace(true);
}
// Basic (mutually-exclusive) operations.

View File

@ -56,8 +56,10 @@ class Test {
static void set_coloured_trace(bool value) { coloured_trace_ = value; }
static bool instruction_stats() { return instruction_stats_; }
static void set_instruction_stats(bool value) { instruction_stats_ = value; }
static bool sim_test_trace() { return sim_test_trace_; }
static void set_sim_test_trace(bool value) { sim_test_trace_ = value; }
static bool generate_test_trace() { return generate_test_trace_; }
static void set_generate_test_trace(bool value) {
generate_test_trace_ = value;
}
// The debugger is needed to trace register values.
static bool run_debugger() { return debug_; }
@ -75,7 +77,7 @@ class Test {
static bool trace_write_;
static bool coloured_trace_;
static bool instruction_stats_;
static bool sim_test_trace_;
static bool generate_test_trace_;
};
// Define helper macros for test files.

View File

@ -40,11 +40,12 @@ namespace vixl {
//
// These simulator tests check instruction behaviour against a trace taken from
// real AArch64 hardware. The same test code is used to generate the trace; the
// results are printed to stdout when the test is run with --sim_test_trace.
// results are printed to stdout when the test is run with
// --generate_test_trace.
//
// The input lists and expected results are stored in test/traces. The expected
// results can be regenerated using tools/generate_simulator_traces.py. Adding
// a test for a new instruction is described at the top of
// results can be regenerated using tools/generate_simulator_traces.py. Adding a
// test for a new instruction is described at the top of
// test-simulator-traces-a64.h.
#define __ masm.
@ -261,7 +262,7 @@ static void Test1Op(const char * name, Test1OpFPHelper_t helper,
Test1Op_Helper(helper, reinterpret_cast<uintptr_t>(inputs), inputs_length,
reinterpret_cast<uintptr_t>(results), d_bits, n_bits);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const uint%u_t kExpected_%s[] = {\n", d_bits, name);
for (unsigned d = 0; d < results_length; d++) {
@ -375,7 +376,7 @@ static void Test2Op(const char * name, Test2OpFPHelper_t helper,
Test2Op_Helper(helper, reinterpret_cast<uintptr_t>(inputs), inputs_length,
reinterpret_cast<uintptr_t>(results), bits);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const uint%u_t kExpected_%s[] = {\n", bits, name);
for (unsigned d = 0; d < results_length; d++) {
@ -505,7 +506,7 @@ static void Test3Op(const char * name, Test3OpFPHelper_t helper,
Test3Op_Helper(helper, reinterpret_cast<uintptr_t>(inputs), inputs_length,
reinterpret_cast<uintptr_t>(results), bits);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const uint%u_t kExpected_%s[] = {\n", bits, name);
for (unsigned d = 0; d < results_length; d++) {
@ -632,7 +633,7 @@ static void TestCmp(const char * name, TestFPCmpHelper_t helper,
TestCmp_Helper(helper, reinterpret_cast<uintptr_t>(inputs), inputs_length,
reinterpret_cast<uintptr_t>(results), bits);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const uint8_t kExpected_%s[] = {\n", name);
for (unsigned d = 0; d < results_length; d++) {
@ -751,7 +752,7 @@ static void TestCmpZero(const char * name, TestFPCmpZeroHelper_t helper,
TestCmpZero_Helper(helper, reinterpret_cast<uintptr_t>(inputs), inputs_length,
reinterpret_cast<uintptr_t>(results), bits);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const uint8_t kExpected_%s[] = {\n", name);
for (unsigned d = 0; d < results_length; d++) {
@ -918,7 +919,7 @@ static void TestFPToS(const char * name, TestFPToIntHelper_t helper,
TestFPToInt_Helper(helper, reinterpret_cast<uintptr_t>(inputs), inputs_length,
reinterpret_cast<uintptr_t>(results), d_bits, n_bits);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const int%u_t kExpected_%s[] = {\n", d_bits, name);
// There is no simple C++ literal for INT*_MIN that doesn't produce
@ -996,7 +997,7 @@ static void TestFPToU(const char * name, TestFPToIntHelper_t helper,
reinterpret_cast<uintptr_t>(inputs), inputs_length,
reinterpret_cast<uintptr_t>(results), d_bits, n_bits);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const uint%u_t kExpected_%s[] = {\n", d_bits, name);
for (unsigned d = 0; d < results_length; d++) {
@ -1056,7 +1057,7 @@ static void TestFPToFixedS(const char * name, TestFPToFixedHelper_t helper,
reinterpret_cast<uintptr_t>(inputs), inputs_length,
reinterpret_cast<uintptr_t>(results), d_bits, n_bits);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const int%u_t kExpected_%s[] = {\n", d_bits, name);
// There is no simple C++ literal for INT*_MIN that doesn't produce
@ -1136,7 +1137,7 @@ static void TestFPToFixedU(const char * name, TestFPToFixedHelper_t helper,
reinterpret_cast<uintptr_t>(inputs), inputs_length,
reinterpret_cast<uintptr_t>(results), d_bits, n_bits);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const uint%u_t kExpected_%s[] = {\n", d_bits, name);
for (unsigned d = 0; d < results_length; d++) {
@ -1286,7 +1287,7 @@ static void Test1OpNEON(const char * name, Test1OpNEONHelper_t helper,
reinterpret_cast<uintptr_t>(results),
vd_form, vn_form);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const uint%u_t kExpected_NEON_%s[] = {\n", lane_bit, name);
for (unsigned iteration = 0; iteration < results_length; iteration++) {
@ -1477,7 +1478,7 @@ static void Test1OpAcrossNEON(const char * name, Test1OpNEONHelper_t helper,
reinterpret_cast<uintptr_t>(results),
vd_form, vn_form);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const uint%u_t kExpected_NEON_%s[] = {\n", lane_bit, name);
for (unsigned iteration = 0; iteration < results_length; iteration++) {
@ -1708,7 +1709,7 @@ static void Test2OpNEON(const char * name, Test2OpNEONHelper_t helper,
reinterpret_cast<uintptr_t>(results),
vd_form, vn_form, vm_form);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const uint%u_t kExpected_NEON_%s[] = {\n", lane_bit, name);
for (unsigned iteration = 0; iteration < results_length; iteration++) {
@ -1945,7 +1946,7 @@ static void TestByElementNEON(const char *name,
reinterpret_cast<uintptr_t>(results),
vd_form, vn_form, vm_form);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const uint%u_t kExpected_NEON_%s[] = {\n", lane_bit, name);
for (unsigned iteration = 0; iteration < results_length; iteration++) {
@ -2155,7 +2156,7 @@ static void Test2OpImmNEON(
reinterpret_cast<uintptr_t>(results),
vd_form, vn_form);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const uint%u_t kExpected_NEON_%s[] = {\n", lane_bit, name);
for (unsigned iteration = 0; iteration < results_length; iteration++) {
@ -2374,7 +2375,7 @@ static void TestOpImmOpImmNEON(const char * name,
reinterpret_cast<uintptr_t>(results),
vd_form, vn_form);
if (Test::sim_test_trace()) {
if (Test::generate_test_trace()) {
// Print the results.
printf("const uint%u_t kExpected_NEON_%s[] = {\n", lane_bit, name);
for (unsigned iteration = 0; iteration < results_length; iteration++) {

2701
test/test-trace-a64.cc Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

View File

@ -0,0 +1,739 @@
# x0: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x2: 0x~~~~~~~~~~~~~~~~
# x3: 0x0300003000300303
# x4: 0x0400004000400404
# x5: 0x0500005000500505
# x6: 0x0600006000600606
# x7: 0x0700007000700707
# x8: 0x0800008000800808
# x9: 0x0900009000900909
# x10: 0x0a0000a000a00a0a
# x11: 0x0b0000b000b00b0b
# x12: 0x0c0000c000c00c0c
# x13: 0x0d0000d000d00d0d
# x14: 0x0e0000e000e00e0e
# x15: 0x0f0000f000f00f0f
# x16: 0x1000010001001010
# x17: 0x1100011001101111
# x18: 0x1200012001201212
# x19: 0x1300013001301313
# x20: 0x1400014001401414
# x21: 0x1500015001501515
# x22: 0x1600016001601616
# x23: 0x1700017001701717
# x24: 0x1800018001801818
# x25: 0x1900019001901919
# x26: 0x1a0001a001a01a1a
# x27: 0x1b0001b001b01b1b
# x28: 0x1c0001c001c01c1c
# x29: 0x1d0001d001d01d1d
# lr: 0x0000000000000000
# sp: 0x~~~~~~~~~~~~~~~~
# x3: 0x0000000000900909
# x6: 0x0f0000f000f00f0f
# x9: 0x0000000001501515
# x12: 0x1b0001b001b01b1b
# x15: 0x0000000002102121
# x18: 0x2700027002702727
# x21: 0x0000000002d02d2d
# x24: 0x3300033003303333
# x27: 0x0000000001c01c1c
# x2: 0x~~~~~~~~~~~~~~~~
# x5: 0x0000000000700707
# x8: 0x0000000000000000
# x11: 0x0000000001b01b1b
# x13: 0x0700007000700707
# x15: 0x0000000000000080
# x18: 0x0000013000130013
# x21: 0x0000000002d02d2c
# x23: 0x1700017001701716
# x25: 0x0000000000200202
# x28: 0x1d0001d001d01d1d
# x3: 0x0000000000000000
# x6: 0x0700007000700707
# x17: 0x0000000000130014
# x17: 0x0000000000130013
# x19: 0x1400014001401414
# x19: 0x1400014001401415
# x21: 0x0000000001601616
# x21: 0x00000000fe9fe9e9
# x23: 0xccfffccffccfcccc
# x23: 0x3300033003303333
# x25: 0x0000000000000006
# x27: 0x0000000000000002
# x29: 0x0000000000000020
# x3: 0x0000000000000005
# x13: 0x0000000000e00e0e
# x13: 0x00000000ff1ff1f2
# x15: 0x1000010001001010
# x15: 0xeffffefffeffeff0
# x17: 0x00000000e963b635
# x20: 0x00000000ad83ccb8
# x23: 0x000000003ed5525d
# x26: 0x00000000bc365145
# x4: 0x0000000000000070
# x7: 0x00000000b096abf4
# x13: 0x0000000000e00e0e
# x13: 0x00000000feffeff0
# x16: 0x0000013000130013
# x16: 0x00000000e963b635
# x19: 0x0000000000000000
# x19: 0x0000000000000001
# x20: 0x0000000000000001
# x20: 0x0000000000000000
# x21: 0x0000000000000000
# x21: 0x00000000ffffffff
# x22: 0x0000000000000000
# x22: 0xffffffffffffffff
# x23: 0x0000000003303333
# x23: 0x0000000000000007
# x26: 0x1d0001d001d01d1e
# x26: 0x0000000000000002
# x29: 0x00000000fffffffa
# x29: 0x0000000000000000
# x4: 0x0000000000700707
# x4: 0xf8ffff8fff8ff8f8
# x7: 0x00000000feafeaeb
# x7: 0x0000000000000000
# x10: 0xe4fffe4ffe4fe4e5
# x10: 0x0000000001b01b1b
# x13: 0x0000000001e01e01
# x16: 0xfffffecf168f49d9
# x19: 0x00000000ffffffff
# x22: 0x3300033003303334
# x25: 0x0000000001000000
# x28: 0x0000000000000000
# x3: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
# x4: 0x0706050403020100 <- 0x~~~~~~~~~~~~~~~~
# x5: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
# x6: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
# x7: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
# x8: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
# x9: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
# x10: 0x0000000007060504 <- 0x~~~~~~~~~~~~~~~~
# x11: 0x0706050403020100 <- 0x~~~~~~~~~~~~~~~~
# x12: 0x0f0e0d0c0b0a0908 <- 0x~~~~~~~~~~~~~~~~
# x13: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
# x14: 0x0706050403020100 <- 0x~~~~~~~~~~~~~~~~
# x15: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
# x16: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
# x17: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
# x18: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
# x19: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
# x20: 0x0000000007060504 <- 0x~~~~~~~~~~~~~~~~
# x21: 0x0706050403020100 <- 0x~~~~~~~~~~~~~~~~
# x22: 0x0f0e0d0c0b0a0908 <- 0x~~~~~~~~~~~~~~~~
# x23: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
# x24: 0x0000000007060504 <- 0x~~~~~~~~~~~~~~~~
# x23: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
# x24: 0x0000000007060504 <- 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x23: 0x0000000013121110 <- 0x~~~~~~~~~~~~~~~~
# x24: 0x0000000017161514 <- 0x~~~~~~~~~~~~~~~~
# x25: 0x0706050403020100 <- 0x~~~~~~~~~~~~~~~~
# x26: 0x0f0e0d0c0b0a0908 <- 0x~~~~~~~~~~~~~~~~
# x25: 0x1716151413121110 <- 0x~~~~~~~~~~~~~~~~
# x26: 0x1f1e1d1c1b1a1918 <- 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x25: 0x3736353433323130 <- 0x~~~~~~~~~~~~~~~~
# x26: 0x3f3e3d3c3b3a3938 <- 0x~~~~~~~~~~~~~~~~
# x27: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
# x28: 0x0000000007060504 <- 0x~~~~~~~~~~~~~~~~
# x27: 0x0000000033323130 <- 0x~~~~~~~~~~~~~~~~
# x28: 0x0000000037363534 <- 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x27: 0x0000000043424140 <- 0x~~~~~~~~~~~~~~~~
# x28: 0x0000000047464544 <- 0x~~~~~~~~~~~~~~~~
# x29: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
# x29: 0x0000000043424140 <- 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x29: 0x000000004b4a4948 <- 0x~~~~~~~~~~~~~~~~
# x2: 0x~~~~~~~~~~~~~~~~ <- 0x~~~~~~~~~~~~~~~~
# x2: 0x~~~~~~~~~~~~~~~~ <- 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x2: 0x~~~~~~~~~~~~~~~~ <- 0x~~~~~~~~~~~~~~~~
# x3: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
# x3: 0x0000000000000058 <- 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x3: 0x000000000000005a <- 0x~~~~~~~~~~~~~~~~
# x4: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
# x4: 0x000000000000005a <- 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x4: 0x000000000000005c <- 0x~~~~~~~~~~~~~~~~
# x5: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
# x5: 0x0000000000005d5c <- 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x5: 0x0000000000006160 <- 0x~~~~~~~~~~~~~~~~
# x6: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
# x6: 0x0000000000006160 <- 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x6: 0x0000000000006564 <- 0x~~~~~~~~~~~~~~~~
# x7: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
# x7: 0x0000000000000064 <- 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x7: 0x0000000000000066 <- 0x~~~~~~~~~~~~~~~~
# x8: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
# x8: 0x0000000000000066 <- 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x8: 0x0000000000000068 <- 0x~~~~~~~~~~~~~~~~
# x9: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
# x9: 0x0000000000006968 <- 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x9: 0x0000000000006d6c <- 0x~~~~~~~~~~~~~~~~
# x10: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
# x10: 0x0000000000006d6c <- 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x10: 0x0000000000007170 <- 0x~~~~~~~~~~~~~~~~
# x11: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
# x11: 0x0000000073727170 <- 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x11: 0x000000007b7a7978 <- 0x~~~~~~~~~~~~~~~~
# x12: 0x000000000a090807 <- 0x~~~~~~~~~~~~~~~~
# x13: 0x161514131211100f <- 0x~~~~~~~~~~~~~~~~
# x14: 0x0000000000000001 <- 0x~~~~~~~~~~~~~~~~
# x15: 0x0000000000000001 <- 0x~~~~~~~~~~~~~~~~
# x16: 0x0000000000000403 <- 0x~~~~~~~~~~~~~~~~
# x17: 0x0000000000000403 <- 0x~~~~~~~~~~~~~~~~
# x18: 0x0000000000000001 <- 0x~~~~~~~~~~~~~~~~
# x19: 0x0000000000000001 <- 0x~~~~~~~~~~~~~~~~
# x20: 0x0000000000000403 <- 0x~~~~~~~~~~~~~~~~
# x21: 0x0000000000000403 <- 0x~~~~~~~~~~~~~~~~
# x22: 0x000000000a090807 <- 0x~~~~~~~~~~~~~~~~
# x23: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
# x24: 0x0000000007060504 <- 0x~~~~~~~~~~~~~~~~
# x25: 0x0706050403020100 <- 0x~~~~~~~~~~~~~~~~
# x26: 0x0f0e0d0c0b0a0908 <- 0x~~~~~~~~~~~~~~~~
# x27: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
# x28: 0x0706050403020100 <- 0x~~~~~~~~~~~~~~~~
# x29: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
# x2: 0x~~~~~~~~~~~~~~~~ <- 0x~~~~~~~~~~~~~~~~
# x3: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
# x4: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
# x5: 0x0000000000019590
# x7: 0x0000000000000340
# x9: 0x0000000070000000
# x12: 0x2c2a28262422201e
# x15: 0x0000000000000040
# x17: 0x0000000000000000
# x19: 0x0000000000000080
# x22: 0x0000000000302010
# x25: 0x00000000371b0900
# x29: 0x0000000000000100
# x5: 0x00000000feb67b00
# x8: 0xffffce5f00000000
# x11: 0x000000002422201e
# x13: 0x0000000000000001
# x15: 0x0000000000000082
# x16: 0x0000000000000083
# x17: 0x00000000ffffff7b
# x18: 0xffffffffffffff7a
# x19: 0x0000000000000086
# x20: 0x0000000000000087
# x22: 0x000000001b0e0500
# x26: 0xe3e9eff5fbff0100
# x2: 0x~~~~~~~~~~~~~~~~
# x5: 0x0000000001498500
# x8: 0x000000008fffffff
# x10: 0xffffffffdbdddfe1
# x12: 0x00000000ffffffff
# x14: 0xffffffffffffff7e
# x16: 0x0000000000000085
# x18: 0xffffffffffffff7a
# x20: 0x00000000fffffbfc
# x22: 0xfffffffffcfdfeff
# x24: 0x00000000c8e4f6ff
# x26: 0xfffffffffcfdfeff
# x28: 0x00000000fffeffff
# x3: 0xfffffffffeb67bff
# x6: 0x000000008fffffff
# x9: 0xffffffffffffffff
# x12: 0x0000000080000000
# x14: 0x4100000000000000
# x16: 0x000000007bffffff
# x18: 0x8600000000000000
# x20: 0x0000000000000304
# x22: 0x0000000002030001
# x24: 0x0000000000091b37
# x26: 0x0000000006040200
# x29: 0x0000000000020000
# x4: 0x0000000071498500
# x7: 0x000000008fffffff
# x10: 0x00000000a422201d
# x13: 0x40ffffffffffff7d
# x16: 0x000000000000000c
# x18: 0x0000000000000060
# x22: 0x0000000000000004
# x24: 0xffffffffffffff09
# x26: 0x00000000fffffcff
# x29: 0x0000000000000000
# x12: 0x1080ffffffffffde
# x24: 0x0000000000000001
# x27: 0x0000000000000001
# x2: 0x~~~~~~~~~~~~~~~~
# x4: 0x0000000000000001
# x6: 0x0000000000000001
# x8: 0x0000000000000001
# x10: 0x0000000000000001
# x12: 0x0000000000000001
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x6: 0x0000000000000001
# x9: 0x0000000000000001
# x12: 0x0000000000000001
# x14: 0x0000000000000001
# x16: 0x0000000000000001
# x18: 0x0000000000000001
# x20: 0x0000000000000001
# x22: 0x0000000000000001
# x24: 0x00000000371b0c01
# x27: 0x00000000fffeffff
# x2: 0x~~~~~~~~~~~~~~~~
# x5: 0xffffffff70000002
# x8: 0x0000000000000001
# x10: 0x000000000000001e
# x12: 0x00000000ffffff7d
# x14: 0x0000000000000082
# x16: 0x00000000ffffff7b
# x18: 0x0000000000000086
# x24: 0x0000000000040000
# x26: 0x0000000001fff000
# x28: 0x0000000000000000
# x2: 0x~~~~~~~~~~~~~~~~
# x4: 0x0000000000000000
# x6: 0x000000000000003f
# x8: 0x0000000000000000
# x11: 0x0000000000000000
# x22: 0x0000000000000000
# x28: 0x0000000000000000
# x2: 0x~~~~~~~~~~~~~~~~
# x4: 0x0000000000000002
# x6: 0x000000000000ffff
# x8: 0x0000000000000001
# x10: 0x0000000000000000
# x18: 0x0000000000000000
# x29: 0x0000000000000000
# x9: 0x0000000000000000
# lr: 0x0000000000000000
# x16: 0x0000000000000000
# x18: 0x0000000000000000
# x26: 0x0000000000000009
# x25: 0x0000000000000000
# x9: 0x0000000000000009
# x19: 0x0000000000000007
# x6: 0x0000000000000008
# x22: 0x0000000000000008
# x29: 0x0000000000000000
# x26: 0x0000000000000000
# x13: 0x0000000000000000
# x5: 0x0000000000000000
# x21: 0x0000000000000014
# x18: 0x0000000000000000
# x8: 0x0000000000000000
# x17: 0x0000000000000000
# x29: 0x0000000000000000
# x25: 0x0000000000000000
# lr: 0x0000000000000000
# x27: 0x0000000000000000
# x15: 0x0000000000000001
# x16: 0x0000000000000009
# x13: 0x000000000000001b
# x3: 0x000000000000001d
# x26: 0x0000000000000001
# x27: 0x0000000000000001
# x29: 0x0000000000000001
# x6: 0x000000000000000c
# x25: 0x0000000000000000
# x9: 0x0000000000000000
# x17: 0x0000000000000000
# x19: 0x0000000000000000
# x22: 0x0000000000000000
# x14: 0x0000000000000018
# x3: 0x0000000000000000
# x11: 0x0000000000000000
# x7: 0x0000000000000000
# x18: 0x0000000000000000
# x14: 0x0000000000000000
# x22: 0x0000000000000000
# x8: 0x0000000000000000
# x7: 0x0000000000000018
# x22: 0x00008a4396000000
# x18: 0x0000000000000001
# x18: 0x0000000000000000
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x18: 0x0000000000000000
# x28: 0xe3e2e3e2e3e2e3e2
# x21: 0x0000000000000000
# x13: 0x0000000000000000
# x24: 0x0000000000000000
# x7: 0x00000000000003c9
# x29: 0x0000000000000000
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# x1: 0x~~~~~~~~~~~~~~~~
# lr: 0x0000000000000000
# x18: 0x0000000000000000

View File

@ -0,0 +1,739 @@
#  x0: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x2: 0x~~~~~~~~~~~~~~~~
#  x3: 0x0300003000300303
#  x4: 0x0400004000400404
#  x5: 0x0500005000500505
#  x6: 0x0600006000600606
#  x7: 0x0700007000700707
#  x8: 0x0800008000800808
#  x9: 0x0900009000900909
#  x10: 0x0a0000a000a00a0a
#  x11: 0x0b0000b000b00b0b
#  x12: 0x0c0000c000c00c0c
#  x13: 0x0d0000d000d00d0d
#  x14: 0x0e0000e000e00e0e
#  x15: 0x0f0000f000f00f0f
#  x16: 0x1000010001001010
#  x17: 0x1100011001101111
#  x18: 0x1200012001201212
#  x19: 0x1300013001301313
#  x20: 0x1400014001401414
#  x21: 0x1500015001501515
#  x22: 0x1600016001601616
#  x23: 0x1700017001701717
#  x24: 0x1800018001801818
#  x25: 0x1900019001901919
#  x26: 0x1a0001a001a01a1a
#  x27: 0x1b0001b001b01b1b
#  x28: 0x1c0001c001c01c1c
#  x29: 0x1d0001d001d01d1d
#  lr: 0x0000000000000000
#  sp: 0x~~~~~~~~~~~~~~~~
#  x3: 0x0000000000900909
#  x6: 0x0f0000f000f00f0f
#  x9: 0x0000000001501515
#  x12: 0x1b0001b001b01b1b
#  x15: 0x0000000002102121
#  x18: 0x2700027002702727
#  x21: 0x0000000002d02d2d
#  x24: 0x3300033003303333
#  x27: 0x0000000001c01c1c
#  x2: 0x~~~~~~~~~~~~~~~~
#  x5: 0x0000000000700707
#  x8: 0x0000000000000000
#  x11: 0x0000000001b01b1b
#  x13: 0x0700007000700707
#  x15: 0x0000000000000080
#  x18: 0x0000013000130013
#  x21: 0x0000000002d02d2c
#  x23: 0x1700017001701716
#  x25: 0x0000000000200202
#  x28: 0x1d0001d001d01d1d
#  x3: 0x0000000000000000
#  x6: 0x0700007000700707
#  x17: 0x0000000000130014
#  x17: 0x0000000000130013
#  x19: 0x1400014001401414
#  x19: 0x1400014001401415
#  x21: 0x0000000001601616
#  x21: 0x00000000fe9fe9e9
#  x23: 0xccfffccffccfcccc
#  x23: 0x3300033003303333
#  x25: 0x0000000000000006
#  x27: 0x0000000000000002
#  x29: 0x0000000000000020
#  x3: 0x0000000000000005
#  x13: 0x0000000000e00e0e
#  x13: 0x00000000ff1ff1f2
#  x15: 0x1000010001001010
#  x15: 0xeffffefffeffeff0
#  x17: 0x00000000e963b635
#  x20: 0x00000000ad83ccb8
#  x23: 0x000000003ed5525d
#  x26: 0x00000000bc365145
#  x4: 0x0000000000000070
#  x7: 0x00000000b096abf4
#  x13: 0x0000000000e00e0e
#  x13: 0x00000000feffeff0
#  x16: 0x0000013000130013
#  x16: 0x00000000e963b635
#  x19: 0x0000000000000000
#  x19: 0x0000000000000001
#  x20: 0x0000000000000001
#  x20: 0x0000000000000000
#  x21: 0x0000000000000000
#  x21: 0x00000000ffffffff
#  x22: 0x0000000000000000
#  x22: 0xffffffffffffffff
#  x23: 0x0000000003303333
#  x23: 0x0000000000000007
#  x26: 0x1d0001d001d01d1e
#  x26: 0x0000000000000002
#  x29: 0x00000000fffffffa
#  x29: 0x0000000000000000
#  x4: 0x0000000000700707
#  x4: 0xf8ffff8fff8ff8f8
#  x7: 0x00000000feafeaeb
#  x7: 0x0000000000000000
#  x10: 0xe4fffe4ffe4fe4e5
#  x10: 0x0000000001b01b1b
#  x13: 0x0000000001e01e01
#  x16: 0xfffffecf168f49d9
#  x19: 0x00000000ffffffff
#  x22: 0x3300033003303334
#  x25: 0x0000000001000000
#  x28: 0x0000000000000000
#  x3: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
#  x4: 0x0706050403020100 <- 0x~~~~~~~~~~~~~~~~
#  x5: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
#  x6: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
#  x7: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
#  x8: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
#  x9: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
#  x10: 0x0000000007060504 <- 0x~~~~~~~~~~~~~~~~
#  x11: 0x0706050403020100 <- 0x~~~~~~~~~~~~~~~~
#  x12: 0x0f0e0d0c0b0a0908 <- 0x~~~~~~~~~~~~~~~~
#  x13: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
#  x14: 0x0706050403020100 <- 0x~~~~~~~~~~~~~~~~
#  x15: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
#  x16: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
#  x17: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
#  x18: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
#  x19: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
#  x20: 0x0000000007060504 <- 0x~~~~~~~~~~~~~~~~
#  x21: 0x0706050403020100 <- 0x~~~~~~~~~~~~~~~~
#  x22: 0x0f0e0d0c0b0a0908 <- 0x~~~~~~~~~~~~~~~~
#  x23: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
#  x24: 0x0000000007060504 <- 0x~~~~~~~~~~~~~~~~
#  x23: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
#  x24: 0x0000000007060504 <- 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x23: 0x0000000013121110 <- 0x~~~~~~~~~~~~~~~~
#  x24: 0x0000000017161514 <- 0x~~~~~~~~~~~~~~~~
#  x25: 0x0706050403020100 <- 0x~~~~~~~~~~~~~~~~
#  x26: 0x0f0e0d0c0b0a0908 <- 0x~~~~~~~~~~~~~~~~
#  x25: 0x1716151413121110 <- 0x~~~~~~~~~~~~~~~~
#  x26: 0x1f1e1d1c1b1a1918 <- 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x25: 0x3736353433323130 <- 0x~~~~~~~~~~~~~~~~
#  x26: 0x3f3e3d3c3b3a3938 <- 0x~~~~~~~~~~~~~~~~
#  x27: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
#  x28: 0x0000000007060504 <- 0x~~~~~~~~~~~~~~~~
#  x27: 0x0000000033323130 <- 0x~~~~~~~~~~~~~~~~
#  x28: 0x0000000037363534 <- 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x27: 0x0000000043424140 <- 0x~~~~~~~~~~~~~~~~
#  x28: 0x0000000047464544 <- 0x~~~~~~~~~~~~~~~~
#  x29: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
#  x29: 0x0000000043424140 <- 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x29: 0x000000004b4a4948 <- 0x~~~~~~~~~~~~~~~~
#  x2: 0x~~~~~~~~~~~~~~~~ <- 0x~~~~~~~~~~~~~~~~
#  x2: 0x~~~~~~~~~~~~~~~~ <- 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x2: 0x~~~~~~~~~~~~~~~~ <- 0x~~~~~~~~~~~~~~~~
#  x3: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
#  x3: 0x0000000000000058 <- 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x3: 0x000000000000005a <- 0x~~~~~~~~~~~~~~~~
#  x4: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
#  x4: 0x000000000000005a <- 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x4: 0x000000000000005c <- 0x~~~~~~~~~~~~~~~~
#  x5: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
#  x5: 0x0000000000005d5c <- 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x5: 0x0000000000006160 <- 0x~~~~~~~~~~~~~~~~
#  x6: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
#  x6: 0x0000000000006160 <- 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x6: 0x0000000000006564 <- 0x~~~~~~~~~~~~~~~~
#  x7: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
#  x7: 0x0000000000000064 <- 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x7: 0x0000000000000066 <- 0x~~~~~~~~~~~~~~~~
#  x8: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
#  x8: 0x0000000000000066 <- 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x8: 0x0000000000000068 <- 0x~~~~~~~~~~~~~~~~
#  x9: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
#  x9: 0x0000000000006968 <- 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x9: 0x0000000000006d6c <- 0x~~~~~~~~~~~~~~~~
#  x10: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
#  x10: 0x0000000000006d6c <- 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x10: 0x0000000000007170 <- 0x~~~~~~~~~~~~~~~~
#  x11: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
#  x11: 0x0000000073727170 <- 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x11: 0x000000007b7a7978 <- 0x~~~~~~~~~~~~~~~~
#  x12: 0x000000000a090807 <- 0x~~~~~~~~~~~~~~~~
#  x13: 0x161514131211100f <- 0x~~~~~~~~~~~~~~~~
#  x14: 0x0000000000000001 <- 0x~~~~~~~~~~~~~~~~
#  x15: 0x0000000000000001 <- 0x~~~~~~~~~~~~~~~~
#  x16: 0x0000000000000403 <- 0x~~~~~~~~~~~~~~~~
#  x17: 0x0000000000000403 <- 0x~~~~~~~~~~~~~~~~
#  x18: 0x0000000000000001 <- 0x~~~~~~~~~~~~~~~~
#  x19: 0x0000000000000001 <- 0x~~~~~~~~~~~~~~~~
#  x20: 0x0000000000000403 <- 0x~~~~~~~~~~~~~~~~
#  x21: 0x0000000000000403 <- 0x~~~~~~~~~~~~~~~~
#  x22: 0x000000000a090807 <- 0x~~~~~~~~~~~~~~~~
#  x23: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
#  x24: 0x0000000007060504 <- 0x~~~~~~~~~~~~~~~~
#  x25: 0x0706050403020100 <- 0x~~~~~~~~~~~~~~~~
#  x26: 0x0f0e0d0c0b0a0908 <- 0x~~~~~~~~~~~~~~~~
#  x27: 0x0000000003020100 <- 0x~~~~~~~~~~~~~~~~
#  x28: 0x0706050403020100 <- 0x~~~~~~~~~~~~~~~~
#  x29: 0x0000000000000000 <- 0x~~~~~~~~~~~~~~~~
#  x2: 0x~~~~~~~~~~~~~~~~ <- 0x~~~~~~~~~~~~~~~~
#  x3: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
#  x4: 0x0000000000000100 <- 0x~~~~~~~~~~~~~~~~
#  x5: 0x0000000000019590
#  x7: 0x0000000000000340
#  x9: 0x0000000070000000
#  x12: 0x2c2a28262422201e
#  x15: 0x0000000000000040
#  x17: 0x0000000000000000
#  x19: 0x0000000000000080
#  x22: 0x0000000000302010
#  x25: 0x00000000371b0900
#  x29: 0x0000000000000100
#  x5: 0x00000000feb67b00
#  x8: 0xffffce5f00000000
#  x11: 0x000000002422201e
#  x13: 0x0000000000000001
#  x15: 0x0000000000000082
#  x16: 0x0000000000000083
#  x17: 0x00000000ffffff7b
#  x18: 0xffffffffffffff7a
#  x19: 0x0000000000000086
#  x20: 0x0000000000000087
#  x22: 0x000000001b0e0500
#  x26: 0xe3e9eff5fbff0100
#  x2: 0x~~~~~~~~~~~~~~~~
#  x5: 0x0000000001498500
#  x8: 0x000000008fffffff
#  x10: 0xffffffffdbdddfe1
#  x12: 0x00000000ffffffff
#  x14: 0xffffffffffffff7e
#  x16: 0x0000000000000085
#  x18: 0xffffffffffffff7a
#  x20: 0x00000000fffffbfc
#  x22: 0xfffffffffcfdfeff
#  x24: 0x00000000c8e4f6ff
#  x26: 0xfffffffffcfdfeff
#  x28: 0x00000000fffeffff
#  x3: 0xfffffffffeb67bff
#  x6: 0x000000008fffffff
#  x9: 0xffffffffffffffff
#  x12: 0x0000000080000000
#  x14: 0x4100000000000000
#  x16: 0x000000007bffffff
#  x18: 0x8600000000000000
#  x20: 0x0000000000000304
#  x22: 0x0000000002030001
#  x24: 0x0000000000091b37
#  x26: 0x0000000006040200
#  x29: 0x0000000000020000
#  x4: 0x0000000071498500
#  x7: 0x000000008fffffff
#  x10: 0x00000000a422201d
#  x13: 0x40ffffffffffff7d
#  x16: 0x000000000000000c
#  x18: 0x0000000000000060
#  x22: 0x0000000000000004
#  x24: 0xffffffffffffff09
#  x26: 0x00000000fffffcff
#  x29: 0x0000000000000000
#  x12: 0x1080ffffffffffde
#  x24: 0x0000000000000001
#  x27: 0x0000000000000001
#  x2: 0x~~~~~~~~~~~~~~~~
#  x4: 0x0000000000000001
#  x6: 0x0000000000000001
#  x8: 0x0000000000000001
#  x10: 0x0000000000000001
#  x12: 0x0000000000000001
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x6: 0x0000000000000001
#  x9: 0x0000000000000001
#  x12: 0x0000000000000001
#  x14: 0x0000000000000001
#  x16: 0x0000000000000001
#  x18: 0x0000000000000001
#  x20: 0x0000000000000001
#  x22: 0x0000000000000001
#  x24: 0x00000000371b0c01
#  x27: 0x00000000fffeffff
#  x2: 0x~~~~~~~~~~~~~~~~
#  x5: 0xffffffff70000002
#  x8: 0x0000000000000001
#  x10: 0x000000000000001e
#  x12: 0x00000000ffffff7d
#  x14: 0x0000000000000082
#  x16: 0x00000000ffffff7b
#  x18: 0x0000000000000086
#  x24: 0x0000000000040000
#  x26: 0x0000000001fff000
#  x28: 0x0000000000000000
#  x2: 0x~~~~~~~~~~~~~~~~
#  x4: 0x0000000000000000
#  x6: 0x000000000000003f
#  x8: 0x0000000000000000
#  x11: 0x0000000000000000
#  x22: 0x0000000000000000
#  x28: 0x0000000000000000
#  x2: 0x~~~~~~~~~~~~~~~~
#  x4: 0x0000000000000002
#  x6: 0x000000000000ffff
#  x8: 0x0000000000000001
#  x10: 0x0000000000000000
#  x18: 0x0000000000000000
#  x29: 0x0000000000000000
#  x9: 0x0000000000000000
#  lr: 0x0000000000000000
#  x16: 0x0000000000000000
#  x18: 0x0000000000000000
#  x26: 0x0000000000000009
#  x25: 0x0000000000000000
#  x9: 0x0000000000000009
#  x19: 0x0000000000000007
#  x6: 0x0000000000000008
#  x22: 0x0000000000000008
#  x29: 0x0000000000000000
#  x26: 0x0000000000000000
#  x13: 0x0000000000000000
#  x5: 0x0000000000000000
#  x21: 0x0000000000000014
#  x18: 0x0000000000000000
#  x8: 0x0000000000000000
#  x17: 0x0000000000000000
#  x29: 0x0000000000000000
#  x25: 0x0000000000000000
#  lr: 0x0000000000000000
#  x27: 0x0000000000000000
#  x15: 0x0000000000000001
#  x16: 0x0000000000000009
#  x13: 0x000000000000001b
#  x3: 0x000000000000001d
#  x26: 0x0000000000000001
#  x27: 0x0000000000000001
#  x29: 0x0000000000000001
#  x6: 0x000000000000000c
#  x25: 0x0000000000000000
#  x9: 0x0000000000000000
#  x17: 0x0000000000000000
#  x19: 0x0000000000000000
#  x22: 0x0000000000000000
#  x14: 0x0000000000000018
#  x3: 0x0000000000000000
#  x11: 0x0000000000000000
#  x7: 0x0000000000000000
#  x18: 0x0000000000000000
#  x14: 0x0000000000000000
#  x22: 0x0000000000000000
#  x8: 0x0000000000000000
#  x7: 0x0000000000000018
#  x22: 0x00008a4396000000
#  x18: 0x0000000000000001
#  x18: 0x0000000000000000
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x18: 0x0000000000000000
#  x28: 0xe3e2e3e2e3e2e3e2
#  x21: 0x0000000000000000
#  x13: 0x0000000000000000
#  x24: 0x0000000000000000
#  x7: 0x00000000000003c9
#  x29: 0x0000000000000000
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  x1: 0x~~~~~~~~~~~~~~~~
#  lr: 0x0000000000000000
#  x18: 0x0000000000000000

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:1 C:0 V:0
# NZCV: N:0 Z:1 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:1
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:1 V:1
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:1 Z:0 C:0 V:1
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:1 Z:0 C:1 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:1 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:0 Z:1 C:1 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:0 Z:0 C:1 V:1
# NZCV: N:0 Z:1 C:1 V:0

View File

@ -0,0 +1,46 @@
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:1 C:0 V:0
# NZCV: N:0 Z:1 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:1
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:1 V:1
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:1 Z:0 C:0 V:1
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:1 Z:0 C:1 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:1 C:0 V:0
# NZCV: N:0 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:0 Z:1 C:1 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:1 Z:0 C:0 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:0 Z:0 C:1 V:0
# NZCV: N:0 Z:0 C:1 V:1
# NZCV: N:0 Z:1 C:1 V:0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,406 @@
# w18: 0x00000060 -> 0x~~~~~~~~~~~~~~~~
# x19: 0x0000000000000086 -> 0x~~~~~~~~~~~~~~~~
# w20<7:0>: 0x04 -> 0x~~~~~~~~~~~~~~~~
# w21<7:0>: 0x03 -> 0x~~~~~~~~~~~~~~~~
# w22<15:0>: 0x0004 -> 0x~~~~~~~~~~~~~~~~
# w23<15:0>: 0x0100 -> 0x~~~~~~~~~~~~~~~~
# w14: 0x00000000 -> 0x~~~~~~~~~~~~~~~~
# w15: 0x00000082 -> 0x~~~~~~~~~~~~~~~~
# x16: 0x000000000000000c -> 0x~~~~~~~~~~~~~~~~
# x17: 0x00000000ffffff7b -> 0x~~~~~~~~~~~~~~~~
# w18: 0x00000060 -> 0x~~~~~~~~~~~~~~~~
# w19: 0x00000086 -> 0x~~~~~~~~~~~~~~~~
# w18: 0x00000060 -> 0x~~~~~~~~~~~~~~~~
# w19: 0x00000086 -> 0x~~~~~~~~~~~~~~~~
# w18: 0x00000060 -> 0x~~~~~~~~~~~~~~~~
# w19: 0x00000086 -> 0x~~~~~~~~~~~~~~~~
# x20: 0x0000000000000304 -> 0x~~~~~~~~~~~~~~~~
# x21: 0x0000000000000403 -> 0x~~~~~~~~~~~~~~~~
# x20: 0x0000000000000304 -> 0x~~~~~~~~~~~~~~~~
# x21: 0x0000000000000403 -> 0x~~~~~~~~~~~~~~~~
# x20: 0x0000000000000304 -> 0x~~~~~~~~~~~~~~~~
# x21: 0x0000000000000403 -> 0x~~~~~~~~~~~~~~~~
# w22: 0x00000004 -> 0x~~~~~~~~~~~~~~~~
# w22: 0x00000004 -> 0x~~~~~~~~~~~~~~~~
# w22: 0x00000004 -> 0x~~~~~~~~~~~~~~~~
# x23: 0x0000000003020100 -> 0x~~~~~~~~~~~~~~~~
# x23: 0x0000000003020100 -> 0x~~~~~~~~~~~~~~~~
# x23: 0x0000000003020100 -> 0x~~~~~~~~~~~~~~~~
# w24<7:0>: 0x01 -> 0x~~~~~~~~~~~~~~~~
# w24<7:0>: 0x01 -> 0x~~~~~~~~~~~~~~~~
# w24<7:0>: 0x01 -> 0x~~~~~~~~~~~~~~~~
# w25<7:0>: 0x00 -> 0x~~~~~~~~~~~~~~~~
# w25<7:0>: 0x00 -> 0x~~~~~~~~~~~~~~~~
# w25<7:0>: 0x00 -> 0x~~~~~~~~~~~~~~~~
# w26<15:0>: 0xfcff -> 0x~~~~~~~~~~~~~~~~
# w26<15:0>: 0xfcff -> 0x~~~~~~~~~~~~~~~~
# w26<15:0>: 0xfcff -> 0x~~~~~~~~~~~~~~~~
# w27<15:0>: 0x0001 -> 0x~~~~~~~~~~~~~~~~
# w27<15:0>: 0x0001 -> 0x~~~~~~~~~~~~~~~~
# w27<15:0>: 0x0001 -> 0x~~~~~~~~~~~~~~~~
# w28: 0xfffeffff -> 0x~~~~~~~~~~~~~~~~
# x29: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# w2<7:0>: 0x01 -> 0x~~~~~~~~~~~~~~~~
# w3<7:0>: 0xff -> 0x~~~~~~~~~~~~~~~~
# w4<15:0>: 0x0001 -> 0x~~~~~~~~~~~~~~~~
# w5<15:0>: 0x8500 -> 0x~~~~~~~~~~~~~~~~
# v18: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v19: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v20: 0x00000000000000000000000000000020 -> 0x~~~~~~~~~~~~~~~~
# v21: 0x000000000000000000000000ffff8007 -> 0x~~~~~~~~~~~~~~~~
# v10: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v11: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v12: 0x000000000000000000000000ffffffff -> 0x~~~~~~~~~~~~~~~~
# v13: 0x0000000000000000ffffffffffefffe1 -> 0x~~~~~~~~~~~~~~~~
# v27: 0x00000000000000fe0001000000010000 -> 0x~~~~~~~~~~~~~~~~
# v28: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v29: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v30: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v16: 0x00000000000000000000000000007ff9 -> 0x~~~~~~~~~~~~~~~~
# v17: 0x00000000000000000000000000000400 -> 0x~~~~~~~~~~~~~~~~
# v18: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v21: 0x000000000000000000000000ffff8007 -> 0x~~~~~~~~~~~~~~~~
# v22: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v23: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v9: 0x00000000000000000020000000200040 -> 0x~~~~~~~~~~~~~~~~
# v10: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v11: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v7: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v8: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v26: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v27: 0x00000000000000fe0001000000010000 -> 0x~~~~~~~~~~~~~~~~
# v22: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v23: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v23: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v28: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v2: 0x00000000000000000020000000200040 -> 0x~~~~~~~~~~~~~~~~
# v29: 0x0000000000000000 (d29: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v30: 0x0000000000000000 (d30: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v31: 0x0000000000000000 (d31: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v0: 0x0000000000000000 (d0: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v12: 0x00000000ffffffff (d12: 2.12200e-314) -> 0x~~~~~~~~~~~~~~~~
# v13: 0xffffffffffefffe1 (d13: -nan) -> 0x~~~~~~~~~~~~~~~~
# v14: 0x0000000000000001 (d14: 4.94066e-324) -> 0x~~~~~~~~~~~~~~~~
# v15: 0x0000000000000000 (d15: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v30: 0x0000000000000000 (d30: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v31: 0x0000000000000000 (d31: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v0: 0x0000000000000000 (d0: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v1: 0x0000000000000000 (d1: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v16: 0x0000000000007ff9 (d16: 1.61861e-319) -> 0x~~~~~~~~~~~~~~~~
# v17: 0x0000000000000400 (d17: 5.05923e-321) -> 0x~~~~~~~~~~~~~~~~
# v18: 0x0000000000000000 (d18: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v3: 0x0000000000000000 (d3: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v4: 0x0000000000000000 (d4: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v5: 0x0000000000000000 (d5: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v14: 0x0000000000000001 (d14: 4.94066e-324) -> 0x~~~~~~~~~~~~~~~~
# v15: 0x0000000000000000 (d15: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v16: 0x0000000000007ff9 (d16: 1.61861e-319) -> 0x~~~~~~~~~~~~~~~~
# v18: 0x0000000000000000 (d18: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v19: 0x0000000000000000 (d19: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v5: 0x0000000000000000 (d5: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v6: 0x0000000000000000 (d6: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v2: 0x0020000000200040 (d2: 4.45015e-308) -> 0x~~~~~~~~~~~~~~~~
# v3: 0x0000000000000000 (d3: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v4: 0x0000000000000000 (d4: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v27: 0x0001000000010000 (d27: 1.39067e-309) -> 0x~~~~~~~~~~~~~~~~
# v23: 0x0000000000000000 (d23: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v2: 0x00000000000000000020000000200040 (0.00000, 4.45015e-308) -> 0x~~~~~~~~~~~~~~~~
# v3: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v4: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v5: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v22: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v23: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v24: 0x00000000000000000000000000007ff9 (0.00000, 1.61861e-319) -> 0x~~~~~~~~~~~~~~~~
# v25: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v28: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v29: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v30: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v31: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v17: 0x00000000000000000000000000000400 (0.00000, 5.05923e-321) -> 0x~~~~~~~~~~~~~~~~
# v18: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v19: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v16: 0x00000000000000000000000000007ff9 (0.00000, 1.61861e-319) -> 0x~~~~~~~~~~~~~~~~
# v17: 0x00000000000000000000000000000400 (0.00000, 5.05923e-321) -> 0x~~~~~~~~~~~~~~~~
# v18: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v22: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v23: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v24: 0x00000000000000000000000000007ff9 (0.00000, 1.61861e-319) -> 0x~~~~~~~~~~~~~~~~
# v21: 0x000000000000000000000000ffff8007 (0.00000, 2.12198e-314) -> 0x~~~~~~~~~~~~~~~~
# v22: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v6: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v7: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v27: 0x00000000000000fe0001000000010000 (1.25493e-321, 1.39067e-309) -> 0x~~~~~~~~~~~~~~~~
# v28: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v21: 0x000000000000000000000000ffff8007 (0.00000, 2.12198e-314) -> 0x~~~~~~~~~~~~~~~~
# v29: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v20: 0x00000000000000000000000000000020 (0.00000, 1.58101e-322) -> 0x~~~~~~~~~~~~~~~~
# v22: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v23: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v24: 0x0000000000007ff9 (..., 0.00000, 4.59079e-41) -> 0x~~~~~~~~~~~~~~~~
# v25: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v8: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v9: 0x0020000000200040 (..., 2.93874e-39, 2.93883e-39) -> 0x~~~~~~~~~~~~~~~~
# v10: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v11: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v15: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v16: 0x0000000000007ff9 (..., 0.00000, 4.59079e-41) -> 0x~~~~~~~~~~~~~~~~
# v17: 0x0000000000000400 (..., 0.00000, 1.43493e-42) -> 0x~~~~~~~~~~~~~~~~
# v18: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v2: 0x0020000000200040 (..., 2.93874e-39, 2.93883e-39) -> 0x~~~~~~~~~~~~~~~~
# v3: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v4: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v23: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v24: 0x0000000000007ff9 (..., 0.00000, 4.59079e-41) -> 0x~~~~~~~~~~~~~~~~
# v25: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v7: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v8: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v9: 0x0020000000200040 (..., 2.93874e-39, 2.93883e-39) -> 0x~~~~~~~~~~~~~~~~
# v28: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v29: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v29: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v30: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v23: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v24: 0x0000000000007ff9 (..., 0.00000, 4.59079e-41) -> 0x~~~~~~~~~~~~~~~~
# v6: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v11: 0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v17: 0x0000000000000400 (..., 0.00000, 1.43493e-42) -> 0x~~~~~~~~~~~~~~~~
# v6: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v7: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v8: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v9: 0x0020000000200040 -> 0x~~~~~~~~~~~~~~~~
# v9: 0x0020000000200040 -> 0x~~~~~~~~~~~~~~~~
# v10: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v11: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v12: 0x00000000ffffffff -> 0x~~~~~~~~~~~~~~~~
# v25: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v26: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v27: 0x0001000000010000 -> 0x~~~~~~~~~~~~~~~~
# v28: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v11: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v12: 0x00000000ffffffff -> 0x~~~~~~~~~~~~~~~~
# v13: 0xffffffffffefffe1 -> 0x~~~~~~~~~~~~~~~~
# v10: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v11: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v12: 0x00000000ffffffff -> 0x~~~~~~~~~~~~~~~~
# v12: 0x00000000ffffffff -> 0x~~~~~~~~~~~~~~~~
# v13: 0xffffffffffefffe1 -> 0x~~~~~~~~~~~~~~~~
# v14: 0x0000000000000001 -> 0x~~~~~~~~~~~~~~~~
# v13: 0xffffffffffefffe1 -> 0x~~~~~~~~~~~~~~~~
# v14: 0x0000000000000001 -> 0x~~~~~~~~~~~~~~~~
# v15: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v16: 0x0000000000007ff9 -> 0x~~~~~~~~~~~~~~~~
# v21: 0x00000000ffff8007 -> 0x~~~~~~~~~~~~~~~~
# v22: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v16: 0x0000000000007ff9 -> 0x~~~~~~~~~~~~~~~~
# v8: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v30: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v3: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v4: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v5: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v6: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v25: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v26: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v27: 0x00000000000000fe0001000000010000 (0.00000, 3.55930e-43, 9.18355e-41, 9.18355e-41) -> 0x~~~~~~~~~~~~~~~~
# v28: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v5: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v6: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v7: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v8: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v31: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v0: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v1: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v30: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v31: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v0: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v6: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v7: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v8: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v17: 0x00000000000000000000000000000400 (0.00000, 0.00000, 0.00000, 1.43493e-42) -> 0x~~~~~~~~~~~~~~~~
# v18: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v31: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v0: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v1: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v2: 0x00000000000000000020000000200040 (0.00000, 0.00000, 2.93874e-39, 2.93883e-39) -> 0x~~~~~~~~~~~~~~~~
# v26: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v15: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v13: 0x0000000000000000ffffffffffefffe1 (0.00000, 0.00000, -nan, -nan) -> 0x~~~~~~~~~~~~~~~~
# v26: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v27: 0x0001000000010000 -> 0x~~~~~~~~~~~~~~~~
# v28: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v29: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v10: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v11: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v12: 0x00000000ffffffff -> 0x~~~~~~~~~~~~~~~~
# v13: 0xffffffffffefffe1 -> 0x~~~~~~~~~~~~~~~~
# v15: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v16: 0x0000000000007ff9 -> 0x~~~~~~~~~~~~~~~~
# v17: 0x0000000000000400 -> 0x~~~~~~~~~~~~~~~~
# v18: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v19: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v20: 0x0000000000000020 -> 0x~~~~~~~~~~~~~~~~
# v21: 0x00000000ffff8007 -> 0x~~~~~~~~~~~~~~~~
# v31: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v0: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v1: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v9: 0x0020000000200040 -> 0x~~~~~~~~~~~~~~~~
# v10: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v11: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v12: 0x00000000ffffffff -> 0x~~~~~~~~~~~~~~~~
# v13: 0xffffffffffefffe1 -> 0x~~~~~~~~~~~~~~~~
# v2: 0x0020000000200040 -> 0x~~~~~~~~~~~~~~~~
# v3: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v0: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v1: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v16: 0x0000000000007ff9 -> 0x~~~~~~~~~~~~~~~~
# v25: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v31: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v4: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v5: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v6: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v7: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v3: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v4: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v5: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v6: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v26: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v27: 0x00000000000000fe0001000000010000 -> 0x~~~~~~~~~~~~~~~~
# v28: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v29: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v10: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v11: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v12: 0x000000000000000000000000ffffffff -> 0x~~~~~~~~~~~~~~~~
# v21: 0x000000000000000000000000ffff8007 -> 0x~~~~~~~~~~~~~~~~
# v22: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v23: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v18: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v19: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v20: 0x00000000000000000000000000000020 -> 0x~~~~~~~~~~~~~~~~
# v26: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v27: 0x00000000000000fe0001000000010000 -> 0x~~~~~~~~~~~~~~~~
# v24: 0x00000000000000000000000000007ff9 -> 0x~~~~~~~~~~~~~~~~
# v25: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v17: 0x00000000000000000000000000000400 -> 0x~~~~~~~~~~~~~~~~
# v18: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v29: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v19: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v23: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
# v19: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v25: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v4: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v13: 0xffffffffffefffe1 (d13: -nan) -> 0x~~~~~~~~~~~~~~~~
# v30: 0x0000000000000000 (d30: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v3: 0x0000000000000000 (d3: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v22: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v31: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v23: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v0: 0x00000000 (s0: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v11: 0x00000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v24: 0x00000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v8: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v9: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v8: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v9: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v7: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v8: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v25: 0x0000000000000000 (d25: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v26: 0x0000000000000000 (d26: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v17: 0x0000000000000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v18: 0x0000000000000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v3: 0x0000000000000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v4: 0x0000000000000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v4: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v5: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v0: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v1: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v22: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v23: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v14: 0x00000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v15: 0x00000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v23: 0x00000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v24: 0x00000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v0: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v1: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v31: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v0: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v1: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v4: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v5: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v6: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v5: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v6: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v7: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v5: 0x0000000000000000 (d5: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v6: 0x0000000000000000 (d6: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v7: 0x0000000000000000 (d7: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v6: 0x0000000000000000 (d6: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v7: 0x0000000000000000 (d7: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v8: 0x0000000000000000 (d8: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v0: 0x0000000000000000 (d0: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v1: 0x0000000000000000 (d1: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v2: 0x0020000000200040 (d2: 4.45015e-308) -> 0x~~~~~~~~~~~~~~~~
# v31: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v0: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v1: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v14: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v15: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v16: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v21: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v22: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v23: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v21: 0xffff8007 (s21: -nan) -> 0x~~~~~~~~~~~~~~~~
# v22: 0x00000000 (s22: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v23: 0x00000000 (s23: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v11: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v12: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v13: 0xffffffff (..., -nan, ...) -> 0x~~~~~~~~~~~~~~~~
# v15: 0x00000000 (s15: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v16: 0x00007ff9 (s16: 4.59079e-41) -> 0x~~~~~~~~~~~~~~~~
# v17: 0x00000400 (s17: 1.43493e-42) -> 0x~~~~~~~~~~~~~~~~
# v0: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v1: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v2: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v3: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v4: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v5: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v6: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v7: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v9: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v10: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v11: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v12: 0x00 -> 0x~~~~~~~~~~~~~~~~
# v2: 0x0000000000000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v3: 0x0000000000000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v4: 0x0000000000000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v5: 0x0000000000000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v7: 0x0000000000000000 (d7: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v8: 0x0000000000000000 (d8: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v9: 0x0020000000200040 (d9: 4.45015e-308) -> 0x~~~~~~~~~~~~~~~~
# v10: 0x0000000000000000 (d10: 0.00000) -> 0x~~~~~~~~~~~~~~~~
# v31: 0x0000000000000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v0: 0x0000000000000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v1: 0x0000000000000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v2: 0x0000000000000000 (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v2: 0x0020 -> 0x~~~~~~~~~~~~~~~~
# v3: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v4: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v5: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v27: 0x0001 -> 0x~~~~~~~~~~~~~~~~
# v28: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v29: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v30: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v24: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v25: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v26: 0x0000 -> 0x~~~~~~~~~~~~~~~~
# v27: 0x00fe -> 0x~~~~~~~~~~~~~~~~
# v18: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v19: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v20: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v21: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v6: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v7: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v8: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v9: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v25: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v26: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
# v27: 0x00010000 (..., 9.18355e-41, ...) -> 0x~~~~~~~~~~~~~~~~
# v28: 0x00000000 (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~

View File

@ -0,0 +1,406 @@
#  w18: 0x00000060 -> 0x~~~~~~~~~~~~~~~~
#  x19: 0x0000000000000086 -> 0x~~~~~~~~~~~~~~~~
#  w20<7:0>: 0x04 -> 0x~~~~~~~~~~~~~~~~
#  w21<7:0>: 0x03 -> 0x~~~~~~~~~~~~~~~~
#  w22<15:0>: 0x0004 -> 0x~~~~~~~~~~~~~~~~
#  w23<15:0>: 0x0100 -> 0x~~~~~~~~~~~~~~~~
#  w14: 0x00000000 -> 0x~~~~~~~~~~~~~~~~
#  w15: 0x00000082 -> 0x~~~~~~~~~~~~~~~~
#  x16: 0x000000000000000c -> 0x~~~~~~~~~~~~~~~~
#  x17: 0x00000000ffffff7b -> 0x~~~~~~~~~~~~~~~~
#  w18: 0x00000060 -> 0x~~~~~~~~~~~~~~~~
#  w19: 0x00000086 -> 0x~~~~~~~~~~~~~~~~
#  w18: 0x00000060 -> 0x~~~~~~~~~~~~~~~~
#  w19: 0x00000086 -> 0x~~~~~~~~~~~~~~~~
#  w18: 0x00000060 -> 0x~~~~~~~~~~~~~~~~
#  w19: 0x00000086 -> 0x~~~~~~~~~~~~~~~~
#  x20: 0x0000000000000304 -> 0x~~~~~~~~~~~~~~~~
#  x21: 0x0000000000000403 -> 0x~~~~~~~~~~~~~~~~
#  x20: 0x0000000000000304 -> 0x~~~~~~~~~~~~~~~~
#  x21: 0x0000000000000403 -> 0x~~~~~~~~~~~~~~~~
#  x20: 0x0000000000000304 -> 0x~~~~~~~~~~~~~~~~
#  x21: 0x0000000000000403 -> 0x~~~~~~~~~~~~~~~~
#  w22: 0x00000004 -> 0x~~~~~~~~~~~~~~~~
#  w22: 0x00000004 -> 0x~~~~~~~~~~~~~~~~
#  w22: 0x00000004 -> 0x~~~~~~~~~~~~~~~~
#  x23: 0x0000000003020100 -> 0x~~~~~~~~~~~~~~~~
#  x23: 0x0000000003020100 -> 0x~~~~~~~~~~~~~~~~
#  x23: 0x0000000003020100 -> 0x~~~~~~~~~~~~~~~~
#  w24<7:0>: 0x01 -> 0x~~~~~~~~~~~~~~~~
#  w24<7:0>: 0x01 -> 0x~~~~~~~~~~~~~~~~
#  w24<7:0>: 0x01 -> 0x~~~~~~~~~~~~~~~~
#  w25<7:0>: 0x00 -> 0x~~~~~~~~~~~~~~~~
#  w25<7:0>: 0x00 -> 0x~~~~~~~~~~~~~~~~
#  w25<7:0>: 0x00 -> 0x~~~~~~~~~~~~~~~~
#  w26<15:0>: 0xfcff -> 0x~~~~~~~~~~~~~~~~
#  w26<15:0>: 0xfcff -> 0x~~~~~~~~~~~~~~~~
#  w26<15:0>: 0xfcff -> 0x~~~~~~~~~~~~~~~~
#  w27<15:0>: 0x0001 -> 0x~~~~~~~~~~~~~~~~
#  w27<15:0>: 0x0001 -> 0x~~~~~~~~~~~~~~~~
#  w27<15:0>: 0x0001 -> 0x~~~~~~~~~~~~~~~~
#  w28: 0xfffeffff -> 0x~~~~~~~~~~~~~~~~
#  x29: 0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  w2<7:0>: 0x01 -> 0x~~~~~~~~~~~~~~~~
#  w3<7:0>: 0xff -> 0x~~~~~~~~~~~~~~~~
#  w4<15:0>: 0x0001 -> 0x~~~~~~~~~~~~~~~~
#  w5<15:0>: 0x8500 -> 0x~~~~~~~~~~~~~~~~
#  v18: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v19: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v20: 0x00000000000000000000000000000020 -> 0x~~~~~~~~~~~~~~~~
#  v21: 0x000000000000000000000000ffff8007 -> 0x~~~~~~~~~~~~~~~~
#  v10: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v11: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v12: 0x000000000000000000000000ffffffff -> 0x~~~~~~~~~~~~~~~~
#  v13: 0x0000000000000000ffffffffffefffe1 -> 0x~~~~~~~~~~~~~~~~
#  v27: 0x00000000000000fe0001000000010000 -> 0x~~~~~~~~~~~~~~~~
#  v28: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v29: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v30: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v16: 0x00000000000000000000000000007ff9 -> 0x~~~~~~~~~~~~~~~~
#  v17: 0x00000000000000000000000000000400 -> 0x~~~~~~~~~~~~~~~~
#  v18: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v21: 0x000000000000000000000000ffff8007 -> 0x~~~~~~~~~~~~~~~~
#  v22: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v23: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v9: 0x00000000000000000020000000200040 -> 0x~~~~~~~~~~~~~~~~
#  v10: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v11: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v7: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v8: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v26: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v27: 0x00000000000000fe0001000000010000 -> 0x~~~~~~~~~~~~~~~~
#  v22: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v23: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v23: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v28: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v2: 0x00000000000000000020000000200040 -> 0x~~~~~~~~~~~~~~~~
#  v29:  0x0000000000000000 (d29: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v30:  0x0000000000000000 (d30: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v31:  0x0000000000000000 (d31: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v0:  0x0000000000000000 (d0: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v12:  0x00000000ffffffff (d12: 2.12200e-314) -> 0x~~~~~~~~~~~~~~~~
#  v13:  0xffffffffffefffe1 (d13: -nan) -> 0x~~~~~~~~~~~~~~~~
#  v14:  0x0000000000000001 (d14: 4.94066e-324) -> 0x~~~~~~~~~~~~~~~~
#  v15:  0x0000000000000000 (d15: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v30:  0x0000000000000000 (d30: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v31:  0x0000000000000000 (d31: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v0:  0x0000000000000000 (d0: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v1:  0x0000000000000000 (d1: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v16:  0x0000000000007ff9 (d16: 1.61861e-319) -> 0x~~~~~~~~~~~~~~~~
#  v17:  0x0000000000000400 (d17: 5.05923e-321) -> 0x~~~~~~~~~~~~~~~~
#  v18:  0x0000000000000000 (d18: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v3:  0x0000000000000000 (d3: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v4:  0x0000000000000000 (d4: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v5:  0x0000000000000000 (d5: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v14:  0x0000000000000001 (d14: 4.94066e-324) -> 0x~~~~~~~~~~~~~~~~
#  v15:  0x0000000000000000 (d15: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v16:  0x0000000000007ff9 (d16: 1.61861e-319) -> 0x~~~~~~~~~~~~~~~~
#  v18:  0x0000000000000000 (d18: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v19:  0x0000000000000000 (d19: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v5:  0x0000000000000000 (d5: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v6:  0x0000000000000000 (d6: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v2:  0x0020000000200040 (d2: 4.45015e-308) -> 0x~~~~~~~~~~~~~~~~
#  v3:  0x0000000000000000 (d3: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v4:  0x0000000000000000 (d4: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v27:  0x0001000000010000 (d27: 1.39067e-309) -> 0x~~~~~~~~~~~~~~~~
#  v23:  0x0000000000000000 (d23: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v2: 0x00000000000000000020000000200040 (0.00000, 4.45015e-308) -> 0x~~~~~~~~~~~~~~~~
#  v3: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v4: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v5: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v22: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v23: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v24: 0x00000000000000000000000000007ff9 (0.00000, 1.61861e-319) -> 0x~~~~~~~~~~~~~~~~
#  v25: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v28: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v29: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v30: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v31: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v17: 0x00000000000000000000000000000400 (0.00000, 5.05923e-321) -> 0x~~~~~~~~~~~~~~~~
#  v18: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v19: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v16: 0x00000000000000000000000000007ff9 (0.00000, 1.61861e-319) -> 0x~~~~~~~~~~~~~~~~
#  v17: 0x00000000000000000000000000000400 (0.00000, 5.05923e-321) -> 0x~~~~~~~~~~~~~~~~
#  v18: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v22: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v23: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v24: 0x00000000000000000000000000007ff9 (0.00000, 1.61861e-319) -> 0x~~~~~~~~~~~~~~~~
#  v21: 0x000000000000000000000000ffff8007 (0.00000, 2.12198e-314) -> 0x~~~~~~~~~~~~~~~~
#  v22: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v6: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v7: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v27: 0x00000000000000fe0001000000010000 (1.25493e-321, 1.39067e-309) -> 0x~~~~~~~~~~~~~~~~
#  v28: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v21: 0x000000000000000000000000ffff8007 (0.00000, 2.12198e-314) -> 0x~~~~~~~~~~~~~~~~
#  v29: 0x00000000000000000000000000000000 (0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v20: 0x00000000000000000000000000000020 (0.00000, 1.58101e-322) -> 0x~~~~~~~~~~~~~~~~
#  v22:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v23:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v24:  0x0000000000007ff9 (..., 0.00000, 4.59079e-41) -> 0x~~~~~~~~~~~~~~~~
#  v25:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v8:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v9:  0x0020000000200040 (..., 2.93874e-39, 2.93883e-39) -> 0x~~~~~~~~~~~~~~~~
#  v10:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v11:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v15:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v16:  0x0000000000007ff9 (..., 0.00000, 4.59079e-41) -> 0x~~~~~~~~~~~~~~~~
#  v17:  0x0000000000000400 (..., 0.00000, 1.43493e-42) -> 0x~~~~~~~~~~~~~~~~
#  v18:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v2:  0x0020000000200040 (..., 2.93874e-39, 2.93883e-39) -> 0x~~~~~~~~~~~~~~~~
#  v3:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v4:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v23:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v24:  0x0000000000007ff9 (..., 0.00000, 4.59079e-41) -> 0x~~~~~~~~~~~~~~~~
#  v25:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v7:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v8:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v9:  0x0020000000200040 (..., 2.93874e-39, 2.93883e-39) -> 0x~~~~~~~~~~~~~~~~
#  v28:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v29:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v29:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v30:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v23:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v24:  0x0000000000007ff9 (..., 0.00000, 4.59079e-41) -> 0x~~~~~~~~~~~~~~~~
#  v6:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v11:  0x0000000000000000 (..., 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v17:  0x0000000000000400 (..., 0.00000, 1.43493e-42) -> 0x~~~~~~~~~~~~~~~~
#  v6:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v7:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v8:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v9:  0x0020000000200040 -> 0x~~~~~~~~~~~~~~~~
#  v9:  0x0020000000200040 -> 0x~~~~~~~~~~~~~~~~
#  v10:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v11:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v12:  0x00000000ffffffff -> 0x~~~~~~~~~~~~~~~~
#  v25:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v26:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v27:  0x0001000000010000 -> 0x~~~~~~~~~~~~~~~~
#  v28:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v11:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v12:  0x00000000ffffffff -> 0x~~~~~~~~~~~~~~~~
#  v13:  0xffffffffffefffe1 -> 0x~~~~~~~~~~~~~~~~
#  v10:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v11:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v12:  0x00000000ffffffff -> 0x~~~~~~~~~~~~~~~~
#  v12:  0x00000000ffffffff -> 0x~~~~~~~~~~~~~~~~
#  v13:  0xffffffffffefffe1 -> 0x~~~~~~~~~~~~~~~~
#  v14:  0x0000000000000001 -> 0x~~~~~~~~~~~~~~~~
#  v13:  0xffffffffffefffe1 -> 0x~~~~~~~~~~~~~~~~
#  v14:  0x0000000000000001 -> 0x~~~~~~~~~~~~~~~~
#  v15:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v16:  0x0000000000007ff9 -> 0x~~~~~~~~~~~~~~~~
#  v21:  0x00000000ffff8007 -> 0x~~~~~~~~~~~~~~~~
#  v22:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v16:  0x0000000000007ff9 -> 0x~~~~~~~~~~~~~~~~
#  v8:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v30:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v3: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v4: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v5: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v6: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v25: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v26: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v27: 0x00000000000000fe0001000000010000 (0.00000, 3.55930e-43, 9.18355e-41, 9.18355e-41) -> 0x~~~~~~~~~~~~~~~~
#  v28: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v5: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v6: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v7: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v8: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v31: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v0: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v1: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v30: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v31: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v0: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v6: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v7: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v8: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v17: 0x00000000000000000000000000000400 (0.00000, 0.00000, 0.00000, 1.43493e-42) -> 0x~~~~~~~~~~~~~~~~
#  v18: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v31: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v0: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v1: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v2: 0x00000000000000000020000000200040 (0.00000, 0.00000, 2.93874e-39, 2.93883e-39) -> 0x~~~~~~~~~~~~~~~~
#  v26: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v15: 0x00000000000000000000000000000000 (0.00000, 0.00000, 0.00000, 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v13: 0x0000000000000000ffffffffffefffe1 (0.00000, 0.00000, -nan, -nan) -> 0x~~~~~~~~~~~~~~~~
#  v26:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v27:  0x0001000000010000 -> 0x~~~~~~~~~~~~~~~~
#  v28:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v29:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v10:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v11:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v12:  0x00000000ffffffff -> 0x~~~~~~~~~~~~~~~~
#  v13:  0xffffffffffefffe1 -> 0x~~~~~~~~~~~~~~~~
#  v15:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v16:  0x0000000000007ff9 -> 0x~~~~~~~~~~~~~~~~
#  v17:  0x0000000000000400 -> 0x~~~~~~~~~~~~~~~~
#  v18:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v19:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v20:  0x0000000000000020 -> 0x~~~~~~~~~~~~~~~~
#  v21:  0x00000000ffff8007 -> 0x~~~~~~~~~~~~~~~~
#  v31:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v0:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v1:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v9:  0x0020000000200040 -> 0x~~~~~~~~~~~~~~~~
#  v10:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v11:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v12:  0x00000000ffffffff -> 0x~~~~~~~~~~~~~~~~
#  v13:  0xffffffffffefffe1 -> 0x~~~~~~~~~~~~~~~~
#  v2:  0x0020000000200040 -> 0x~~~~~~~~~~~~~~~~
#  v3:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v0:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v1:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v16:  0x0000000000007ff9 -> 0x~~~~~~~~~~~~~~~~
#  v25:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v31:  0x0000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v4: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v5: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v6: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v7: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v3: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v4: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v5: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v6: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v26: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v27: 0x00000000000000fe0001000000010000 -> 0x~~~~~~~~~~~~~~~~
#  v28: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v29: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v10: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v11: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v12: 0x000000000000000000000000ffffffff -> 0x~~~~~~~~~~~~~~~~
#  v21: 0x000000000000000000000000ffff8007 -> 0x~~~~~~~~~~~~~~~~
#  v22: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v23: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v18: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v19: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v20: 0x00000000000000000000000000000020 -> 0x~~~~~~~~~~~~~~~~
#  v26: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v27: 0x00000000000000fe0001000000010000 -> 0x~~~~~~~~~~~~~~~~
#  v24: 0x00000000000000000000000000007ff9 -> 0x~~~~~~~~~~~~~~~~
#  v25: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v17: 0x00000000000000000000000000000400 -> 0x~~~~~~~~~~~~~~~~
#  v18: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v29: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v19: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v23: 0x00000000000000000000000000000000 -> 0x~~~~~~~~~~~~~~~~
#  v19: 0x00  -> 0x~~~~~~~~~~~~~~~~
#  v25:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v4:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v13:  0xffffffffffefffe1 (d13: -nan) -> 0x~~~~~~~~~~~~~~~~
#  v30:  0x0000000000000000 (d30: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v3:  0x0000000000000000 (d3: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v22:  0x0000 -> 0x~~~~~~~~~~~~~~~~
#  v31: 0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v23:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v0:  0x00000000 (s0: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v11: 0x00000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v24: 0x00000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v8: 0x00  -> 0x~~~~~~~~~~~~~~~~
#  v9: 0x00  -> 0x~~~~~~~~~~~~~~~~
#  v8: 0x00  -> 0x~~~~~~~~~~~~~~~~
#  v9: 0x00  -> 0x~~~~~~~~~~~~~~~~
#  v7:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v8:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v25:  0x0000000000000000 (d25: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v26:  0x0000000000000000 (d26: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v17: 0x0000000000000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v18: 0x0000000000000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v3: 0x0000000000000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v4: 0x0000000000000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v4:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v5:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v0:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v1:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v22:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v23:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v14: 0x00000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v15: 0x00000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v23: 0x00000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v24: 0x00000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v0:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v1:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v31:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v0:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v1:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v4:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v5:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v6:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v5:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v6:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v7:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v5:  0x0000000000000000 (d5: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v6:  0x0000000000000000 (d6: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v7:  0x0000000000000000 (d7: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v6:  0x0000000000000000 (d6: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v7:  0x0000000000000000 (d7: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v8:  0x0000000000000000 (d8: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v0:  0x0000000000000000 (d0: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v1:  0x0000000000000000 (d1: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v2:  0x0020000000200040 (d2: 4.45015e-308) -> 0x~~~~~~~~~~~~~~~~
#  v31:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v0:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v1:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v14:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v15:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v16:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v21:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v22:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v23:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v21:  0xffff8007 (s21: -nan) -> 0x~~~~~~~~~~~~~~~~
#  v22:  0x00000000 (s22: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v23:  0x00000000 (s23: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v11:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v12:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v13:  0xffffffff  (..., -nan, ...) -> 0x~~~~~~~~~~~~~~~~
#  v15:  0x00000000 (s15: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v16:  0x00007ff9 (s16: 4.59079e-41) -> 0x~~~~~~~~~~~~~~~~
#  v17:  0x00000400 (s17: 1.43493e-42) -> 0x~~~~~~~~~~~~~~~~
#  v0:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v1:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v2:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v3:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v4:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v5:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v6:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v7:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v9:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v10:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v11:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v12:  0x00  -> 0x~~~~~~~~~~~~~~~~
#  v2: 0x0000000000000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v3: 0x0000000000000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v4: 0x0000000000000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v5: 0x0000000000000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v7:  0x0000000000000000 (d7: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v8:  0x0000000000000000 (d8: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v9:  0x0020000000200040 (d9: 4.45015e-308) -> 0x~~~~~~~~~~~~~~~~
#  v10:  0x0000000000000000 (d10: 0.00000) -> 0x~~~~~~~~~~~~~~~~
#  v31: 0x0000000000000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v0: 0x0000000000000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v1: 0x0000000000000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v2: 0x0000000000000000  (0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v2:  0x0020  -> 0x~~~~~~~~~~~~~~~~
#  v3:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v4:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v5:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v27:  0x0001  -> 0x~~~~~~~~~~~~~~~~
#  v28:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v29:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v30:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v24:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v25:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v26:  0x0000  -> 0x~~~~~~~~~~~~~~~~
#  v27:  0x00fe  -> 0x~~~~~~~~~~~~~~~~
#  v18:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v19:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v20:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v21:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v6:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v7:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v8:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v9:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v25:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v26:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~
#  v27:  0x00010000  (..., 9.18355e-41, ...) -> 0x~~~~~~~~~~~~~~~~
#  v28:  0x00000000  (..., 0.00000, ...) -> 0x~~~~~~~~~~~~~~~~

View File

@ -430,7 +430,7 @@ void RegisterDump::Dump(MacroAssembler* masm) {
__ Str(tmp, MemOperand(dump_base, flags_offset));
// To dump the values that were in tmp amd dump, we need a new scratch
// register. We can use any of the already dumped registers since we can
// register. We can use any of the already dumped registers since we can
// easily restore them.
Register dump2_base = x10;
Register dump2 = x11;

193
tools/clang_format.py Executable file
View File

@ -0,0 +1,193 @@
#!/usr/bin/env python2.7
# Copyright 2016, ARM Limited
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of ARM Limited nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import argparse
import fnmatch
import multiprocessing
import os
import signal
import subprocess
import sys
import tempfile
import config
import git
import printer
import util
is_output_redirected = not sys.stdout.isatty()
# Catch SIGINT to gracefully exit when ctrl+C is pressed.
def sigint_handler(signal, frame):
sys.exit(1)
signal.signal(signal.SIGINT, sigint_handler)
def BuildOptions():
parser = argparse.ArgumentParser(
description = '''This tool runs `clang-format` on C++ files.
If no files are provided on the command-line, all C++ source files in `src`,
`sample`, and `benchmarks` are processed.
When available, `colordiff` is automatically used to clour the output.''',
# Print default values.
formatter_class = argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('files', nargs = '*')
parser.add_argument('--in-place', '-i',
action = 'store_true', default = False,
help = 'Edit files in place.')
parser.add_argument('--jobs', '-j', metavar = 'N', type = int, nargs = '?',
default = multiprocessing.cpu_count(),
const = multiprocessing.cpu_count(),
help = '''Runs the tests using N jobs. If the option is set
but no value is provided, the script will use as many jobs
as it thinks useful.''')
return parser.parse_args()
# Returns 0 if the file is correctly formatted, or 1 otherwise.
def ClangFormat(filename, in_place = False, progress_prefix = ''):
rc = 0
printer.PrintOverwritableLine('Processing %s' % filename,
type = printer.LINE_TYPE_LINTER)
cmd_format = ['clang-format-3.6', filename]
temp_file, temp_file_name = tempfile.mkstemp(prefix = 'clang_format_')
cmd_format_string = '$ ' + ' '.join(cmd_format) + ' > %s' % temp_file_name
p_format = subprocess.Popen(cmd_format,
stdout = temp_file, stderr = subprocess.STDOUT)
rc += p_format.wait()
cmd_diff = ['diff', '--unified', filename, temp_file_name]
cmd_diff_string = '$ ' + ' '.join(cmd_diff)
p_diff = subprocess.Popen(cmd_diff,
stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
if util.IsCommandAvailable('colordiff') and not is_output_redirected:
p_colordiff = subprocess.Popen(
['colordiff', '--unified'],
stdin = p_diff.stdout,
stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
out, unused = p_colordiff.communicate()
else:
out, unused = p_diff.communicate()
rc += p_diff.wait()
if in_place:
cmd_format = ['clang-format-3.6', '-i', filename]
p_format = subprocess.Popen(cmd_format,
stdout=temp_file, stderr=subprocess.STDOUT)
if rc != 0:
printer.Print('Incorrectly formatted file: ' + filename + '\n' + \
cmd_format_string + '\n' + \
cmd_diff_string + '\n' + \
out)
return 0 if rc == 0 else 1
# The multiprocessing map_async function does not allow passing multiple
# arguments directly, so use a wrapper.
def ClangFormatWrapper(args):
# Run under a try-catch to avoid flooding the output when the script is
# interrupted from the keyboard with ctrl+C.
try:
return ClangFormat(*args)
except:
sys.exit(1)
# Returns the total number of files incorrectly formatted.
def ClangFormatFiles(files, in_place = False, jobs = 1, progress_prefix = ''):
if not util.IsCommandAvailable('clang-format-3.6'):
print(
printer.COLOUR_RED + \
("`clang-format-3.6` not found. Please ensure it is installed "
"and in your PATH.") + \
printer.NO_COLOUR)
return -1
pool = multiprocessing.Pool(jobs)
# The '.get(9999999)' is workaround to allow killing the test script with
# ctrl+C from the shell. This bug is documented at
# http://bugs.python.org/issue8296.
tasks = [(f, in_place, progress_prefix) for f in files]
# Run under a try-catch to avoid flooding the output when the script is
# interrupted from the keyboard with ctrl+C.
try:
results = pool.map_async(ClangFormatWrapper, tasks).get(9999999)
pool.close()
pool.join()
except KeyboardInterrupt:
pool.terminate()
sys.exit(1)
rc = sum(results)
printer.PrintOverwritableLine(
progress_prefix + '%d files are incorrectly formatted.' % rc,
type = printer.LINE_TYPE_LINTER)
printer.EnsureNewLine()
return rc
def Find(path, filters = ['*']):
files_found = []
def NameMatchesAnyFilter(name, ff):
for f in ff:
if fnmatch.fnmatch(name, f):
return True
return False
for root, dirs, files in os.walk(path):
files_found += [os.path.relpath(os.path.join(root, fn))
for fn in files if NameMatchesAnyFilter(fn, filters)]
return files_found
def GetCppSourceFilesToFormat():
sources = []
source_dirs = [config.dir_benchmarks,
config.dir_examples,
config.dir_src_vixl ]
for directory in source_dirs:
sources += Find(directory, ['*.h', '*.cc'])
return sources
if __name__ == '__main__':
# Parse the arguments.
args = BuildOptions()
files = args.files
if not files:
files = GetCppSourceFilesToFormat()
rc = ClangFormatFiles(files, in_place = args.in_place, jobs = args.jobs)
sys.exit(rc)

View File

@ -106,7 +106,8 @@ trace_header = """
def BuildOptions(root):
result = argparse.ArgumentParser(description = 'Simulator test generator.')
result.add_argument('--runner', action='store', default=root+'/test-runner',
result.add_argument('--runner', action='store',
default=os.path.join(root, 'obj/latest/test/test-runner'),
help='The test executable to run.')
result.add_argument('--out', action='store',
default='test/test-simulator-traces-a64.h')
@ -120,8 +121,8 @@ if __name__ == '__main__':
args = BuildOptions(root_dir)
# Run each simulator test (SIM_*) with the --sim_test_trace option, and use
# the output to create the traces header (from --out). In addition, the
# Run each simulator test (SIM_*) with the --generate_test_trace option, and
# use the output to create the traces header (from --out). In addition, the
# test-simulator-traces-a64.h file, the master trace file, which includes all
# other trace files is generated.
@ -140,7 +141,7 @@ if __name__ == '__main__':
for test in tests:
# Run each test.
print 'Generating trace for ' + test;
cmd = ' '.join([args.runner, '--sim_test_trace', test])
cmd = ' '.join([args.runner, '--generate_test_trace', test])
status, output = util.getstatusoutput(cmd)
if status != 0: util.abort('Failed to run ' + cmd + '.')

View File

@ -0,0 +1,77 @@
#!/usr/bin/env python2.7
# Copyright 2016, ARM Limited
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of ARM Limited nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os
import sys
import argparse
import re
import util
def BuildOptions(root):
result = argparse.ArgumentParser(
description = 'Generate reference output for TRACE_* tests')
result.add_argument('--runner', action='store',
default=os.path.join(root, 'obj/latest/test/test-runner'),
help='The test executable to run.')
result.add_argument('--outdir', action='store',
default='test/test-trace-reference/')
return result.parse_args()
if __name__ == '__main__':
root_dir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
os.chdir(root_dir)
args = BuildOptions(root_dir)
# Run each trace test (TRACE_*) with the --generate_test_trace option, and
# use the output to create the reference traces (in --outdir).
# Find the trace tests.
status, output = util.getstatusoutput(args.runner + ' --list')
if status != 0: util.abort('Failed to list all tests')
tests = filter(lambda t: 'TRACE_' in t, output.split())
tests.sort()
if not os.path.exists(args.outdir):
os.makedirs(args.outdir)
for test in tests:
# Run each test.
print 'Generating trace for ' + test;
cmd = ' '.join([args.runner, '--generate_test_trace', test])
status, output = util.getstatusoutput(cmd)
if status != 0: util.abort('Failed to run ' + cmd + '.')
# Create a new trace header file.
trace_filename = 'log-' + test.replace('TRACE_', '').lower().replace('_', '-')
trace_f = open(os.path.join(args.outdir, trace_filename), 'w')
trace_f.write(output)
# `getstatusoutput` removes the trailing newline. Put it back, but only if
# the output was not empty.
if len(output) > 0: trace_f.write('\n')

View File

@ -45,18 +45,21 @@ def sigint_handler(signal, frame):
signal.signal(signal.SIGINT, sigint_handler)
def BuildOptions():
result = argparse.ArgumentParser(
parser = argparse.ArgumentParser(
description =
'''This tool lints the C++ files tracked by the git repository, and
produces a summary of the errors found.''',
'''This tool lints C++ files and produces a summary of the errors found.
If no files are provided on the command-line, all C++ source files in the
repository are processed.''',
# Print default values.
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
result.add_argument('--jobs', '-j', metavar='N', type=int, nargs='?',
default=1, const=multiprocessing.cpu_count(),
parser.add_argument('files', nargs = '*')
parser.add_argument('--jobs', '-j', metavar='N', type=int, nargs='?',
default=multiprocessing.cpu_count(),
const=multiprocessing.cpu_count(),
help='''Runs the tests using N jobs. If the option is set
but no value is provided, the script will use as many jobs
as it thinks useful.''')
return result.parse_args()
return parser.parse_args()
@ -178,9 +181,10 @@ if __name__ == '__main__':
# Parse the arguments.
args = BuildOptions()
retcode, default_tracked_files = GetDefaultTrackedFiles()
if retcode:
sys.exit(retcode)
retcode = LintFiles(default_tracked_files,
jobs = args.jobs)
files = args.files
if not files:
retcode, files = GetDefaultTrackedFiles()
if retcode:
sys.exit(retcode)
retcode = LintFiles(files, jobs = args.jobs)
sys.exit(retcode)

View File

@ -26,6 +26,9 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
use v5.10.1;
no warnings 'experimental::smartmatch';
# Assembler header file.
my $hfile = "src/vixl/a64/assembler-a64.h";
@ -35,7 +38,7 @@ my @extras = qw/bind debug dci dc32 dc64 place/;
my %inst = (); # Global hash of instructions.
$/ = '';
open(IN, "<$hfile") or die("Can't open header file $header.\n");
open(IN, "<$hfile") or die("Can't open header file $hfile.\n");
while(<IN>)
{
# Find a function formatted like an instruction.

View File

@ -40,6 +40,7 @@ import sys
import time
import config
import clang_format
import lint
import printer
import test
@ -178,7 +179,7 @@ test_options = \
def BuildOptions():
args = argparse.ArgumentParser(
description =
'''This tool runs all tests matching the speficied filters for multiple
'''This tool runs all tests matching the specified filters for multiple
environment, build options, and runtime options configurations.''',
# Print default values.
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
@ -204,12 +205,13 @@ def BuildOptions():
general_arguments = args.add_argument_group('General options')
general_arguments.add_argument('--fast', action='store_true',
help='''Skip the lint tests, and run only with
one compiler, in one mode, with one C++
standard, and with an appropriate default for
runtime options. The compiler, mode, and C++
standard used are the first ones provided to
the script or in the default arguments.''')
help='''Skip the lint and clang-format tests,
and run only with one compiler, in one mode,
with one C++ standard, and with an appropriate
default for runtime options. The compiler,
mode, and C++ standard used are the first ones
provided to the script or in the default
arguments.''')
general_arguments.add_argument(
'--jobs', '-j', metavar='N', type=int, nargs='?',
default=multiprocessing.cpu_count(),
@ -220,6 +222,8 @@ def BuildOptions():
help='Do not run benchmarks.')
general_arguments.add_argument('--nolint', action='store_true',
help='Do not run the linter.')
general_arguments.add_argument('--noclang-format', action='store_true',
help='Do not run clang-format.')
general_arguments.add_argument('--notest', action='store_true',
help='Do not run tests.')
sim_default = 'off' if platform.machine() == 'aarch64' else 'on'
@ -323,6 +327,12 @@ def RunLinter():
jobs = args.jobs, progress_prefix = 'cpp lint: ')
def RunClangFormat():
return clang_format.ClangFormatFiles(clang_format.GetCppSourceFilesToFormat(),
jobs = args.jobs,
progress_prefix = 'clang-format: ')
def BuildAll(build_options, jobs):
scons_command = ["scons", "-C", dir_root, 'all', '-j', str(jobs)]
@ -368,6 +378,8 @@ if __name__ == '__main__':
if not args.nolint and not args.fast:
rc |= RunLinter()
if not args.noclang_format and not args.fast:
rc |= RunClangFormat()
# Don't try to test the debugger if we are not running with the simulator.
if not args.simulator:

View File

@ -52,6 +52,11 @@ def getstatusoutput(command, shell=False):
return e.returncode, e.output.rstrip('\n')
def IsCommandAvailable(command):
retcode, unused_output = getstatusoutput('which %s' % command)
return retcode == 0
def ensure_dir(path_name):
if not os.path.exists(path_name):
os.makedirs(path_name)