1 /**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <gtest/gtest.h>
17
18 #include <type_traits>
19
20 #include <cstddef>
21 #include <cstdint>
22
23 #include "bytecode_instruction-inl.h"
24
25 namespace panda::test {
26
TEST(BytecodeInstruction,Parse)27 TEST(BytecodeInstruction, Parse)
28 {
29 // V4_IMM4
30 {
31 const uint8_t bytecode[] = {0x00, 0xa1, 0xff};
32 BytecodeInstruction inst(bytecode);
33 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
34 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_IMM4, 0>()), 1);
35 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V4_IMM4, 0>()), -6);
36 }
37
38 {
39 const uint8_t bytecode[] = {0x00, 0x2f, 0xff};
40 BytecodeInstruction inst(bytecode);
41 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
42 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_IMM4, 0>()), 0xf);
43 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V4_IMM4, 0>()), 0x2);
44 }
45
46 // IMM8
47 {
48 const uint8_t bytecode[] = {0x00, 0xf2, 0xff};
49 BytecodeInstruction inst(bytecode);
50 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
51 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM8, 0>()), static_cast<int8_t>(0xf2));
52 }
53
54 {
55 const uint8_t bytecode[] = {0x00, 0x21, 0xff};
56 BytecodeInstruction inst(bytecode);
57 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
58 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM8, 0>()), 0x21);
59 }
60
61 // V8_IMM8
62 {
63 const uint8_t bytecode[] = {0x00, 0x12, 0xf2, 0xff};
64 BytecodeInstruction inst(bytecode);
65 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
66 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM8, 0>()), 0x12);
67 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM8, 0>()), static_cast<int8_t>(0xf2));
68 }
69
70 {
71 const uint8_t bytecode[] = {0x00, 0xf2, 0x12, 0xff};
72 BytecodeInstruction inst(bytecode);
73 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
74 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM8, 0>()), 0xf2);
75 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM8, 0>()), 0x12);
76 }
77
78 // IMM16
79 {
80 const uint8_t bytecode[] = {0x00, 0xf2, 0x12, 0xff};
81 BytecodeInstruction inst(bytecode);
82 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
83 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM16, 0>()), 0x12f2);
84 }
85
86 {
87 const uint8_t bytecode[] = {0x00, 0x12, 0xf2, 0xff};
88 BytecodeInstruction inst(bytecode);
89 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
90 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM16, 0>()), static_cast<int16_t>(0xf212));
91 }
92
93 // V8_IMM16
94 {
95 const uint8_t bytecode[] = {0x00, 0x10, 0xf2, 0x12, 0xff};
96 BytecodeInstruction inst(bytecode);
97 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
98 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM16, 0>()), 0x10);
99 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM16, 0>()), 0x12f2);
100 }
101
102 {
103 const uint8_t bytecode[] = {0x00, 0xff, 0x12, 0xf2, 0xff};
104 BytecodeInstruction inst(bytecode);
105 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
106 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM16, 0>()), 0xff);
107 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM16, 0>()), static_cast<int16_t>(0xf212));
108 }
109
110 // IMM32
111 {
112 const uint8_t bytecode[] = {0x00, 0x34, 0xf2, 0x12, 0x10, 0xff};
113 BytecodeInstruction inst(bytecode);
114 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
115 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM32, 0>()), 0x1012f234);
116 }
117
118 {
119 const uint8_t bytecode[] = {0x00, 0x34, 0x12, 0xf2, 0xf1, 0xff};
120 BytecodeInstruction inst(bytecode);
121 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
122 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM32, 0>()), static_cast<int32_t>(0xf1f21234));
123 }
124
125 // V8_IMM32
126 {
127 const uint8_t bytecode[] = {0x00, 0x04, 0x34, 0xf2, 0x12, 0x10, 0xff};
128 BytecodeInstruction inst(bytecode);
129 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
130 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM32, 0>()), 0x04);
131 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM32, 0>()), 0x1012f234);
132 }
133
134 {
135 const uint8_t bytecode[] = {0x00, 0xaa, 0x34, 0x12, 0xf2, 0xf1, 0xff};
136 BytecodeInstruction inst(bytecode);
137 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
138 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM32, 0>()), 0xaa);
139 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM32, 0>()), static_cast<int32_t>(0xf1f21234));
140 }
141
142 // IMM64
143 {
144 const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0x4, 0xff};
145 BytecodeInstruction inst(bytecode);
146 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
147 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM64, 0>()), 0x041012f23456789a);
148 }
149
150 {
151 const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xab, 0xff};
152 BytecodeInstruction inst(bytecode);
153 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
154 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::IMM64, 0>()), static_cast<int64_t>(0xab1012f23456789a));
155 }
156
157 // V8_IMM64
158 {
159 const uint8_t bytecode[] = {0x00, 0x11, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0x4, 0xff};
160 BytecodeInstruction inst(bytecode);
161 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
162 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM64, 0>()), 0x11);
163 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM64, 0>()), 0x041012f23456789a);
164 }
165
166 {
167 const uint8_t bytecode[] = {0x00, 0xab, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xab, 0xff};
168 BytecodeInstruction inst(bytecode);
169 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
170 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_IMM64, 0>()), 0xab);
171 EXPECT_EQ((inst.GetImm<BytecodeInstruction::Format::V8_IMM64, 0>()), static_cast<int64_t>(0xab1012f23456789a));
172 }
173
174 // V4_V4
175 {
176 const uint8_t bytecode[] = {0x00, 0xba, 0xff};
177 BytecodeInstruction inst(bytecode);
178 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
179 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4, 0>()), 0xa);
180 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4, 1>()), 0xb);
181 }
182
183 // V8
184 {
185 const uint8_t bytecode[] = {0x00, 0xab, 0xff};
186 BytecodeInstruction inst(bytecode);
187 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
188 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8, 0>()), 0xab);
189 }
190
191 // V8_V8
192 {
193 const uint8_t bytecode[] = {0x00, 0xab, 0xcd, 0xff};
194 BytecodeInstruction inst(bytecode);
195 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
196 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_V8, 0>()), 0xab);
197 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_V8, 1>()), 0xcd);
198 }
199
200 // V16_V16
201 {
202 const uint8_t bytecode[] = {0x00, 0xcd, 0xab, 0xf1, 0xee, 0xff};
203 BytecodeInstruction inst(bytecode);
204 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
205 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V16_V16, 0>()), 0xabcd);
206 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V16_V16, 1>()), 0xeef1);
207 }
208
209 // ID32
210 {
211 const uint8_t bytecode[] = {0x00, 0xf1, 0xee, 0xcd, 0xab, 0xff};
212 BytecodeInstruction inst(bytecode);
213 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
214 EXPECT_EQ((inst.GetId<BytecodeInstruction::Format::ID32, 0>()), BytecodeId(0xabcdeef1));
215 }
216
217 // V4_V4_ID16
218 {
219 const uint8_t bytecode[] = {0x00, 0x21, 0xf1, 0xee, 0xcd, 0xab, 0xff};
220 BytecodeInstruction inst(bytecode);
221 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
222 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4_ID16, 0>()), 0x1);
223 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4_ID16, 1>()), 0x2);
224 EXPECT_EQ((inst.GetId<BytecodeInstruction::Format::V4_V4_ID16, 0>()), BytecodeId(0xeef1));
225 }
226
227 // V8_ID16
228 {
229 const uint8_t bytecode[] = {0x00, 0x12, 0xf1, 0xee, 0xcd, 0xab, 0xff};
230 BytecodeInstruction inst(bytecode);
231 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
232 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V8_ID16, 0>()), 0x12);
233 EXPECT_EQ((inst.GetId<BytecodeInstruction::Format::V8_ID16, 0>()), BytecodeId(0xeef1));
234 }
235
236 // V4_V4_V4_V4_ID16
237 {
238 const uint8_t bytecode[] = {0x00, 0x21, 0x43, 0xf1, 0xee, 0xcd, 0xab, 0xff};
239 BytecodeInstruction inst(bytecode);
240 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
241 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4_V4_V4_ID16, 0x0>()), 0x1);
242 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4_V4_V4_ID16, 0x1>()), 0x2);
243 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4_V4_V4_ID16, 0x2>()), 0x3);
244 EXPECT_EQ((inst.GetVReg<BytecodeInstruction::Format::V4_V4_V4_V4_ID16, 0x3>()), 0x4);
245 EXPECT_EQ((inst.GetId<BytecodeInstruction::Format::V4_V4_V4_V4_ID16, 0>()), BytecodeId(0xeef1));
246 }
247 }
248
TEST(BytecodeInstruction,JumpTo)249 TEST(BytecodeInstruction, JumpTo)
250 {
251 const uint8_t bytecode[] = {0x00, 0x11, 0x22, 0x33};
252 BytecodeInstruction inst(bytecode);
253 BytecodeInstruction next = inst.JumpTo(2);
254 EXPECT_EQ(static_cast<uint8_t>(next.GetOpcode()), bytecode[2]);
255 }
256
TEST(BytecodeInstructionSafe,Parse)257 TEST(BytecodeInstructionSafe, Parse)
258 {
259 // Positive tests
260 // V4_IMM4
261 {
262 const uint8_t bytecode[] = {0x00, 0xa1, 0xff};
263 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
264 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
265 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_IMM4, 0>()), 1);
266 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V4_IMM4, 0>()), -6);
267 }
268
269 {
270 const uint8_t bytecode[] = {0x00, 0x2f, 0xff};
271 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
272 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
273 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_IMM4, 0>()), 0xf);
274 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V4_IMM4, 0>()), 0x2);
275 }
276
277 // IMM8
278 {
279 const uint8_t bytecode[] = {0x00, 0xf2, 0xff};
280 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
281 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
282 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM8, 0>()), static_cast<int8_t>(0xf2));
283 }
284
285 {
286 const uint8_t bytecode[] = {0x00, 0x21, 0xff};
287 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
288 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
289 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM8, 0>()), 0x21);
290 }
291
292 // V8_IMM8
293 {
294 const uint8_t bytecode[] = {0x00, 0x12, 0xf2, 0xff};
295 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
296 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
297 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM8, 0>()), 0x12);
298 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM8, 0>()), static_cast<int8_t>(0xf2));
299 }
300
301 {
302 const uint8_t bytecode[] = {0x00, 0xf2, 0x12, 0xff};
303 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
304 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
305 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM8, 0>()), 0xf2);
306 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM8, 0>()), 0x12);
307 }
308
309 // IMM16
310 {
311 const uint8_t bytecode[] = {0x00, 0xf2, 0x12, 0xff};
312 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
313 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
314 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM16, 0>()), 0x12f2);
315 }
316
317 {
318 const uint8_t bytecode[] = {0x00, 0x12, 0xf2, 0xff};
319 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
320 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
321 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM16, 0>()), static_cast<int16_t>(0xf212));
322 }
323
324 // V8_IMM16
325 {
326 const uint8_t bytecode[] = {0x00, 0x10, 0xf2, 0x12, 0xff};
327 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
328 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
329 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM16, 0>()), 0x10);
330 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM16, 0>()), 0x12f2);
331 }
332
333 {
334 const uint8_t bytecode[] = {0x00, 0xff, 0x12, 0xf2, 0xff};
335 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
336 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
337 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM16, 0>()), 0xff);
338 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM16, 0>()), static_cast<int16_t>(0xf212));
339 }
340
341 // IMM32
342 {
343 const uint8_t bytecode[] = {0x00, 0x34, 0xf2, 0x12, 0x10, 0xff};
344 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
345 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
346 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM32, 0>()), 0x1012f234);
347 }
348
349 {
350 const uint8_t bytecode[] = {0x00, 0x34, 0x12, 0xf2, 0xf1, 0xff};
351 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
352 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
353 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM32, 0>()), static_cast<int32_t>(0xf1f21234));
354 }
355
356 // V8_IMM32
357 {
358 const uint8_t bytecode[] = {0x00, 0x04, 0x34, 0xf2, 0x12, 0x10, 0xff};
359 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
360 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
361 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM32, 0>()), 0x04);
362 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM32, 0>()), 0x1012f234);
363 }
364
365 {
366 const uint8_t bytecode[] = {0x00, 0xaa, 0x34, 0x12, 0xf2, 0xf1, 0xff};
367 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
368 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
369 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM32, 0>()), 0xaa);
370 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM32, 0>()), static_cast<int32_t>(0xf1f21234));
371 }
372
373 // IMM64
374 {
375 const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0x4, 0xff};
376 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
377 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
378 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM64, 0>()), 0x041012f23456789a);
379 }
380
381 {
382 const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xab, 0xff};
383 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
384 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
385 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM64, 0>()), static_cast<int64_t>(0xab1012f23456789a));
386 }
387
388 // V8_IMM64
389 {
390 const uint8_t bytecode[] = {0x00, 0x11, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0x4, 0xff};
391 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
392 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
393 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM64, 0>()), 0x11);
394 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM64, 0>()), 0x041012f23456789a);
395 }
396
397 {
398 const uint8_t bytecode[] = {0x00, 0xab, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xab, 0xff};
399 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
400 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
401 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM64, 0>()), 0xab);
402 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM64, 0>()),
403 static_cast<int64_t>(0xab1012f23456789a));
404 }
405
406 // V4_V4
407 {
408 const uint8_t bytecode[] = {0x00, 0xba, 0xff};
409 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
410 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
411 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4, 0>()), 0xa);
412 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4, 1>()), 0xb);
413 }
414
415 // V8
416 {
417 const uint8_t bytecode[] = {0x00, 0xab, 0xff};
418 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
419 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
420 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8, 0>()), 0xab);
421 }
422
423 // V8_V8
424 {
425 const uint8_t bytecode[] = {0x00, 0xab, 0xcd, 0xff};
426 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
427 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
428 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_V8, 0>()), 0xab);
429 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_V8, 1>()), 0xcd);
430 }
431
432 // V16_V16
433 {
434 const uint8_t bytecode[] = {0x00, 0xcd, 0xab, 0xf1, 0xee, 0xff};
435 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
436 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
437 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V16_V16, 0>()), 0xabcd);
438 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V16_V16, 1>()), 0xeef1);
439 }
440
441 // ID32
442 {
443 const uint8_t bytecode[] = {0x00, 0xf1, 0xee, 0xcd, 0xab, 0xff};
444 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
445 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
446 EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::ID32, 0>()), BytecodeId(0xabcdeef1));
447 }
448
449 // V4_V4_ID16
450 {
451 const uint8_t bytecode[] = {0x00, 0x21, 0xf1, 0xee, 0xcd, 0xab, 0xff};
452 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
453 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
454 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_ID16, 0>()), 0x1);
455 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_ID16, 1>()), 0x2);
456 EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::V4_V4_ID16, 0>()), BytecodeId(0xeef1));
457 }
458
459 // V8_ID16
460 {
461 const uint8_t bytecode[] = {0x00, 0x12, 0xf1, 0xee, 0xcd, 0xab, 0xff};
462 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
463 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
464 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_ID16, 0>()), 0x12);
465 EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::V8_ID16, 0>()), BytecodeId(0xeef1));
466 }
467
468 // V4_V4_V4_V4_ID16
469 {
470 const uint8_t bytecode[] = {0x00, 0x21, 0x43, 0xf1, 0xee, 0xcd, 0xab, 0xff};
471 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
472 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
473 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x0>()), 0x1);
474 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x1>()), 0x2);
475 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x2>()), 0x3);
476 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x3>()), 0x4);
477 EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0>()), BytecodeId(0xeef1));
478 }
479
480 // Negative tests
481
482 // V4_IMM4
483 {
484 const uint8_t bytecode[] = {0x00};
485 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
486 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
487 EXPECT_TRUE(inst.IsValid());
488 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_IMM4, 0>()), 0);
489 EXPECT_FALSE(inst.IsValid());
490 }
491
492 {
493 const uint8_t bytecode[] = {0x00};
494 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
495 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
496 EXPECT_TRUE(inst.IsValid());
497 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V4_IMM4, 0>()), 0);
498 EXPECT_FALSE(inst.IsValid());
499 }
500
501 // IMM8
502 {
503 const uint8_t bytecode[] = {0x00};
504 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
505 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
506 EXPECT_TRUE(inst.IsValid());
507 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM8, 0>()), static_cast<int8_t>(0));
508 EXPECT_FALSE(inst.IsValid());
509 }
510
511 {
512 const uint8_t bytecode[] = {0x00};
513 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
514 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
515 EXPECT_TRUE(inst.IsValid());
516 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM8, 0>()), 0);
517 EXPECT_FALSE(inst.IsValid());
518 }
519
520 // V8_IMM8
521 {
522 const uint8_t bytecode[] = {0x00, 0x12};
523 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
524 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
525 EXPECT_TRUE(inst.IsValid());
526 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM8, 0>()), 0x12);
527 EXPECT_TRUE(inst.IsValid());
528 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM8, 0>()), static_cast<int8_t>(0));
529 EXPECT_FALSE(inst.IsValid());
530 }
531
532 // IMM16
533 {
534 const uint8_t bytecode[] = {0x00, 0xf2, 0xff};
535 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]);
536 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
537 EXPECT_TRUE(inst.IsValid());
538 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM16, 0>()), 0xf2);
539 EXPECT_FALSE(inst.IsValid());
540 }
541
542 // V8_IMM16
543 {
544 const uint8_t bytecode[] = {0x00, 0x10, 0xf2, 0xff};
545 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]);
546 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
547 EXPECT_TRUE(inst.IsValid());
548 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM16, 0>()), 0x10);
549 EXPECT_TRUE(inst.IsValid());
550 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM16, 0>()), 0xf2);
551 EXPECT_FALSE(inst.IsValid());
552 }
553
554 // IMM32
555 {
556 const uint8_t bytecode[] = {0x00, 0x34, 0xf2, 0x12, 0xff};
557 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]);
558 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
559 EXPECT_TRUE(inst.IsValid());
560 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM32, 0>()), 0x12f234);
561 EXPECT_FALSE(inst.IsValid());
562 }
563
564 // V8_IMM32
565 {
566 const uint8_t bytecode[] = {0x00, 0x04, 0x34, 0xf2, 0x12, 0xff};
567 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]);
568 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
569 EXPECT_TRUE(inst.IsValid());
570 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM32, 0>()), 0x04);
571 EXPECT_TRUE(inst.IsValid());
572 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM32, 0>()), 0x12f234);
573 EXPECT_FALSE(inst.IsValid());
574 }
575
576 // IMM64
577 {
578 const uint8_t bytecode[] = {0x00, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xff};
579 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 3]);
580 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
581 EXPECT_TRUE(inst.IsValid());
582 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::IMM64, 0>()), 0x12f23456789a);
583 EXPECT_FALSE(inst.IsValid());
584 }
585
586 // V8_IMM64
587 {
588 const uint8_t bytecode[] = {0x00, 0x11, 0x9a, 0x78, 0x56, 0x34, 0xf2, 0x12, 0x10, 0xff};
589 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 3]);
590 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
591 EXPECT_TRUE(inst.IsValid());
592 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_IMM64, 0>()), 0x11);
593 EXPECT_TRUE(inst.IsValid());
594 EXPECT_EQ((inst.GetImm<BytecodeInstructionSafe::Format::V8_IMM64, 0>()), 0x12f23456789a);
595 EXPECT_FALSE(inst.IsValid());
596 }
597
598 // V4_V4
599 {
600 const uint8_t bytecode[] = {0x00};
601 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
602 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
603 EXPECT_TRUE(inst.IsValid());
604 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4, 0>()), 0);
605 EXPECT_FALSE(inst.IsValid());
606 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4, 1>()), 0);
607 EXPECT_FALSE(inst.IsValid());
608 }
609
610 // V8
611 {
612 const uint8_t bytecode[] = {0x00};
613 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
614 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
615 EXPECT_TRUE(inst.IsValid());
616 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8, 0>()), 0);
617 EXPECT_FALSE(inst.IsValid());
618 }
619
620 // V8_V8
621 {
622 const uint8_t bytecode[] = {0x00, 0xab};
623 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
624 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
625 EXPECT_TRUE(inst.IsValid());
626 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_V8, 0>()), 0xab);
627 EXPECT_TRUE(inst.IsValid());
628 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_V8, 1>()), 0);
629 EXPECT_FALSE(inst.IsValid());
630 }
631
632 // V16_V16
633 {
634 const uint8_t bytecode[] = {0x00, 0xcd, 0xab, 0xf1, 0xff};
635 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]);
636 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
637 EXPECT_TRUE(inst.IsValid());
638 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V16_V16, 0>()), 0xabcd);
639 EXPECT_TRUE(inst.IsValid());
640 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V16_V16, 1>()), 0xf1);
641 EXPECT_FALSE(inst.IsValid());
642 }
643
644 // ID32
645 {
646 const uint8_t bytecode[] = {0x00, 0xf1, 0xee, 0xcd, 0xff};
647 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]);
648 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
649 EXPECT_TRUE(inst.IsValid());
650 EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::ID32, 0>()), BytecodeId(0xcdeef1));
651 EXPECT_FALSE(inst.IsValid());
652 }
653
654 // V4_V4_ID16
655 {
656 const uint8_t bytecode[] = {0x00, 0x21, 0xf1, 0xee};
657 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 2]);
658 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
659 EXPECT_TRUE(inst.IsValid());
660 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_ID16, 0>()), 0x1);
661 EXPECT_TRUE(inst.IsValid());
662 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_ID16, 1>()), 0x2);
663 EXPECT_TRUE(inst.IsValid());
664 EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::V4_V4_ID16, 0>()), BytecodeId(0xf1));
665 EXPECT_FALSE(inst.IsValid());
666 }
667
668 // V8_ID16
669 {
670 const uint8_t bytecode[] = {0x00, 0x12, 0xf1, 0xee};
671 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 3]);
672 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
673 EXPECT_TRUE(inst.IsValid());
674 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V8_ID16, 0>()), 0x12);
675 EXPECT_TRUE(inst.IsValid());
676 EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::V8_ID16, 0>()), BytecodeId(0x00));
677 EXPECT_FALSE(inst.IsValid());
678 }
679
680 // V4_V4_V4_V4_ID16
681 {
682 const uint8_t bytecode[] = {0x00, 0x21, 0x43, 0xf1, 0xee};
683 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 3]);
684 EXPECT_EQ(static_cast<uint8_t>(inst.GetOpcode()), 0x00);
685 EXPECT_TRUE(inst.IsValid());
686 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x0>()), 0x1);
687 EXPECT_TRUE(inst.IsValid());
688 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x1>()), 0x2);
689 EXPECT_TRUE(inst.IsValid());
690 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x2>()), 0x3);
691 EXPECT_TRUE(inst.IsValid());
692 EXPECT_EQ((inst.GetVReg<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0x3>()), 0x4);
693 EXPECT_TRUE(inst.IsValid());
694 EXPECT_EQ((inst.GetId<BytecodeInstructionSafe::Format::V4_V4_V4_V4_ID16, 0>()), BytecodeId(0x0));
695 EXPECT_FALSE(inst.IsValid());
696 }
697 }
698
TEST(BytecodeInstructionSafe,JumpTo)699 TEST(BytecodeInstructionSafe, JumpTo)
700 {
701 // Positive
702 {
703 const uint8_t bytecode[] = {0x00, 0x11, 0x22, 0x33};
704 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
705 BytecodeInstructionSafe next = inst.JumpTo(2);
706 EXPECT_EQ(static_cast<uint8_t>(next.GetOpcode()), bytecode[2]);
707 }
708 // Negative
709 {
710 const uint8_t bytecode[] = {0x00, 0x11, 0x22, 0x33};
711 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
712 BytecodeInstructionSafe next = inst.JumpTo(4);
713 EXPECT_FALSE(inst.IsValid());
714 EXPECT_FALSE(next.IsValid());
715 }
716 {
717 const uint8_t bytecode[] = {0x00, 0x11, 0x22, 0x33};
718 BytecodeInstructionSafe inst(bytecode, &bytecode[0], &bytecode[sizeof(bytecode) - 1]);
719 BytecodeInstructionSafe next = inst.JumpTo(-1);
720 EXPECT_FALSE(inst.IsValid());
721 EXPECT_FALSE(next.IsValid());
722 }
723 }
724
725 } // namespace panda::test
726