aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarmvixl <vixl@arm.com>2015-10-23 13:38:33 +0100
committerarmvixl <vixl@arm.com>2015-10-23 13:38:33 +0100
commit684cd2a7f5845539b58d0da7e012e39df49ceff0 (patch)
tree9cc167c2cf3a42d44477bdf0f6d8f67bc479c2f2
parentdb6443499376478f5281607a3923e6ffc4c8d8ec (diff)
VIXL Release 1.11
Refer to the README.md and LICENCE files for details.
-rw-r--r--README.md2
-rw-r--r--SConstruct5
-rw-r--r--doc/changelog.md7
-rw-r--r--examples/abs.cc4
-rw-r--r--examples/add2-vectors.cc4
-rw-r--r--examples/add3-double.cc4
-rw-r--r--examples/add4-double.cc4
-rw-r--r--examples/check-bounds.cc4
-rw-r--r--examples/crc-checksums.cc4
-rw-r--r--examples/debugger.cc4
-rw-r--r--examples/factorial-rec.cc4
-rw-r--r--examples/factorial.cc4
-rw-r--r--examples/getting-started.cc4
-rw-r--r--examples/literal.cc8
-rw-r--r--examples/neon-matrix-multiply.cc4
-rw-r--r--examples/non-const-visitor.cc6
-rw-r--r--examples/sum-array.cc4
-rw-r--r--examples/swap-int32.cc4
-rw-r--r--examples/swap4.cc4
-rw-r--r--src/vixl/a64/debugger-a64.cc27
-rw-r--r--src/vixl/a64/debugger-a64.h4
-rw-r--r--src/vixl/a64/decoder-a64.h12
-rw-r--r--src/vixl/a64/instrument-a64.cc3
-rw-r--r--src/vixl/a64/instrument-a64.h4
-rw-r--r--src/vixl/a64/logic-a64.cc4
-rw-r--r--src/vixl/a64/macro-assembler-a64.cc80
-rw-r--r--src/vixl/a64/macro-assembler-a64.h35
-rw-r--r--src/vixl/a64/simulator-a64.cc67
-rw-r--r--src/vixl/a64/simulator-a64.h137
-rw-r--r--src/vixl/a64/simulator-constants-a64.h141
-rw-r--r--src/vixl/globals.h32
-rw-r--r--test/examples/test-examples.cc4
-rw-r--r--test/test-assembler-a64.cc515
-rw-r--r--test/test-disasm-a64.cc75
-rw-r--r--test/test-simulator-a64.cc6
-rw-r--r--third_party/android/Android.mk.template7
-rwxr-xr-xtools/test.py9
-rw-r--r--tools/threaded_tests.py6
38 files changed, 812 insertions, 440 deletions
diff --git a/README.md b/README.md
index 45144233..4b73303e 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-VIXL: AArch64 Runtime Code Generation Library Version 1.10
+VIXL: AArch64 Runtime Code Generation Library Version 1.11
==========================================================
Contents:
diff --git a/SConstruct b/SConstruct
index 3293263d..ecbd29a3 100644
--- a/SConstruct
+++ b/SConstruct
@@ -52,7 +52,7 @@ class TopLevelTargets:
self.targets.append(target)
self.help_messages.append(help_message)
def Help(self):
- res = ""
+ res = ""
for i in range(len(self.targets)):
res += '\t{0:<{1}}{2:<{3}}\n'.format(
'scons ' + self.targets[i],
@@ -78,6 +78,7 @@ options = {
'-Wextra',
'-Wredundant-decls',
'-pedantic',
+ '-Wmissing-noreturn',
'-Wwrite-strings'],
'CPPPATH' : [config.dir_src_vixl]
},
@@ -91,7 +92,7 @@ options = {
'CCFLAGS' : ['-O3']
},
'simulator:on' : {
- 'CCFLAGS' : ['-DUSE_SIMULATOR'],
+ 'CCFLAGS' : ['-DVIXL_INCLUDE_SIMULATOR'],
},
'symbols:on' : {
'CCFLAGS' : ['-g'],
diff --git a/doc/changelog.md b/doc/changelog.md
index 83a9c269..e3c4e2a6 100644
--- a/doc/changelog.md
+++ b/doc/changelog.md
@@ -1,6 +1,13 @@
VIXL Change Log
===============
+* 1.11
+ + Fix bug in simulation of add with carry.
+ + Fix use-after-free bug in Literal handling.
+ + Build system updates for Android.
+ + Add option to run test.py under Valgrind.
+ + Other small bug fixes and improvements.
+
* 1.10
+ Improved support for externally managed literals.
+ Reworked build and test infrastructure.
diff --git a/examples/abs.cc b/examples/abs.cc
index 8d6d052c..634c375c 100644
--- a/examples/abs.cc
+++ b/examples/abs.cc
@@ -43,7 +43,7 @@ void GenerateAbs(MacroAssembler* masm) {
#ifndef TEST_EXAMPLES
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
int main(void) {
// Create and initialize the assembler and the simulator.
byte assm_buf[BUF_SIZE];
@@ -68,5 +68,5 @@ int main(void) {
#else
// Without the simulator there is nothing to test.
int main(void) { return 0; }
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
#endif // TEST_EXAMPLES
diff --git a/examples/add2-vectors.cc b/examples/add2-vectors.cc
index 47618552..4992708e 100644
--- a/examples/add2-vectors.cc
+++ b/examples/add2-vectors.cc
@@ -126,7 +126,7 @@ int main(void) {
vecC[i] = vecA[i] + vecB[i];
}
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
uintptr_t vecA_addr = reinterpret_cast<uintptr_t>(vecA);
uintptr_t vecB_addr = reinterpret_cast<uintptr_t>(vecB);
@@ -148,7 +148,7 @@ int main(void) {
// Placeholder to run test natively.
printf("Running tests natively is not supported yet.\n");
return 0;
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
// Check that the computed value in NEON matches the C version.
for (unsigned i = 0; i < ARRAY_SIZE(vecA); i++) {
assert(vecC[i] == vecA[i]);
diff --git a/examples/add3-double.cc b/examples/add3-double.cc
index 460917ce..f14947f0 100644
--- a/examples/add3-double.cc
+++ b/examples/add3-double.cc
@@ -44,7 +44,7 @@ void GenerateAdd3Double(MacroAssembler* masm) {
#ifndef TEST_EXAMPLES
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
int main(void) {
// Create and initialize the assembler and the simulator.
byte assm_buf[BUF_SIZE];
@@ -73,5 +73,5 @@ int main(void) {
#else
// Without the simulator there is nothing to test.
int main(void) { return 0; }
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
#endif // TEST_EXAMPLES
diff --git a/examples/add4-double.cc b/examples/add4-double.cc
index 51addbba..ac259641 100644
--- a/examples/add4-double.cc
+++ b/examples/add4-double.cc
@@ -52,7 +52,7 @@ void GenerateAdd4Double(MacroAssembler* masm) {
#ifndef TEST_EXAMPLES
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
int main(void) {
// Create and initialize the assembler and the simulator.
byte assm_buf[BUF_SIZE];
@@ -83,5 +83,5 @@ int main(void) {
#else
// Without the simulator there is nothing to test.
int main(void) { return 0; }
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
#endif // TEST_EXAMPLES
diff --git a/examples/check-bounds.cc b/examples/check-bounds.cc
index 18622b24..635918e5 100644
--- a/examples/check-bounds.cc
+++ b/examples/check-bounds.cc
@@ -58,7 +58,7 @@ void GenerateCheckBounds(MacroAssembler* masm) {
#ifndef TEST_EXAMPLES
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
void run_function(Simulator *simulator, Instruction * function,
uint64_t value, uint64_t low, uint64_t high) {
simulator->set_xreg(0, value);
@@ -97,5 +97,5 @@ int main(void) {
#else
// Without the simulator there is nothing to test.
int main(void) { return 0; }
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
#endif // TEST_EXAMPLES
diff --git a/examples/crc-checksums.cc b/examples/crc-checksums.cc
index e6fbb355..4fc9556b 100644
--- a/examples/crc-checksums.cc
+++ b/examples/crc-checksums.cc
@@ -77,7 +77,7 @@ void runExample(const char *msg) {
GenerateCrc32(&masm);
masm.FinalizeCode();
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
// Run example function in the simulator.
uintptr_t msg_addr = reinterpret_cast<uintptr_t>(msg);
size_t msg_size = strlen(msg);
@@ -91,7 +91,7 @@ void runExample(const char *msg) {
// Run example function natively.
printf("Not yet implemented.\n");
USE(msg);
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
}
diff --git a/examples/debugger.cc b/examples/debugger.cc
index 3a6db63e..db56f2d2 100644
--- a/examples/debugger.cc
+++ b/examples/debugger.cc
@@ -49,7 +49,7 @@ void GenerateBreak(MacroAssembler* masm) {
}
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
int main(void) {
// Create and initialize the assembler and the debugger.
byte assm_buf[BUF_SIZE];
@@ -72,5 +72,5 @@ int main(void) {
#else
// Without the simulator there is nothing to test.
int main(void) { return 0; }
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
#endif // TEST_EXAMPLES
diff --git a/examples/factorial-rec.cc b/examples/factorial-rec.cc
index ee07ef74..5d1e5df3 100644
--- a/examples/factorial-rec.cc
+++ b/examples/factorial-rec.cc
@@ -55,7 +55,7 @@ void GenerateFactorialRec(MacroAssembler* masm) {
#ifndef TEST_EXAMPLES
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
int main(void) {
// Create and initialize the assembler and the simulator.
byte assm_buf[BUF_SIZE];
@@ -80,5 +80,5 @@ int main(void) {
#else
// Without the simulator there is nothing to test.
int main(void) { return 0; }
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
#endif // TEST_EXAMPLES
diff --git a/examples/factorial.cc b/examples/factorial.cc
index 78d4c5f4..9df65f1e 100644
--- a/examples/factorial.cc
+++ b/examples/factorial.cc
@@ -53,7 +53,7 @@ void GenerateFactorial(MacroAssembler* masm) {
#ifndef TEST_EXAMPLES
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
int main(void) {
// Create and initialize the assembler and the simulator.
byte assm_buf[BUF_SIZE];
@@ -78,5 +78,5 @@ int main(void) {
#else
// Without the simulator there is nothing to test.
int main(void) { return 0; }
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
#endif // TEST_EXAMPLES
diff --git a/examples/getting-started.cc b/examples/getting-started.cc
index 0987429c..6cd8bba2 100644
--- a/examples/getting-started.cc
+++ b/examples/getting-started.cc
@@ -41,7 +41,7 @@ void GenerateDemoFunction(MacroAssembler *masm) {
#ifndef TEST_EXAMPLES
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
int main() {
byte assm_buf[BUF_SIZE];
MacroAssembler masm(assm_buf, BUF_SIZE);
@@ -62,5 +62,5 @@ int main() {
#else
// Without the simulator there is nothing to test.
int main(void) { return 0; }
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
#endif // TEST_EXAMPLES
diff --git a/examples/literal.cc b/examples/literal.cc
index e7d475d5..02de7efc 100644
--- a/examples/literal.cc
+++ b/examples/literal.cc
@@ -29,7 +29,7 @@
#define BASE_BUF_SIZE (4096)
#define __ masm.
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
int64_t LiteralExample(int64_t a, int64_t b) {
// Create and initialize the macro-assembler and the simulator.
MacroAssembler masm(BASE_BUF_SIZE);
@@ -85,13 +85,13 @@ int64_t LiteralExample(int64_t a, int64_t b) {
#endif
#ifndef TEST_EXAMPLES
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
int main(void) {
- LiteralExample(1, 2);
+ VIXL_CHECK(LiteralExample(1, 2) == 3);
return 0;
}
#else
// Without the simulator there is nothing to test.
int main(void) { return 0; }
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
#endif // TEST_EXAMPLES
diff --git a/examples/neon-matrix-multiply.cc b/examples/neon-matrix-multiply.cc
index 6a271508..26193396 100644
--- a/examples/neon-matrix-multiply.cc
+++ b/examples/neon-matrix-multiply.cc
@@ -95,7 +95,7 @@ void GenerateNEONMatrixMultiply(MacroAssembler* masm) {
#ifndef TEST_EXAMPLES
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
int main(void) {
// Create and initialize the assembler and the simulator.
byte assm_buf[BUF_SIZE];
@@ -164,5 +164,5 @@ int main(void) {
#else
// Without the simulator there is nothing to test.
int main(void) { return 0; }
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
#endif // TEST_EXAMPLES
diff --git a/examples/non-const-visitor.cc b/examples/non-const-visitor.cc
index bd022392..a616f12c 100644
--- a/examples/non-const-visitor.cc
+++ b/examples/non-const-visitor.cc
@@ -43,7 +43,7 @@ void GenerateNonConstVisitorTestCode(MacroAssembler* masm) {
int64_t RunNonConstVisitorTestGeneratedCode(const Instruction* start_instr) {
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
Decoder simulator_decoder;
Simulator simulator(&simulator_decoder);
@@ -65,7 +65,7 @@ int64_t RunNonConstVisitorTestGeneratedCode(const Instruction* start_instr) {
#ifndef TEST_EXAMPLES
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
int main(void) {
// Create and initialize the assembler.
byte assm_buf[BUF_SIZE];
@@ -110,7 +110,7 @@ int main(void) {
#else
// Without the simulator there is nothing to test.
int main(void) { return 0; }
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
#endif // TEST_EXAMPLES
diff --git a/examples/sum-array.cc b/examples/sum-array.cc
index 03f41d45..88039623 100644
--- a/examples/sum-array.cc
+++ b/examples/sum-array.cc
@@ -59,7 +59,7 @@ void GenerateSumArray(MacroAssembler* masm) {
#ifndef TEST_EXAMPLES
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
int main(void) {
// Create and initialize the assembler and the simulator.
byte assm_buf[BUF_SIZE];
@@ -91,5 +91,5 @@ int main(void) {
#else
// Without the simulator there is nothing to test.
int main(void) { return 0; }
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
#endif // TEST_EXAMPLES
diff --git a/examples/swap-int32.cc b/examples/swap-int32.cc
index 29074cad..0ea24352 100644
--- a/examples/swap-int32.cc
+++ b/examples/swap-int32.cc
@@ -61,7 +61,7 @@ void GenerateSwapInt32(MacroAssembler* masm) {
#ifndef TEST_EXAMPLES
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
int main(void) {
// Create and initialize the assembler and the simulator.
byte assm_buf[BUF_SIZE];
@@ -96,5 +96,5 @@ int main(void) {
#else
// Without the simulator there is nothing to test.
int main(void) { return 0; }
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
#endif // TEST_EXAMPLES
diff --git a/examples/swap4.cc b/examples/swap4.cc
index 132df940..808b148c 100644
--- a/examples/swap4.cc
+++ b/examples/swap4.cc
@@ -47,7 +47,7 @@ void GenerateSwap4(MacroAssembler* masm) {
#ifndef TEST_EXAMPLES
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
int main(void) {
// Create and initialize the assembler and the simulator.
byte assm_buf[BUF_SIZE];
@@ -90,5 +90,5 @@ int main(void) {
#else
// Without the simulator there is nothing to test.
int main(void) { return 0; }
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
#endif // TEST_EXAMPLES
diff --git a/src/vixl/a64/debugger-a64.cc b/src/vixl/a64/debugger-a64.cc
index 5f5b36ca..359e51b2 100644
--- a/src/vixl/a64/debugger-a64.cc
+++ b/src/vixl/a64/debugger-a64.cc
@@ -24,7 +24,7 @@
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
#include "vixl/a64/debugger-a64.h"
@@ -55,7 +55,7 @@ class Token {
virtual bool IsUnknown() const { return false; }
// Token properties.
virtual bool CanAddressMemory() const { return false; }
- virtual uint8_t* ToAddress(Debugger* debugger) const;
+ virtual uint8_t* ToAddress(Debugger* debugger) const = 0;
virtual void Print(FILE* out = stdout) const = 0;
static Token* Tokenize(const char* arg);
@@ -69,6 +69,11 @@ template<typename T> class ValueToken : public Token {
T value() const { return value_; }
+ VIXL_NO_RETURN virtual uint8_t* ToAddress(Debugger* debugger) const {
+ USE(debugger);
+ VIXL_ABORT();
+ }
+
protected:
T value_;
};
@@ -194,6 +199,11 @@ class FormatToken : public Token {
virtual void PrintData(void* data, FILE* out = stdout) const = 0;
virtual void Print(FILE* out = stdout) const = 0;
+ VIXL_NO_RETURN virtual uint8_t* ToAddress(Debugger* debugger) const {
+ USE(debugger);
+ VIXL_ABORT();
+ }
+
static Token* Tokenize(const char* arg);
static FormatToken* Cast(Token* tok) {
VIXL_ASSERT(tok->IsFormat());
@@ -229,6 +239,10 @@ class UnknownToken : public Token {
strncpy(unknown_, arg, size);
}
virtual ~UnknownToken() { delete[] unknown_; }
+ VIXL_NO_RETURN virtual uint8_t* ToAddress(Debugger* debugger) const {
+ USE(debugger);
+ VIXL_ABORT();
+ }
virtual bool IsUnknown() const { return true; }
virtual void Print(FILE* out = stdout) const;
@@ -788,13 +802,6 @@ static bool StringToInt64(int64_t* value, const char* line, int base = 10) {
}
-uint8_t* Token::ToAddress(Debugger* debugger) const {
- USE(debugger);
- VIXL_UNREACHABLE();
- return NULL;
-}
-
-
Token* Token::Tokenize(const char* arg) {
if ((arg == NULL) || (*arg == '\0')) {
return NULL;
@@ -1516,4 +1523,4 @@ bool InvalidCommand::Run(Debugger* debugger) {
} // namespace vixl
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
diff --git a/src/vixl/a64/debugger-a64.h b/src/vixl/a64/debugger-a64.h
index 0be170f2..16394f13 100644
--- a/src/vixl/a64/debugger-a64.h
+++ b/src/vixl/a64/debugger-a64.h
@@ -24,6 +24,8 @@
// 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.
+#ifdef VIXL_INCLUDE_SIMULATOR
+
#ifndef VIXL_A64_DEBUGGER_A64_H_
#define VIXL_A64_DEBUGGER_A64_H_
@@ -112,3 +114,5 @@ class Debugger : public Simulator {
} // namespace vixl
#endif // VIXL_A64_DEBUGGER_A64_H_
+
+#endif // VIXL_INCLUDE_SIMULATOR
diff --git a/src/vixl/a64/decoder-a64.h b/src/vixl/a64/decoder-a64.h
index 4f4f19c6..b3f04f68 100644
--- a/src/vixl/a64/decoder-a64.h
+++ b/src/vixl/a64/decoder-a64.h
@@ -35,7 +35,7 @@
// List macro containing all visitors needed by the decoder class.
-#define VISITOR_LIST(V) \
+#define VISITOR_LIST_THAT_RETURN(V) \
V(PCRelAddressing) \
V(AddSubImmediate) \
V(LogicalImmediate) \
@@ -104,8 +104,14 @@
V(NEONShiftImmediate) \
V(NEONTable) \
V(NEONPerm) \
- 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) \
namespace vixl {
diff --git a/src/vixl/a64/instrument-a64.cc b/src/vixl/a64/instrument-a64.cc
index 21ec6041..7de12559 100644
--- a/src/vixl/a64/instrument-a64.cc
+++ b/src/vixl/a64/instrument-a64.cc
@@ -169,7 +169,8 @@ void Instrument::Update() {
VIXL_ASSERT(counter->type() == Cumulative);
counter->Increment();
- if (counter->IsEnabled() && (counter->count() % sample_period_) == 0) {
+ if ((sample_period_ != 0) && counter->IsEnabled()
+ && (counter->count() % sample_period_) == 0) {
DumpCounters();
}
}
diff --git a/src/vixl/a64/instrument-a64.h b/src/vixl/a64/instrument-a64.h
index 8468ceb6..e1da5b3b 100644
--- a/src/vixl/a64/instrument-a64.h
+++ b/src/vixl/a64/instrument-a64.h
@@ -99,6 +99,10 @@ class Instrument: public DecoderVisitor {
std::list<Counter*> counters_;
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
+ // Instrumentation class is destroyed.
uint64_t sample_period_;
};
diff --git a/src/vixl/a64/logic-a64.cc b/src/vixl/a64/logic-a64.cc
index 5ee62ade..3bccb6ea 100644
--- a/src/vixl/a64/logic-a64.cc
+++ b/src/vixl/a64/logic-a64.cc
@@ -24,6 +24,8 @@
// 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.
+#ifdef VIXL_INCLUDE_SIMULATOR
+
#include <cmath>
#include "vixl/a64/simulator-a64.h"
@@ -4871,3 +4873,5 @@ LogicVRegister Simulator::ucvtf(VectorFormat vform,
} // namespace vixl
+
+#endif // VIXL_INCLUDE_SIMULATOR
diff --git a/src/vixl/a64/macro-assembler-a64.cc b/src/vixl/a64/macro-assembler-a64.cc
index 25d222f1..44f0f0d0 100644
--- a/src/vixl/a64/macro-assembler-a64.cc
+++ b/src/vixl/a64/macro-assembler-a64.cc
@@ -24,6 +24,8 @@
// 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.
+#include <ctype.h>
+
#include "vixl/a64/macro-assembler-a64.h"
namespace vixl {
@@ -287,6 +289,7 @@ MacroAssembler::MacroAssembler(size_t capacity,
#ifdef VIXL_DEBUG
allow_macro_instructions_(true),
#endif
+ allow_simulator_instructions_(VIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE),
sp_(sp),
tmp_list_(ip0, ip1),
fptmp_list_(d31),
@@ -304,6 +307,7 @@ MacroAssembler::MacroAssembler(byte * buffer,
#ifdef VIXL_DEBUG
allow_macro_instructions_(true),
#endif
+ allow_simulator_instructions_(VIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE),
sp_(sp),
tmp_list_(ip0, ip1),
fptmp_list_(d31),
@@ -2183,8 +2187,7 @@ void MacroAssembler::PrintfNoPreserve(const char * format,
// Actually call printf. This part needs special handling for the simulator,
// since the system printf function will use a different instruction set and
// the procedure-call standard will not be compatible.
-#ifdef USE_SIMULATOR
- {
+ if (allow_simulator_instructions_) {
InstructionAccurateScope scope(this, kPrintfLength / kInstructionSize);
hlt(kPrintfOpcode);
dc32(arg_count); // kPrintfArgCountOffset
@@ -2203,12 +2206,11 @@ void MacroAssembler::PrintfNoPreserve(const char * format,
arg_pattern_list |= (arg_pattern << (kPrintfArgPatternBits * i));
}
dc32(arg_pattern_list); // kPrintfArgPatternListOffset
+ } else {
+ Register tmp = temps.AcquireX();
+ Mov(tmp, reinterpret_cast<uintptr_t>(printf));
+ Blr(tmp);
}
-#else
- Register tmp = temps.AcquireX();
- Mov(tmp, reinterpret_cast<uintptr_t>(printf));
- Blr(tmp);
-#endif
}
@@ -2283,51 +2285,51 @@ void MacroAssembler::Printf(const char * format,
void MacroAssembler::Trace(TraceParameters parameters, TraceCommand command) {
VIXL_ASSERT(allow_macro_instructions_);
-#ifdef USE_SIMULATOR
- // The arguments to the trace pseudo instruction need to be contiguous in
- // memory, so make sure we don't try to emit a literal pool.
- InstructionAccurateScope scope(this, kTraceLength / kInstructionSize);
+ if (allow_simulator_instructions_) {
+ // The arguments to the trace pseudo instruction need to be contiguous in
+ // memory, so make sure we don't try to emit a literal pool.
+ InstructionAccurateScope scope(this, kTraceLength / kInstructionSize);
- Label start;
- bind(&start);
+ Label start;
+ bind(&start);
- // Refer to simulator-a64.h for a description of the marker and its
- // arguments.
- hlt(kTraceOpcode);
+ // Refer to simulator-a64.h for a description of the marker and its
+ // arguments.
+ hlt(kTraceOpcode);
- VIXL_ASSERT(SizeOfCodeGeneratedSince(&start) == kTraceParamsOffset);
- dc32(parameters);
+ VIXL_ASSERT(SizeOfCodeGeneratedSince(&start) == kTraceParamsOffset);
+ dc32(parameters);
- VIXL_ASSERT(SizeOfCodeGeneratedSince(&start) == kTraceCommandOffset);
- dc32(command);
-#else
- // Emit nothing on real hardware.
- USE(parameters, command);
-#endif
+ VIXL_ASSERT(SizeOfCodeGeneratedSince(&start) == kTraceCommandOffset);
+ dc32(command);
+ } else {
+ // Emit nothing on real hardware.
+ USE(parameters, command);
+ }
}
void MacroAssembler::Log(TraceParameters parameters) {
VIXL_ASSERT(allow_macro_instructions_);
-#ifdef USE_SIMULATOR
- // The arguments to the log pseudo instruction need to be contiguous in
- // memory, so make sure we don't try to emit a literal pool.
- InstructionAccurateScope scope(this, kLogLength / kInstructionSize);
+ if (allow_simulator_instructions_) {
+ // The arguments to the log pseudo instruction need to be contiguous in
+ // memory, so make sure we don't try to emit a literal pool.
+ InstructionAccurateScope scope(this, kLogLength / kInstructionSize);
- Label start;
- bind(&start);
+ Label start;
+ bind(&start);
- // Refer to simulator-a64.h for a description of the marker and its
- // arguments.
- hlt(kLogOpcode);
+ // Refer to simulator-a64.h for a description of the marker and its
+ // arguments.
+ hlt(kLogOpcode);
- VIXL_ASSERT(SizeOfCodeGeneratedSince(&start) == kLogParamsOffset);
- dc32(parameters);
-#else
- // Emit nothing on real hardware.
- USE(parameters);
-#endif
+ VIXL_ASSERT(SizeOfCodeGeneratedSince(&start) == kLogParamsOffset);
+ dc32(parameters);
+ } else {
+ // Emit nothing on real hardware.
+ USE(parameters);
+ }
}
diff --git a/src/vixl/a64/macro-assembler-a64.h b/src/vixl/a64/macro-assembler-a64.h
index 6d3838dd..c635af2c 100644
--- a/src/vixl/a64/macro-assembler-a64.h
+++ b/src/vixl/a64/macro-assembler-a64.h
@@ -33,6 +33,8 @@
#include "vixl/globals.h"
#include "vixl/a64/assembler-a64.h"
#include "vixl/a64/debugger-a64.h"
+#include "vixl/a64/instrument-a64.h"
+#include "vixl/a64/simulator-constants-a64.h"
#define LS_MACRO_LIST(V) \
@@ -2074,13 +2076,13 @@ class MacroAssembler : public Assembler {
void Unreachable() {
VIXL_ASSERT(allow_macro_instructions_);
SingleEmissionCheckScope guard(this);
-#ifdef USE_SIMULATOR
- hlt(kUnreachableOpcode);
-#else
- // Branch to 0 to generate a segfault.
- // lr - kInstructionSize is the address of the offending instruction.
- blr(xzr);
-#endif
+ if (allow_simulator_instructions_) {
+ hlt(kUnreachableOpcode);
+ } else {
+ // Branch to 0 to generate a segfault.
+ // lr - kInstructionSize is the address of the offending instruction.
+ blr(xzr);
+ }
}
void Uxtb(const Register& rd, const Register& rn) {
VIXL_ASSERT(allow_macro_instructions_);
@@ -2902,7 +2904,7 @@ class MacroAssembler : public Assembler {
// one instruction. Refer to the implementation for details.
void BumpSystemStackPointer(const Operand& space);
-#if VIXL_DEBUG
+#ifdef VIXL_DEBUG
void SetAllowMacroInstructions(bool value) {
allow_macro_instructions_ = value;
}
@@ -2912,6 +2914,14 @@ class MacroAssembler : public Assembler {
}
#endif
+ void SetAllowSimulatorInstructions(bool value) {
+ allow_simulator_instructions_ = value;
+ }
+
+ bool AllowSimulatorInstructions() const {
+ return allow_simulator_instructions_;
+ }
+
void BlockLiteralPool() { literal_pool_.Block(); }
void ReleaseLiteralPool() { literal_pool_.Release(); }
bool IsLiteralPoolBlocked() const { return literal_pool_.IsBlocked(); }
@@ -3099,13 +3109,16 @@ class MacroAssembler : public Assembler {
label->location() - CursorOffset());
}
-#if VIXL_DEBUG
+#ifdef VIXL_DEBUG
// Tell whether any of the macro instruction can be used. When false the
// MacroAssembler will assert if a method which can emit a variable number
// of instructions is called.
bool allow_macro_instructions_;
#endif
+ // Tell whether we should generate code that will run on the simulator or not.
+ bool allow_simulator_instructions_;
+
// The register to use as a stack pointer for stack operations.
Register sp_;
@@ -3326,10 +3339,10 @@ class UseScratchRegisterScope {
#endif
// Disallow copy constructor and operator=.
- UseScratchRegisterScope(const UseScratchRegisterScope&) {
+ VIXL_DEBUG_NO_RETURN UseScratchRegisterScope(const UseScratchRegisterScope&) {
VIXL_UNREACHABLE();
}
- void operator=(const UseScratchRegisterScope&) {
+ VIXL_DEBUG_NO_RETURN void operator=(const UseScratchRegisterScope&) {
VIXL_UNREACHABLE();
}
};
diff --git a/src/vixl/a64/simulator-a64.cc b/src/vixl/a64/simulator-a64.cc
index 3cb029a3..69a664ba 100644
--- a/src/vixl/a64/simulator-a64.cc
+++ b/src/vixl/a64/simulator-a64.cc
@@ -24,7 +24,7 @@
// 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.
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
#include <string.h>
#include <cmath>
@@ -273,56 +273,39 @@ void Simulator::set_instruction_stats(bool value) {
}
// Helpers ---------------------------------------------------------------------
-int64_t Simulator::AddWithCarry(unsigned reg_size,
- bool set_flags,
- int64_t src1,
- int64_t src2,
- int64_t carry_in) {
+uint64_t Simulator::AddWithCarry(unsigned reg_size,
+ bool set_flags,
+ uint64_t left,
+ uint64_t right,
+ int carry_in) {
VIXL_ASSERT((carry_in == 0) || (carry_in == 1));
VIXL_ASSERT((reg_size == kXRegSize) || (reg_size == kWRegSize));
- uint64_t u1, u2;
- int64_t result;
- int64_t signed_sum = src1 + src2 + carry_in;
+ uint64_t max_uint = (reg_size == kWRegSize) ? kWMaxUInt : kXMaxUInt;
+ uint64_t reg_mask = (reg_size == kWRegSize) ? kWRegMask : kXRegMask;
+ uint64_t sign_mask = (reg_size == kWRegSize) ? kWSignMask : kXSignMask;
- uint32_t N, Z, C, V;
+ left &= reg_mask;
+ right &= reg_mask;
+ uint64_t result = (left + right + carry_in) & reg_mask;
- if (reg_size == kWRegSize) {
- u1 = static_cast<uint64_t>(src1) & kWRegMask;
- u2 = static_cast<uint64_t>(src2) & kWRegMask;
-
- result = signed_sum & kWRegMask;
- // Compute the C flag by comparing the sum to the max unsigned integer.
- C = ((kWMaxUInt - u1) < (u2 + carry_in)) ||
- ((kWMaxUInt - u1 - carry_in) < u2);
- // Overflow iff the sign bit is the same for the two inputs and different
- // for the result.
- int64_t s_src1 = src1 << (kXRegSize - kWRegSize);
- int64_t s_src2 = src2 << (kXRegSize - kWRegSize);
- int64_t s_result = result << (kXRegSize - kWRegSize);
- V = ((s_src1 ^ s_src2) >= 0) && ((s_src1 ^ s_result) < 0);
+ if (set_flags) {
+ nzcv().SetN(CalcNFlag(result, reg_size));
+ nzcv().SetZ(CalcZFlag(result));
- } else {
- u1 = static_cast<uint64_t>(src1);
- u2 = static_cast<uint64_t>(src2);
+ // Compute the C flag by comparing the result to the max unsigned integer.
+ uint64_t max_uint_2op = max_uint - carry_in;
+ bool C = (left > max_uint_2op) || ((max_uint_2op - left) < right);
+ nzcv().SetC(C ? 1 : 0);
- result = signed_sum;
- // Compute the C flag by comparing the sum to the max unsigned integer.
- C = ((kXMaxUInt - u1) < (u2 + carry_in)) ||
- ((kXMaxUInt - u1 - carry_in) < u2);
// Overflow iff the sign bit is the same for the two inputs and different
// for the result.
- V = ((src1 ^ src2) >= 0) && ((src1 ^ result) < 0);
- }
+ uint64_t left_sign = left & sign_mask;
+ uint64_t right_sign = right & sign_mask;
+ uint64_t result_sign = result & sign_mask;
+ bool V = (left_sign == right_sign) && (left_sign != result_sign);
+ nzcv().SetV(V ? 1 : 0);
- N = CalcNFlag(result, reg_size);
- Z = CalcZFlag(result);
-
- if (set_flags) {
- nzcv().SetN(N);
- nzcv().SetZ(Z);
- nzcv().SetC(C);
- nzcv().SetV(V);
LogSystemRegister(NZCV);
}
return result;
@@ -4052,4 +4035,4 @@ void Simulator::DoPrintf(const Instruction* instr) {
} // namespace vixl
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
diff --git a/src/vixl/a64/simulator-a64.h b/src/vixl/a64/simulator-a64.h
index dd8f6a83..8eb1ea9f 100644
--- a/src/vixl/a64/simulator-a64.h
+++ b/src/vixl/a64/simulator-a64.h
@@ -33,123 +33,10 @@
#include "vixl/a64/assembler-a64.h"
#include "vixl/a64/disasm-a64.h"
#include "vixl/a64/instrument-a64.h"
+#include "vixl/a64/simulator-constants-a64.h"
namespace vixl {
-// Debug instructions.
-//
-// VIXL's macro-assembler and simulator support a few pseudo instructions to
-// make debugging easier. These pseudo instructions do not exist on real
-// hardware.
-//
-// TODO: Provide controls to prevent the macro assembler from emitting
-// pseudo-instructions. This is important for ahead-of-time compilers, where the
-// macro assembler is built with USE_SIMULATOR but the code will eventually be
-// run on real hardware.
-//
-// TODO: Also consider allowing these pseudo-instructions to be disabled in the
-// simulator, so that users can check that the input is a valid native code.
-// (This isn't possible in all cases. Printf won't work, for example.)
-//
-// Each debug pseudo instruction is represented by a HLT instruction. The HLT
-// immediate field is used to identify the type of debug pseudo instruction.
-
-enum DebugHltOpcodes {
- kUnreachableOpcode = 0xdeb0,
- kPrintfOpcode,
- kTraceOpcode,
- kLogOpcode,
- // Aliases.
- kDebugHltFirstOpcode = kUnreachableOpcode,
- kDebugHltLastOpcode = kLogOpcode
-};
-
-// Each pseudo instruction uses a custom encoding for additional arguments, as
-// described below.
-
-// Unreachable - kUnreachableOpcode
-//
-// Instruction which should never be executed. This is used as a guard in parts
-// of the code that should not be reachable, such as in data encoded inline in
-// the instructions.
-
-// Printf - kPrintfOpcode
-// - arg_count: The number of arguments.
-// - arg_pattern: A set of PrintfArgPattern values, packed into two-bit fields.
-//
-// Simulate a call to printf.
-//
-// Floating-point and integer arguments are passed in separate sets of registers
-// in AAPCS64 (even for varargs functions), so it is not possible to determine
-// the type of each argument without some information about the values that were
-// passed in. This information could be retrieved from the printf format string,
-// but the format string is not trivial to parse so we encode the relevant
-// information with the HLT instruction.
-//
-// Also, the following registers are populated (as if for a native A64 call):
-// x0: The format string
-// x1-x7: Optional arguments, if type == CPURegister::kRegister
-// d0-d7: Optional arguments, if type == CPURegister::kFPRegister
-const unsigned kPrintfArgCountOffset = 1 * kInstructionSize;
-const unsigned kPrintfArgPatternListOffset = 2 * kInstructionSize;
-const unsigned kPrintfLength = 3 * kInstructionSize;
-
-const unsigned kPrintfMaxArgCount = 4;
-
-// The argument pattern is a set of two-bit-fields, each with one of the
-// following values:
-enum PrintfArgPattern {
- kPrintfArgW = 1,
- kPrintfArgX = 2,
- // There is no kPrintfArgS because floats are always converted to doubles in C
- // varargs calls.
- kPrintfArgD = 3
-};
-static const unsigned kPrintfArgPatternBits = 2;
-
-// Trace - kTraceOpcode
-// - parameter: TraceParameter stored as a uint32_t
-// - command: TraceCommand stored as a uint32_t
-//
-// Allow for trace management in the generated code. This enables or disables
-// automatic tracing of the specified information for every simulated
-// instruction.
-const unsigned kTraceParamsOffset = 1 * kInstructionSize;
-const unsigned kTraceCommandOffset = 2 * kInstructionSize;
-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_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
-};
-
-// Log - kLogOpcode
-// - parameter: TraceParameter stored as a uint32_t
-//
-// Print the specified information once. This mechanism is separate from Trace.
-// In particular, _all_ of the specified registers are printed, rather than just
-// the registers that the instruction writes.
-//
-// Any combination of the TraceParameters values can be used, except that
-// LOG_DISASM is not supported for Log.
-const unsigned kLogParamsOffset = 1 * kInstructionSize;
-const unsigned kLogLength = 2 * kInstructionSize;
-
-
// Assemble the specified IEEE-754 components into the target type and apply
// appropriate rounding.
// sign: 0 = positive, 1 = negative
@@ -831,9 +718,15 @@ class Simulator : public DecoderVisitor {
// Declare all Visitor functions.
#define DECLARE(A) virtual void Visit##A(const Instruction* instr);
- VISITOR_LIST(DECLARE)
+ VISITOR_LIST_THAT_RETURN(DECLARE)
#undef DECLARE
+ #define DECLARE(A) \
+ VIXL_DEBUG_NO_RETURN virtual void Visit##A(const Instruction* instr);
+ VISITOR_LIST_THAT_DONT_RETURN(DECLARE)
+ #undef DECLARE
+
+
// Integer register accessors.
// Basic accessor: Read the register as the specified type.
@@ -1295,7 +1188,7 @@ class Simulator : public DecoderVisitor {
void PrintVRegisterFPHelper(unsigned code, unsigned lane_size_in_bytes,
int lane_count = 1, int rightmost_lane = 0);
- void DoUnreachable(const Instruction* instr);
+ VIXL_NO_RETURN void DoUnreachable(const Instruction* instr);
void DoTrace(const Instruction* instr);
void DoLog(const Instruction* instr);
@@ -1388,11 +1281,11 @@ class Simulator : public DecoderVisitor {
}
void AddSubHelper(const Instruction* instr, int64_t op2);
- int64_t AddWithCarry(unsigned reg_size,
- bool set_flags,
- int64_t src1,
- int64_t src2,
- int64_t carry_in = 0);
+ uint64_t AddWithCarry(unsigned reg_size,
+ bool set_flags,
+ uint64_t left,
+ uint64_t right,
+ int carry_in = 0);
void LogicalHelper(const Instruction* instr, int64_t op2);
void ConditionalCompareHelper(const Instruction* instr, int64_t op2);
void LoadStoreHelper(const Instruction* instr,
@@ -2631,7 +2524,7 @@ class Simulator : public DecoderVisitor {
}
static int CalcZFlag(uint64_t result) {
- return result == 0;
+ return (result == 0) ? 1 : 0;
}
static const uint32_t kConditionFlagsMask = 0xf0000000;
diff --git a/src/vixl/a64/simulator-constants-a64.h b/src/vixl/a64/simulator-constants-a64.h
new file mode 100644
index 00000000..16a3c32a
--- /dev/null
+++ b/src/vixl/a64/simulator-constants-a64.h
@@ -0,0 +1,141 @@
+// Copyright 2015, 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.
+
+#ifndef VIXL_A64_SIMULATOR_CONSTANTS_A64_H_
+#define VIXL_A64_SIMULATOR_CONSTANTS_A64_H_
+
+namespace vixl {
+
+// Debug instructions.
+//
+// VIXL's macro-assembler and simulator support a few pseudo instructions to
+// make debugging easier. These pseudo instructions do not exist on real
+// hardware.
+//
+// TODO: Also consider allowing these pseudo-instructions to be disabled in the
+// simulator, so that users can check that the input is a valid native code.
+// (This isn't possible in all cases. Printf won't work, for example.)
+//
+// Each debug pseudo instruction is represented by a HLT instruction. The HLT
+// immediate field is used to identify the type of debug pseudo instruction.
+
+enum DebugHltOpcodes {
+ kUnreachableOpcode = 0xdeb0,
+ kPrintfOpcode,
+ kTraceOpcode,
+ kLogOpcode,
+ // Aliases.
+ kDebugHltFirstOpcode = kUnreachableOpcode,
+ kDebugHltLastOpcode = kLogOpcode
+};
+
+// Each pseudo instruction uses a custom encoding for additional arguments, as
+// described below.
+
+// Unreachable - kUnreachableOpcode
+//
+// Instruction which should never be executed. This is used as a guard in parts
+// of the code that should not be reachable, such as in data encoded inline in
+// the instructions.
+
+// Printf - kPrintfOpcode
+// - arg_count: The number of arguments.
+// - arg_pattern: A set of PrintfArgPattern values, packed into two-bit fields.
+//
+// Simulate a call to printf.
+//
+// Floating-point and integer arguments are passed in separate sets of registers
+// in AAPCS64 (even for varargs functions), so it is not possible to determine
+// the type of each argument without some information about the values that were
+// passed in. This information could be retrieved from the printf format string,
+// but the format string is not trivial to parse so we encode the relevant
+// information with the HLT instruction.
+//
+// Also, the following registers are populated (as if for a native A64 call):
+// x0: The format string
+// x1-x7: Optional arguments, if type == CPURegister::kRegister
+// d0-d7: Optional arguments, if type == CPURegister::kFPRegister
+const unsigned kPrintfArgCountOffset = 1 * kInstructionSize;
+const unsigned kPrintfArgPatternListOffset = 2 * kInstructionSize;
+const unsigned kPrintfLength = 3 * kInstructionSize;
+
+const unsigned kPrintfMaxArgCount = 4;
+
+// The argument pattern is a set of two-bit-fields, each with one of the
+// following values:
+enum PrintfArgPattern {
+ kPrintfArgW = 1,
+ kPrintfArgX = 2,
+ // There is no kPrintfArgS because floats are always converted to doubles in C
+ // varargs calls.
+ kPrintfArgD = 3
+};
+static const unsigned kPrintfArgPatternBits = 2;
+
+// Trace - kTraceOpcode
+// - parameter: TraceParameter stored as a uint32_t
+// - command: TraceCommand stored as a uint32_t
+//
+// Allow for trace management in the generated code. This enables or disables
+// automatic tracing of the specified information for every simulated
+// instruction.
+const unsigned kTraceParamsOffset = 1 * kInstructionSize;
+const unsigned kTraceCommandOffset = 2 * kInstructionSize;
+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_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
+};
+
+// Log - kLogOpcode
+// - parameter: TraceParameter stored as a uint32_t
+//
+// Print the specified information once. This mechanism is separate from Trace.
+// In particular, _all_ of the specified registers are printed, rather than just
+// the registers that the instruction writes.
+//
+// Any combination of the TraceParameters values can be used, except that
+// LOG_DISASM is not supported for Log.
+const unsigned kLogParamsOffset = 1 * kInstructionSize;
+const unsigned kLogLength = 2 * kInstructionSize;
+} // namespace vixl
+
+#endif // VIXL_A64_SIMULATOR_CONSTANTS_A64_H_
diff --git a/src/vixl/globals.h b/src/vixl/globals.h
index 42938dbb..61dc9f7f 100644
--- a/src/vixl/globals.h
+++ b/src/vixl/globals.h
@@ -116,4 +116,36 @@ inline void USE(T1, T2, T3, T4) {}
#define VIXL_FALLTHROUGH() do {} while (0)
#endif
+#if __cplusplus >= 201103L
+ #define VIXL_NO_RETURN [[noreturn]] //NOLINT
+#else
+ #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
+#else
+ #define VIXL_DEBUG_NO_RETURN
+#endif
+
+#ifdef VIXL_INCLUDE_SIMULATOR
+#ifndef VIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE
+ #define VIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE 1
+#endif
+#else
+#ifndef VIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE
+ #define VIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE 0
+#endif
+#if VIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE
+ #warning "Generating Simulator instructions without Simulator support."
+#endif
+#endif
+
+#ifdef USE_SIMULATOR
+ #error "Please see the release notes for USE_SIMULATOR."
+#endif
+
#endif // VIXL_GLOBALS_H
diff --git a/test/examples/test-examples.cc b/test/examples/test-examples.cc
index 5ff9625f..83fe5467 100644
--- a/test/examples/test-examples.cc
+++ b/test/examples/test-examples.cc
@@ -45,7 +45,7 @@ TEST(custom_disassembler) {
// The tests below only work with the simulator.
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
#define ARRAY_SIZE(Array) (sizeof(Array) / sizeof((Array)[0]))
#define BUF_SIZE (4096)
@@ -573,4 +573,4 @@ TEST(literal_example) {
LiteralExample(INT64_C(0x100000000), 0x1) == INT64_C(0x100000001));
}
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
diff --git a/test/test-assembler-a64.cc b/test/test-assembler-a64.cc
index 642b3d4d..67cdf736 100644
--- a/test/test-assembler-a64.cc
+++ b/test/test-assembler-a64.cc
@@ -94,7 +94,7 @@ namespace vixl {
#define BUF_SIZE (4096)
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
// Run tests with the simulator.
#define SETUP() \
@@ -107,6 +107,7 @@ namespace vixl {
SETUP_COMMON()
#define SETUP_COMMON() \
+ masm.SetAllowSimulatorInstructions(true); \
Decoder decoder; \
Simulator* simulator = Test::run_debugger() ? new Debugger(&decoder) \
: new Simulator(&decoder); \
@@ -158,7 +159,7 @@ namespace vixl {
#define TEARDOWN_COMMON() \
delete simulator;
-#else // ifdef USE_SIMULATOR.
+#else // ifdef VIXL_INCLUDE_SIMULATOR.
// Run the test on real hardware or models.
#define SETUP() \
MacroAssembler masm(BUF_SIZE); \
@@ -170,6 +171,7 @@ namespace vixl {
SETUP_COMMON()
#define SETUP_COMMON() \
+ masm.SetAllowSimulatorInstructions(false); \
RegisterDump core; \
CPU::SetUp()
@@ -205,7 +207,7 @@ namespace vixl {
#define TEARDOWN_CUSTOM() \
delete[] buf; \
-#endif // ifdef USE_SIMULATOR.
+#endif // ifdef VIXL_INCLUDE_SIMULATOR.
#define ASSERT_EQUAL_NZCV(expected) \
assert(EqualNzcv(expected, core.flags_nzcv()))
@@ -7664,6 +7666,378 @@ TEST(neg) {
}
+template<typename T, typename Op>
+static void AdcsSbcsHelper(Op op, T left, T right, int carry,
+ T expected, StatusFlags expected_flags) {
+ int reg_size = sizeof(T) * 8;
+ Register left_reg(0, reg_size);
+ Register right_reg(1, reg_size);
+ Register result_reg(2, reg_size);
+
+ SETUP();
+ START();
+
+ __ Mov(left_reg, left);
+ __ Mov(right_reg, right);
+ __ Mov(x10, (carry ? CFlag : NoFlag));
+
+ __ Msr(NZCV, x10);
+ (masm.*op)(result_reg, left_reg, right_reg);
+
+ END();
+ RUN();
+
+ ASSERT_EQUAL_64(left, left_reg.X());
+ ASSERT_EQUAL_64(right, right_reg.X());
+ ASSERT_EQUAL_64(expected, result_reg.X());
+ ASSERT_EQUAL_NZCV(expected_flags);
+
+ TEARDOWN();
+}
+
+
+TEST(adcs_sbcs_x) {
+ uint64_t inputs[] = {
+ 0x0000000000000000, 0x0000000000000001,
+ 0x7ffffffffffffffe, 0x7fffffffffffffff,
+ 0x8000000000000000, 0x8000000000000001,
+ 0xfffffffffffffffe, 0xffffffffffffffff,
+ };
+ static const size_t input_count = sizeof(inputs) / sizeof(inputs[0]);
+
+ struct Expected {
+ uint64_t carry0_result;
+ StatusFlags carry0_flags;
+ uint64_t carry1_result;
+ StatusFlags carry1_flags;
+ };
+
+ static const Expected expected_adcs_x[input_count][input_count] = {
+ {{0x0000000000000000, ZFlag, 0x0000000000000001, NoFlag},
+ {0x0000000000000001, NoFlag, 0x0000000000000002, NoFlag},
+ {0x7ffffffffffffffe, NoFlag, 0x7fffffffffffffff, NoFlag},
+ {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
+ {0x8000000000000000, NFlag, 0x8000000000000001, NFlag},
+ {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
+ {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
+ {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag}},
+ {{0x0000000000000001, NoFlag, 0x0000000000000002, NoFlag},
+ {0x0000000000000002, NoFlag, 0x0000000000000003, NoFlag},
+ {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
+ {0x8000000000000000, NVFlag, 0x8000000000000001, NVFlag},
+ {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
+ {0x8000000000000002, NFlag, 0x8000000000000003, NFlag},
+ {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
+ {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag}},
+ {{0x7ffffffffffffffe, NoFlag, 0x7fffffffffffffff, NoFlag},
+ {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
+ {0xfffffffffffffffc, NVFlag, 0xfffffffffffffffd, NVFlag},
+ {0xfffffffffffffffd, NVFlag, 0xfffffffffffffffe, NVFlag},
+ {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
+ {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
+ {0x7ffffffffffffffc, CFlag, 0x7ffffffffffffffd, CFlag},
+ {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag}},
+ {{0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
+ {0x8000000000000000, NVFlag, 0x8000000000000001, NVFlag},
+ {0xfffffffffffffffd, NVFlag, 0xfffffffffffffffe, NVFlag},
+ {0xfffffffffffffffe, NVFlag, 0xffffffffffffffff, NVFlag},
+ {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
+ {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
+ {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
+ {0x7ffffffffffffffe, CFlag, 0x7fffffffffffffff, CFlag}},
+ {{0x8000000000000000, NFlag, 0x8000000000000001, NFlag},
+ {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
+ {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
+ {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
+ {0x0000000000000000, ZCVFlag, 0x0000000000000001, CVFlag},
+ {0x0000000000000001, CVFlag, 0x0000000000000002, CVFlag},
+ {0x7ffffffffffffffe, CVFlag, 0x7fffffffffffffff, CVFlag},
+ {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag}},
+ {{0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
+ {0x8000000000000002, NFlag, 0x8000000000000003, NFlag},
+ {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
+ {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
+ {0x0000000000000001, CVFlag, 0x0000000000000002, CVFlag},
+ {0x0000000000000002, CVFlag, 0x0000000000000003, CVFlag},
+ {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
+ {0x8000000000000000, NCFlag, 0x8000000000000001, NCFlag}},
+ {{0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
+ {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
+ {0x7ffffffffffffffc, CFlag, 0x7ffffffffffffffd, CFlag},
+ {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
+ {0x7ffffffffffffffe, CVFlag, 0x7fffffffffffffff, CVFlag},
+ {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
+ {0xfffffffffffffffc, NCFlag, 0xfffffffffffffffd, NCFlag},
+ {0xfffffffffffffffd, NCFlag, 0xfffffffffffffffe, NCFlag}},
+ {{0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
+ {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
+ {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
+ {0x7ffffffffffffffe, CFlag, 0x7fffffffffffffff, CFlag},
+ {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
+ {0x8000000000000000, NCFlag, 0x8000000000000001, NCFlag},
+ {0xfffffffffffffffd, NCFlag, 0xfffffffffffffffe, NCFlag},
+ {0xfffffffffffffffe, NCFlag, 0xffffffffffffffff, NCFlag}}
+ };
+
+ static const Expected expected_sbcs_x[input_count][input_count] = {
+ {{0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
+ {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
+ {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
+ {0x8000000000000000, NFlag, 0x8000000000000001, NFlag},
+ {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
+ {0x7ffffffffffffffe, NoFlag, 0x7fffffffffffffff, NoFlag},
+ {0x0000000000000001, NoFlag, 0x0000000000000002, NoFlag},
+ {0x0000000000000000, ZFlag, 0x0000000000000001, NoFlag}},
+ {{0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
+ {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
+ {0x8000000000000002, NFlag, 0x8000000000000003, NFlag},
+ {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
+ {0x8000000000000000, NVFlag, 0x8000000000000001, NVFlag},
+ {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
+ {0x0000000000000002, NoFlag, 0x0000000000000003, NoFlag},
+ {0x0000000000000001, NoFlag, 0x0000000000000002, NoFlag}},
+ {{0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
+ {0x7ffffffffffffffc, CFlag, 0x7ffffffffffffffd, CFlag},
+ {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
+ {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
+ {0xfffffffffffffffd, NVFlag, 0xfffffffffffffffe, NVFlag},
+ {0xfffffffffffffffc, NVFlag, 0xfffffffffffffffd, NVFlag},
+ {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag},
+ {0x7ffffffffffffffe, NoFlag, 0x7fffffffffffffff, NoFlag}},
+ {{0x7ffffffffffffffe, CFlag, 0x7fffffffffffffff, CFlag},
+ {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
+ {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
+ {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
+ {0xfffffffffffffffe, NVFlag, 0xffffffffffffffff, NVFlag},
+ {0xfffffffffffffffd, NVFlag, 0xfffffffffffffffe, NVFlag},
+ {0x8000000000000000, NVFlag, 0x8000000000000001, NVFlag},
+ {0x7fffffffffffffff, NoFlag, 0x8000000000000000, NVFlag}},
+ {{0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
+ {0x7ffffffffffffffe, CVFlag, 0x7fffffffffffffff, CVFlag},
+ {0x0000000000000001, CVFlag, 0x0000000000000002, CVFlag},
+ {0x0000000000000000, ZCVFlag, 0x0000000000000001, CVFlag},
+ {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
+ {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag},
+ {0x8000000000000001, NFlag, 0x8000000000000002, NFlag},
+ {0x8000000000000000, NFlag, 0x8000000000000001, NFlag}},
+ {{0x8000000000000000, NCFlag, 0x8000000000000001, NCFlag},
+ {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
+ {0x0000000000000002, CVFlag, 0x0000000000000003, CVFlag},
+ {0x0000000000000001, CVFlag, 0x0000000000000002, CVFlag},
+ {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
+ {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
+ {0x8000000000000002, NFlag, 0x8000000000000003, NFlag},
+ {0x8000000000000001, NFlag, 0x8000000000000002, NFlag}},
+ {{0xfffffffffffffffd, NCFlag, 0xfffffffffffffffe, NCFlag},
+ {0xfffffffffffffffc, NCFlag, 0xfffffffffffffffd, NCFlag},
+ {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
+ {0x7ffffffffffffffe, CVFlag, 0x7fffffffffffffff, CVFlag},
+ {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
+ {0x7ffffffffffffffc, CFlag, 0x7ffffffffffffffd, CFlag},
+ {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag},
+ {0xfffffffffffffffe, NFlag, 0xffffffffffffffff, NFlag}},
+ {{0xfffffffffffffffe, NCFlag, 0xffffffffffffffff, NCFlag},
+ {0xfffffffffffffffd, NCFlag, 0xfffffffffffffffe, NCFlag},
+ {0x8000000000000000, NCFlag, 0x8000000000000001, NCFlag},
+ {0x7fffffffffffffff, CVFlag, 0x8000000000000000, NCFlag},
+ {0x7ffffffffffffffe, CFlag, 0x7fffffffffffffff, CFlag},
+ {0x7ffffffffffffffd, CFlag, 0x7ffffffffffffffe, CFlag},
+ {0x0000000000000000, ZCFlag, 0x0000000000000001, CFlag},
+ {0xffffffffffffffff, NFlag, 0x0000000000000000, ZCFlag}}
+ };
+
+ for (size_t left = 0; left < input_count; left++) {
+ for (size_t right = 0; right < input_count; right++) {
+ const Expected & expected = expected_adcs_x[left][right];
+ AdcsSbcsHelper(&MacroAssembler::Adcs, inputs[left], inputs[right], 0,
+ expected.carry0_result, expected.carry0_flags);
+ AdcsSbcsHelper(&MacroAssembler::Adcs, inputs[left], inputs[right], 1,
+ expected.carry1_result, expected.carry1_flags);
+ }
+ }
+
+ for (size_t left = 0; left < input_count; left++) {
+ for (size_t right = 0; right < input_count; right++) {
+ const Expected & expected = expected_sbcs_x[left][right];
+ AdcsSbcsHelper(&MacroAssembler::Sbcs, inputs[left], inputs[right], 0,
+ expected.carry0_result, expected.carry0_flags);
+ AdcsSbcsHelper(&MacroAssembler::Sbcs, inputs[left], inputs[right], 1,
+ expected.carry1_result, expected.carry1_flags);
+ }
+ }
+}
+
+
+TEST(adcs_sbcs_w) {
+ uint32_t inputs[] = {
+ 0x00000000, 0x00000001, 0x7ffffffe, 0x7fffffff,
+ 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff,
+ };
+ static const size_t input_count = sizeof(inputs) / sizeof(inputs[0]);
+
+ struct Expected {
+ uint32_t carry0_result;
+ StatusFlags carry0_flags;
+ uint32_t carry1_result;
+ StatusFlags carry1_flags;
+ };
+
+ static const Expected expected_adcs_w[input_count][input_count] = {
+ {{0x00000000, ZFlag, 0x00000001, NoFlag},
+ {0x00000001, NoFlag, 0x00000002, NoFlag},
+ {0x7ffffffe, NoFlag, 0x7fffffff, NoFlag},
+ {0x7fffffff, NoFlag, 0x80000000, NVFlag},
+ {0x80000000, NFlag, 0x80000001, NFlag},
+ {0x80000001, NFlag, 0x80000002, NFlag},
+ {0xfffffffe, NFlag, 0xffffffff, NFlag},
+ {0xffffffff, NFlag, 0x00000000, ZCFlag}},
+ {{0x00000001, NoFlag, 0x00000002, NoFlag},
+ {0x00000002, NoFlag, 0x00000003, NoFlag},
+ {0x7fffffff, NoFlag, 0x80000000, NVFlag},
+ {0x80000000, NVFlag, 0x80000001, NVFlag},
+ {0x80000001, NFlag, 0x80000002, NFlag},
+ {0x80000002, NFlag, 0x80000003, NFlag},
+ {0xffffffff, NFlag, 0x00000000, ZCFlag},
+ {0x00000000, ZCFlag, 0x00000001, CFlag}},
+ {{0x7ffffffe, NoFlag, 0x7fffffff, NoFlag},
+ {0x7fffffff, NoFlag, 0x80000000, NVFlag},
+ {0xfffffffc, NVFlag, 0xfffffffd, NVFlag},
+ {0xfffffffd, NVFlag, 0xfffffffe, NVFlag},
+ {0xfffffffe, NFlag, 0xffffffff, NFlag},
+ {0xffffffff, NFlag, 0x00000000, ZCFlag},
+ {0x7ffffffc, CFlag, 0x7ffffffd, CFlag},
+ {0x7ffffffd, CFlag, 0x7ffffffe, CFlag}},
+ {{0x7fffffff, NoFlag, 0x80000000, NVFlag},
+ {0x80000000, NVFlag, 0x80000001, NVFlag},
+ {0xfffffffd, NVFlag, 0xfffffffe, NVFlag},
+ {0xfffffffe, NVFlag, 0xffffffff, NVFlag},
+ {0xffffffff, NFlag, 0x00000000, ZCFlag},
+ {0x00000000, ZCFlag, 0x00000001, CFlag},
+ {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
+ {0x7ffffffe, CFlag, 0x7fffffff, CFlag}},
+ {{0x80000000, NFlag, 0x80000001, NFlag},
+ {0x80000001, NFlag, 0x80000002, NFlag},
+ {0xfffffffe, NFlag, 0xffffffff, NFlag},
+ {0xffffffff, NFlag, 0x00000000, ZCFlag},
+ {0x00000000, ZCVFlag, 0x00000001, CVFlag},
+ {0x00000001, CVFlag, 0x00000002, CVFlag},
+ {0x7ffffffe, CVFlag, 0x7fffffff, CVFlag},
+ {0x7fffffff, CVFlag, 0x80000000, NCFlag}},
+ {{0x80000001, NFlag, 0x80000002, NFlag},
+ {0x80000002, NFlag, 0x80000003, NFlag},
+ {0xffffffff, NFlag, 0x00000000, ZCFlag},
+ {0x00000000, ZCFlag, 0x00000001, CFlag},
+ {0x00000001, CVFlag, 0x00000002, CVFlag},
+ {0x00000002, CVFlag, 0x00000003, CVFlag},
+ {0x7fffffff, CVFlag, 0x80000000, NCFlag},
+ {0x80000000, NCFlag, 0x80000001, NCFlag}},
+ {{0xfffffffe, NFlag, 0xffffffff, NFlag},
+ {0xffffffff, NFlag, 0x00000000, ZCFlag},
+ {0x7ffffffc, CFlag, 0x7ffffffd, CFlag},
+ {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
+ {0x7ffffffe, CVFlag, 0x7fffffff, CVFlag},
+ {0x7fffffff, CVFlag, 0x80000000, NCFlag},
+ {0xfffffffc, NCFlag, 0xfffffffd, NCFlag},
+ {0xfffffffd, NCFlag, 0xfffffffe, NCFlag}},
+ {{0xffffffff, NFlag, 0x00000000, ZCFlag},
+ {0x00000000, ZCFlag, 0x00000001, CFlag},
+ {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
+ {0x7ffffffe, CFlag, 0x7fffffff, CFlag},
+ {0x7fffffff, CVFlag, 0x80000000, NCFlag},
+ {0x80000000, NCFlag, 0x80000001, NCFlag},
+ {0xfffffffd, NCFlag, 0xfffffffe, NCFlag},
+ {0xfffffffe, NCFlag, 0xffffffff, NCFlag}}
+ };
+
+ static const Expected expected_sbcs_w[input_count][input_count] = {
+ {{0xffffffff, NFlag, 0x00000000, ZCFlag},
+ {0xfffffffe, NFlag, 0xffffffff, NFlag},
+ {0x80000001, NFlag, 0x80000002, NFlag},
+ {0x80000000, NFlag, 0x80000001, NFlag},
+ {0x7fffffff, NoFlag, 0x80000000, NVFlag},
+ {0x7ffffffe, NoFlag, 0x7fffffff, NoFlag},
+ {0x00000001, NoFlag, 0x00000002, NoFlag},
+ {0x00000000, ZFlag, 0x00000001, NoFlag}},
+ {{0x00000000, ZCFlag, 0x00000001, CFlag},
+ {0xffffffff, NFlag, 0x00000000, ZCFlag},
+ {0x80000002, NFlag, 0x80000003, NFlag},
+ {0x80000001, NFlag, 0x80000002, NFlag},
+ {0x80000000, NVFlag, 0x80000001, NVFlag},
+ {0x7fffffff, NoFlag, 0x80000000, NVFlag},
+ {0x00000002, NoFlag, 0x00000003, NoFlag},
+ {0x00000001, NoFlag, 0x00000002, NoFlag}},
+ {{0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
+ {0x7ffffffc, CFlag, 0x7ffffffd, CFlag},
+ {0xffffffff, NFlag, 0x00000000, ZCFlag},
+ {0xfffffffe, NFlag, 0xffffffff, NFlag},
+ {0xfffffffd, NVFlag, 0xfffffffe, NVFlag},
+ {0xfffffffc, NVFlag, 0xfffffffd, NVFlag},
+ {0x7fffffff, NoFlag, 0x80000000, NVFlag},
+ {0x7ffffffe, NoFlag, 0x7fffffff, NoFlag}},
+ {{0x7ffffffe, CFlag, 0x7fffffff, CFlag},
+ {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
+ {0x00000000, ZCFlag, 0x00000001, CFlag},
+ {0xffffffff, NFlag, 0x00000000, ZCFlag},
+ {0xfffffffe, NVFlag, 0xffffffff, NVFlag},
+ {0xfffffffd, NVFlag, 0xfffffffe, NVFlag},
+ {0x80000000, NVFlag, 0x80000001, NVFlag},
+ {0x7fffffff, NoFlag, 0x80000000, NVFlag}},
+ {{0x7fffffff, CVFlag, 0x80000000, NCFlag},
+ {0x7ffffffe, CVFlag, 0x7fffffff, CVFlag},
+ {0x00000001, CVFlag, 0x00000002, CVFlag},
+ {0x00000000, ZCVFlag, 0x00000001, CVFlag},
+ {0xffffffff, NFlag, 0x00000000, ZCFlag},
+ {0xfffffffe, NFlag, 0xffffffff, NFlag},
+ {0x80000001, NFlag, 0x80000002, NFlag},
+ {0x80000000, NFlag, 0x80000001, NFlag}},
+ {{0x80000000, NCFlag, 0x80000001, NCFlag},
+ {0x7fffffff, CVFlag, 0x80000000, NCFlag},
+ {0x00000002, CVFlag, 0x00000003, CVFlag},
+ {0x00000001, CVFlag, 0x00000002, CVFlag},
+ {0x00000000, ZCFlag, 0x00000001, CFlag},
+ {0xffffffff, NFlag, 0x00000000, ZCFlag},
+ {0x80000002, NFlag, 0x80000003, NFlag},
+ {0x80000001, NFlag, 0x80000002, NFlag}},
+ {{0xfffffffd, NCFlag, 0xfffffffe, NCFlag},
+ {0xfffffffc, NCFlag, 0xfffffffd, NCFlag},
+ {0x7fffffff, CVFlag, 0x80000000, NCFlag},
+ {0x7ffffffe, CVFlag, 0x7fffffff, CVFlag},
+ {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
+ {0x7ffffffc, CFlag, 0x7ffffffd, CFlag},
+ {0xffffffff, NFlag, 0x00000000, ZCFlag},
+ {0xfffffffe, NFlag, 0xffffffff, NFlag}},
+ {{0xfffffffe, NCFlag, 0xffffffff, NCFlag},
+ {0xfffffffd, NCFlag, 0xfffffffe, NCFlag},
+ {0x80000000, NCFlag, 0x80000001, NCFlag},
+ {0x7fffffff, CVFlag, 0x80000000, NCFlag},
+ {0x7ffffffe, CFlag, 0x7fffffff, CFlag},
+ {0x7ffffffd, CFlag, 0x7ffffffe, CFlag},
+ {0x00000000, ZCFlag, 0x00000001, CFlag},
+ {0xffffffff, NFlag, 0x00000000, ZCFlag}}
+ };
+
+ for (size_t left = 0; left < input_count; left++) {
+ for (size_t right = 0; right < input_count; right++) {
+ const Expected & expected = expected_adcs_w[left][right];
+ AdcsSbcsHelper(&MacroAssembler::Adcs, inputs[left], inputs[right], 0,
+ expected.carry0_result, expected.carry0_flags);
+ AdcsSbcsHelper(&MacroAssembler::Adcs, inputs[left], inputs[right], 1,
+ expected.carry1_result, expected.carry1_flags);
+ }
+ }
+
+ for (size_t left = 0; left < input_count; left++) {
+ for (size_t right = 0; right < input_count; right++) {
+ const Expected & expected = expected_sbcs_w[left][right];
+ AdcsSbcsHelper(&MacroAssembler::Sbcs, inputs[left], inputs[right], 0,
+ expected.carry0_result, expected.carry0_flags);
+ AdcsSbcsHelper(&MacroAssembler::Sbcs, inputs[left], inputs[right], 1,
+ expected.carry1_result, expected.carry1_flags);
+ }
+ }
+}
+
+
TEST(adc_sbc_shift) {
SETUP();
@@ -7731,132 +8105,6 @@ TEST(adc_sbc_shift) {
ASSERT_EQUAL_32(0x91111110 + 1, w26);
ASSERT_EQUAL_32(0x9a222221 + 1, w27);
- // Check that adc correctly sets the condition flags.
- START();
- __ Mov(x0, 1);
- __ Mov(x1, 0xffffffffffffffff);
- // Clear the C flag.
- __ Adds(x0, x0, Operand(0));
- __ Adcs(x10, x0, Operand(x1));
- END();
-
- RUN();
-
- ASSERT_EQUAL_NZCV(ZCFlag);
- ASSERT_EQUAL_64(0, x10);
-
- START();
- __ Mov(x0, 1);
- __ Mov(x1, 0x8000000000000000);
- // Clear the C flag.
- __ Adds(x0, x0, Operand(0));
- __ Adcs(x10, x0, Operand(x1, ASR, 63));
- END();
-
- RUN();
-
- ASSERT_EQUAL_NZCV(ZCFlag);
- ASSERT_EQUAL_64(0, x10);
-
- START();
- __ Mov(x0, 0x10);
- __ Mov(x1, 0x07ffffffffffffff);
- // Clear the C flag.
- __ Adds(x0, x0, Operand(0));
- __ Adcs(x10, x0, Operand(x1, LSL, 4));
- END();
-
- RUN();
-
- ASSERT_EQUAL_NZCV(NVFlag);
- ASSERT_EQUAL_64(0x8000000000000000, x10);
-
- // Check that sbc correctly sets the condition flags.
- START();
- __ Mov(x0, 0);
- __ Mov(x1, 0xffffffffffffffff);
- // Clear the C flag.
- __ Adds(x0, x0, Operand(0));
- __ Sbcs(x10, x0, Operand(x1));
- END();
-
- RUN();
-
- ASSERT_EQUAL_NZCV(ZFlag);
- ASSERT_EQUAL_64(0, x10);
-
- START();
- __ Mov(x0, 1);
- __ Mov(x1, 0xffffffffffffffff);
- // Clear the C flag.
- __ Adds(x0, x0, Operand(0));
- __ Sbcs(x10, x0, Operand(x1, LSR, 1));
- END();
-
- RUN();
-
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0x8000000000000001, x10);
-
- START();
- __ Mov(x0, 0);
- // Clear the C flag.
- __ Adds(x0, x0, Operand(0));
- __ Sbcs(x10, x0, Operand(0xffffffffffffffff));
- END();
-
- RUN();
-
- ASSERT_EQUAL_NZCV(ZFlag);
- ASSERT_EQUAL_64(0, x10);
-
- START();
- __ Mov(w0, 0x7fffffff);
- // Clear the C flag.
- __ Adds(x0, x0, Operand(0));
- __ Ngcs(w10, w0);
- END();
-
- RUN();
-
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0x80000000, x10);
-
- START();
- // Clear the C flag.
- __ Adds(x0, x0, Operand(0));
- __ Ngcs(x10, 0x7fffffffffffffff);
- END();
-
- RUN();
-
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0x8000000000000000, x10);
-
- START();
- __ Mov(x0, 0);
- // Set the C flag.
- __ Cmp(x0, Operand(x0));
- __ Sbcs(x10, x0, Operand(1));
- END();
-
- RUN();
-
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0xffffffffffffffff, x10);
-
- START();
- __ Mov(x0, 0);
- // Set the C flag.
- __ Cmp(x0, Operand(x0));
- __ Ngcs(x10, 0x7fffffffffffffff);
- END();
-
- RUN();
-
- ASSERT_EQUAL_NZCV(NFlag);
- ASSERT_EQUAL_64(0x8000000000000001, x10);
-
TEARDOWN();
}
@@ -14080,7 +14328,7 @@ TEST(printf_no_preserve) {
}
-#ifndef USE_SIMULATOR
+#ifndef VIXL_INCLUDE_SIMULATOR
TEST(trace) {
// The Trace helper should not generate any code unless the simulator (or
// debugger) is being used.
@@ -14099,7 +14347,7 @@ TEST(trace) {
#endif
-#ifndef USE_SIMULATOR
+#ifndef VIXL_INCLUDE_SIMULATOR
TEST(log) {
// The Log helper should not generate any code unless the simulator (or
// debugger) is being used.
@@ -15140,7 +15388,7 @@ TEST(clrex) {
}
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
// Check that the simulator occasionally makes store-exclusive fail.
TEST(ldxr_stxr_fail) {
uint64_t data[] = {0, 0, 0};
@@ -15224,7 +15472,7 @@ TEST(ldxr_stxr_fail) {
#endif
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
// Check that the simulator occasionally makes store-exclusive fail.
TEST(ldaxr_stlxr_fail) {
uint64_t data[] = {0, 0, 0};
@@ -21744,7 +21992,6 @@ TEST(literal_deletion_policies) {
masm.EmitLiteralPool(LiteralPool::kBranchRequired);
VIXL_ASSERT(lit_manual.IsPlaced());
- VIXL_ASSERT(lit_deleted_on_placement->IsPlaced());
VIXL_ASSERT(lit_deleted_on_pool_destruction->IsPlaced());
lit_deleted_on_pool_destruction->UpdateValue(128, &masm);
diff --git a/test/test-disasm-a64.cc b/test/test-disasm-a64.cc
index 0f54288c..d4fa02f3 100644
--- a/test/test-disasm-a64.cc
+++ b/test/test-disasm-a64.cc
@@ -45,7 +45,18 @@
#define SETUP() SETUP_CLASS(Assembler)
-#define SETUP_MACRO() SETUP_CLASS(MacroAssembler)
+#ifdef VIXL_INCLUDE_SIMULATOR
+// Run tests with the simulator.
+#define SETUP_MACRO() \
+ SETUP_CLASS(MacroAssembler); \
+ masm->SetAllowSimulatorInstructions(true)
+
+#else // ifdef VIXL_INCLUDE_SIMULATOR.
+#define SETUP_MACRO() \
+ SETUP_CLASS(MacroAssembler); \
+ masm->SetAllowSimulatorInstructions(false)
+
+#endif // ifdef VIXL_INCLUDE_SIMULATOR.
#define COMPARE(ASM, EXP) \
masm->Reset(); \
@@ -137,7 +148,7 @@ TEST(bootstrap) {
TEST(mov_mvn) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Mov(w0, Operand(0x1234)), "mov w0, #0x1234");
COMPARE(Mov(x1, Operand(0x1234)), "mov x1, #0x1234");
@@ -203,7 +214,7 @@ TEST(move_immediate) {
TEST(move_immediate_2) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
// Move instructions expected for certain immediates. This is really a macro
// assembler test, to ensure it generates immediates efficiently.
@@ -1848,7 +1859,7 @@ TEST(load_store_pair_nontemp) {
TEST(load_literal_macro) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
// In each case, the literal will be placed at PC+8:
// ldr x10, pc+8 // Test instruction.
@@ -2187,7 +2198,7 @@ TEST(cond_select) {
TEST(cond_select_macro) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Csel(w0, w1, -1, eq), "csinv w0, w1, wzr, eq");
COMPARE(Csel(w2, w3, 0, ne), "csel w2, w3, wzr, ne");
@@ -2219,7 +2230,7 @@ TEST(cond_cmp) {
TEST(cond_cmp_macro) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Ccmp(w0, -1, VFlag, hi), "ccmn w0, #1, #nzcV, hi");
COMPARE(Ccmp(x1, -31, CFlag, ge), "ccmn x1, #31, #nzCv, ge");
@@ -2584,9 +2595,9 @@ TEST(system_nop) {
TEST(unreachable) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
VIXL_ASSERT(kUnreachableOpcode == 0xdeb0);
COMPARE(Unreachable(), "hlt #0xdeb0");
#else
@@ -2597,9 +2608,9 @@ TEST(unreachable) {
}
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
TEST(trace) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
VIXL_ASSERT(kTraceOpcode == 0xdeb2);
@@ -2612,9 +2623,9 @@ TEST(trace) {
#endif
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
TEST(log) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
VIXL_ASSERT(kLogOpcode == 0xdeb3);
@@ -2661,7 +2672,7 @@ TEST(svc) {
TEST(add_sub_negative) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Add(x10, x0, -42), "sub x10, x0, #0x2a (42)");
COMPARE(Add(x11, x1, -687), "sub x11, x1, #0x2af (687)");
@@ -2698,7 +2709,7 @@ TEST(add_sub_negative) {
TEST(logical_immediate_move) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(And(w0, w1, 0), "mov w0, #0x0");
COMPARE(And(x0, x1, 0), "mov x0, #0x0");
@@ -2737,7 +2748,7 @@ TEST(logical_immediate_move) {
TEST(barriers) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
// DMB
COMPARE(Dmb(FullSystem, BarrierAll), "dmb sy");
@@ -2837,7 +2848,7 @@ TEST(barriers) {
V(V4S(), "4s")
TEST(neon_load_store_vector) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
#define DISASM_INST(M, S) \
COMPARE(Ld1(v0.M, MemOperand(x15)), \
@@ -3023,7 +3034,7 @@ TEST(neon_load_store_vector) {
TEST(neon_load_store_lane) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Ld1(v0.V8B(), 0, MemOperand(x15)), "ld1 {v0.b}[0], [x15]");
COMPARE(Ld1(v1.V16B(), 1, MemOperand(x16)), "ld1 {v1.b}[1], [x16]");
@@ -3419,7 +3430,7 @@ TEST(neon_load_store_lane) {
TEST(neon_load_all_lanes) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Ld1r(v14.V8B(), MemOperand(x0)), "ld1r {v14.8b}, [x0]");
COMPARE(Ld1r(v15.V16B(), MemOperand(x1)), "ld1r {v15.16b}, [x1]");
@@ -3567,7 +3578,7 @@ TEST(neon_load_all_lanes) {
TEST(neon_3same) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
#define DISASM_INST(M, S) \
COMPARE(Cmeq(v0.M, v1.M, v2.M), "cmeq v0." S ", v1." S ", v2." S);
@@ -3832,7 +3843,7 @@ TEST(neon_3same) {
V(V2D(), "2d")
TEST(neon_fp_3same) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
#define DISASM_INST(M, S) \
COMPARE(Fadd(v0.M, v1.M, v2.M), "fadd v0." S ", v1." S ", v2." S);
@@ -3965,7 +3976,7 @@ TEST(neon_fp_3same) {
V(D(), "d")
TEST(neon_scalar_3same) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
// Instructions that only support D-sized scalar operations.
COMPARE(Add(v0.D(), v1.D(), v2.D()), "add d0, d1, d2");
@@ -4050,7 +4061,7 @@ TEST(neon_scalar_3same) {
TEST(neon_byelement) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Mul(v0.V4H(), v1.V4H(), v2.H(), 0), "mul v0.4h, v1.4h, v2.h[0]");
COMPARE(Mul(v2.V8H(), v3.V8H(), v15.H(), 7), "mul v2.8h, v3.8h, v15.h[7]");
@@ -4169,7 +4180,7 @@ TEST(neon_byelement) {
TEST(neon_fp_byelement) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Fmul(v0.V2S(), v1.V2S(), v2.S(), 0), "fmul v0.2s, v1.2s, v2.s[0]");
COMPARE(Fmul(v2.V4S(), v3.V4S(), v15.S(), 3), "fmul v2.4s, v3.4s, v15.s[3]");
@@ -4200,7 +4211,7 @@ TEST(neon_fp_byelement) {
TEST(neon_3different) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
#define DISASM_INST(TA, TAS, TB, TBS) \
COMPARE(Uaddl(v0.TA, v1.TB, v2.TB), "uaddl v0." TAS ", v1." TBS ", v2." TBS);
@@ -4465,7 +4476,7 @@ TEST(neon_3different) {
TEST(neon_perm) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
#define DISASM_INST(M, S) \
COMPARE(Trn1(v0.M, v1.M, v2.M), "trn1 v0." S ", v1." S ", v2." S);
@@ -4502,7 +4513,7 @@ TEST(neon_perm) {
TEST(neon_copy) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Ins(v1.V16B(), 4, v5.V16B(), 0), "mov v1.b[4], v5.b[0]");
COMPARE(Ins(v2.V8B(), 5, v6.V8B(), 1), "mov v2.b[5], v6.b[1]");
@@ -4618,7 +4629,7 @@ TEST(neon_copy) {
TEST(neon_extract) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Ext(v4.V8B(), v5.V8B(), v6.V8B(), 0), "ext v4.8b, v5.8b, v6.8b, #0");
COMPARE(Ext(v1.V8B(), v2.V8B(), v3.V8B(), 7), "ext v1.8b, v2.8b, v3.8b, #7");
@@ -4632,7 +4643,7 @@ TEST(neon_extract) {
TEST(neon_modimm) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Orr(v4.V4H(), 0xaa, 0), "orr v4.4h, #0xaa, lsl #0");
COMPARE(Orr(v1.V8H(), 0xcc, 8), "orr v1.8h, #0xcc, lsl #8");
@@ -4691,7 +4702,7 @@ TEST(neon_modimm) {
TEST(neon_2regmisc) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Shll(v1.V8H(), v8.V8B(), 8), "shll v1.8h, v8.8b, #8");
COMPARE(Shll(v3.V4S(), v1.V4H(), 16), "shll v3.4s, v1.4h, #16");
@@ -5072,7 +5083,7 @@ TEST(neon_2regmisc) {
}
TEST(neon_acrosslanes) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Smaxv(b4, v5.V8B()), "smaxv b4, v5.8b");
COMPARE(Smaxv(b4, v5.V16B()), "smaxv b4, v5.16b");
@@ -5125,7 +5136,7 @@ TEST(neon_acrosslanes) {
}
TEST(neon_scalar_pairwise) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Addp(d0, v1.V2D()), "addp d0, v1.2d");
COMPARE(Faddp(s0, v1.V2S()), "faddp s0, v1.2s");
@@ -5142,7 +5153,7 @@ TEST(neon_scalar_pairwise) {
}
TEST(neon_shift_immediate) {
- SETUP_CLASS(MacroAssembler);
+ SETUP_MACRO();
COMPARE(Sshr(v0.V8B(), v1.V8B(), 1), "sshr v0.8b, v1.8b, #1");
COMPARE(Sshr(v2.V8B(), v3.V8B(), 8), "sshr v2.8b, v3.8b, #8");
diff --git a/test/test-simulator-a64.cc b/test/test-simulator-a64.cc
index 863fd4cc..e67177bf 100644
--- a/test/test-simulator-a64.cc
+++ b/test/test-simulator-a64.cc
@@ -52,7 +52,7 @@ namespace vixl {
#define BUF_SIZE (256)
-#ifdef USE_SIMULATOR
+#ifdef VIXL_INCLUDE_SIMULATOR
#define SETUP() \
MacroAssembler masm(BUF_SIZE); \
@@ -94,7 +94,7 @@ namespace vixl {
#define TEARDOWN() \
delete simulator;
-#else // USE_SIMULATOR
+#else // VIXL_INCLUDE_SIMULATOR
#define SETUP() \
MacroAssembler masm(BUF_SIZE); \
@@ -123,7 +123,7 @@ namespace vixl {
#define TEARDOWN()
-#endif // USE_SIMULATOR
+#endif // VIXL_INCLUDE_SIMULATOR
// The maximum number of errors to report in detail for each test.
diff --git a/third_party/android/Android.mk.template b/third_party/android/Android.mk.template
index 12472513..9a1cee6b 100644
--- a/third_party/android/Android.mk.template
+++ b/third_party/android/Android.mk.template
@@ -68,13 +68,15 @@ vixl_test_files := \
{vixl_test_files}
vixl_cpp_flags := \
- -DUSE_SIMULATOR \
+ -DVIXL_INCLUDE_SIMULATOR \
+ -DVIXL_GENERATE_SIMULATOR_INSTRUCTIONS_VALUE=0 \
-Wall \
-Wextra \
-Werror \
-fdiagnostics-show-option \
-Wredundant-decls \
-Wunreachable-code \
+ -Wmissing-noreturn \
-pedantic \
-std=c++11 \
@@ -105,7 +107,6 @@ LOCAL_CLANG := true
LOCAL_CPP_EXTENSION := .cc
LOCAL_CPPFLAGS := $(vixl_cpp_flags_release)
LOCAL_CLANG_CFLAGS := -Wimplicit-fallthrough
-LOCAL_CPPFLAGS_arm64 := -UUSE_SIMULATOR
LOCAL_C_INCLUDES := $(vixl_include_files)
LOCAL_SRC_FILES := $(vixl_src_files)
LOCAL_SHARED_LIBRARIES := liblog
@@ -120,7 +121,6 @@ LOCAL_CLANG := true
LOCAL_CPP_EXTENSION := .cc
LOCAL_CPPFLAGS := $(vixl_cpp_flags_debug)
LOCAL_CLANG_CFLAGS := -Wimplicit-fallthrough
-LOCAL_CPPFLAGS_arm64 := -UUSE_SIMULATOR
LOCAL_C_INCLUDES := $(vixl_include_files)
LOCAL_SRC_FILES := $(vixl_src_files)
LOCAL_SHARED_LIBRARIES := liblog
@@ -222,4 +222,5 @@ include $(BUILD_HOST_EXECUTABLE)
run-vixl-tests: vixl-test-runner
$(vixl_root)/third_party/android/check_top_level_android_mk.sh
$(HOST_OUT)/bin/vixl-test-runner --run_all
+ $(HOST_OUT)/bin/vixl-test-runner --run_all --debugger
@echo vixl tests PASSED
diff --git a/tools/test.py b/tools/test.py
index efc41ed0..b4e9da9d 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -227,6 +227,11 @@ def BuildOptions():
'--simulator', action='store', choices=['on', 'off'],
default=sim_default,
help='Explicitly enable or disable the simulator.')
+ general_arguments.add_argument(
+ '--under_valgrind', action='store_true',
+ help='''Run the test-runner commands under Valgrind.
+ Note that a few tests are known to fail because of
+ issues in Valgrind''')
return args.parse_args()
@@ -349,6 +354,9 @@ if __name__ == '__main__':
args = BuildOptions()
+ if args.under_valgrind:
+ util.require_program('valgrind')
+
if args.fast:
def SetFast(option, specified, default):
option.val_test_choices = \
@@ -400,6 +408,7 @@ if __name__ == '__main__':
rc |= threaded_tests.RunTests(test_executable,
args.filters,
list(runtime_options),
+ args.under_valgrind,
jobs = args.jobs, prefix = prefix)
if not args.nobench:
diff --git a/tools/threaded_tests.py b/tools/threaded_tests.py
index dcb17cbc..37001422 100644
--- a/tools/threaded_tests.py
+++ b/tools/threaded_tests.py
@@ -65,6 +65,7 @@ n_tests_failed = multiprocessing.Value('i', 0)
# Read-only for workers.
test_runner = None
test_runner_runtime_options = None
+test_runner_under_valgrind = False
n_tests = None
start_time = None
progress_prefix = None
@@ -72,6 +73,8 @@ progress_prefix = None
def RunTest(test):
command = [test_runner, test] + test_runner_runtime_options
+ if test_runner_under_valgrind:
+ command = ['valgrind'] + command
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
@@ -109,9 +112,11 @@ def RunTest(test):
# multiprocessing module.
__run_tests_lock__ = multiprocessing.Lock()
def RunTests(test_runner_command, filters, runtime_options,
+ under_valgrind = False,
jobs = 1, prefix = ''):
global test_runner
global test_runner_runtime_options
+ global test_runner_under_valgrind
global n_tests
global start_time
global progress_prefix
@@ -128,6 +133,7 @@ def RunTests(test_runner_command, filters, runtime_options,
start_time = time.time()
test_runner = test_runner_command
test_runner_runtime_options = runtime_options
+ test_runner_under_valgrind = under_valgrind
n_tests = len(tests)
n_tests_passed.value = 0
n_tests_failed.value = 0