1dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky/*
2dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * Copyright (C) 2015 The Android Open Source Project
3dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky *
4dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * Licensed under the Apache License, Version 2.0 (the "License");
5dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * you may not use this file except in compliance with the License.
6dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * You may obtain a copy of the License at
7dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky *
8dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky *      http://www.apache.org/licenses/LICENSE-2.0
9dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky *
10dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * Unless required by applicable law or agreed to in writing, software
11dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * distributed under the License is distributed on an "AS IS" BASIS,
12dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * See the License for the specific language governing permissions and
14dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky * limitations under the License.
15dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky */
16dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
17dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include <memory>
18dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include <vector>
19dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
20dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include "arch/instruction_set.h"
21dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include "cfi_test.h"
22dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include "gtest/gtest.h"
23dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include "jni/quick/calling_convention.h"
24dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include "utils/assembler.h"
25dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
26dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#include "jni/jni_cfi_test_expected.inc"
27dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
28dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbeckynamespace art {
29dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
30dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky// Run the tests only on host.
31dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#ifndef HAVE_ANDROID_OS
32dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
33dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbeckyclass JNICFITest : public CFITest {
34dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky public:
35dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  // Enable this flag to generate the expected outputs.
36dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  static constexpr bool kGenerateExpected = false;
37dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
38dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  void TestImpl(InstructionSet isa, const char* isa_str,
39dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky                const std::vector<uint8_t>& expected_asm,
40dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky                const std::vector<uint8_t>& expected_cfi) {
41dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    // Description of simple method.
42dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    const bool is_static = true;
43dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    const bool is_synchronized = false;
44dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    const char* shorty = "IIFII";
45dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    std::unique_ptr<JniCallingConvention> jni_conv(
46dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky        JniCallingConvention::Create(is_static, is_synchronized, shorty, isa));
47dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    std::unique_ptr<ManagedRuntimeCallingConvention> mr_conv(
48dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky        ManagedRuntimeCallingConvention::Create(is_static, is_synchronized, shorty, isa));
49dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    const int frame_size(jni_conv->FrameSize());
50dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    const std::vector<ManagedRegister>& callee_save_regs = jni_conv->CalleeSaveRegisters();
51dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
52dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    // Assemble the method.
53dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    std::unique_ptr<Assembler> jni_asm(Assembler::Create(isa));
54dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    jni_asm->BuildFrame(frame_size, mr_conv->MethodRegister(),
55dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky                        callee_save_regs, mr_conv->EntrySpills());
56dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    jni_asm->IncreaseFrameSize(32);
57dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    jni_asm->DecreaseFrameSize(32);
58dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    jni_asm->RemoveFrame(frame_size, callee_save_regs);
59dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    jni_asm->EmitSlowPaths();
60dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    std::vector<uint8_t> actual_asm(jni_asm->CodeSize());
61dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    MemoryRegion code(&actual_asm[0], actual_asm.size());
62dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    jni_asm->FinalizeInstructions(code);
63dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    ASSERT_EQ(jni_asm->cfi().GetCurrentCFAOffset(), frame_size);
64dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    const std::vector<uint8_t>& actual_cfi = *(jni_asm->cfi().data());
65dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
66dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    if (kGenerateExpected) {
67dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      GenerateExpected(stdout, isa, isa_str, actual_asm, actual_cfi);
68dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    } else {
69dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      EXPECT_EQ(expected_asm, actual_asm);
70dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky      EXPECT_EQ(expected_cfi, actual_cfi);
71dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    }
72dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  }
73dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky};
74dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
75dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#define TEST_ISA(isa) \
76dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  TEST_F(JNICFITest, isa) { \
77dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    std::vector<uint8_t> expected_asm(expected_asm_##isa, \
78dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky        expected_asm_##isa + arraysize(expected_asm_##isa)); \
79dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    std::vector<uint8_t> expected_cfi(expected_cfi_##isa, \
80dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky        expected_cfi_##isa + arraysize(expected_cfi_##isa)); \
81dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky    TestImpl(isa, #isa, expected_asm, expected_cfi); \
82dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky  }
83dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
84dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid SrbeckyTEST_ISA(kThumb2)
85dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid SrbeckyTEST_ISA(kArm64)
86dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid SrbeckyTEST_ISA(kX86)
87dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid SrbeckyTEST_ISA(kX86_64)
88dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid SrbeckyTEST_ISA(kMips)
89dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid SrbeckyTEST_ISA(kMips64)
90dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
91dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky#endif  // HAVE_ANDROID_OS
92dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky
93dd97393aca1a3ff2abec4dc4f78d7724300971bcDavid Srbecky}  // namespace art
94