blob: 12568a4ad43a1943927f8164db3dbead0e800d4f [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.
Andreas Gampec60e1b72015-07-30 08:57:50 -070039#ifndef __ANDROID__
David Srbecky1109fb32015-04-07 20:21:06 +010040
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,
Jeff Haodcdc85b2015-12-04 14:06:18 -080061 nullptr,
David Srbecky1109fb32015-04-07 20:21:06 +010062 false,
63 CompilerOptions::kDefaultTopKProfileThreshold,
64 false,
David Srbecky8363c772015-05-28 16:12:43 +010065 true, // generate_debug_info.
David Srbecky1109fb32015-04-07 20:21:06 +010066 false,
67 false,
68 false,
69 false,
70 nullptr,
David Srbecky1109fb32015-04-07 20:21:06 +010071 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));
Jeff Haodcdc85b2015-12-04 14:06:18 -080078 CompilerDriver driver(&compiler_options,
79 &verification_results,
80 &method_inliner_map,
81 Compiler::kQuick,
82 isa,
83 isa_features.get(),
84 false,
85 nullptr,
86 nullptr,
87 nullptr,
88 0,
89 false,
90 false,
91 "",
92 false,
93 0,
94 -1,
Calin Juravle998c2162015-12-21 15:39:33 +020095 nullptr,
Jeff Haodcdc85b2015-12-04 14:06:18 -080096 nullptr);
David Srbecky1109fb32015-04-07 20:21:06 +010097 ClassLinker* linker = nullptr;
98 CompilationUnit cu(&pool, isa, &driver, linker);
99 DexFile::CodeItem code_item { 0, 0, 0, 0, 0, 0, { 0 } }; // NOLINT
100 cu.mir_graph.reset(new MIRGraph(&cu, &arena));
101 cu.mir_graph->current_code_item_ = &code_item;
102
103 // Generate empty method with some spills.
David Srbecky46325a02015-04-09 22:51:56 +0100104 std::unique_ptr<Mir2Lir> m2l(QuickCompiler::GetCodeGenerator(&cu, nullptr));
David Srbecky1109fb32015-04-07 20:21:06 +0100105 m2l->frame_size_ = 64u;
106 m2l->CompilerInitializeRegAlloc();
107 for (const auto& info : m2l->reg_pool_->core_regs_) {
108 if (m2l->num_core_spills_ < 2 && !info->IsTemp() && !info->InUse()) {
Dan Albertf9036802015-04-16 11:52:45 -0700109 m2l->core_spill_mask_ |= 1 << info->GetReg().GetRegNum();
David Srbecky1109fb32015-04-07 20:21:06 +0100110 m2l->num_core_spills_++;
111 }
112 }
113 for (const auto& info : m2l->reg_pool_->sp_regs_) {
114 if (m2l->num_fp_spills_ < 2 && !info->IsTemp() && !info->InUse()) {
Dan Albertf9036802015-04-16 11:52:45 -0700115 m2l->fp_spill_mask_ |= 1 << info->GetReg().GetRegNum();
David Srbecky1109fb32015-04-07 20:21:06 +0100116 m2l->num_fp_spills_++;
117 }
118 }
119 m2l->AdjustSpillMask();
Mathieu Chartiere401d142015-04-22 13:56:20 -0700120 m2l->GenEntrySequence(nullptr, m2l->GetCompilationUnit()->target64 ?
121 m2l->LocCReturnWide() : m2l->LocCReturnRef());
David Srbecky1109fb32015-04-07 20:21:06 +0100122 m2l->GenExitSequence();
123 m2l->HandleSlowPaths();
124 m2l->AssembleLIR();
125 std::vector<uint8_t> actual_asm(m2l->code_buffer_.begin(), m2l->code_buffer_.end());
126 auto const& cfi_data = m2l->cfi().Patch(actual_asm.size());
127 std::vector<uint8_t> actual_cfi(cfi_data->begin(), cfi_data->end());
128 EXPECT_EQ(m2l->cfi().GetCurrentPC(), static_cast<int>(actual_asm.size()));
129
130 if (kGenerateExpected) {
131 GenerateExpected(stdout, isa, isa_str, actual_asm, actual_cfi);
132 } else {
133 EXPECT_EQ(expected_asm, actual_asm);
134 EXPECT_EQ(expected_cfi, actual_cfi);
135 }
136 }
137};
138
139#define TEST_ISA(isa) \
140 TEST_F(QuickCFITest, isa) { \
141 std::vector<uint8_t> expected_asm(expected_asm_##isa, \
142 expected_asm_##isa + arraysize(expected_asm_##isa)); \
143 std::vector<uint8_t> expected_cfi(expected_cfi_##isa, \
144 expected_cfi_##isa + arraysize(expected_cfi_##isa)); \
145 TestImpl(isa, #isa, expected_asm, expected_cfi); \
146 }
147
148TEST_ISA(kThumb2)
149TEST_ISA(kArm64)
150TEST_ISA(kX86)
151TEST_ISA(kX86_64)
152TEST_ISA(kMips)
153TEST_ISA(kMips64)
154
Andreas Gampec60e1b72015-07-30 08:57:50 -0700155#endif // __ANDROID__
David Srbecky1109fb32015-04-07 20:21:06 +0100156
157} // namespace art