summaryrefslogtreecommitdiff
path: root/compiler/utils/assembler_thumb_test.cc
diff options
context:
space:
mode:
author David Srbecky <dsrbecky@google.com> 2020-07-07 01:10:07 +0100
committer David Srbecky <dsrbecky@google.com> 2020-07-09 15:58:18 +0000
commit194f555db74816aa380d2f46f63c8626f38e9b71 (patch)
treed81626d2023f2d5a7f77b1ff4718e353ee76bc90 /compiler/utils/assembler_thumb_test.cc
parentd6e14e0b6a3447d6e89a93d0a017e92b11dc5f6f (diff)
Refactor arm assembly tests.
Another step in preparation to move to the LLVM toolchain. Bug: 147817558 Test: m test-art-host-gtest Change-Id: Ie5be337165d8f24e04740de0486144fa6a62f063
Diffstat (limited to 'compiler/utils/assembler_thumb_test.cc')
-rw-r--r--compiler/utils/assembler_thumb_test.cc189
1 files changed, 37 insertions, 152 deletions
diff --git a/compiler/utils/assembler_thumb_test.cc b/compiler/utils/assembler_thumb_test.cc
index 4e1518b7cd..72dfef184d 100644
--- a/compiler/utils/assembler_thumb_test.cc
+++ b/compiler/utils/assembler_thumb_test.cc
@@ -25,6 +25,7 @@
#include "jni/quick/calling_convention.h"
#include "utils/arm/jni_macro_assembler_arm_vixl.h"
+#include "utils/assembler_test_base.h"
#include "base/hex_dump.h"
#include "base/malloc_arena_pool.h"
@@ -36,170 +37,54 @@ namespace arm {
// Include results file (generated manually)
#include "assembler_thumb_test_expected.cc.inc"
-#ifndef ART_TARGET_ANDROID
-// This controls whether the results are printed to the
-// screen or compared against the expected output.
-// To generate new expected output, set this to true and
-// copy the output into the .cc.inc file in the form
-// of the other results.
-//
-// When this is false, the results are not printed to the
-// output, but are compared against the expected results
-// in the .cc.inc file.
-static constexpr bool kPrintResults = false;
-#endif
-
-void SetAndroidData() {
- const char* data = getenv("ANDROID_DATA");
- if (data == nullptr) {
- setenv("ANDROID_DATA", "/tmp", 1);
- }
-}
+class ArmVIXLAssemblerTest : public AssemblerTestBase {
+ public:
+ ArmVIXLAssemblerTest() : pool(), allocator(&pool), assembler(&allocator) { }
-int CompareIgnoringSpace(const char* s1, const char* s2) {
- while (*s1 != '\0') {
- while (isspace(*s1)) ++s1;
- while (isspace(*s2)) ++s2;
- if (*s1 == '\0' || *s1 != *s2) {
- break;
- }
- ++s1;
- ++s2;
- }
- return *s1 - *s2;
-}
+ protected:
+ InstructionSet GetIsa() override { return InstructionSet::kThumb2; }
-void InitResults() {
- if (test_results.empty()) {
- setup_results();
- }
-}
-
-std::string GetToolsDir() {
+ void DumpAndCheck(std::vector<uint8_t>& code, const char* testname, const std::string& expected) {
#ifndef ART_TARGET_ANDROID
- // This will only work on the host. There is no as, objcopy or objdump on the device.
- static std::string toolsdir;
-
- if (toolsdir.empty()) {
- setup_results();
- toolsdir = CommonRuntimeTest::GetAndroidTargetToolsDir(InstructionSet::kThumb2);
- SetAndroidData();
+ std::string obj_file = scratch_dir_->GetPath() + testname + ".o";
+ WriteElf</*IsElf64=*/false>(obj_file, InstructionSet::kThumb2, code);
+ std::string disassembly;
+ ASSERT_TRUE(Disassemble(obj_file, &disassembly));
+
+ std::string expected2 = "\n" +
+ obj_file + ": file format elf32-littlearm\n\n\n"
+ "Disassembly of section .text:\n\n"
+ "00000000 <.text>:\n" +
+ expected;
+ EXPECT_EQ(expected2, disassembly);
+ if (expected2 != disassembly) {
+ std::string out = " \"" + Replace(disassembly, "\n", "\\n\"\n \"") + "\"";
+ printf("C++ formatted disassembler output for %s:\n%s\n", testname, out.c_str());
+ }
+#endif // ART_TARGET_ANDROID
}
- return toolsdir;
-#else
- return std::string();
-#endif
-}
+#define __ assembler.
-void DumpAndCheck(std::vector<uint8_t>& code, const char* testname, const char* const* results) {
-#ifndef ART_TARGET_ANDROID
- static std::string toolsdir = GetToolsDir();
-
- ScratchFile file;
-
- const char* filename = file.GetFilename().c_str();
-
- std::ofstream out(filename);
- if (out) {
- out << ".section \".text\"\n";
- out << ".syntax unified\n";
- out << ".arch armv7-a\n";
- out << ".thumb\n";
- out << ".thumb_func\n";
- out << ".type " << testname << ", #function\n";
- out << ".global " << testname << "\n";
- out << testname << ":\n";
- out << ".fnstart\n";
-
- for (uint32_t i = 0 ; i < code.size(); ++i) {
- out << ".byte " << (static_cast<int>(code[i]) & 0xff) << "\n";
- }
- out << ".fnend\n";
- out << ".size " << testname << ", .-" << testname << "\n";
- }
- out.close();
-
- char cmd[1024];
-
- // Assemble the .S
- snprintf(cmd, sizeof(cmd), "%sas %s -o %s.o", toolsdir.c_str(), filename, filename);
- int cmd_result = system(cmd);
- ASSERT_EQ(cmd_result, 0) << cmd << strerror(errno);
-
- // Disassemble.
- snprintf(cmd, sizeof(cmd), "%sobjdump -D -M force-thumb --section=.text %s.o | grep '^ *[0-9a-f][0-9a-f]*:'",
- toolsdir.c_str(), filename);
- if (kPrintResults) {
- // Print the results only, don't check. This is used to generate new output for inserting
- // into the .inc file, so let's add the appropriate prefix/suffix needed in the C++ code.
- strcat(cmd, " | sed '-es/^/ \"/' | sed '-es/$/\\\\n\",/'");
- int cmd_result3 = system(cmd);
- ASSERT_EQ(cmd_result3, 0) << strerror(errno);
- } else {
- // Check the results match the appropriate results in the .inc file.
- FILE *fp = popen(cmd, "r");
- ASSERT_TRUE(fp != nullptr);
-
- uint32_t lineindex = 0;
-
- while (!feof(fp)) {
- char testline[256];
- char *s = fgets(testline, sizeof(testline), fp);
- if (s == nullptr) {
- break;
- }
- if (CompareIgnoringSpace(results[lineindex], testline) != 0) {
- LOG(FATAL) << "Output is not as expected at line: " << lineindex
- << results[lineindex] << "/" << testline << ", test name: " << testname;
- }
- ++lineindex;
- }
- // Check that we are at the end.
- ASSERT_TRUE(results[lineindex] == nullptr);
- fclose(fp);
+ void EmitAndCheck(const char* testname, const char* expected) {
+ __ FinalizeCode();
+ size_t cs = __ CodeSize();
+ std::vector<uint8_t> managed_code(cs);
+ MemoryRegion code(&managed_code[0], managed_code.size());
+ __ FinalizeInstructions(code);
+
+ DumpAndCheck(managed_code, testname, expected);
}
- char buf[FILENAME_MAX];
- snprintf(buf, sizeof(buf), "%s.o", filename);
- unlink(buf);
-#endif // ART_TARGET_ANDROID
-}
+#undef __
-class ArmVIXLAssemblerTest : public ::testing::Test {
- public:
- ArmVIXLAssemblerTest() : pool(), allocator(&pool), assembler(&allocator) { }
+#define __ assembler.
MallocArenaPool pool;
ArenaAllocator allocator;
ArmVIXLJNIMacroAssembler assembler;
};
-#define __ assembler->
-
-void EmitAndCheck(ArmVIXLJNIMacroAssembler* assembler, const char* testname,
- const char* const* results) {
- __ FinalizeCode();
- size_t cs = __ CodeSize();
- std::vector<uint8_t> managed_code(cs);
- MemoryRegion code(&managed_code[0], managed_code.size());
- __ FinalizeInstructions(code);
-
- DumpAndCheck(managed_code, testname, results);
-}
-
-void EmitAndCheck(ArmVIXLJNIMacroAssembler* assembler, const char* testname) {
- InitResults();
- std::map<std::string, const char* const*>::iterator results = test_results.find(testname);
- ASSERT_NE(results, test_results.end());
-
- EmitAndCheck(assembler, testname, results->second);
-}
-
-#undef __
-
-#define __ assembler.
-
TEST_F(ArmVIXLAssemblerTest, VixlJniHelpers) {
// Run the test only with Baker read barriers, as the expected
// generated code contains a Marking Register refresh instruction.
@@ -296,7 +181,7 @@ TEST_F(ArmVIXLAssemblerTest, VixlJniHelpers) {
__ DecreaseFrameSize(32);
__ RemoveFrame(frame_size, callee_save_regs, /* may_suspend= */ true);
- EmitAndCheck(&assembler, "VixlJniHelpers");
+ EmitAndCheck("VixlJniHelpers", VixlJniHelpersResults);
}
#undef __
@@ -339,7 +224,7 @@ TEST_F(ArmVIXLAssemblerTest, VixlLoadFromOffset) {
__ LoadFromOffset(kLoadUnsignedByte, R2, R4, 12);
__ LoadFromOffset(kLoadSignedHalfword, R2, R4, 12);
- EmitAndCheck(&assembler, "VixlLoadFromOffset");
+ EmitAndCheck("VixlLoadFromOffset", VixlLoadFromOffsetResults);
}
TEST_F(ArmVIXLAssemblerTest, VixlStoreToOffset) {
@@ -370,7 +255,7 @@ TEST_F(ArmVIXLAssemblerTest, VixlStoreToOffset) {
__ StoreToOffset(kStoreByte, R2, R4, 12);
- EmitAndCheck(&assembler, "VixlStoreToOffset");
+ EmitAndCheck("VixlStoreToOffset", VixlStoreToOffsetResults);
}
#undef __