• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2024 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// NOLINTNEXTLINE(readability-function-size)
17
18#ifndef PANDA_VERIFICATION_ABSINT_HANDLE_CONVERSION_GEN_H
19#define PANDA_VERIFICATION_ABSINT_HANDLE_CONVERSION_GEN_H
20
21namespace ark::verifier {
22%
23%
24% # =============================================================================================
25% # ---------------------------------------------------------------------------------------------
26% # stuff to gen CheckBinaryOp and CheckBinaryOp2 funcs
27% # ---------------------------------------------------------------------------------------------
28% logical_arr = ['And', 'Or', 'Xor', 'Shl', 'Shr', 'Ashr']
29% arithm_arr = ['Add', 'Sub', 'Mul', 'Div', 'Mod']
30% binary_vreg_arr = ['Andv', 'Orv', 'Xorv', 'Shlv', 'Shrv', 'Ashrv', 'Addv', 'Subv', 'Mulv', 'Divv', 'Modv']
31% binary_arr = logical_arr + arithm_arr + binary_vreg_arr
32% # ---------------------------------------------------------------------------------------------
33%
34%
35% # ---------------------------------------------------------------------------------------------
36% # stuff to gen HandleConversion funcs, not implemeted, CheckBinaryOp, CheckBinaryOp2Imm
37% # ---------------------------------------------------------------------------------------------
38% handle_conversion_arr = ['I32', 'U32', 'I64', 'U64', 'F32', 'F64']
39% first_arg_arr = ['integral32_', 'integral32_', 'integral64_', 'integral64_', 'f32_', 'f64_']
40% # ---------------------------------------------------------------------------------------------
41%
42%
43% # ---------------------------------------------------------------------------------------------
44% # stuff to gen comparative funcs. Here we keep insts with comparative signatures from isa.yaml
45% # ---------------------------------------------------------------------------------------------
46% comp_op_arr = ['equal_to','not_equal_to', 'less', 'greater', 'less_equal', 'greater_equal']
47% comparative_sig = Array.new()
48% # ---------------------------------------------------------------------------------------------
49% # =============================================================================================
50%
51%
52%
53%
54% # =============================================================================================
55% # ---------------------------------------------------------------------------------------------
56% Panda::instructions.each do |i|
57%   if (i.namespace == 'core' || i.namespace == 'ets')
58%       mnemonic = i.mnemonic.split('.').map { |p| p == '64' ? 'Wide' : p.capitalize }.join
59% # ---------------------------------------------------------------------------------------------
60%
61%
62% # ---------------------------------------------------------------------------------------------
63% # gen CheckBinaryOp2 insts
64% # ---------------------------------------------------------------------------------------------
65%       res_check_binary_op_2 = i.verification.include?('acc_type') && i.verification.include?('v1_type') && !i.verification.include?('branch_target')
66%       if res_check_binary_op_2
67%           mnemonic = i.mnemonic.split('.').map { |p| p == '64' ? 'Wide' : p.capitalize }.join
68%           res_binary_find = res_arithm_find = res_logic_find = false
69%           for bin in binary_arr
70%               res_binary_find = mnemonic.include?(bin)
71%               res_binary_find ? res_arithm_find = arithm_arr.include?(bin) : res_arithm_find = false
72%               res_logic_find = res_binary_find ^ res_arithm_find
73%               res_binary_find ? break : next
74%           end
75%           flag_integral = mnemonic.include?('U') || (res_binary_find)
76%           flag_float = mnemonic.include?('F')
77%           flag_wide = mnemonic.include?('Wide')
78%           flag_u = mnemonic.include?('Divu') || mnemonic.include?('Modu')
79%           flag_reg = mnemonic.include?('2v')
80%           if (!flag_integral) && (!flag_float)
81%               call_func_arg = 'i64_, i64_, i32_'
82%           elsif flag_float
83%               if mnemonic.include?('cmp')
84%                   flag_wide ? call_func_arg = 'f64_, f64_, i32_' : call_func_arg = 'f32_, f32_, i32_'
85%               else
86%                   flag_wide ? call_func_arg = 'f64_, f64_, f64_' : call_func_arg = 'f32_, f32_, f32_'
87%               end
88%           elsif flag_integral
89%               if res_arithm_find && !flag_u
90%                   flag_wide ? call_func_arg = 'integral64_, integral64_, i64_' : call_func_arg = 'integral32_, integral32_, i32_'
91%               elsif res_logic_find && !flag_u
92%                   flag_wide ? call_func_arg = 'integral64_, integral64_' : call_func_arg = 'integral32_, integral32_'
93%               elsif mnemonic.include?('cmp')
94%                   flag_wide ? call_func_arg = 'integral64_, integral64_, i32_' : call_func_arg = 'integral32_, integral32_, i32_'
95%               else
96%                   (!flag_wide) ? call_func_arg = 'integral32_, integral32_, u32_' : (flag_u ? call_func_arg = 'integral64_, integral64_, u64_' : call_func_arg = '')
97%               end
98%           end
99
100    template <BytecodeInstructionSafe::Format FORMAT>
101    bool AbsIntInstructionHandler::Handle<%= mnemonic %>()
102    {
103        LOG_INST();
104        DBGBRK();
105        Sync();
106        return CheckBinaryOp2<FORMAT, <%= flag_reg %>>(<%= call_func_arg %>);
107    }
108%       end
109% # ---------------------------------------------------------------------------------------------
110%
111%
112% # ---------------------------------------------------------------------------------------------
113% # gen HandleConversion insts
114% # ---------------------------------------------------------------------------------------------
115%       for curr_string in handle_conversion_arr
116%           if mnemonic.include?(curr_string)
117%               index = handle_conversion_arr.index(curr_string)
118
119    template <BytecodeInstructionSafe::Format FORMAT>
120    bool AbsIntInstructionHandler::Handle<%= mnemonic %>()
121    {
122        LOG_INST();
123        DBGBRK();
124        Sync();
125        return HandleConversion<FORMAT>(<%= first_arg_arr[index]%>, <%= mnemonic.split('to')[1]%>_);
126    }
127%               break
128%           end
129%       end
130% # ---------------------------------------------------------------------------------------------
131%
132%
133% # ---------------------------------------------------------------------------------------------
134% # gen not implemented (now .dyn and .sts) inst
135% # ---------------------------------------------------------------------------------------------
136%       res_not_impl = (mnemonic.include?('Dyn')) && !mnemonic.include?('MovDyn')
137%       if res_not_impl
138
139    template <BytecodeInstructionSafe::Format FORMAT>
140    bool AbsIntInstructionHandler::Handle<%= mnemonic %>()
141    {
142        LOG_INST();
143        DBGBRK();
144        Sync();
145        LOG(ERROR, VERIFIER) << "Verifier error: instruction is not implemented";
146        status_ = VerificationStatus::ERROR;
147        return false;
148    }
149%       end
150% # ---------------------------------------------------------------------------------------------
151%
152%
153% # ---------------------------------------------------------------------------------------------
154% # gen CheckBinaryOp insts
155% # ---------------------------------------------------------------------------------------------
156%       for curr_mnemonic in binary_arr
157%           if mnemonic == curr_mnemonic
158
159    template <BytecodeInstructionSafe::Format FORMAT>
160    bool AbsIntInstructionHandler::Handle<%= mnemonic %>()
161    {
162        LOG_INST();
163        DBGBRK();
164        Sync();
165        return CheckBinaryOp<FORMAT, <%= binary_vreg_arr.include?(curr_mnemonic) %>>(integral32_, integral32_, i32_);
166    }
167%               break
168%           end
169%       end
170% # ---------------------------------------------------------------------------------------------
171%
172%
173% # ---------------------------------------------------------------------------------------------
174% # gen CheckBinaryOp2Imm insts
175% # ---------------------------------------------------------------------------------------------
176%       for curr_log in logical_arr
177%           if mnemonic == curr_log + 'i'
178
179    template <BytecodeInstructionSafe::Format FORMAT>
180    bool AbsIntInstructionHandler::Handle<%= mnemonic %>()
181    {
182        LOG_INST();
183        DBGBRK();
184        Sync();
185        return CheckBinaryOp2Imm<FORMAT>(integral32_);
186    }
187%               break
188%           elsif mnemonic == (curr_log + 'iv')
189
190    template <BytecodeInstructionSafe::Format FORMAT>
191    bool AbsIntInstructionHandler::Handle<%= mnemonic %>()
192    {
193        LOG_INST();
194        DBGBRK();
195        Sync();
196        return CheckBinaryOpImm<FORMAT>(integral32_, i32_);
197    }
198%               break
199%           end
200%       end
201%
202%       for curr_log in arithm_arr
203%           if mnemonic == (curr_log + 'i')
204
205    template <BytecodeInstructionSafe::Format FORMAT>
206    bool AbsIntInstructionHandler::Handle<%= mnemonic %>()
207    {
208        LOG_INST();
209        DBGBRK();
210        Sync();
211        return CheckBinaryOp2Imm<FORMAT>(integral32_, i32_);
212    }
213%               break
214%           elsif mnemonic == (curr_log + 'iv')
215
216    template <BytecodeInstructionSafe::Format FORMAT>
217    bool AbsIntInstructionHandler::Handle<%= mnemonic %>()
218    {
219        LOG_INST();
220        DBGBRK();
221        Sync();
222        return CheckBinaryOpImm<FORMAT>(integral32_, i32_);
223    }
224%               break
225%           end
226%       end
227% # ---------------------------------------------------------------------------------------------
228%
229%
230% # ---------------------------------------------------------------------------------------------
231% # gen HandleCondJmp and HandleCondJmpz insts
232% # ---------------------------------------------------------------------------------------------
233%       if i.conditional?
234%           elem = mnemonic.capitalize
235%           if i.verification.include?('v1_type') && !(comparative_sig.include?(elem))
236%               comparative_sig.push(elem)
237
238    template <BytecodeInstructionSafe::Format FORMAT>
239    bool AbsIntInstructionHandler::Handle<%= elem %>()
240    {
241        LOG_INST();
242        DBGBRK();
243        Sync();
244        return HandleCondJmp<FORMAT, std::<%=comp_op_arr[comparative_sig.index(elem)]%>>();
245    }
246
247    template <BytecodeInstructionSafe::Format FORMAT>
248    bool AbsIntInstructionHandler::Handle<%= elem %>z()
249    {
250        LOG_INST();
251        DBGBRK();
252        Sync();
253        return HandleCondJmpz<FORMAT, std::<%=comp_op_arr[comparative_sig.index(elem)]%>>();
254    }
255%           end
256%       end
257% # ---------------------------------------------------------------------------------------------
258%   end # end for core namespace
259% end # end for Panda::instructions
260% # =============================================================================================
261}  // namespace ark::verifier
262
263#endif // PANDA_VERIFICATION_ABSINT_HANDLE_CONVERSION_GEN_H