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