• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.mnemonic.include? "null"
96    UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), graph_->GetOrCreateNullPtr());
97    % elsif inst.acc_and_operands[1].imm?
98    %   if inst.mnemonic == "movi"
99    if (graph_->IsBytecodeOptimizer()) {
100        UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), FindOrCreate32BitConstant(instruction->GetImm<<%=inst.get_format%>, 0>()));
101    } else {
102        UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), FindOrCreateConstant(instruction->GetImm<<%=inst.get_format%>, 0>()));
103    }
104    %   else
105    UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), FindOrCreateConstant(instruction->GetImm<<%=inst.get_format%>, 0>()));
106    %   end
107    % else
108    % raise "Unsupported instruction type" unless inst.acc_and_operands[1].reg?
109    UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), GetDefinition(instruction->GetVReg<<%=inst.get_format%>, 1>()));
110    % end
111  fmovi: |-
112    % if inst.mnemonic == "fmovi"
113    auto imm = bit_cast<float>(instruction->GetImm<<%=inst.get_format%>, 0>());
114    UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), FindOrCreateFloatConstant(imm));
115    % else
116    auto imm = bit_cast<double>(instruction->GetImm<<%=inst.get_format%>, 0>());
117    UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), FindOrCreateDoubleConstant(imm));
118    % end
119  sta: |-
120    UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), GetDefinitionAcc());
121    % if inst.properties.include? "dynamic"
122    if (GetGraph()->IsBytecodeOptimizer() && GetGraph()->IsDynamicMethod()) {
123        TryFillInstIdTypePair(GetDefinitionAcc()->GetId(), static_cast<int>(GetPc(instruction->GetAddress())));
124    }
125    % end
126  lda: |-
127    % if inst.mnemonic.include? "null"
128    UpdateDefinitionAcc(graph_->GetOrCreateNullPtr());
129    % elsif inst.acc_and_operands[1].imm?
130    %   if inst.mnemonic == "ldai"
131    if (graph_->IsBytecodeOptimizer()) {
132        UpdateDefinitionAcc(FindOrCreate32BitConstant(instruction->GetImm<<%=inst.get_format%>, 0>()));
133    } else {
134        UpdateDefinitionAcc(FindOrCreateConstant(instruction->GetImm<<%=inst.get_format%>, 0>()));
135    }
136    %   else
137    UpdateDefinitionAcc(FindOrCreateConstant(instruction->GetImm<<%=inst.get_format%>, 0>()));
138    %     if inst.properties.include? "dynamic"
139    if (GetGraph()->IsBytecodeOptimizer() && GetGraph()->IsDynamicMethod()) {
140        TryFillInstIdTypePair(GetDefinitionAcc()->GetId(), static_cast<int>(GetPc(instruction->GetAddress())));
141    }
142    BuildCastToAnyNumber(instruction);
143    %     end
144    %   end
145    % elsif inst.acc_and_operands[1].id?
146    BuildLoadFromPool<Opcode::<%= inst.opcode =~ /lda_type/ ? 'LoadType' : 'LoadString' %>>(instruction);
147    %       if inst.opcode =~ /lda_str/
148    if (GetGraph()->IsBytecodeOptimizer() && GetGraph()->IsDynamicMethod()) {
149        TryFillInstIdTypePair(GetDefinitionAcc()->GetId(), static_cast<int>(GetPc(instruction->GetAddress())));
150    }
151    %       end
152    % else
153    % raise "Unsupported instruction type" unless inst.acc_and_operands[1].reg?
154    UpdateDefinitionAcc(GetDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>()));
155    % end
156  fldai: |-
157    auto imm = bit_cast<double>(instruction->GetImm<<%=inst.get_format%>, 0>());
158    UpdateDefinitionAcc(FindOrCreateDoubleConstant(imm));
159    % if inst.properties.include? "dynamic"
160    if (GetGraph()->IsBytecodeOptimizer() && GetGraph()->IsDynamicMethod()) {
161        TryFillInstIdTypePair(GetDefinitionAcc()->GetId(), static_cast<int>(GetPc(instruction->GetAddress())));
162    }
163    BuildCastToAnyNumber(instruction);
164    % end
165  operands: |-
166    % inst.inputs.each_with_index do |op, idx|
167    %   if op.imm?
168    if (graph_->IsBytecodeOptimizer()) {
169        inst->SetInput(<%= idx %>, FindOrCreate32BitConstant(instruction->GetImm<<%= inst.get_format %>, 0>()));
170    } else {
171        inst->SetInput(<%= idx %>, <%= inst.get_input_string(idx) %>);
172    }
173    %   else
174    inst->SetInput(<%= idx %>, <%= inst.get_input_string(idx) %>);
175    %   end
176    % end
177    % if inst.has_dst?
178    %   if inst.acc_and_operands.first.acc?
179    UpdateDefinitionAcc(inst);
180    %   else
181    UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), inst);
182    %   end
183    % end
184  return: |-
185    % opcode = inst.opcode.include?('void') ? 'ReturnVoid' : 'Return'
186    auto inst = graph_->CreateInst<%= opcode %>(GetCurrentMethodReturnType(), GetPc(instruction->GetAddress()));
187    <%=template('operands', inst, '')-%>
188    AddInstruction(inst);
189  ecma: |-
190    % name = inst.opcode.upcase.split('')[1]
191    % case name
192    % when "RETURNUNDEFINED"
193    auto cvat_input = FindOrCreateConstant(0);
194    cvat_input->SetType(DataType::Type::INT64);
195    auto cvat = graph->CreateInstCastValueToAnyType(0);
196    cvat->SetAnyType(panda::compiler::AnyBaseType::ECMASCRIPT_UNDEFINED_TYPE);
197    cvat->SetInput(0, cvat_input);
198    auto inst = graph_->CreateInstReturn(DataType::ANY, GetPc(instruction->GetAddress()));
199    inst->SetInput(0, cvat);
200    AddInstruction(cvat);
201    AddInstruction(inst);
202    % when "RETURN"
203    auto inst = graph_->CreateInstReturn(DataType::ANY, GetPc(instruction->GetAddress()));
204    inst->SetInput(0, GetDefinitionAcc());
205    AddInstruction(inst);
206    % when "JFALSE", "JTRUE"
207    % cmp_imm = name == "JFALSE" ? 0 : 1
208    auto cvat_input = FindOrCreateConstant(<%= cmp_imm %>);
209    cvat_input->SetType(DataType::INT64);
210    auto cvat = graph_->CreateInstCastValueToAnyType(0);
211    cvat->SetAnyType(panda::compiler::AnyBaseType::ECMASCRIPT_BOOLEAN_TYPE);
212    cvat->SetInput(0, cvat_input);
213    auto cmp_inst = graph_->CreateInstCompare(DataType::BOOL, GetPc(instruction->GetAddress()), ConditionCode::CC_EQ);
214    cmp_inst->SetOperandsType(DataType::ANY);
215    cmp_inst->SetInput(0, GetDefinitionAcc());
216    cmp_inst->SetInput(1, cvat);
217    auto jmp_inst = graph_->CreateInstIfImm(DataType::NO_TYPE, GetPc(instruction->GetAddress()), ConditionCode::CC_NE, 0);
218    jmp_inst->SetOperandsType(DataType::BOOL);
219    jmp_inst->SetInput(0, cmp_inst);
220    AddInstruction(cvat);
221    AddInstruction(cmp_inst);
222    AddInstruction(jmp_inst);
223    % else
224    BuildEcma(instruction);
225    auto pc = static_cast<int>(GetPc(instruction->GetAddress()));
226    if (GetGraph()->IsBytecodeOptimizer() && GetGraph()->IsDynamicMethod() && GetGraph()->GetRuntime()->IsPcBindType(pc)) {
227        TryFillInstIdTypePair(GetDefinitionAcc()->GetId(), pc);
228    }
229    % end
230  nop: |-
231  unimplemented: |-
232    // TODO(msherstennikov): implement
233