1/** 2 * Copyright (c) 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// Autogenerated file -- DO NOT EDIT! 17 18<% 19require 'yaml' 20 21def get_type(type) 22 @type_map ||= { 23 'u1' => 'DataType::BOOL', 24 'i8' => 'DataType::INT8', 25 'i16' => 'DataType::INT16', 26 'i32' => 'DataType::INT32', 27 'i64' => 'DataType::INT64', 28 'u8' => 'DataType::UINT8', 29 'u16' => 'DataType::UINT16', 30 'u32' => 'DataType::UINT32', 31 'u64' => 'DataType::UINT64', 32 'b32' => 'DataType::UINT32', 33 'b64' => 'DataType::UINT64', 34 'f32' => 'DataType::FLOAT32', 35 'f64' => 'DataType::FLOAT64', 36 'ref' => 'DataType::REFERENCE', 37 'any' => 'DataType::ANY', 38 'i8[]' => 'DataType::INT8', 39 'i16[]' => 'DataType::INT16', 40 'i32[]' => 'DataType::INT32', 41 'i64[]' => 'DataType::INT64', 42 'u8[]' => 'DataType::UINT8', 43 'u16[]' => 'DataType::UINT16', 44 'u32[]' => 'DataType::UINT32', 45 'u64[]' => 'DataType::UINT64', 46 'b32[]' => 'DataType::UINT32', 47 'b64[]' => 'DataType::UINT64', 48 'f32[]' => 'DataType::FLOAT32', 49 'f64[]' => 'DataType::FLOAT64', 50 'ref[]' => 'DataType::REFERENCE', 51 'none' => 'DataType::VOID'} 52 raise "Unknown type #{type}" if @type_map[type].nil? 53 @type_map[type] 54end 55 56def get_cc(inst) 57 return 'ConditionCode::CC_EQ' if inst.opcode.start_with? 'jeq' 58 return 'ConditionCode::CC_NE' if inst.opcode.start_with? 'jne' 59 return 'ConditionCode::CC_LT' if inst.opcode.start_with? 'jlt' 60 return 'ConditionCode::CC_GT' if inst.opcode.start_with? 'jgt' 61 return 'ConditionCode::CC_LE' if inst.opcode.start_with? 'jle' 62 return 'ConditionCode::CC_GE' if inst.opcode.start_with? 'jge' 63 raise 'get_cc: wrong opcode #{inst.opcode}' 64end 65 66%> 67 68#include "abckit_intrinsics.inl" 69 70void ark::compiler::AbcKitInstBuilder::BuildDefaultAbcKitIntrinsic(const BytecodeInstruction *bcInst, RuntimeInterface::IntrinsicId intrinsicId) 71{ 72 auto pc = GetPc(bcInst->GetAddress()); 73 ASSERT(!IsAbcKitInitObject(intrinsicId) && !IsAbcKitLoadObject(intrinsicId) && !IsAbcKitStoreObject(intrinsicId) && 74 !IsAbcKitLoadStatic(intrinsicId) && !IsAbcKitStoreStatic(intrinsicId) && !IsAbcKitLoadArray(intrinsicId) && !IsAbcKitStoreArray(intrinsicId)); 75 switch (intrinsicId) { 76% inst = nil 77% Compiler::intrinsics.select {|intrinsic| intrinsic.space == "abckit" }.each do |intrinsic| 78 case ark::compiler::RuntimeInterface::IntrinsicId::<%= intrinsic.entrypoint_name %>: { 79% Panda::instructions.each do |asm_ins| 80% if (asm_ins.mnemonic == intrinsic.method_name) 81% inst = asm_ins 82% end 83% end 84% if (inst) 85% format = "BytecodeInst::Format::" + inst.format.pretty.upcase 86% acc_read = inst.acc.include?("in") 87% acc_write = inst.acc.include?("out") 88% ret_type = acc_write ? get_type(intrinsic.signature.ret) : "DataType::VOID" 89% params_arr = inst.operands 90% num_vregs = params_arr.select{|b| b.reg? && b.src?}.length 91% num_imms = params_arr.select{|b| b.imm?}.length 92% num_ids = params_arr.select{|b| b.id?}.length 93% num_inputs = acc_read ? num_vregs + 1 : num_vregs 94 auto retType = ark::compiler::<%= get_type(intrinsic.signature.ret) %>; 95 ark::compiler::IntrinsicInst *inst = GetGraph()->CreateInstIntrinsic(retType, pc, intrinsicId); 96% if (num_inputs != 0) 97 size_t inputsCount = <%= num_inputs %>; 98 inst->ReserveInputs(inputsCount); 99 inst->AllocateInputTypes(GetGraph()->GetAllocator(), inputsCount); 100% end 101% if acc_read 102 { 103 auto input = GetDefinitionAcc(); 104 inst->AppendInput(input); 105% op = inst.acc_and_operands.select { |op| op.acc? && op.src? }.first 106 inst->AddInputType(ark::compiler::<%= get_type(op.type) %>); 107 } 108% end 109% imm_index = 0 110% vreg_index = 0 111% id16_index = 0 112% out_idx = nil 113% params_arr.each do |param| 114% if param.imm? 115 auto imm<%= imm_index %> = static_cast<uint32_t>(bcInst->GetImm<<%= format %>, <%= imm_index %>>()); 116 inst->AddImm(GetGraph()->GetAllocator(), imm<%= imm_index %>); 117% imm_index = imm_index + 1 118% elsif param.reg? 119% if param.src? 120 { 121 auto input = GetDefinition(bcInst->GetVReg(<%= vreg_index %>)); 122 inst->AppendInput(input); 123 inst->AddInputType(ark::compiler::<%= get_type(param.type) %>); 124 } 125% else 126% out_idx = vreg_index 127% end 128% vreg_index = vreg_index + 1 129% elsif param.id? 130% if inst.properties.include?("string_id") 131 uint32_t stringId<%= id16_index %> = bcInst->GetId(<%= id16_index %>).AsFileId().GetOffset(); 132 inst->AddImm(GetGraph()->GetAllocator(), stringId<%= id16_index %>); 133% elsif inst.properties.include?("literalarray_id") 134 uint32_t literalarrayId<%= id16_index %> = bcInst->GetId(<%= id16_index %>).AsIndex(); 135 inst->AddImm(GetGraph()->GetAllocator(), literalarrayId<%= id16_index %>); 136% elsif inst.properties.include?("type_id") 137 uint32_t typeId<%= id16_index %> = bcInst->GetId(<%= id16_index %>).AsIndex(); 138 typeId<%= id16_index %> = GetRuntime()->ResolveTypeIndex(GetGraph()->GetMethod(), typeId<%= id16_index %>); 139 inst->AddImm(GetGraph()->GetAllocator(), typeId<%= id16_index %>); 140% elsif inst.properties.include?("method_id") 141 uint32_t mId<%= id16_index %> = bcInst->GetId(<%= id16_index %>).AsIndex(); 142 mId<%= id16_index %> = GetRuntime()->ResolveMethodIndex(GetGraph()->GetMethod(), mId<%= id16_index %>); 143 inst->AddImm(GetGraph()->GetAllocator(), mId<%= id16_index %>); 144% end 145% id16_index = id16_index + 1 146% end 147% end 148 auto method = GetGraph()->GetMethod(); 149 inst->SetMethod(method); 150 AddInstruction(inst); 151% if acc_write 152 UpdateDefinitionAcc(inst); 153% end 154% if out_idx 155 UpdateDefinition(bcInst->GetVReg(<%= out_idx %>), inst); 156% end 157% end 158 return; 159 } 160% end 161 default: 162 return; 163 } 164} 165 166constexpr ark::compiler::Register MAX_NUM_SHORT_CALL_ARGS = 2; 167constexpr ark::compiler::Register MAX_NUM_NON_RANGE_ARGS = 4; 168 169void ark::compiler::AbcKitInstBuilder::BuildAbcKitInitObjectIntrinsic(const BytecodeInstruction *bcInst, bool isRange) 170{ 171 auto methodId = GetRuntime()->ResolveMethodIndex(GetMethod(), bcInst->GetId(0).AsIndex()); 172 size_t argsCount = GetMethodArgumentsCount(methodId); 173 ark::compiler::IntrinsicInst *inst {nullptr}; 174 if (argsCount > MAX_NUM_NON_RANGE_ARGS) { 175 inst = GetGraph()->CreateInstIntrinsic(ark::compiler::DataType::REFERENCE, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_INIT_OBJECT_RANGE); 176 } else if (argsCount > MAX_NUM_SHORT_CALL_ARGS) { 177 inst = GetGraph()->CreateInstIntrinsic(ark::compiler::DataType::REFERENCE, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_INIT_OBJECT); 178 } else { 179 inst = GetGraph()->CreateInstIntrinsic(ark::compiler::DataType::REFERENCE, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_INIT_OBJECT_SHORT); 180 } 181 inst->AddImm(GetGraph()->GetAllocator(), methodId); 182 inst->AllocateInputTypes(GetGraph()->GetAllocator(), argsCount); 183 if (isRange) { 184 auto startReg = bcInst->GetVReg(0); 185 for (size_t i = 0; i < argsCount; startReg++, i++) { 186 inst->AppendInput(GetDefinition(startReg)); 187 inst->AddInputType(GetRuntime()->GetMethodArgumentType(GetMethod(), methodId, i)); 188 } 189 } else { 190 for (size_t i = 0; i < argsCount; i++) { 191 inst->AppendInput(GetDefinition(bcInst->GetVReg(i))); 192 inst->AddInputType(GetRuntime()->GetMethodArgumentType(GetMethod(), methodId, i)); 193 } 194 } 195 auto method = GetGraph()->GetMethod(); 196 inst->SetMethod(method); 197 AddInstruction(inst); 198 UpdateDefinitionAcc(inst); 199} 200 201template<bool IS_ACC_WRITE> 202void ark::compiler::AbcKitInstBuilder::BuildAbcKitLoadObjectIntrinsic(const BytecodeInstruction *bcInst, ark::compiler::DataType::Type rawRetType) 203{ 204 auto fieldId = GetRuntime()->ResolveFieldIndex(GetMethod(), bcInst->GetId(0).AsIndex()); 205 auto retType = rawRetType; 206 if (rawRetType != ark::compiler::DataType::REFERENCE) { 207 retType = GetRuntime()->GetFieldTypeById(GetMethod(), fieldId); 208 } 209 ark::compiler::IntrinsicInst *inst {nullptr}; 210 switch (rawRetType) { 211 case ark::compiler::DataType::UINT32: { 212 inst = GetGraph()->CreateInstIntrinsic(retType, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_LOAD_OBJECT); 213 break; 214 } 215 case ark::compiler::DataType::UINT64: { 216 inst = GetGraph()->CreateInstIntrinsic(retType, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_LOAD_OBJECT_WIDE); 217 break; 218 } 219 case ark::compiler::DataType::REFERENCE: { 220 inst = GetGraph()->CreateInstIntrinsic(retType, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_LOAD_OBJECT_OBJECT); 221 break; 222 } 223 default: 224 UNREACHABLE(); 225 } 226 inst->AddImm(GetGraph()->GetAllocator(), fieldId); 227 inst->AllocateInputTypes(GetGraph()->GetAllocator(), 1); 228 inst->AppendInput(GetDefinition(bcInst->GetVReg(IS_ACC_WRITE ? 0 : 1))); 229 inst->AddInputType(ark::compiler::DataType::REFERENCE); 230 231 auto method = GetGraph()->GetMethod(); 232 inst->SetMethod(method); 233 AddInstruction(inst); 234 if constexpr (IS_ACC_WRITE) { 235 UpdateDefinitionAcc(inst); 236 } else { 237 UpdateDefinition(bcInst->GetVReg(0), inst); 238 } 239} 240 241template<bool IS_ACC_READ> 242void ark::compiler::AbcKitInstBuilder::BuildAbcKitStoreObjectIntrinsic(const BytecodeInstruction *bcInst, ark::compiler::DataType::Type rawType) 243{ 244 auto fieldId = GetRuntime()->ResolveFieldIndex(GetMethod(), bcInst->GetId(0).AsIndex()); 245 auto type = rawType; 246 if (rawType != ark::compiler::DataType::REFERENCE) { 247 type = GetRuntime()->GetFieldTypeById(GetMethod(), fieldId); 248 } 249 ark::compiler::IntrinsicInst *inst {nullptr}; 250 switch (rawType) { 251 case ark::compiler::DataType::UINT32: { 252 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_STORE_OBJECT); 253 break; 254 } 255 case ark::compiler::DataType::UINT64: { 256 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_STORE_OBJECT_WIDE); 257 break; 258 } 259 case ark::compiler::DataType::REFERENCE: { 260 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_STORE_OBJECT_OBJECT); 261 break; 262 } 263 default: 264 UNREACHABLE(); 265 } 266 267 inst->AddImm(GetGraph()->GetAllocator(), fieldId); 268 inst->AllocateInputTypes(GetGraph()->GetAllocator(), 2); 269 ark::compiler::Inst *storeVal = nullptr; 270 if constexpr (IS_ACC_READ) { 271 storeVal = GetDefinitionAcc(); 272 } else { 273 storeVal = GetDefinition(bcInst->GetVReg(0)); 274 } 275 inst->AppendInput(storeVal); 276 inst->AddInputType(type); 277 inst->AppendInput(GetDefinition(bcInst->GetVReg(IS_ACC_READ ? 0 : 1))); 278 inst->AddInputType(ark::compiler::DataType::REFERENCE); 279 280 auto method = GetGraph()->GetMethod(); 281 inst->SetMethod(method); 282 AddInstruction(inst); 283} 284 285void ark::compiler::AbcKitInstBuilder::BuildAbcKitLoadStaticIntrinsic(const BytecodeInstruction *bcInst, ark::compiler::DataType::Type rawType) 286{ 287 auto fieldId = GetRuntime()->ResolveFieldIndex(GetMethod(), bcInst->GetId(0).AsIndex()); 288 auto type = rawType; 289 if (rawType != ark::compiler::DataType::REFERENCE) { 290 type = GetRuntime()->GetFieldTypeById(GetMethod(), fieldId); 291 } 292 ark::compiler::IntrinsicInst *inst {nullptr}; 293 switch (rawType) { 294 case ark::compiler::DataType::UINT32: { 295 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_LOAD_STATIC); 296 break; 297 } 298 case ark::compiler::DataType::UINT64: { 299 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_LOAD_STATIC_WIDE); 300 break; 301 } 302 case ark::compiler::DataType::REFERENCE: { 303 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_LOAD_STATIC_OBJECT); 304 break; 305 } 306 default: 307 UNREACHABLE(); 308 } 309 inst->AddImm(GetGraph()->GetAllocator(), fieldId); 310 311 auto method = GetGraph()->GetMethod(); 312 inst->SetMethod(method); 313 AddInstruction(inst); 314 UpdateDefinitionAcc(inst); 315} 316 317void ark::compiler::AbcKitInstBuilder::BuildAbcKitStoreStaticIntrinsic(const BytecodeInstruction *bcInst, ark::compiler::DataType::Type rawType) 318{ 319 auto fieldId = GetRuntime()->ResolveFieldIndex(GetMethod(), bcInst->GetId(0).AsIndex()); 320 auto type = rawType; 321 if (rawType != ark::compiler::DataType::REFERENCE) { 322 type = GetRuntime()->GetFieldTypeById(GetMethod(), fieldId); 323 } 324 ark::compiler::IntrinsicInst *inst {nullptr}; 325 switch (rawType) { 326 case ark::compiler::DataType::UINT32: { 327 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_STORE_STATIC); 328 break; 329 } 330 case ark::compiler::DataType::UINT64: { 331 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_STORE_STATIC_WIDE); 332 break; 333 } 334 case ark::compiler::DataType::REFERENCE: { 335 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_STORE_STATIC_OBJECT); 336 break; 337 } 338 default: 339 UNREACHABLE(); 340 } 341 inst->AddImm(GetGraph()->GetAllocator(), fieldId); 342 inst->AllocateInputTypes(GetGraph()->GetAllocator(), 1); 343 inst->AppendInput(GetDefinitionAcc()); 344 inst->AddInputType(type); 345 346 auto method = GetGraph()->GetMethod(); 347 inst->SetMethod(method); 348 AddInstruction(inst); 349} 350 351void ark::compiler::AbcKitInstBuilder::BuildAbcKitLoadArrayIntrinsic(const BytecodeInstruction *bcInst, ark::compiler::DataType::Type type) 352{ 353 ark::compiler::IntrinsicInst *inst {nullptr}; 354 switch (type) { 355 case ark::compiler::DataType::UINT8: 356 case ark::compiler::DataType::INT8: 357 case ark::compiler::DataType::UINT16: 358 case ark::compiler::DataType::INT16: 359 case ark::compiler::DataType::UINT32: 360 case ark::compiler::DataType::INT32: 361 case ark::compiler::DataType::FLOAT32: { 362 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_LOAD_ARRAY); 363 break; 364 } 365 case ark::compiler::DataType::UINT64: 366 case ark::compiler::DataType::INT64: 367 case ark::compiler::DataType::FLOAT64: { 368 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_LOAD_ARRAY_WIDE); 369 break; 370 } 371 case ark::compiler::DataType::REFERENCE: { 372 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_LOAD_ARRAY_OBJECT); 373 break; 374 } 375 default: 376 UNREACHABLE(); 377 } 378 inst->AllocateInputTypes(GetGraph()->GetAllocator(), 2); 379 inst->AppendInput(GetDefinitionAcc()); 380 inst->AddInputType(ark::compiler::DataType::INT32); 381 inst->AppendInput(GetDefinition(bcInst->GetVReg(0))); 382 inst->AddInputType(ark::compiler::DataType::REFERENCE); 383 384 auto method = GetGraph()->GetMethod(); 385 inst->SetMethod(method); 386 AddInstruction(inst); 387 UpdateDefinitionAcc(inst); 388} 389 390void ark::compiler::AbcKitInstBuilder::BuildAbcKitStoreArrayIntrinsic(const BytecodeInstruction *bcInst, ark::compiler::DataType::Type type) 391{ 392 ark::compiler::IntrinsicInst *inst {nullptr}; 393 switch (type) { 394 case ark::compiler::DataType::UINT8: 395 case ark::compiler::DataType::INT8: 396 case ark::compiler::DataType::UINT16: 397 case ark::compiler::DataType::INT16: 398 case ark::compiler::DataType::UINT32: 399 case ark::compiler::DataType::INT32: 400 case ark::compiler::DataType::FLOAT32: { 401 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_STORE_ARRAY); 402 break; 403 } 404 case ark::compiler::DataType::UINT64: 405 case ark::compiler::DataType::INT64: 406 case ark::compiler::DataType::FLOAT64: { 407 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_STORE_ARRAY_WIDE); 408 break; 409 } 410 case ark::compiler::DataType::REFERENCE: { 411 inst = GetGraph()->CreateInstIntrinsic(type, GetPc(bcInst->GetAddress()), ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_STORE_ARRAY_OBJECT); 412 break; 413 } 414 default: 415 UNREACHABLE(); 416 } 417 inst->AllocateInputTypes(GetGraph()->GetAllocator(), 3); 418 inst->AppendInput(GetDefinitionAcc()); 419 inst->AddInputType(type); 420 inst->AppendInput(GetDefinition(bcInst->GetVReg(0))); 421 inst->AddInputType(ark::compiler::DataType::REFERENCE); 422 inst->AppendInput(GetDefinition(bcInst->GetVReg(1))); 423 inst->AddInputType(ark::compiler::DataType::INT32); 424 425 auto method = GetGraph()->GetMethod(); 426 inst->SetMethod(method); 427 AddInstruction(inst); 428} 429