1b1994897Sopenharmony_ci/*
2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License.
5b1994897Sopenharmony_ci * You may obtain a copy of the License at
6b1994897Sopenharmony_ci *
7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
8b1994897Sopenharmony_ci *
9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and
13b1994897Sopenharmony_ci * limitations under the License.
14b1994897Sopenharmony_ci */
15b1994897Sopenharmony_ci
16b1994897Sopenharmony_ci#include <iostream>
17b1994897Sopenharmony_ci#include <string>
18b1994897Sopenharmony_ci
19b1994897Sopenharmony_ci#include <gtest/gtest.h>
20b1994897Sopenharmony_ci#include "disassembler.h"
21b1994897Sopenharmony_ci
22b1994897Sopenharmony_ciusing namespace panda::disasm;
23b1994897Sopenharmony_ci
24b1994897Sopenharmony_ci#cmakedefine DISASM_BIN_DIR "@DISASM_BIN_DIR@/"
25b1994897Sopenharmony_ci
26b1994897Sopenharmony_ciTEST(instructions_test, test_language_panda_assembly)
27b1994897Sopenharmony_ci{
28b1994897Sopenharmony_ci    Disassembler d {};
29b1994897Sopenharmony_ci
30b1994897Sopenharmony_ci    std::stringstream ss {};
31b1994897Sopenharmony_ci    d.Disassemble(std::string(DISASM_BIN_DIR) + "empty_record.bc");
32b1994897Sopenharmony_ci    d.Serialize(ss);
33b1994897Sopenharmony_ci
34b1994897Sopenharmony_ci    EXPECT_TRUE(ss.str().find(".language PandaAssembly") != std::string::npos);
35b1994897Sopenharmony_ci}
36b1994897Sopenharmony_ci
37b1994897Sopenharmony_ciTEST(instructions_test, test_ins)
38b1994897Sopenharmony_ci{
39b1994897Sopenharmony_ci    Disassembler d {};
40b1994897Sopenharmony_ci
41b1994897Sopenharmony_ci    std::stringstream ss {};
42b1994897Sopenharmony_ci    d.Disassemble(std::string(DISASM_BIN_DIR) + "instructions.bc");
43b1994897Sopenharmony_ci    d.Serialize(ss);
44b1994897Sopenharmony_ci
45b1994897Sopenharmony_ci    size_t beg_g = ss.str().find("g() <static> {");
46b1994897Sopenharmony_ci    size_t end_g = ss.str().find('}', beg_g);
47b1994897Sopenharmony_ci
48b1994897Sopenharmony_ci    ASSERT_TRUE(beg_g != std::string::npos && end_g != std::string::npos) << "function g not found";
49b1994897Sopenharmony_ci
50b1994897Sopenharmony_ci    std::string body_g = ss.str().substr(beg_g + strlen("g() {"), end_g - (beg_g + strlen("g() {")));
51b1994897Sopenharmony_ci
52b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmov v0, v1") != std::string::npos);
53b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmov.64 v2, v3") != std::string::npos);
54b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmov.obj v4, v5") != std::string::npos);
55b1994897Sopenharmony_ci
56b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmovi v0, 0xffffffffffffffff") != std::string::npos);
57b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmovi.64 v0, 0x2") != std::string::npos);
58b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tfmovi.64 v0, 0x4008147ae147ae14") != std::string::npos);
59b1994897Sopenharmony_ci
60b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tlda v1") != std::string::npos);
61b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tlda.64 v0") != std::string::npos);
62b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tlda.obj v1") != std::string::npos);
63b1994897Sopenharmony_ci
64b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldai 0x1") != std::string::npos);
65b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldai.64 0x2") != std::string::npos);
66b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tfldai.64 0x4008147ae147ae14") != std::string::npos);
67b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tlda.str \"kek\"") != std::string::npos);
68b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tlda.type A") != std::string::npos);
69b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tlda.null") != std::string::npos);
70b1994897Sopenharmony_ci
71b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tsta v0") != std::string::npos);
72b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tsta.64 v1") != std::string::npos);
73b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tsta.obj v2") != std::string::npos);
74b1994897Sopenharmony_ci
75b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("jump_label_0:\n\tjmp jump_label_0") != std::string::npos);
76b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tjeq v1, jump_label_1") != std::string::npos);
77b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldai 0x1") != std::string::npos);
78b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tjmp jump_label_2") != std::string::npos);
79b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("jump_label_1:\n\tldai 0x0") != std::string::npos);
80b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("jump_label_2:\n\tcmp.64 v1") != std::string::npos);
81b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tucmp v2") != std::string::npos);
82b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tucmp.64 v3") != std::string::npos);
83b1994897Sopenharmony_ci
84b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tfcmpl.64 v1") != std::string::npos);
85b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tfcmpg.64 v1") != std::string::npos);
86b1994897Sopenharmony_ci
87b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tjeqz jump_label_0") != std::string::npos);
88b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tjnez jump_label_0") != std::string::npos);
89b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tjltz jump_label_0") != std::string::npos);
90b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tjgtz jump_label_0") != std::string::npos);
91b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tjlez jump_label_0") != std::string::npos);
92b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tjgez jump_label_0") != std::string::npos);
93b1994897Sopenharmony_ci
94b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tjeq v2, jump_label_0") != std::string::npos);
95b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tjne v2, jump_label_0") != std::string::npos);
96b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tjlt v2, jump_label_0") != std::string::npos);
97b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tjgt v2, jump_label_0") != std::string::npos);
98b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tjle v2, jump_label_0") != std::string::npos);
99b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tjge v2, jump_label_0") != std::string::npos);
100b1994897Sopenharmony_ci
101b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tfadd2.64 v1") != std::string::npos);
102b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tfsub2.64 v1") != std::string::npos);
103b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tfmul2.64 v1") != std::string::npos);
104b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tfdiv2.64 v1") != std::string::npos);
105b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tfmod2.64 v1") != std::string::npos);
106b1994897Sopenharmony_ci
107b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tadd2 v2") != std::string::npos);
108b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tadd2.64 v2") != std::string::npos);
109b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tsub2 v2") != std::string::npos);
110b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tsub2.64 v2") != std::string::npos);
111b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmul2 v2") != std::string::npos);
112b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmul2.64 v2") != std::string::npos);
113b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tand2 v2") != std::string::npos);
114b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tand2.64 v2") != std::string::npos);
115b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tor2 v2") != std::string::npos);
116b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tor2.64 v2") != std::string::npos);
117b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\txor2 v2") != std::string::npos);
118b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\txor2.64 v2") != std::string::npos);
119b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tshl2 v2") != std::string::npos);
120b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tshl2.64 v2") != std::string::npos);
121b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tshr2 v2") != std::string::npos);
122b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tshr2.64 v2") != std::string::npos);
123b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tashr2 v2") != std::string::npos);
124b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tashr2.64 v2") != std::string::npos);
125b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tdiv2 v2") != std::string::npos);
126b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tdiv2.64 v2") != std::string::npos);
127b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmod2 v2") != std::string::npos);
128b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmod2.64 v2") != std::string::npos);
129b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tdivu2 v2") != std::string::npos);
130b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tdivu2.64 v2") != std::string::npos);
131b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmodu2 v2") != std::string::npos);
132b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmodu2.64 v2") != std::string::npos);
133b1994897Sopenharmony_ci
134b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tadd v1, v2") != std::string::npos);
135b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tsub v1, v2") != std::string::npos);
136b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmul v1, v2") != std::string::npos);
137b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tand v1, v2") != std::string::npos);
138b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tor v1, v2") != std::string::npos);
139b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\txor v1, v2") != std::string::npos);
140b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tshl v1, v2") != std::string::npos);
141b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tshr v1, v2") != std::string::npos);
142b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tashr v1, v2") != std::string::npos);
143b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tdiv v1, v2") != std::string::npos);
144b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmod v1, v2") != std::string::npos);
145b1994897Sopenharmony_ci
146b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\taddi 0x1") != std::string::npos);
147b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tsubi 0x1") != std::string::npos);
148b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmuli 0x1") != std::string::npos);
149b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tandi 0x1") != std::string::npos);
150b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tori 0x1") != std::string::npos);
151b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\txori 0x1") != std::string::npos);
152b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tshli 0x1") != std::string::npos);
153b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tshri 0x1") != std::string::npos);
154b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tashri 0x1") != std::string::npos);
155b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tdivi 0x1") != std::string::npos);
156b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tmodi 0x1") != std::string::npos);
157b1994897Sopenharmony_ci
158b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tneg") != std::string::npos);
159b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tneg.64") != std::string::npos);
160b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tnot") != std::string::npos);
161b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tnot.64") != std::string::npos);
162b1994897Sopenharmony_ci
163b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\ti32tof64") != std::string::npos);
164b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tu32tof64") != std::string::npos);
165b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\ti64tof64") != std::string::npos);
166b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tu64tof64") != std::string::npos);
167b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tf64toi32") != std::string::npos);
168b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tf64toi64") != std::string::npos);
169b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tf64tou32") != std::string::npos);
170b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tf64tou64") != std::string::npos);
171b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\ti32toi64") != std::string::npos);
172b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\ti64toi32") != std::string::npos);
173b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tu32toi64") != std::string::npos);
174b1994897Sopenharmony_ci
175b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldarr.8 v1") != std::string::npos);
176b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldarru.8 v2") != std::string::npos);
177b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldarr.16 v1") != std::string::npos);
178b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldarru.16 v1") != std::string::npos);
179b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldarr v1") != std::string::npos);
180b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldarr.64 v1") != std::string::npos);
181b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tfldarr.32 v1") != std::string::npos);
182b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tfldarr.64 v1") != std::string::npos);
183b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldarr.obj v1") != std::string::npos);
184b1994897Sopenharmony_ci
185b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tstarr.8 v1, v2") != std::string::npos);
186b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tstarr.16 v1, v2") != std::string::npos);
187b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tstarr v1, v2") != std::string::npos);
188b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tstarr.64 v1, v2") != std::string::npos);
189b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tfstarr.32 v1, v2") != std::string::npos);
190b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tfstarr.64 v1, v2") != std::string::npos);
191b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tstarr.obj v1, v2") != std::string::npos);
192b1994897Sopenharmony_ci
193b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tnewobj v6, A") != std::string::npos);
194b1994897Sopenharmony_ci
195b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tinitobj.short A.init:()") != std::string::npos);
196b1994897Sopenharmony_ci
197b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldobj v0, A.kek") != std::string::npos);
198b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldobj.64 v0, A.kek") != std::string::npos);
199b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldobj.obj v0, A.kek") != std::string::npos);
200b1994897Sopenharmony_ci
201b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tstobj v1, A.kek") != std::string::npos);
202b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tstobj.64 v1, A.kek") != std::string::npos);
203b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tstobj.obj v1, A.kek") != std::string::npos);
204b1994897Sopenharmony_ci
205b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldstatic A.kek") != std::string::npos);
206b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldstatic.64 A.kek") != std::string::npos);
207b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tldstatic.obj A.kek") != std::string::npos);
208b1994897Sopenharmony_ci
209b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tststatic A.kek") != std::string::npos);
210b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tststatic.64 A.kek") != std::string::npos);
211b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tststatic.obj A.kek") != std::string::npos);
212b1994897Sopenharmony_ci
213b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcheckcast A") != std::string::npos);
214b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tisinstance A") != std::string::npos);
215b1994897Sopenharmony_ci}
216b1994897Sopenharmony_ci
217b1994897Sopenharmony_ciTEST(instructions_test, test_calls)
218b1994897Sopenharmony_ci{
219b1994897Sopenharmony_ci    Disassembler d {};
220b1994897Sopenharmony_ci
221b1994897Sopenharmony_ci    std::stringstream ss {};
222b1994897Sopenharmony_ci    d.Disassemble(std::string(DISASM_BIN_DIR) + "calls.bc");
223b1994897Sopenharmony_ci    d.Serialize(ss);
224b1994897Sopenharmony_ci
225b1994897Sopenharmony_ci    size_t beg_g = ss.str().find("g(u1 a0) <static> {");
226b1994897Sopenharmony_ci    size_t end_g = ss.str().find('}', beg_g);
227b1994897Sopenharmony_ci
228b1994897Sopenharmony_ci    ASSERT_TRUE(beg_g != std::string::npos && end_g != std::string::npos) << "function g not found";
229b1994897Sopenharmony_ci
230b1994897Sopenharmony_ci    std::string body_g =
231b1994897Sopenharmony_ci        ss.str().substr(beg_g + strlen("g(u1 a0) <static> {"), end_g - (beg_g + strlen("g(u1 a0) <static> {")));
232b1994897Sopenharmony_ci
233b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcall.virt.short B.Bhandler_unspec:(B), v4") != std::string::npos);
234b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcall.virt.short B.Bhandler_short:(B,u1), v4, v1") != std::string::npos);
235b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcall.virt B.Bhandler_short2:(B,u1[],i64), v4, v1, v2") != std::string::npos);
236b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcall.virt B.Bhandler_long:(B,i8,i16,i32), v4, v0, v1, v2") != std::string::npos);
237b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcall.virt.range B.Bhandler_range:(B,i8,i16,i32,i8,i16,i32), v4") != std::string::npos);
238b1994897Sopenharmony_ci
239b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcall.short handler_unspec:()") != std::string::npos);
240b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcall.short handler_short:(u1), v1") != std::string::npos);
241b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcall.short handler_short2:(u1,i64), v1, v2") != std::string::npos);
242b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcall handler_long:(i8,i16,i32), v0, v1, v2") != std::string::npos);
243b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcall handler_long2:(i8,i16,i32,f64), v0, v1, v2, v3") != std::string::npos);
244b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcall.range handler_range:(i8,i16,i32,i8,i16,i32), v0") != std::string::npos);
245b1994897Sopenharmony_ci
246b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tinitobj.short B.Bhandler_unspec:(B)") != std::string::npos);
247b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tinitobj.short B.Bhandler_short:(B,u1), v1") != std::string::npos);
248b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tinitobj.short B.Bhandler_short2:(B,u1[],i64), v1, v2") != std::string::npos);
249b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tinitobj B.Bhandler_long:(B,i8,i16,i32), v0, v1, v2") != std::string::npos);
250b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tinitobj B.Bhandler_long2:(B,i8,i16,i32,i64), v0, v1, v2, v3") != std::string::npos);
251b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tinitobj.range B.Bhandler_range:(B,i8,i16,i32,i8,i16,i32), v0") != std::string::npos);
252b1994897Sopenharmony_ci
253b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcall.acc.short handler_short:(u1), v0, 0x0") != std::string::npos);
254b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcall.acc.short handler_short2:(u1,i64), a0, 0x1") != std::string::npos);
255b1994897Sopenharmony_ci
256b1994897Sopenharmony_ci    EXPECT_TRUE(
257b1994897Sopenharmony_ci        ss.str().find(".function u16 long_function(i8 a0, i16 a1, i32 a2, i8 a3, i16 a4, i32 a5, i64 a6, f32 a7)") !=
258b1994897Sopenharmony_ci        std::string::npos);
259b1994897Sopenharmony_ci
260b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tcalli.dyn.short 0x1, v0") != std::string::npos);
261b1994897Sopenharmony_ci}
262b1994897Sopenharmony_ci
263b1994897Sopenharmony_ciTEST(instructions_test, test_returns)
264b1994897Sopenharmony_ci{
265b1994897Sopenharmony_ci    Disassembler d {};
266b1994897Sopenharmony_ci
267b1994897Sopenharmony_ci    std::stringstream ss {};
268b1994897Sopenharmony_ci    d.Disassemble(std::string(DISASM_BIN_DIR) + "returns.bc");
269b1994897Sopenharmony_ci    d.Serialize(ss);
270b1994897Sopenharmony_ci
271b1994897Sopenharmony_ci    EXPECT_TRUE(ss.str().find("\treturn") != std::string::npos);
272b1994897Sopenharmony_ci    EXPECT_TRUE(ss.str().find("\treturn.64") != std::string::npos);
273b1994897Sopenharmony_ci    EXPECT_TRUE(ss.str().find("\treturn.obj") != std::string::npos);
274b1994897Sopenharmony_ci    EXPECT_TRUE(ss.str().find("\treturn.void") != std::string::npos);
275b1994897Sopenharmony_ci}
276b1994897Sopenharmony_ci
277b1994897Sopenharmony_ciTEST(instructions_test, test_newarr)
278b1994897Sopenharmony_ci{
279b1994897Sopenharmony_ci    Disassembler d {};
280b1994897Sopenharmony_ci
281b1994897Sopenharmony_ci    std::stringstream ss {};
282b1994897Sopenharmony_ci    d.Disassemble(std::string(DISASM_BIN_DIR) + "newarrs.bc");
283b1994897Sopenharmony_ci    d.Serialize(ss);
284b1994897Sopenharmony_ci
285b1994897Sopenharmony_ci    size_t beg_g = ss.str().find("g(u1 a0) <static> {");
286b1994897Sopenharmony_ci    size_t end_g = ss.str().find('}', beg_g);
287b1994897Sopenharmony_ci
288b1994897Sopenharmony_ci    ASSERT_TRUE(beg_g != std::string::npos && end_g != std::string::npos) << "function g not found";
289b1994897Sopenharmony_ci
290b1994897Sopenharmony_ci    std::string body_g = ss.str().substr(beg_g + strlen("g() {"), end_g - (beg_g + strlen("g() {")));
291b1994897Sopenharmony_ci
292b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tnewarr v0, a0, u1[]") != std::string::npos);
293b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tnewarr v0, a0, i8[]") != std::string::npos);
294b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tnewarr v0, a0, u8[]") != std::string::npos);
295b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tnewarr v0, a0, i16[]") != std::string::npos);
296b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tnewarr v0, a0, u16[]") != std::string::npos);
297b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tnewarr v0, a0, i32[]") != std::string::npos);
298b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tnewarr v0, a0, u32[]") != std::string::npos);
299b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tnewarr v0, a0, f32[]") != std::string::npos);
300b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tnewarr v0, a0, f64[]") != std::string::npos);
301b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tnewarr v0, a0, i64[]") != std::string::npos);
302b1994897Sopenharmony_ci    EXPECT_TRUE(body_g.find("\tnewarr v0, a0, u64[]") != std::string::npos);
303b1994897Sopenharmony_ci}
304b1994897Sopenharmony_ci
305b1994897Sopenharmony_ciTEST(instructions_test, test_debug_info)
306b1994897Sopenharmony_ci{
307b1994897Sopenharmony_ci    Disassembler d;
308b1994897Sopenharmony_ci
309b1994897Sopenharmony_ci    std::stringstream ss;
310b1994897Sopenharmony_ci    d.Disassemble(std::string(DISASM_BIN_DIR) + "instructions.bc");
311b1994897Sopenharmony_ci    d.CollectInfo();
312b1994897Sopenharmony_ci    d.Serialize(ss, true, true);
313b1994897Sopenharmony_ci
314b1994897Sopenharmony_ci    size_t beg_g = ss.str().find("g() <static> {");
315b1994897Sopenharmony_ci    size_t end_g = ss.str().find('}', beg_g);
316b1994897Sopenharmony_ci
317b1994897Sopenharmony_ci    ASSERT_TRUE(beg_g != std::string::npos && end_g != std::string::npos) << "function g not found";
318b1994897Sopenharmony_ci
319b1994897Sopenharmony_ci    std::string body_g = ss.str().substr(beg_g + strlen("g() {"), end_g - (beg_g + strlen("g() {")));
320b1994897Sopenharmony_ci
321b1994897Sopenharmony_ci    ASSERT_NE(body_g.find("#   LINE_NUMBER_TABLE:"), std::string::npos);
322b1994897Sopenharmony_ci    ASSERT_NE(body_g.find("#\tline 26: 0\n"), std::string::npos);
323b1994897Sopenharmony_ci
324b1994897Sopenharmony_ci    size_t code_start = body_g.find("#   CODE:\n");
325b1994897Sopenharmony_ci    ASSERT_NE(code_start, std::string::npos) << "Code section in function g not found";
326b1994897Sopenharmony_ci    size_t code_end = body_g.find("\n\n");  // First gap in function body is code section end
327b1994897Sopenharmony_ci    ASSERT_NE(code_end, std::string::npos) << "Gap after code section in function g not found";
328b1994897Sopenharmony_ci    ASSERT_LT(code_start, code_end);
329b1994897Sopenharmony_ci    std::string instructions =
330b1994897Sopenharmony_ci        body_g.substr(code_start + strlen("#   CODE:\n"), code_end + 1 - (code_start + strlen("#   CODE:\n")));
331b1994897Sopenharmony_ci    size_t instruction_count = std::count(instructions.begin(), instructions.end(), '\n');
332b1994897Sopenharmony_ci
333b1994897Sopenharmony_ci    const ProgInfo &prog_info = d.GetProgInfo();
334b1994897Sopenharmony_ci    auto g_it = prog_info.methods_info.find("g:()");
335b1994897Sopenharmony_ci    ASSERT_NE(g_it, prog_info.methods_info.end());
336b1994897Sopenharmony_ci    // In case of pandasm the table should contain entry on each instruction
337b1994897Sopenharmony_ci    ASSERT_EQ(g_it->second.line_number_table.size(), instruction_count);
338b1994897Sopenharmony_ci
339b1994897Sopenharmony_ci    // There should be no local variables for panda assembler
340b1994897Sopenharmony_ci    ASSERT_EQ(body_g.find("#   LOCAL_VARIABLE_TABLE:"), std::string::npos);
341b1994897Sopenharmony_ci}
342b1994897Sopenharmony_ci
343b1994897Sopenharmony_ci#undef DISASM_BIN_DIR
344