blob: ba95e212bb579ab69090b811581ade7300258fca [file] [log] [blame]
Andreas Gampe3b165bc2016-08-01 22:07:04 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_COMPILER_UTILS_JNI_MACRO_ASSEMBLER_TEST_H_
18#define ART_COMPILER_UTILS_JNI_MACRO_ASSEMBLER_TEST_H_
19
20#include "jni_macro_assembler.h"
21
22#include "assembler_test_base.h"
23#include "common_runtime_test.h" // For ScratchFile
24
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070025#include <sys/stat.h>
26
Andreas Gampe3b165bc2016-08-01 22:07:04 -070027#include <cstdio>
28#include <cstdlib>
29#include <fstream>
30#include <iterator>
Andreas Gampe3b165bc2016-08-01 22:07:04 -070031
32namespace art {
33
34template<typename Ass>
35class JNIMacroAssemblerTest : public testing::Test {
36 public:
37 Ass* GetAssembler() {
38 return assembler_.get();
39 }
40
41 typedef std::string (*TestFn)(JNIMacroAssemblerTest* assembler_test, Ass* assembler);
42
Andreas Gampe2e965ac2016-11-03 17:24:15 -070043 void DriverFn(TestFn f, const std::string& test_name) {
Andreas Gampe3b165bc2016-08-01 22:07:04 -070044 DriverWrapper(f(this, assembler_.get()), test_name);
45 }
46
47 // This driver assumes the assembler has already been called.
Andreas Gampe2e965ac2016-11-03 17:24:15 -070048 void DriverStr(const std::string& assembly_string, const std::string& test_name) {
Andreas Gampe3b165bc2016-08-01 22:07:04 -070049 DriverWrapper(assembly_string, test_name);
50 }
51
52 // This is intended to be run as a test.
53 bool CheckTools() {
54 return test_helper_->CheckTools();
55 }
56
57 protected:
58 explicit JNIMacroAssemblerTest() {}
59
60 void SetUp() OVERRIDE {
61 arena_.reset(new ArenaAllocator(&pool_));
62 assembler_.reset(CreateAssembler(arena_.get()));
63 test_helper_.reset(
64 new AssemblerTestInfrastructure(GetArchitectureString(),
65 GetAssemblerCmdName(),
66 GetAssemblerParameters(),
67 GetObjdumpCmdName(),
68 GetObjdumpParameters(),
69 GetDisassembleCmdName(),
70 GetDisassembleParameters(),
71 GetAssemblyHeader()));
72
73 SetUpHelpers();
74 }
75
76 void TearDown() OVERRIDE {
77 test_helper_.reset(); // Clean up the helper.
78 assembler_.reset();
79 arena_.reset();
80 }
81
82 // Override this to set up any architecture-specific things, e.g., CPU revision.
Vladimir Markoe764d2e2017-10-05 14:35:55 +010083 virtual Ass* CreateAssembler(ArenaAllocator* allocator) {
84 return new (allocator) Ass(allocator);
Andreas Gampe3b165bc2016-08-01 22:07:04 -070085 }
86
87 // Override this to set up any architecture-specific things, e.g., register vectors.
88 virtual void SetUpHelpers() {}
89
90 // Get the typically used name for this architecture, e.g., aarch64, x86_64, ...
91 virtual std::string GetArchitectureString() = 0;
92
93 // Get the name of the assembler, e.g., "as" by default.
94 virtual std::string GetAssemblerCmdName() {
95 return "as";
96 }
97
98 // Switches to the assembler command. Default none.
99 virtual std::string GetAssemblerParameters() {
100 return "";
101 }
102
103 // Get the name of the objdump, e.g., "objdump" by default.
104 virtual std::string GetObjdumpCmdName() {
105 return "objdump";
106 }
107
108 // Switches to the objdump command. Default is " -h".
109 virtual std::string GetObjdumpParameters() {
110 return " -h";
111 }
112
113 // Get the name of the objdump, e.g., "objdump" by default.
114 virtual std::string GetDisassembleCmdName() {
115 return "objdump";
116 }
117
118 // Switches to the objdump command. As it's a binary, one needs to push the architecture and
119 // such to objdump, so it's architecture-specific and there is no default.
120 virtual std::string GetDisassembleParameters() = 0;
121
122 // If the assembly file needs a header, return it in a sub-class.
123 virtual const char* GetAssemblyHeader() {
124 return nullptr;
125 }
126
127 private:
128 // Override this to pad the code with NOPs to a certain size if needed.
129 virtual void Pad(std::vector<uint8_t>& data ATTRIBUTE_UNUSED) {
130 }
131
Andreas Gampe2e965ac2016-11-03 17:24:15 -0700132 void DriverWrapper(const std::string& assembly_text, const std::string& test_name) {
Andreas Gampe3b165bc2016-08-01 22:07:04 -0700133 assembler_->FinalizeCode();
134 size_t cs = assembler_->CodeSize();
135 std::unique_ptr<std::vector<uint8_t>> data(new std::vector<uint8_t>(cs));
136 MemoryRegion code(&(*data)[0], data->size());
137 assembler_->FinalizeInstructions(code);
138 Pad(*data);
139 test_helper_->Driver(*data, assembly_text, test_name);
140 }
141
142 ArenaPool pool_;
143 std::unique_ptr<ArenaAllocator> arena_;
144 std::unique_ptr<Ass> assembler_;
145 std::unique_ptr<AssemblerTestInfrastructure> test_helper_;
146
147 DISALLOW_COPY_AND_ASSIGN(JNIMacroAssemblerTest);
148};
149
150} // namespace art
151
152#endif // ART_COMPILER_UTILS_JNI_MACRO_ASSEMBLER_TEST_H_