1# Copyright (c) 2021-2022 Huawei Device Co., Ltd. 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# 6# http://www.apache.org/licenses/LICENSE-2.0 7# 8# Unless required by applicable law or agreed to in writing, software 9# distributed under the License is distributed on an "AS IS" BASIS, 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11# See the License for the specific language governing permissions and 12# limitations under the License. 13 14templates: 15 binop: |- 16 % regex_arithm = /(fdiv|fmod|add|sub|mul|and|or|xor|ashr|shr|shl|neg|not)[2i]?/ 17 % opc = inst.stripped_mnemonic.match regex_arithm 18 % raise "Wrong binop instruction" unless opc 19 % opc = opc[1].capitalize.gsub('Ashr', 'AShr').gsub('Fdiv', 'Div').gsub('Fmod', 'Mod') 20 auto inst = graph_->CreateInst<%= opc %>(<%= get_type(inst.dtype) %>, GetPc(instruction->GetAddress())); 21 <%=template('operands', inst, '')-%> 22 AddInstruction(inst); 23 binop_z: |- 24 % opc = inst.stripped_mnemonic =~ /div/ ? 'Div' : 'Mod' 25 auto inst_save_state = CreateSaveState(Opcode::SaveState, GetPc(instruction->GetAddress())); 26 auto inst_check = graph_->CreateInstZeroCheck(<%= get_type(inst.dtype) %>, GetPc(instruction->GetAddress())); 27 % if inst.acc_and_operands.last.imm? 28 if (graph_->IsBytecodeOptimizer()) { 29 inst_check->SetInput(0, FindOrCreate32BitConstant(instruction->GetImm<<%= inst.get_format %>, 0>())); 30 } else { 31 inst_check->SetInput(0, <%= inst.get_input_string(1) %>); 32 } 33 % else 34 inst_check->SetInput(0, <%= inst.get_input_string(1) %>); 35 % end 36 inst_check->SetInput(1, inst_save_state); 37 auto inst = graph_->CreateInst<%= opc %>(<%= get_type(inst.dtype) %>, GetPc(instruction->GetAddress())); 38 inst->SetInput(0, <%= inst.get_input_string(0) %>); 39 inst->SetInput(1, inst_check); 40 UpdateDefinitionAcc(inst); 41 AddInstruction(inst_save_state); 42 AddInstruction(inst_check); 43 AddInstruction(inst); 44 inci: |- 45 auto inst = graph_->CreateInstAdd(<%= get_type(inst.dtype) %>, GetPc(instruction->GetAddress())); 46 inst->SetInput(0, GetDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>())); 47 if (graph_->IsBytecodeOptimizer()) { 48 inst->SetInput(1, FindOrCreate32BitConstant(instruction->GetImm<<%=inst.get_format%>, 0>())); 49 } else { 50 inst->SetInput(1, FindOrCreateConstant(instruction->GetImm<<%=inst.get_format%>, 0>())); 51 } 52 AddInstruction(inst); 53 UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), inst); 54 cast: |- 55 auto inst = graph_->CreateInstCast(<%= get_type(inst.dtype) %>, GetPc(instruction->GetAddress())); 56 auto input = GetDefinitionAcc(); 57 inst->SetInput(0, input); 58 inst->SetOperandsType(<%= get_type(inst.type(0)) %>); 59 if (!input->HasType()) { 60 input->SetType(<%= get_type(inst.type(0)) %>); 61 } 62 UpdateDefinitionAcc(inst); 63 AddInstruction(inst); 64 cmp: |- 65 % if inst.mnemonic.include? "obj" 66 auto inst = graph_->CreateInstCompare(DataType::BOOL, GetPc(instruction->GetAddress()), ConditionCode::CC_NE); 67 % else 68 auto inst = graph_->CreateInstCmp(<%= get_type(inst.dtype) %>, GetPc(instruction->GetAddress())); 69 % end 70 inst->SetInput(0, GetDefinitionAcc()); 71 inst->SetInput(1, GetDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>())); 72 inst->SetOperandsType(<%= get_type(inst.type(0)) %>); 73 % if inst.stripped_mnemonic.start_with? 'fcmp' 74 inst->Set<%= inst.opcode =~ /^fcmpg/ ? 'Fcmpg' : 'Fcmpl' %>(); 75 % end 76 AddInstruction(inst); 77 UpdateDefinitionAcc(inst); 78 if: |- 79 auto inst = graph_->CreateInstCompare(DataType::BOOL, GetPc(instruction->GetAddress()), <%= get_cc(inst) %>); 80 inst->SetOperandsType(<%= get_type(inst.type(0)) %>); 81 % if inst.acc_and_operands.size > 2 82 inst->SetInput(1, GetDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>())); 83 % else 84 inst->SetInput(1, FindOrCreateConstant(0)); 85 % end 86 inst->SetInput(0, GetDefinitionAcc()); 87 auto inst_jump = graph_->CreateInstIfImm(DataType::NO_TYPE, GetPc(instruction->GetAddress()), ConditionCode::CC_NE, 0); 88 inst_jump->SetOperandsType(DataType::BOOL); 89 inst_jump->SetInput(0, inst); 90 inst_jump->SetMethod(graph_->GetMethod()); 91 AddInstruction(inst); 92 AddInstruction(inst_jump); 93 jump: |- 94 mov: |- 95 % if inst.acc_and_operands[1].imm? 96 % if inst.mnemonic == "movi" 97 if (graph_->IsBytecodeOptimizer()) { 98 UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), FindOrCreate32BitConstant(instruction->GetImm<<%=inst.get_format%>, 0>())); 99 } else { 100 UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), FindOrCreateConstant(instruction->GetImm<<%=inst.get_format%>, 0>())); 101 } 102 % else 103 UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), FindOrCreateConstant(instruction->GetImm<<%=inst.get_format%>, 0>())); 104 % end 105 % else 106 % raise "Unsupported instruction type" unless inst.acc_and_operands[1].reg? 107 UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), GetDefinition(instruction->GetVReg<<%=inst.get_format%>, 1>())); 108 % end 109 fmovi: |- 110 % if inst.mnemonic == "fmovi" 111 auto imm = bit_cast<float>(instruction->GetImm<<%=inst.get_format%>, 0>()); 112 UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), FindOrCreateFloatConstant(imm)); 113 % else 114 auto imm = bit_cast<double>(instruction->GetImm<<%=inst.get_format%>, 0>()); 115 UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), FindOrCreateDoubleConstant(imm)); 116 % end 117 sta: |- 118 UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), GetDefinitionAcc()); 119 % if inst.properties.include? "dynamic" 120 if (GetGraph()->IsBytecodeOptimizer() && GetGraph()->IsDynamicMethod()) { 121 TryFillInstIdTypePair(GetDefinitionAcc()->GetId(), static_cast<int>(GetPc(instruction->GetAddress()))); 122 } 123 % end 124 lda: |- 125 % if inst.acc_and_operands[1].imm? 126 % if inst.mnemonic == "ldai" 127 if (graph_->IsBytecodeOptimizer()) { 128 UpdateDefinitionAcc(FindOrCreate32BitConstant(instruction->GetImm<<%=inst.get_format%>, 0>())); 129 } else { 130 UpdateDefinitionAcc(FindOrCreateConstant(instruction->GetImm<<%=inst.get_format%>, 0>())); 131 } 132 % else 133 UpdateDefinitionAcc(FindOrCreateConstant(instruction->GetImm<<%=inst.get_format%>, 0>())); 134 % if inst.properties.include? "dynamic" 135 if (GetGraph()->IsBytecodeOptimizer() && GetGraph()->IsDynamicMethod()) { 136 TryFillInstIdTypePair(GetDefinitionAcc()->GetId(), static_cast<int>(GetPc(instruction->GetAddress()))); 137 } 138 BuildCastToAnyNumber(instruction); 139 % end 140 % end 141 % elsif inst.acc_and_operands[1].id? 142 BuildLoadFromPool<Opcode::<%= inst.opcode =~ /lda_type/ ? 'LoadType' : 'LoadString' %>>(instruction); 143 % if inst.opcode =~ /lda_str/ 144 if (GetGraph()->IsBytecodeOptimizer() && GetGraph()->IsDynamicMethod()) { 145 TryFillInstIdTypePair(GetDefinitionAcc()->GetId(), static_cast<int>(GetPc(instruction->GetAddress()))); 146 } 147 % end 148 % else 149 % raise "Unsupported instruction type" unless inst.acc_and_operands[1].reg? 150 UpdateDefinitionAcc(GetDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>())); 151 % end 152 fldai: |- 153 auto imm = bit_cast<double>(instruction->GetImm<<%=inst.get_format%>, 0>()); 154 UpdateDefinitionAcc(FindOrCreateDoubleConstant(imm)); 155 % if inst.properties.include? "dynamic" 156 if (GetGraph()->IsBytecodeOptimizer() && GetGraph()->IsDynamicMethod()) { 157 TryFillInstIdTypePair(GetDefinitionAcc()->GetId(), static_cast<int>(GetPc(instruction->GetAddress()))); 158 } 159 BuildCastToAnyNumber(instruction); 160 % end 161 operands: |- 162 % inst.inputs.each_with_index do |op, idx| 163 % if op.imm? 164 if (graph_->IsBytecodeOptimizer()) { 165 inst->SetInput(<%= idx %>, FindOrCreate32BitConstant(instruction->GetImm<<%= inst.get_format %>, 0>())); 166 } else { 167 inst->SetInput(<%= idx %>, <%= inst.get_input_string(idx) %>); 168 } 169 % else 170 inst->SetInput(<%= idx %>, <%= inst.get_input_string(idx) %>); 171 % end 172 % end 173 % if inst.has_dst? 174 % if inst.acc_and_operands.first.acc? 175 UpdateDefinitionAcc(inst); 176 % else 177 UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), inst); 178 % end 179 % end 180 return: |- 181 % opcode = inst.opcode.include?('void') ? 'ReturnVoid' : 'Return' 182 auto inst = graph_->CreateInst<%= opcode %>(GetCurrentMethodReturnType(), GetPc(instruction->GetAddress())); 183 <%=template('operands', inst, '')-%> 184 AddInstruction(inst); 185 ecma: |- 186 % name = inst.opcode.upcase.split('')[1] 187 % case name 188 % when "RETURNUNDEFINED" 189 auto cvat_input = FindOrCreateConstant(0); 190 cvat_input->SetType(DataType::Type::INT64); 191 auto cvat = graph->CreateInstCastValueToAnyType(0); 192 cvat->SetAnyType(panda::compiler::AnyBaseType::ECMASCRIPT_UNDEFINED_TYPE); 193 cvat->SetInput(0, cvat_input); 194 auto inst = graph_->CreateInstReturn(DataType::ANY, GetPc(instruction->GetAddress())); 195 inst->SetInput(0, cvat); 196 AddInstruction(cvat); 197 AddInstruction(inst); 198 % when "RETURN" 199 auto inst = graph_->CreateInstReturn(DataType::ANY, GetPc(instruction->GetAddress())); 200 inst->SetInput(0, GetDefinitionAcc()); 201 AddInstruction(inst); 202 % when "JFALSE", "JTRUE" 203 % cmp_imm = name == "JFALSE" ? 0 : 1 204 auto cvat_input = FindOrCreateConstant(<%= cmp_imm %>); 205 cvat_input->SetType(DataType::INT64); 206 auto cvat = graph_->CreateInstCastValueToAnyType(0); 207 cvat->SetAnyType(panda::compiler::AnyBaseType::ECMASCRIPT_BOOLEAN_TYPE); 208 cvat->SetInput(0, cvat_input); 209 auto cmp_inst = graph_->CreateInstCompare(DataType::BOOL, GetPc(instruction->GetAddress()), ConditionCode::CC_EQ); 210 cmp_inst->SetOperandsType(DataType::ANY); 211 cmp_inst->SetInput(0, GetDefinitionAcc()); 212 cmp_inst->SetInput(1, cvat); 213 auto jmp_inst = graph_->CreateInstIfImm(DataType::NO_TYPE, GetPc(instruction->GetAddress()), ConditionCode::CC_NE, 0); 214 jmp_inst->SetOperandsType(DataType::BOOL); 215 jmp_inst->SetInput(0, cmp_inst); 216 AddInstruction(cvat); 217 AddInstruction(cmp_inst); 218 AddInstruction(jmp_inst); 219 % else 220 BuildEcma(instruction); 221 auto pc = static_cast<int>(GetPc(instruction->GetAddress())); 222 if (GetGraph()->IsBytecodeOptimizer() && GetGraph()->IsDynamicMethod() && GetGraph()->GetRuntime()->IsPcBindType(pc)) { 223 TryFillInstIdTypePair(GetDefinitionAcc()->GetId(), pc); 224 } 225 % end 226 nop: |- 227 unimplemented: |- 228 // TODO(msherstennikov): implement 229