blob: 48ed0278828c81c09c04d42ef06c34b212375444 [file] [log] [blame]
Aart Bikb1f37532015-06-29 11:03:55 -07001/*
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 "dex_instruction-inl.h"
Mathieu Chartier1d2d4ff2017-09-23 16:11:06 -070018#include "dex_instruction_iterator.h"
Aart Bikb1f37532015-06-29 11:03:55 -070019#include "gtest/gtest.h"
20
21namespace art {
22
23TEST(StaticGetters, PropertiesOfNopTest) {
24 Instruction::Code nop = Instruction::NOP;
25 EXPECT_STREQ("nop", Instruction::Name(nop));
26 EXPECT_EQ(Instruction::k10x, Instruction::FormatOf(nop));
27 EXPECT_EQ(Instruction::kIndexNone, Instruction::IndexTypeOf(nop));
28 EXPECT_EQ(Instruction::kContinue, Instruction::FlagsOf(nop));
29 EXPECT_EQ(Instruction::kVerifyNone, Instruction::VerifyFlagsOf(nop));
30}
31
Narayan Kamath8ec3bd22016-08-03 12:46:23 +010032static void Build45cc(uint8_t num_args, uint16_t method_idx, uint16_t proto_idx,
33 uint16_t arg_regs, uint16_t* out) {
34 // A = num argument registers
35 // B = method_idx
36 // C - G = argument registers
37 // H = proto_idx
38 //
39 // op = 0xFA
40 //
41 // format:
42 // AG op BBBB FEDC HHHH
43 out[0] = 0;
44 out[0] |= (num_args << 12);
45 out[0] |= 0x00FA;
46
47 out[1] = method_idx;
48 out[2] = arg_regs;
49 out[3] = proto_idx;
50}
51
52static void Build4rcc(uint16_t num_args, uint16_t method_idx, uint16_t proto_idx,
53 uint16_t arg_regs_start, uint16_t* out) {
54 // A = num argument registers
55 // B = method_idx
56 // C = first argument register
57 // H = proto_idx
58 //
59 // op = 0xFB
60 //
61 // format:
62 // AA op BBBB CCCC HHHH
63 out[0] = 0;
64 out[0] |= (num_args << 8);
65 out[0] |= 0x00FB;
66
67 out[1] = method_idx;
68 out[2] = arg_regs_start;
69 out[3] = proto_idx;
70}
71
72TEST(Instruction, PropertiesOf45cc) {
73 uint16_t instruction[4];
74 Build45cc(4u /* num_vregs */, 16u /* method_idx */, 32u /* proto_idx */,
75 0xcafe /* arg_regs */, instruction);
76
Mathieu Chartier1d2d4ff2017-09-23 16:11:06 -070077 DexInstructionIterator ins(instruction);
Narayan Kamath8ec3bd22016-08-03 12:46:23 +010078 ASSERT_EQ(4u, ins->SizeInCodeUnits());
79
80 ASSERT_TRUE(ins->HasVRegA());
81 ASSERT_EQ(4, ins->VRegA());
82 ASSERT_EQ(4u, ins->VRegA_45cc());
83 ASSERT_EQ(4u, ins->VRegA_45cc(instruction[0]));
84
85 ASSERT_TRUE(ins->HasVRegB());
86 ASSERT_EQ(16, ins->VRegB());
87 ASSERT_EQ(16u, ins->VRegB_45cc());
88
89 ASSERT_TRUE(ins->HasVRegC());
90 ASSERT_EQ(0xe, ins->VRegC());
91 ASSERT_EQ(0xe, ins->VRegC_45cc());
92
93 ASSERT_TRUE(ins->HasVRegH());
94 ASSERT_EQ(32, ins->VRegH());
95 ASSERT_EQ(32, ins->VRegH_45cc());
Narayan Kamath673d1fb2016-08-15 16:08:18 +010096
97 ASSERT_TRUE(ins->HasVarArgs());
98
99 uint32_t arg_regs[Instruction::kMaxVarArgRegs];
100 ins->GetVarArgs(arg_regs);
101 ASSERT_EQ(0xeu, arg_regs[0]);
102 ASSERT_EQ(0xfu, arg_regs[1]);
103 ASSERT_EQ(0xau, arg_regs[2]);
104 ASSERT_EQ(0xcu, arg_regs[3]);
Narayan Kamath8ec3bd22016-08-03 12:46:23 +0100105}
106
107TEST(Instruction, PropertiesOf4rcc) {
108 uint16_t instruction[4];
109 Build4rcc(4u /* num_vregs */, 16u /* method_idx */, 32u /* proto_idx */,
110 0xcafe /* arg_regs */, instruction);
111
Mathieu Chartier1d2d4ff2017-09-23 16:11:06 -0700112 DexInstructionIterator ins(instruction);
Narayan Kamath8ec3bd22016-08-03 12:46:23 +0100113 ASSERT_EQ(4u, ins->SizeInCodeUnits());
114
115 ASSERT_TRUE(ins->HasVRegA());
116 ASSERT_EQ(4, ins->VRegA());
117 ASSERT_EQ(4u, ins->VRegA_4rcc());
118 ASSERT_EQ(4u, ins->VRegA_4rcc(instruction[0]));
119
120 ASSERT_TRUE(ins->HasVRegB());
121 ASSERT_EQ(16, ins->VRegB());
122 ASSERT_EQ(16u, ins->VRegB_4rcc());
123
124 ASSERT_TRUE(ins->HasVRegC());
125 ASSERT_EQ(0xcafe, ins->VRegC());
126 ASSERT_EQ(0xcafe, ins->VRegC_4rcc());
127
128 ASSERT_TRUE(ins->HasVRegH());
129 ASSERT_EQ(32, ins->VRegH());
130 ASSERT_EQ(32, ins->VRegH_4rcc());
Narayan Kamath673d1fb2016-08-15 16:08:18 +0100131
132 ASSERT_FALSE(ins->HasVarArgs());
Narayan Kamath8ec3bd22016-08-03 12:46:23 +0100133}
134
Mathieu Chartierbc61cb52017-09-19 16:58:28 -0700135static void Build35c(uint16_t* out,
136 Instruction::Code code,
137 uint16_t method_idx,
138 std::vector<uint16_t> args) {
139 out[0] = 0;
140 out[0] |= (args.size() << 12);
141 out[0] |= static_cast<uint16_t>(code);
142 out[1] = method_idx;
143 size_t i = 0;
144 out[2] = 0;
145 for (; i < 4 && i < args.size(); ++i) {
146 out[2] |= args[i] << (i * 4);
147 }
148 if (args.size() == 5) {
149 out[0] |= args[4] << 8;
150 }
151}
152
153static std::string DumpInst35c(Instruction::Code code,
154 uint16_t method_idx,
155 std::vector<uint16_t> args) {
156 uint16_t inst[6] = {};
157 Build35c(inst, code, method_idx, args);
Mathieu Chartier1d2d4ff2017-09-23 16:11:06 -0700158 return DexInstructionIterator(inst)->DumpString(nullptr);
Mathieu Chartierbc61cb52017-09-19 16:58:28 -0700159}
160
161TEST(Instruction, DumpString) {
162 EXPECT_EQ(DumpInst35c(Instruction::FILLED_NEW_ARRAY, 1234, {3, 2}),
163 "filled-new-array {v3, v2}, type@1234");
164 EXPECT_EQ(DumpInst35c(Instruction::INVOKE_VIRTUAL, 1234, {3, 2, 1, 5, 6}),
165 "invoke-virtual {v3, v2, v1, v5, v6}, thing@1234");
166 EXPECT_EQ(DumpInst35c(Instruction::INVOKE_VIRTUAL_QUICK, 1234, {3, 2, 1, 5}),
167 "invoke-virtual-quick {v3, v2, v1, v5}, thing@1234");
168 EXPECT_EQ(DumpInst35c(Instruction::INVOKE_CUSTOM, 1234, {3, 2, 1}),
169 "invoke-custom {v3, v2, v1}, thing@1234");
170}
171
Aart Bikb1f37532015-06-29 11:03:55 -0700172} // namespace art