summaryrefslogtreecommitdiff
path: root/Source/UnitTests/Core/DSP/DSPAssemblyTest.cpp
diff options
context:
space:
mode:
authorMichael Maltese <mchtly@gmail.com>2017-05-19 17:36:04 -0700
committerMichael Maltese <mchtly@gmail.com>2017-06-05 19:28:40 -0700
commit80710984dc9d0d9ad381277e0894b970604edfa8 (patch)
tree9e8c9eb97656813c8bc75c8179771ca10e3b8289 /Source/UnitTests/Core/DSP/DSPAssemblyTest.cpp
parent1580b6e6276197cf2630856a5e8cda4453f2d7bd (diff)
DSPTool: extract tests into a DSPAssemblyTest
- Moves all test code from DSPTool into UnitTests/Core/DSPAssemblyTest. - Converts test files (which could only be loaded if they were in the shell's working directory, so basically never) into C++ values. - Enables most of the commented-out tests. - Removes non-deterministic random code test.
Diffstat (limited to 'Source/UnitTests/Core/DSP/DSPAssemblyTest.cpp')
-rw-r--r--Source/UnitTests/Core/DSP/DSPAssemblyTest.cpp155
1 files changed, 155 insertions, 0 deletions
diff --git a/Source/UnitTests/Core/DSP/DSPAssemblyTest.cpp b/Source/UnitTests/Core/DSP/DSPAssemblyTest.cpp
new file mode 100644
index 0000000000..5d8a7838ce
--- /dev/null
+++ b/Source/UnitTests/Core/DSP/DSPAssemblyTest.cpp
@@ -0,0 +1,155 @@
+// Copyright 2017 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "Common/FileUtil.h"
+#include "Core/DSP/DSPCodeUtil.h"
+#include "Core/DSP/DSPDisassembler.h"
+
+#include "DSPTestBinary.h"
+#include "DSPTestText.h"
+#include "HermesBinary.h"
+
+#include <gtest/gtest.h>
+
+static bool RoundTrippableDissassemble(const std::vector<u16>& code, std::string& text)
+{
+ DSP::AssemblerSettings settings;
+ settings.ext_separator = '\'';
+ settings.decode_names = true;
+ settings.decode_registers = true;
+ // These two prevent roundtripping.
+ settings.show_hex = false;
+ settings.show_pc = false;
+ DSP::DSPDisassembler disasm(settings);
+
+ return disasm.Disassemble(0x0000, code, 0x0000, text);
+}
+
+// This test goes from text ASM to binary to text ASM and once again back to binary.
+// Then the two binaries are compared.
+static bool RoundTrip(const std::vector<u16>& code1)
+{
+ std::vector<u16> code2;
+ std::string text;
+ if (!RoundTrippableDissassemble(code1, text))
+ {
+ printf("RoundTrip: Disassembly failed.\n");
+ return false;
+ }
+ if (!DSP::Assemble(text, code2))
+ {
+ printf("RoundTrip: Assembly failed.\n");
+ return false;
+ }
+ if (!DSP::Compare(code1, code2))
+ {
+ DSP::Disassemble(code1, true, text);
+ printf("%s", text.c_str());
+ }
+ return true;
+}
+
+// This test goes from text ASM to binary to text ASM and once again back to binary.
+// Very convenient for testing. Then the two binaries are compared.
+static bool SuperTrip(const char* asm_code)
+{
+ std::vector<u16> code1, code2;
+ std::string text;
+ if (!DSP::Assemble(asm_code, code1))
+ {
+ printf("SuperTrip: First assembly failed\n");
+ return false;
+ }
+ printf("First assembly: %i words\n", (int)code1.size());
+
+ if (!RoundTrippableDissassemble(code1, text))
+ {
+ printf("SuperTrip: Disassembly failed\n");
+ return false;
+ }
+ else
+ {
+ printf("Disassembly:\n");
+ printf("%s", text.c_str());
+ }
+
+ if (!DSP::Assemble(text, code2))
+ {
+ printf("SuperTrip: Second assembly failed\n");
+ return false;
+ }
+ return true;
+}
+
+// Let's start out easy - a trivial instruction..
+TEST(DSPAssembly, TrivialInstruction)
+{
+ ASSERT_TRUE(SuperTrip(" NOP\n"));
+}
+
+// Now let's do several.
+TEST(DSPAssembly, SeveralTrivialInstructions)
+{
+ ASSERT_TRUE(SuperTrip(" NOP\n"
+ " NOP\n"
+ " NOP\n"));
+}
+
+// Turning it up a notch.
+TEST(DSPAssembly, SeveralNoParameterInstructions)
+{
+ ASSERT_TRUE(SuperTrip(" SET16\n"
+ " SET40\n"
+ " CLR15\n"
+ " M0\n"
+ " M2\n"));
+}
+
+// Time to try labels and parameters, and comments.
+TEST(DSPAssembly, LabelsParametersAndComments)
+{
+ ASSERT_TRUE(SuperTrip("DIRQ_TEST: equ 0xfffb ; DSP Irq Request\n"
+ " si @0xfffc, #0x8888\n"
+ " si @0xfffd, #0xbeef\n"
+ " si @DIRQ_TEST, #0x0001\n"));
+}
+
+// Let's see if registers roundtrip. Also try predefined labels.
+TEST(DSPAssembly, RegistersAndPredefinedLabels)
+{
+ ASSERT_TRUE(SuperTrip(" si @0xfffc, #0x8888\n"
+ " si @0xfffd, #0xbeef\n"
+ " si @DIRQ, #0x0001\n"));
+}
+
+// Let's try some messy extended instructions.
+TEST(DSPAssembly, ExtendedInstructions)
+{
+ ASSERT_TRUE(SuperTrip(" MULMV'SN $AX0.L, $AX0.H, $ACC0 : @$AR2, $AC1.M\n"
+ " ADDAXL'MV $ACC1, $AX1.L : $AX1.H, $AC1.M\n"));
+}
+
+TEST(DSPAssembly, HermesBinary)
+{
+ ASSERT_TRUE(RoundTrip(s_hermes_bin));
+}
+
+TEST(DSPAssembly, DSPTestText)
+{
+ ASSERT_TRUE(SuperTrip(s_dsp_test_text));
+}
+
+TEST(DSPAssembly, DSPTestBinary)
+{
+ ASSERT_TRUE(RoundTrip(s_dsp_test_bin));
+}
+
+/*
+
+if (File::ReadFileToString("C:/devkitPro/examples/wii/asndlib/dsptest/dsp_test.ds", &dsp_test))
+ SuperTrip(dsp_test.c_str());
+
+//.File::ReadFileToString("C:/devkitPro/trunk/libogc/libasnd/dsp_mixer/dsp_mixer.s", &dsp_test);
+// This is CLOSE to working. Sorry about the local path btw. This is preliminary code.
+*/