aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Bramley <jacob.bramley@arm.com>2018-08-29 17:02:31 +0100
committerJacob Bramley <jacob.bramley@arm.com>2018-09-11 13:24:25 +0100
commit9799d7f0c4dee186db5deb46676e6aee8fadd024 (patch)
tree200b9c834d658f0b779db1c9a62caaf821872b56
parentc44ce3df427b8cd50fcbde874ab49535b66cf98c (diff)
Use PrintDisassembler for --disassemble.
This required a clean-up at the same time, to fix some inconsistencies in the way that the APIs and macros had been used. The new code structure allows for a test-runner option to print the features required by each instruction, but this is not implemented here. Change-Id: I967c8bd44f6a832892fc854ca6643a5e6a682997
-rw-r--r--src/aarch64/decoder-aarch64.h8
-rw-r--r--src/aarch64/disasm-aarch64.cc25
-rw-r--r--src/aarch64/disasm-aarch64.h9
-rw-r--r--src/aarch64/instructions-aarch64.h1
-rw-r--r--test/aarch64/test-assembler-aarch64.cc120
-rw-r--r--test/aarch64/test-disasm-aarch64.cc193
6 files changed, 189 insertions, 167 deletions
diff --git a/src/aarch64/decoder-aarch64.h b/src/aarch64/decoder-aarch64.h
index 4a21b9f5..4ebc7ce1 100644
--- a/src/aarch64/decoder-aarch64.h
+++ b/src/aarch64/decoder-aarch64.h
@@ -160,6 +160,14 @@ class Decoder {
DecodeInstruction(const_cast<const Instruction*>(instr));
}
+ // Decode all instructions from start (inclusive) to end (exclusive).
+ template <typename T>
+ void Decode(T start, T end) {
+ for (T instr = start; instr < end; instr = instr->GetNextInstruction()) {
+ Decode(instr);
+ }
+ }
+
// Register a new visitor class with the decoder.
// Decode() will call the corresponding visitor method from all registered
// visitor classes when decoding reaches the leaf node of the instruction
diff --git a/src/aarch64/disasm-aarch64.cc b/src/aarch64/disasm-aarch64.cc
index b8865d07..0b76ae61 100644
--- a/src/aarch64/disasm-aarch64.cc
+++ b/src/aarch64/disasm-aarch64.cc
@@ -5164,15 +5164,28 @@ void Disassembler::AppendToOutput(const char *format, ...) {
}
-void PrintDisassembler::DisassembleBuffer(const Instruction *start,
- uint64_t size) {
+void PrintDisassembler::Disassemble(const Instruction *instr) {
Decoder decoder;
+ if (cpu_features_auditor_ != NULL) {
+ decoder.AppendVisitor(cpu_features_auditor_);
+ }
decoder.AppendVisitor(this);
- const Instruction *instr_end = start + size;
- for (const Instruction *instr = start; instr < instr_end;
- instr += kInstructionSize) {
- decoder.Decode(instr);
+ decoder.Decode(instr);
+}
+
+void PrintDisassembler::DisassembleBuffer(const Instruction *start,
+ const Instruction *end) {
+ Decoder decoder;
+ if (cpu_features_auditor_ != NULL) {
+ decoder.AppendVisitor(cpu_features_auditor_);
}
+ decoder.AppendVisitor(this);
+ decoder.Decode(start, end);
+}
+
+void PrintDisassembler::DisassembleBuffer(const Instruction *start,
+ uint64_t size) {
+ DisassembleBuffer(start, start + size);
}
diff --git a/src/aarch64/disasm-aarch64.h b/src/aarch64/disasm-aarch64.h
index 825ca278..c650bee9 100644
--- a/src/aarch64/disasm-aarch64.h
+++ b/src/aarch64/disasm-aarch64.h
@@ -174,13 +174,18 @@ class PrintDisassembler : public Disassembler {
cpu_features_prefix_("// Needs: "),
cpu_features_suffix_(""),
stream_(stream) {}
+
+ // Convenience helpers for quick disassembly, without having to manually
+ // create a decoder.
void DisassembleBuffer(const Instruction* start, uint64_t size);
+ void DisassembleBuffer(const Instruction* start, const Instruction* end);
+ void Disassemble(const Instruction* instr);
// If a CPUFeaturesAuditor is specified, it will be used to annotate
// disassembly. The CPUFeaturesAuditor is expected to visit the instructions
// _before_ the disassembler, such that the CPUFeatures information is
// available when the disassembler is called.
- void RegisterCPUFeaturesAuditor(CPUFeaturesAuditor const* auditor) {
+ void RegisterCPUFeaturesAuditor(CPUFeaturesAuditor* auditor) {
cpu_features_auditor_ = auditor;
}
@@ -199,7 +204,7 @@ class PrintDisassembler : public Disassembler {
protected:
virtual void ProcessOutput(const Instruction* instr) VIXL_OVERRIDE;
- CPUFeaturesAuditor const* cpu_features_auditor_;
+ CPUFeaturesAuditor* cpu_features_auditor_;
const char* cpu_features_prefix_;
const char* cpu_features_suffix_;
diff --git a/src/aarch64/instructions-aarch64.h b/src/aarch64/instructions-aarch64.h
index 39c21a11..1f134c10 100644
--- a/src/aarch64/instructions-aarch64.h
+++ b/src/aarch64/instructions-aarch64.h
@@ -473,6 +473,7 @@ class Instruction {
return GetLiteralFP64();
}
+ Instruction* GetNextInstruction() { return this + kInstructionSize; }
const Instruction* GetNextInstruction() const {
return this + kInstructionSize;
}
diff --git a/test/aarch64/test-assembler-aarch64.cc b/test/aarch64/test-assembler-aarch64.cc
index d4bb9b4b..ba680d6c 100644
--- a/test/aarch64/test-assembler-aarch64.cc
+++ b/test/aarch64/test-assembler-aarch64.cc
@@ -96,6 +96,10 @@ namespace aarch64 {
#define __ masm.
#define TEST(name) TEST_(AARCH64_ASM_##name)
+// PushCalleeSavedRegisters(), PopCalleeSavedRegisters() and Dump() use NEON, so
+// we need to enable it in the infrastructure code for each test.
+const CPUFeatures kInfrastructureCPUFeatures(CPUFeatures::kNEON);
+
#ifdef VIXL_INCLUDE_SIMULATOR_AARCH64
// Run tests with the simulator.
@@ -122,9 +126,6 @@ namespace aarch64 {
simulator.SetColouredTrace(Test::coloured_trace()); \
simulator.SetInstructionStats(Test::instruction_stats()); \
simulator.SetCPUFeatures(CPUFeatures::None()); \
- Disassembler disasm; \
- Decoder disassembler_decoder; \
- disassembler_decoder.AppendVisitor(&disasm); \
RegisterDump core; \
ptrdiff_t offset_after_infrastructure_start; \
ptrdiff_t offset_before_infrastructure_end
@@ -133,8 +134,7 @@ namespace aarch64 {
masm.Reset(); \
simulator.ResetState(); \
{ \
- /* PushCalleeSavedRegisters() uses NEON stores. */ \
- SimulationCPUFeaturesScope cpu(&masm, CPUFeatures::kNEON); \
+ SimulationCPUFeaturesScope cpu(&masm, kInfrastructureCPUFeatures); \
__ PushCalleeSavedRegisters(); \
} \
{ \
@@ -154,21 +154,20 @@ namespace aarch64 {
/* Avoid unused-variable warnings in case a test never calls RUN(). */ \
USE(offset_after_infrastructure_start)
-#define END() \
- offset_before_infrastructure_end = masm.GetCursorOffset(); \
- /* Avoid unused-variable warnings in case a test never calls RUN(). */ \
- USE(offset_before_infrastructure_end); \
- if (Test::instruction_stats()) { \
- __ DisableInstrumentation(); \
- } \
- __ Trace(LOG_ALL, TRACE_DISABLE); \
- { \
- /* Dump() and PopCalleeSavedRegisters() use NEON loads and stores. */ \
- SimulationCPUFeaturesScope cpu(&masm, CPUFeatures::kNEON); \
- core.Dump(&masm); \
- __ PopCalleeSavedRegisters(); \
- } \
- __ Ret(); \
+#define END() \
+ offset_before_infrastructure_end = masm.GetCursorOffset(); \
+ /* Avoid unused-variable warnings in case a test never calls RUN(). */ \
+ USE(offset_before_infrastructure_end); \
+ if (Test::instruction_stats()) { \
+ __ DisableInstrumentation(); \
+ } \
+ __ Trace(LOG_ALL, TRACE_DISABLE); \
+ { \
+ SimulationCPUFeaturesScope cpu(&masm, kInfrastructureCPUFeatures); \
+ core.Dump(&masm); \
+ __ PopCalleeSavedRegisters(); \
+ } \
+ __ Ret(); \
masm.FinalizeCode()
#define RUN() \
@@ -229,9 +228,6 @@ namespace aarch64 {
SETUP_COMMON()
#define SETUP_COMMON() \
- Disassembler disasm; \
- Decoder disassembler_decoder; \
- disassembler_decoder.AppendVisitor(&disasm); \
masm.GetCPUFeatures()->Remove(CPUFeatures::All()); \
masm.SetGenerateSimulatorCode(false); \
RegisterDump core; \
@@ -242,25 +238,23 @@ namespace aarch64 {
#define START() \
masm.Reset(); \
{ \
- /* PushCalleeSavedRegisters() uses NEON stores. */ \
- CPUFeaturesScope cpu(&masm, CPUFeatures::kNEON); \
+ CPUFeaturesScope cpu(&masm, kInfrastructureCPUFeatures); \
__ PushCalleeSavedRegisters(); \
} \
offset_after_infrastructure_start = masm.GetCursorOffset(); \
/* Avoid unused-variable warnings in case a test never calls RUN(). */ \
USE(offset_after_infrastructure_start)
-#define END() \
- offset_before_infrastructure_end = masm.GetCursorOffset(); \
- /* Avoid unused-variable warnings in case a test never calls RUN(). */ \
- USE(offset_before_infrastructure_end); \
- { \
- /* Dump() and PopCalleeSavedRegisters() use NEON loads and stores. */ \
- CPUFeaturesScope cpu(&masm, CPUFeatures::kNEON); \
- core.Dump(&masm); \
- __ PopCalleeSavedRegisters(); \
- } \
- __ Ret(); \
+#define END() \
+ offset_before_infrastructure_end = masm.GetCursorOffset(); \
+ /* Avoid unused-variable warnings in case a test never calls RUN(). */ \
+ USE(offset_before_infrastructure_end); \
+ { \
+ CPUFeaturesScope cpu(&masm, kInfrastructureCPUFeatures); \
+ core.Dump(&masm); \
+ __ PopCalleeSavedRegisters(); \
+ } \
+ __ Ret(); \
masm.FinalizeCode()
// Execute the generated code from the memory area.
@@ -284,33 +278,33 @@ namespace aarch64 {
#endif // ifdef VIXL_INCLUDE_SIMULATOR_AARCH64.
-#define DISASSEMBLE() \
- if (Test::disassemble()) { \
- ptrdiff_t start_offset = offset_after_infrastructure_start; \
- ptrdiff_t end_offset = offset_before_infrastructure_end; \
- if (Test::disassemble_infrastructure()) { \
- start_offset = 0; \
- end_offset = masm.GetSizeOfCodeGenerated(); \
- } else { \
- printf( \
- " Warning: Omitting infrastructure code. " \
- "Use --disassemble to see it.\n"); \
- } \
- Instruction* instruction = \
- masm.GetBuffer()->GetOffsetAddress<Instruction*>(start_offset); \
- Instruction* end = \
- masm.GetBuffer()->GetOffsetAddress<Instruction*>(end_offset); \
- while (instruction != end) { \
- disassembler_decoder.Decode(instruction); \
- uint32_t encoding; \
- memcpy(&encoding, instruction, sizeof(encoding)); \
- uint64_t address = reinterpret_cast<uintptr_t>(instruction); \
- printf(" %016" PRIx64 ":\t%08" PRIx32 "\t%s\n", \
- address, \
- encoding, \
- disasm.GetOutput()); \
- instruction += kInstructionSize; \
- } \
+#define DISASSEMBLE() \
+ if (Test::disassemble()) { \
+ PrintDisassembler disasm(stdout); \
+ CodeBuffer* buffer = masm.GetBuffer(); \
+ Instruction* start = buffer->GetOffsetAddress<Instruction*>( \
+ offset_after_infrastructure_start); \
+ Instruction* end = buffer->GetOffsetAddress<Instruction*>( \
+ offset_before_infrastructure_end); \
+ \
+ if (Test::disassemble_infrastructure()) { \
+ Instruction* infra_start = buffer->GetStartAddress<Instruction*>(); \
+ printf("# Infrastructure code (prologue)\n"); \
+ disasm.DisassembleBuffer(infra_start, start); \
+ printf("# Test code\n"); \
+ } else { \
+ printf( \
+ "# Warning: Omitting infrastructure code. " \
+ "Use --disassemble to see it.\n"); \
+ } \
+ \
+ disasm.DisassembleBuffer(start, end); \
+ \
+ if (Test::disassemble_infrastructure()) { \
+ printf("# Infrastructure code (epilogue)\n"); \
+ Instruction* infra_end = buffer->GetEndAddress<Instruction*>(); \
+ disasm.DisassembleBuffer(end, infra_end); \
+ } \
}
#define ASSERT_EQUAL_NZCV(expected) \
diff --git a/test/aarch64/test-disasm-aarch64.cc b/test/aarch64/test-disasm-aarch64.cc
index b494780c..10849219 100644
--- a/test/aarch64/test-disasm-aarch64.cc
+++ b/test/aarch64/test-disasm-aarch64.cc
@@ -37,7 +37,6 @@
#define TEST(name) TEST_(AARCH64_DISASM_##name)
#define SETUP_COMMON() \
- uint32_t encoding = 0; \
MacroAssembler masm; \
masm.GetCPUFeatures()->Combine(CPUFeatures::All()); \
Decoder decoder; \
@@ -61,94 +60,96 @@
// tests.
#define MAX_SIZE_GENERATED 1024
-#define COMPARE(ASM, EXP) \
- masm.Reset(); \
- { \
- ExactAssemblyScope guard(&masm, \
- MAX_SIZE_GENERATED, \
- ExactAssemblyScope::kMaximumSize); \
- masm.ASM; \
- } \
- masm.FinalizeCode(); \
- decoder.Decode(masm.GetBuffer()->GetStartAddress<Instruction*>()); \
- encoding = *masm.GetBuffer()->GetStartAddress<uint32_t*>(); \
- if (strcmp(disasm.GetOutput(), EXP) != 0) { \
- printf("\nEncoding: %08" PRIx32 "\nExpected: %s\nFound: %s\n", \
- encoding, \
- EXP, \
- disasm.GetOutput()); \
- abort(); \
- } \
- if (Test::disassemble()) { \
- printf("----\n"); \
- printf("%08" PRIx32 "\t%s\n", encoding, disasm.GetOutput()); \
- }
-
-#define COMPARE_PREFIX(ASM, EXP) \
- masm.Reset(); \
- { \
- ExactAssemblyScope guard(&masm, \
- MAX_SIZE_GENERATED, \
- ExactAssemblyScope::kMaximumSize); \
- masm.ASM; \
- } \
- masm.FinalizeCode(); \
- decoder.Decode(masm.GetBuffer()->GetStartAddress<Instruction*>()); \
- encoding = *masm.GetBuffer()->GetStartAddress<uint32_t*>(); \
- if (strncmp(disasm.GetOutput(), EXP, strlen(EXP)) != 0) { \
- printf("\nEncoding: %08" PRIx32 "\nExpected: %s\nFound: %s\n", \
- encoding, \
- EXP, \
- disasm.GetOutput()); \
- abort(); \
- } \
- if (Test::disassemble()) { \
- printf("----\n"); \
- printf("%08" PRIx32 "\t%s\n", encoding, disasm.GetOutput()); \
- }
-
-#define COMPARE_MACRO_BASE(ASM, EXP) \
- masm.Reset(); \
- masm.ASM; \
- masm.FinalizeCode(); \
- std::string res; \
- \
- Instruction* instruction = \
- masm.GetBuffer()->GetStartAddress<Instruction*>(); \
- Instruction* end = masm.GetCursorAddress<Instruction*>(); \
- if (Test::disassemble()) { \
- printf("----\n"); \
- } \
- while (instruction != end) { \
- decoder.Decode(instruction); \
- res.append(disasm.GetOutput()); \
- if (Test::disassemble()) { \
- encoding = *reinterpret_cast<uint32_t*>(instruction); \
- printf("%08" PRIx32 "\t%s\n", encoding, disasm.GetOutput()); \
- } \
- instruction += kInstructionSize; \
- if (instruction != end) { \
- res.append("\n"); \
- } \
+#define DISASSEMBLE() \
+ do { \
+ printf("----\n"); \
+ PrintDisassembler print_disasm(stdout); \
+ Instruction* start = masm.GetBuffer()->GetStartAddress<Instruction*>(); \
+ Instruction* end = masm.GetBuffer()->GetEndAddress<Instruction*>(); \
+ print_disasm.DisassembleBuffer(start, end); \
+ } while (0)
+
+#define COMPARE(ASM, EXP) \
+ do { \
+ masm.Reset(); \
+ { \
+ ExactAssemblyScope guard(&masm, \
+ MAX_SIZE_GENERATED, \
+ ExactAssemblyScope::kMaximumSize); \
+ masm.ASM; \
+ } \
+ masm.FinalizeCode(); \
+ decoder.Decode(masm.GetBuffer()->GetStartAddress<Instruction*>()); \
+ uint32_t encoding = *masm.GetBuffer()->GetStartAddress<uint32_t*>(); \
+ if (strcmp(disasm.GetOutput(), EXP) != 0) { \
+ printf("\nEncoding: %08" PRIx32 "\nExpected: %s\nFound: %s\n", \
+ encoding, \
+ EXP, \
+ disasm.GetOutput()); \
+ abort(); \
+ } \
+ if (Test::disassemble()) DISASSEMBLE(); \
+ } while (0)
+
+#define COMPARE_PREFIX(ASM, EXP) \
+ do { \
+ masm.Reset(); \
+ { \
+ ExactAssemblyScope guard(&masm, \
+ MAX_SIZE_GENERATED, \
+ ExactAssemblyScope::kMaximumSize); \
+ masm.ASM; \
+ } \
+ masm.FinalizeCode(); \
+ decoder.Decode(masm.GetBuffer()->GetStartAddress<Instruction*>()); \
+ uint32_t encoding = *masm.GetBuffer()->GetStartAddress<uint32_t*>(); \
+ if (strncmp(disasm.GetOutput(), EXP, strlen(EXP)) != 0) { \
+ printf("\nEncoding: %08" PRIx32 "\nExpected: %s\nFound: %s\n", \
+ encoding, \
+ EXP, \
+ disasm.GetOutput()); \
+ abort(); \
+ } \
+ if (Test::disassemble()) DISASSEMBLE(); \
+ } while (0)
+
+#define COMPARE_MACRO_BASE(ASM, EXP) \
+ masm.Reset(); \
+ masm.ASM; \
+ masm.FinalizeCode(); \
+ std::string res; \
+ \
+ Instruction* instruction = \
+ masm.GetBuffer()->GetStartAddress<Instruction*>(); \
+ Instruction* end = masm.GetCursorAddress<Instruction*>(); \
+ while (instruction != end) { \
+ decoder.Decode(instruction); \
+ res.append(disasm.GetOutput()); \
+ instruction = instruction->GetNextInstruction(); \
+ if (instruction != end) { \
+ res.append("\n"); \
+ } \
}
#define COMPARE_MACRO(ASM, EXP) \
- { \
+ do { \
COMPARE_MACRO_BASE(ASM, EXP) \
if (strcmp(res.c_str(), EXP) != 0) { \
printf("Expected: %s\nFound: %s\n", EXP, res.c_str()); \
abort(); \
} \
- }
+ if (Test::disassemble()) DISASSEMBLE(); \
+ } while (0)
#define COMPARE_MACRO_PREFIX(ASM, EXP) \
- { \
+ do { \
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(); \
} \
- }
+ if (Test::disassemble()) DISASSEMBLE(); \
+ } while (0)
#define CLEANUP()
@@ -2821,7 +2822,7 @@ TEST(fp_cond_compare) {
TEST(fp_select) {
SETUP();
- COMPARE(fcsel(s0, s1, s2, eq), "fcsel s0, s1, s2, eq")
+ COMPARE(fcsel(s0, s1, s2, eq), "fcsel s0, s1, s2, eq");
COMPARE(fcsel(s31, s31, s30, ne), "fcsel s31, s31, s30, ne");
COMPARE(fcsel(d0, d1, d2, mi), "fcsel d0, d1, d2, mi");
COMPARE(fcsel(d31, d30, d31, pl), "fcsel d31, d30, d31, pl");
@@ -3388,22 +3389,22 @@ TEST(neon_load_store_vector) {
COMPARE_MACRO(Ld1(d30, d31, d0, d1, MemOperand(x21, x22, PostIndex)),
"ld1 {v30.1d, v31.1d, v0.1d, v1.1d}, [x21], x22");
-#define DISASM_INST(M, S) \
- COMPARE_MACRO(St1(v20.M, MemOperand(x15)), "st1 {v20." S "}, [x15]"); \
- COMPARE_MACRO(St1(v21.M, v22.M, MemOperand(x16)), \
- "st1 {v21." S ", v22." S "}, [x16]"); \
- COMPARE_MACRO(St1(v23.M, v24.M, v25.M, MemOperand(x17)), \
- "st1 {v23." S ", v24." S ", v25." S "}, [x17]"); \
- COMPARE_MACRO(St1(v26.M, v27.M, v28.M, v29.M, MemOperand(x18)), \
- "st1 {v26." S ", v27." S ", v28." S ", v29." S "}, [x18]") \
- COMPARE_MACRO(St1(v30.M, v31.M, v0.M, v1.M, MemOperand(sp)), \
- "st1 {v30." S ", v31." S ", v0." S ", v1." S "}, [sp]") \
- COMPARE_MACRO(St2(VLIST2(v21.M), MemOperand(x16)), \
- "st2 {v21." S ", v22." S "}, [x16]"); \
- COMPARE_MACRO(St3(v23.M, v24.M, v25.M, MemOperand(x17)), \
- "st3 {v23." S ", v24." S ", v25." S "}, [x17]"); \
- COMPARE_MACRO(St4(v30.M, v31.M, v0.M, v1.M, MemOperand(sp)), \
- "st4 {v30." S ", v31." S ", v0." S ", v1." S "}, [sp]")
+#define DISASM_INST(M, S) \
+ COMPARE_MACRO(St1(v20.M, MemOperand(x15)), "st1 {v20." S "}, [x15]"); \
+ COMPARE_MACRO(St1(v21.M, v22.M, MemOperand(x16)), \
+ "st1 {v21." S ", v22." S "}, [x16]"); \
+ COMPARE_MACRO(St1(v23.M, v24.M, v25.M, MemOperand(x17)), \
+ "st1 {v23." S ", v24." S ", v25." S "}, [x17]"); \
+ COMPARE_MACRO(St1(v26.M, v27.M, v28.M, v29.M, MemOperand(x18)), \
+ "st1 {v26." S ", v27." S ", v28." S ", v29." S "}, [x18]"); \
+ COMPARE_MACRO(St1(v30.M, v31.M, v0.M, v1.M, MemOperand(sp)), \
+ "st1 {v30." S ", v31." S ", v0." S ", v1." S "}, [sp]"); \
+ COMPARE_MACRO(St2(VLIST2(v21.M), MemOperand(x16)), \
+ "st2 {v21." S ", v22." S "}, [x16]"); \
+ COMPARE_MACRO(St3(v23.M, v24.M, v25.M, MemOperand(x17)), \
+ "st3 {v23." S ", v24." S ", v25." S "}, [x17]"); \
+ COMPARE_MACRO(St4(v30.M, v31.M, v0.M, v1.M, MemOperand(sp)), \
+ "st4 {v30." S ", v31." S ", v0." S ", v1." S "}, [sp]");
NEON_FORMAT_LIST(DISASM_INST);
#undef DISASM_INST
@@ -3415,17 +3416,17 @@ TEST(neon_load_store_vector) {
COMPARE_MACRO(St1(v3.M, v4.M, v5.M, MemOperand(x17, x22, PostIndex)), \
"st1 {v3." S ", v4." S ", v5." S "}, [x17], x22"); \
COMPARE_MACRO(St1(v6.M, v7.M, v8.M, v9.M, MemOperand(x18, x23, PostIndex)), \
- "st1 {v6." S ", v7." S ", v8." S ", v9." S "}, [x18], x23") \
+ "st1 {v6." S ", v7." S ", v8." S ", v9." S "}, [x18], x23"); \
COMPARE_MACRO(St1(v30.M, v31.M, v0.M, v1.M, MemOperand(sp, x24, PostIndex)), \
- "st1 {v30." S ", v31." S ", v0." S ", v1." S "}, [sp], x24") \
+ "st1 {v30." S ", v31." S ", v0." S ", v1." S "}, [sp], x24"); \
COMPARE_MACRO(St2(v1.M, v2.M, MemOperand(x16, x21, PostIndex)), \
"st2 {v1." S ", v2." S "}, [x16], x21"); \
COMPARE_MACRO(St3(v3.M, v4.M, v5.M, MemOperand(x17, x22, PostIndex)), \
"st3 {v3." S ", v4." S ", v5." S "}, [x17], x22"); \
COMPARE_MACRO(St4(v6.M, v7.M, v8.M, v9.M, MemOperand(x18, x23, PostIndex)), \
- "st4 {v6." S ", v7." S ", v8." S ", v9." S "}, [x18], x23") \
+ "st4 {v6." S ", v7." S ", v8." S ", v9." S "}, [x18], x23"); \
COMPARE_MACRO(St4(v30.M, v31.M, v0.M, v1.M, MemOperand(sp, x24, PostIndex)), \
- "st4 {v30." S ", v31." S ", v0." S ", v1." S "}, [sp], x24")
+ "st4 {v30." S ", v31." S ", v0." S ", v1." S "}, [sp], x24");
NEON_FORMAT_LIST(DISASM_INST);
#undef DISASM_INST
@@ -4716,7 +4717,7 @@ TEST(neon_3same_extra_fcadd) {
SETUP();
COMPARE_MACRO(Fcadd(v4.V4H(), v5.V4H(), v6.V4H(), 270),
- "fcadd v4.4h, v5.4h, v6.4h, #270")
+ "fcadd v4.4h, v5.4h, v6.4h, #270");
COMPARE_MACRO(Fcadd(v4.V8H(), v5.V8H(), v6.V8H(), 90),
"fcadd v4.8h, v5.8h, v6.8h, #90");
COMPARE_MACRO(Fcadd(v1.V2S(), v2.V2S(), v3.V2S(), 90),