blob: 8318b526b65f0553194d50b962cbe406ea5fbb30 [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,
Calin Juravle0941b9d2015-07-29 18:59:13 +010059 CompilerOptions::kDefaultInlineDepthLimit,
60 CompilerOptions::kDefaultInlineMaxCodeUnits,
David Srbecky1109fb32015-04-07 20:21:06 +010061 false,
62 CompilerOptions::kDefaultTopKProfileThreshold,
63 false,
David Srbecky8363c772015-05-28 16:12:43 +010064 true, // generate_debug_info.
David Srbecky1109fb32015-04-07 20:21:06 +010065 false,
66 false,
67 false,
68 false,
69 nullptr,
70 new PassManagerOptions(),
71 nullptr,
72 false);
73 VerificationResults verification_results(&compiler_options);
74 DexFileToMethodInlinerMap method_inliner_map;
75 std::unique_ptr<const InstructionSetFeatures> isa_features;
76 std::string error;
77 isa_features.reset(InstructionSetFeatures::FromVariant(isa, "default", &error));
78 CompilerDriver driver(&compiler_options, &verification_results, &method_inliner_map,
79 Compiler::kQuick, isa, isa_features.get(),
Andreas Gampe70bef0d2015-04-15 02:37:28 -070080 false, nullptr, nullptr, nullptr, 0, false, false, "", 0, -1, "");
David Srbecky1109fb32015-04-07 20:21:06 +010081 ClassLinker* linker = nullptr;
82 CompilationUnit cu(&pool, isa, &driver, linker);
83 DexFile::CodeItem code_item { 0, 0, 0, 0, 0, 0, { 0 } }; // NOLINT
84 cu.mir_graph.reset(new MIRGraph(&cu, &arena));
85 cu.mir_graph->current_code_item_ = &code_item;
86
87 // Generate empty method with some spills.
David Srbecky46325a02015-04-09 22:51:56 +010088 std::unique_ptr<Mir2Lir> m2l(QuickCompiler::GetCodeGenerator(&cu, nullptr));
David Srbecky1109fb32015-04-07 20:21:06 +010089 m2l->frame_size_ = 64u;
90 m2l->CompilerInitializeRegAlloc();
91 for (const auto& info : m2l->reg_pool_->core_regs_) {
92 if (m2l->num_core_spills_ < 2 && !info->IsTemp() && !info->InUse()) {
Dan Albertf9036802015-04-16 11:52:45 -070093 m2l->core_spill_mask_ |= 1 << info->GetReg().GetRegNum();
David Srbecky1109fb32015-04-07 20:21:06 +010094 m2l->num_core_spills_++;
95 }
96 }
97 for (const auto& info : m2l->reg_pool_->sp_regs_) {
98 if (m2l->num_fp_spills_ < 2 && !info->IsTemp() && !info->InUse()) {
Dan Albertf9036802015-04-16 11:52:45 -070099 m2l->fp_spill_mask_ |= 1 << info->GetReg().GetRegNum();
David Srbecky1109fb32015-04-07 20:21:06 +0100100 m2l->num_fp_spills_++;
101 }
102 }
103 m2l->AdjustSpillMask();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700104 m2l->GenEntrySequence(nullptr, m2l->GetCompilationUnit()->target64 ?
105 m2l->LocCReturnWide() : m2l->LocCReturnRef());
David Srbecky1109fb32015-04-07 20:21:06 +0100106 m2l->GenExitSequence();
107 m2l->HandleSlowPaths();
108 m2l->AssembleLIR();
109 std::vector<uint8_t> actual_asm(m2l->code_buffer_.begin(), m2l->code_buffer_.end());
110 auto const& cfi_data = m2l->cfi().Patch(actual_asm.size());
111 std::vector<uint8_t> actual_cfi(cfi_data->begin(), cfi_data->end());
112 EXPECT_EQ(m2l->cfi().GetCurrentPC(), static_cast<int>(actual_asm.size()));
113
114 if (kGenerateExpected) {
115 GenerateExpected(stdout, isa, isa_str, actual_asm, actual_cfi);
116 } else {
117 EXPECT_EQ(expected_asm, actual_asm);
118 EXPECT_EQ(expected_cfi, actual_cfi);
119 }
120 }
121};
122
123#define TEST_ISA(isa) \
124 TEST_F(QuickCFITest, isa) { \
125 std::vector<uint8_t> expected_asm(expected_asm_##isa, \
126 expected_asm_##isa + arraysize(expected_asm_##isa)); \
127 std::vector<uint8_t> expected_cfi(expected_cfi_##isa, \
128 expected_cfi_##isa + arraysize(expected_cfi_##isa)); \
129 TestImpl(isa, #isa, expected_asm, expected_cfi); \
130 }
131
132TEST_ISA(kThumb2)
133TEST_ISA(kArm64)
134TEST_ISA(kX86)
135TEST_ISA(kX86_64)
136TEST_ISA(kMips)
137TEST_ISA(kMips64)
138
139#endif // HAVE_ANDROID_OS
140
141} // namespace art