1 | //===-- TestArmv7Disassembly.cpp ------------------------------------------===// |
2 | |
3 | // |
4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
5 | // See https://llvm.org/LICENSE.txt for license information. |
6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #include "gtest/gtest.h" |
11 | |
12 | #include "lldb/Core/Address.h" |
13 | #include "lldb/Core/Disassembler.h" |
14 | #include "lldb/Utility/ArchSpec.h" |
15 | #include "lldb/Target/ExecutionContext.h" |
16 | |
17 | #include "Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h" |
18 | #include "llvm/Support/TargetSelect.h" |
19 | |
20 | using namespace lldb; |
21 | using namespace lldb_private; |
22 | |
23 | namespace { |
24 | class TestArmv7Disassembly : public testing::Test { |
25 | public: |
26 | static void SetUpTestCase(); |
27 | static void TearDownTestCase(); |
28 | |
29 | // virtual void SetUp() override { } |
30 | // virtual void TearDown() override { } |
31 | |
32 | protected: |
33 | }; |
34 | |
35 | void TestArmv7Disassembly::SetUpTestCase() { |
36 | llvm::InitializeAllTargets(); |
37 | llvm::InitializeAllAsmPrinters(); |
38 | llvm::InitializeAllTargetMCs(); |
39 | llvm::InitializeAllDisassemblers(); |
40 | DisassemblerLLVMC::Initialize(); |
41 | } |
42 | |
43 | void TestArmv7Disassembly::TearDownTestCase() { |
44 | DisassemblerLLVMC::Terminate(); |
45 | } |
46 | } // namespace |
47 | |
48 | TEST_F(TestArmv7Disassembly, TestCortexFPDisass) { |
49 | ArchSpec arch("armv7em--" ); |
50 | |
51 | const unsigned num_of_instructions = 3; |
52 | uint8_t data[] = { |
53 | 0x00, 0xee, 0x10, 0x2a, // 0xee002a10 : vmov s0, r2 |
54 | 0xb8, 0xee, 0xc0, 0x0b, // 0xeeb80bc0 : vcvt.f64.s32 d0, s0 |
55 | 0xb6, 0xee, 0x00, 0x0a, // 0xeeb60a00 : vmov.f32 s0, #5.000000e-01 |
56 | }; |
57 | |
58 | // these can be disassembled by hand with llvm-mc, e.g. |
59 | // |
60 | // 0x00, 0xee, 0x10, 0x2a, // 0xee002a10 : vmov s0, r2 |
61 | // |
62 | // echo 0x00 0xee 0x10 0x2a | llvm-mc -arch thumb -disassemble -mattr=+fp-armv8 |
63 | // vmov s0, r2 |
64 | |
65 | DisassemblerSP disass_sp; |
66 | Address start_addr(0x100); |
67 | disass_sp = Disassembler::DisassembleBytes(arch, plugin_name: nullptr, flavor: nullptr, start: start_addr, |
68 | bytes: &data, length: sizeof (data), max_num_instructions: num_of_instructions, data_from_file: false); |
69 | |
70 | // If we failed to get a disassembler, we can assume it is because |
71 | // the llvm we linked against was not built with the ARM target, |
72 | // and we should skip these tests without marking anything as failing. |
73 | |
74 | if (disass_sp) { |
75 | const InstructionList inst_list (disass_sp->GetInstructionList()); |
76 | EXPECT_EQ (num_of_instructions, inst_list.GetSize()); |
77 | |
78 | InstructionSP inst_sp; |
79 | const char *mnemonic; |
80 | ExecutionContext exe_ctx (nullptr, nullptr, nullptr); |
81 | inst_sp = inst_list.GetInstructionAtIndex (idx: 0); |
82 | mnemonic = inst_sp->GetMnemonic(exe_ctx: &exe_ctx); |
83 | ASSERT_STREQ ("vmov" , mnemonic); |
84 | |
85 | inst_sp = inst_list.GetInstructionAtIndex (idx: 1); |
86 | mnemonic = inst_sp->GetMnemonic(exe_ctx: &exe_ctx); |
87 | ASSERT_STREQ ("vcvt.f64.s32" , mnemonic); |
88 | |
89 | inst_sp = inst_list.GetInstructionAtIndex (idx: 2); |
90 | mnemonic = inst_sp->GetMnemonic(exe_ctx: &exe_ctx); |
91 | ASSERT_STREQ ("vmov.f32" , mnemonic); |
92 | } |
93 | } |
94 | |