blob: 0540a8c962f76b0aa104f0d7ffc88aa125500a32 [file] [log] [blame]
David Srbecky1109fb32015-04-07 20:21:06 +01001/*
2 * Copyright (C) 2015 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#include <vector>
18#include <memory>
19
20#include "arch/instruction_set.h"
21#include "arch/instruction_set_features.h"
22#include "cfi_test.h"
23#include "dex/compiler_ir.h"
24#include "dex/mir_graph.h"
25#include "dex/pass_manager.h"
26#include "dex/quick/dex_file_to_method_inliner_map.h"
27#include "dex/quick/quick_compiler.h"
28#include "dex/quick/mir_to_lir.h"
29#include "dex/verification_results.h"
30#include "driver/compiler_driver.h"
31#include "driver/compiler_options.h"
32#include "gtest/gtest.h"
33
34#include "dex/quick/quick_cfi_test_expected.inc"
35
36namespace art {
37
38// Run the tests only on host.
39#ifndef HAVE_ANDROID_OS
40
41class QuickCFITest : public CFITest {
42 public:
43 // Enable this flag to generate the expected outputs.
44 static constexpr bool kGenerateExpected = false;
45
46 void TestImpl(InstructionSet isa, const char* isa_str,
47 const std::vector<uint8_t>& expected_asm,
48 const std::vector<uint8_t>& expected_cfi) {
49 // Setup simple compiler context.
50 ArenaPool pool;
51 ArenaAllocator arena(&pool);
52 CompilerOptions compiler_options(
53 CompilerOptions::kDefaultCompilerFilter,
54 CompilerOptions::kDefaultHugeMethodThreshold,
55 CompilerOptions::kDefaultLargeMethodThreshold,
56 CompilerOptions::kDefaultSmallMethodThreshold,
57 CompilerOptions::kDefaultTinyMethodThreshold,
58 CompilerOptions::kDefaultNumDexMethodsThreshold,
59 true, // generate_gdb_information.
60 false,
61 CompilerOptions::kDefaultTopKProfileThreshold,
62 false,
63 true, // include_debug_symbols.
64 false,
65 false,
66 false,
67 false,
68 nullptr,
69 new PassManagerOptions(),
70 nullptr,
71 false);
72 VerificationResults verification_results(&compiler_options);
73 DexFileToMethodInlinerMap method_inliner_map;
74 std::unique_ptr<const InstructionSetFeatures> isa_features;
75 std::string error;
76 isa_features.reset(InstructionSetFeatures::FromVariant(isa, "default", &error));
77 CompilerDriver driver(&compiler_options, &verification_results, &method_inliner_map,
78 Compiler::kQuick, isa, isa_features.get(),
79 false, 0, 0, 0, false, false, "", 0, -1, "");
80 ClassLinker* linker = nullptr;
81 CompilationUnit cu(&pool, isa, &driver, linker);
82 DexFile::CodeItem code_item { 0, 0, 0, 0, 0, 0, { 0 } }; // NOLINT
83 cu.mir_graph.reset(new MIRGraph(&cu, &arena));
84 cu.mir_graph->current_code_item_ = &code_item;
85
86 // Generate empty method with some spills.
87 Mir2Lir* m2l = QuickCompiler::GetCodeGenerator(&cu, NULL);
88 m2l->frame_size_ = 64u;
89 m2l->CompilerInitializeRegAlloc();
90 for (const auto& info : m2l->reg_pool_->core_regs_) {
91 if (m2l->num_core_spills_ < 2 && !info->IsTemp() && !info->InUse()) {
92 m2l->core_spill_mask_ |= 1 << info->GetReg().GetReg();
93 m2l->num_core_spills_++;
94 }
95 }
96 for (const auto& info : m2l->reg_pool_->sp_regs_) {
97 if (m2l->num_fp_spills_ < 2 && !info->IsTemp() && !info->InUse()) {
98 m2l->fp_spill_mask_ |= 1 << info->GetReg().GetReg();
99 m2l->num_fp_spills_++;
100 }
101 }
102 m2l->AdjustSpillMask();
103 m2l->GenEntrySequence(NULL, m2l->LocCReturnRef());
104 m2l->GenExitSequence();
105 m2l->HandleSlowPaths();
106 m2l->AssembleLIR();
107 std::vector<uint8_t> actual_asm(m2l->code_buffer_.begin(), m2l->code_buffer_.end());
108 auto const& cfi_data = m2l->cfi().Patch(actual_asm.size());
109 std::vector<uint8_t> actual_cfi(cfi_data->begin(), cfi_data->end());
110 EXPECT_EQ(m2l->cfi().GetCurrentPC(), static_cast<int>(actual_asm.size()));
111
112 if (kGenerateExpected) {
113 GenerateExpected(stdout, isa, isa_str, actual_asm, actual_cfi);
114 } else {
115 EXPECT_EQ(expected_asm, actual_asm);
116 EXPECT_EQ(expected_cfi, actual_cfi);
117 }
118 }
119};
120
121#define TEST_ISA(isa) \
122 TEST_F(QuickCFITest, isa) { \
123 std::vector<uint8_t> expected_asm(expected_asm_##isa, \
124 expected_asm_##isa + arraysize(expected_asm_##isa)); \
125 std::vector<uint8_t> expected_cfi(expected_cfi_##isa, \
126 expected_cfi_##isa + arraysize(expected_cfi_##isa)); \
127 TestImpl(isa, #isa, expected_asm, expected_cfi); \
128 }
129
130TEST_ISA(kThumb2)
131TEST_ISA(kArm64)
132TEST_ISA(kX86)
133TEST_ISA(kX86_64)
134TEST_ISA(kMips)
135TEST_ISA(kMips64)
136
137#endif // HAVE_ANDROID_OS
138
139} // namespace art