• 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  lda: |-
120    % if inst.acc_and_operands[1].imm?
121    %   if inst.mnemonic == "ldai"
122    if (graph_->IsBytecodeOptimizer()) {
123        UpdateDefinitionAcc(FindOrCreate32BitConstant(instruction->GetImm<<%=inst.get_format%>, 0>()));
124    } else {
125        UpdateDefinitionAcc(FindOrCreateConstant(instruction->GetImm<<%=inst.get_format%>, 0>()));
126    }
127    %   else
128    UpdateDefinitionAcc(FindOrCreateConstant(instruction->GetImm<<%=inst.get_format%>, 0>()));
129    %     if inst.properties.include? "dynamic"
130    BuildCastToAnyNumber(instruction);
131    %     end
132    %   end
133    % elsif inst.acc_and_operands[1].id?
134    BuildLoadFromPool<Opcode::<%= inst.opcode =~ /lda_type/ ? 'LoadType' : 'LoadString' %>>(instruction);
135    % else
136    % raise "Unsupported instruction type" unless inst.acc_and_operands[1].reg?
137    UpdateDefinitionAcc(GetDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>()));
138    % end
139  fldai: |-
140    auto imm = bit_cast<double>(instruction->GetImm<<%=inst.get_format%>, 0>());
141    UpdateDefinitionAcc(FindOrCreateDoubleConstant(imm));
142    % if inst.properties.include? "dynamic"
143    BuildCastToAnyNumber(instruction);
144    % end
145  operands: |-
146    % inst.inputs.each_with_index do |op, idx|
147    %   if op.imm?
148    if (graph_->IsBytecodeOptimizer()) {
149        inst->SetInput(<%= idx %>, FindOrCreate32BitConstant(instruction->GetImm<<%= inst.get_format %>, 0>()));
150    } else {
151        inst->SetInput(<%= idx %>, <%= inst.get_input_string(idx) %>);
152    }
153    %   else
154    inst->SetInput(<%= idx %>, <%= inst.get_input_string(idx) %>);
155    %   end
156    % end
157    % if inst.has_dst?
158    %   if inst.acc_and_operands.first.acc?
159    UpdateDefinitionAcc(inst);
160    %   else
161    UpdateDefinition(instruction->GetVReg<<%=inst.get_format%>, 0>(), inst);
162    %   end
163    % end
164  return: |-
165    % opcode = inst.opcode.include?('void') ? 'ReturnVoid' : 'Return'
166    auto inst = graph_->CreateInst<%= opcode %>(GetCurrentMethodReturnType(), GetPc(instruction->GetAddress()));
167    <%=template('operands', inst, '')-%>
168    AddInstruction(inst);
169  ecma: |-
170    % name = inst.opcode.upcase.split('')[1]
171    % case name
172    % when "RETURNUNDEFINED"
173    auto cvat_input = FindOrCreateConstant(0);
174    cvat_input->SetType(DataType::Type::INT64);
175    auto cvat = graph->CreateInstCastValueToAnyType(0);
176    cvat->SetAnyType(panda::compiler::AnyBaseType::ECMASCRIPT_UNDEFINED_TYPE);
177    cvat->SetInput(0, cvat_input);
178    auto inst = graph_->CreateInstReturn(DataType::ANY, GetPc(instruction->GetAddress()));
179    inst->SetInput(0, cvat);
180    AddInstruction(cvat);
181    AddInstruction(inst);
182    % when "RETURN"
183    auto inst = graph_->CreateInstReturn(DataType::ANY, GetPc(instruction->GetAddress()));
184    inst->SetInput(0, GetDefinitionAcc());
185    AddInstruction(inst);
186    % when "JFALSE", "JTRUE"
187    % cmp_imm = name == "JFALSE" ? 0 : 1
188    auto cvat_input = FindOrCreateConstant(<%= cmp_imm %>);
189    cvat_input->SetType(DataType::INT64);
190    auto cvat = graph_->CreateInstCastValueToAnyType(0);
191    cvat->SetAnyType(panda::compiler::AnyBaseType::ECMASCRIPT_BOOLEAN_TYPE);
192    cvat->SetInput(0, cvat_input);
193    auto cmp_inst = graph_->CreateInstCompare(DataType::BOOL, GetPc(instruction->GetAddress()), ConditionCode::CC_EQ);
194    cmp_inst->SetOperandsType(DataType::ANY);
195    cmp_inst->SetInput(0, GetDefinitionAcc());
196    cmp_inst->SetInput(1, cvat);
197    auto jmp_inst = graph_->CreateInstIfImm(DataType::NO_TYPE, GetPc(instruction->GetAddress()), ConditionCode::CC_NE, 0);
198    jmp_inst->SetOperandsType(DataType::BOOL);
199    jmp_inst->SetInput(0, cmp_inst);
200    AddInstruction(cvat);
201    AddInstruction(cmp_inst);
202    AddInstruction(jmp_inst);
203    % else
204    BuildEcma(instruction);
205    % end
206  nop: |-
207  unimplemented: |-
208    // TODO(msherstennikov): implement
209