• 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.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