• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * Copyright (c) 2021-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
16static ark::compiler::CallInst *CastToCallLaunch(ark::compiler::Inst *inst)
17{
18    switch (inst->GetOpcode()) {
19        case compiler::Opcode::CallLaunchStatic:
20            return inst->CastToCallLaunchStatic();
21        case compiler::Opcode::CallLaunchVirtual:
22            return inst->CastToCallLaunchVirtual();
23        default:
24            UNREACHABLE();
25    }
26}
27
28static ark::pandasm::Opcode ChooseCallLaunchOpcode(ark::compiler::Opcode op, size_t nargs)
29{
30    ASSERT(op == compiler::Opcode::CallLaunchStatic || op == compiler::Opcode::CallLaunchVirtual);
31    if (nargs > MAX_NUM_NON_RANGE_ARGS) {
32        switch (op) {
33            case compiler::Opcode::CallLaunchStatic:
34                return pandasm::Opcode::ETS_LAUNCH_RANGE;
35            case compiler::Opcode::CallLaunchVirtual:
36                return pandasm::Opcode::ETS_LAUNCH_VIRT_RANGE;
37            default:
38                UNREACHABLE();
39        }
40    } else if (nargs > MAX_NUM_SHORT_CALL_ARGS) {
41        switch (op) {
42            case compiler::Opcode::CallLaunchStatic:
43                return pandasm::Opcode::ETS_LAUNCH;
44            case compiler::Opcode::CallLaunchVirtual:
45                return pandasm::Opcode::ETS_LAUNCH_VIRT;
46            default:
47                UNREACHABLE();
48        }
49    }
50    switch (op) {
51        case compiler::Opcode::CallLaunchStatic:
52            return pandasm::Opcode::ETS_LAUNCH_SHORT;
53        case compiler::Opcode::CallLaunchVirtual:
54            return pandasm::Opcode::ETS_LAUNCH_VIRT_SHORT;
55        default:
56            UNREACHABLE();
57    }
58}
59
60static void CallLaunchHandler(ark::compiler::GraphVisitor *visitor, ark::compiler::Inst *inst)
61{
62    auto op = inst->GetOpcode();
63    ASSERT(op == ark::compiler::Opcode::CallLaunchStatic || op == ark::compiler::Opcode::CallLaunchVirtual);
64    auto *enc = static_cast<BytecodeGen *>(visitor);
65    auto callInst = CastToCallLaunch(inst);
66    auto sfCount = inst->GetInputsCount() - (inst->RequireState() ? 1 : 0);
67    size_t start = 1;
68    auto nargs = sfCount - start;
69    pandasm::Ins ins;
70    ins.opcode = ChooseCallLaunchOpcode(op, nargs);
71
72    auto zeroArg = inst->GetInput(0).GetInst();
73    ASSERT(zeroArg->GetOpcode() == Opcode::NewObject);
74    auto newobjInst = zeroArg->CastToNewObject();
75
76    if (nargs > MAX_NUM_NON_RANGE_ARGS) {
77#ifndef NDEBUG
78        auto startReg = inst->GetSrcReg(start);
79        ASSERT(startReg <= MAX_8_BIT_REG);
80        for (size_t i = start; i < sfCount; ++i) {
81            auto reg = inst->GetSrcReg(i);
82            ASSERT(reg - startReg == static_cast<int>(i - start));  // check 'range-ness' of registers
83        }
84#endif  // !NDEBUG
85        ins.regs.emplace_back(inst->GetSrcReg(start));
86    } else {
87        for (size_t i = start; i < sfCount; ++i) {
88            auto reg = inst->GetSrcReg(i);
89            ASSERT(reg < NUM_COMPACTLY_ENCODED_REGS);
90            ins.regs.emplace_back(reg);
91        }
92    }
93    ins.ids.emplace_back(enc->irInterface_->GetMethodIdByOffset(callInst->GetCallMethodId()));
94    enc->result_.emplace_back(ins);
95    if (newobjInst->GetDstReg() != compiler::GetAccReg()) {
96        enc->result_.emplace_back(pandasm::Create_STA_OBJ(newobjInst->GetDstReg()));
97    }
98}
99
100static void VisitCallLaunchStatic(ark::compiler::GraphVisitor *visitor, ark::compiler::Inst *inst)
101{
102    CallLaunchHandler(visitor, inst);
103}
104
105static void VisitCallLaunchVirtual(GraphVisitor *visitor, Inst *inst)
106{
107    CallLaunchHandler(visitor, inst);
108}
109
110static void VisitEtsLdObjByName(BytecodeGen *enc, compiler::IntrinsicInst *inst)
111{
112    auto v0 = inst->GetSrcReg(0);
113    auto bcId0 = enc->irInterface_->GetFieldIdByOffset(static_cast<uint32_t>(inst->GetImms()[0]));
114    switch (inst->GetIntrinsicId()) {
115        case compiler::RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_LD_OBJ_BY_NAME_I32:
116        case compiler::RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_LD_OBJ_BY_NAME_F32:
117            enc->result_.emplace_back(pandasm::Create_ETS_LDOBJ_NAME(v0, bcId0));
118            DoSta(inst->GetDstReg(), enc->result_);
119            break;
120        case compiler::RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_LD_OBJ_BY_NAME_I64:
121        case compiler::RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_LD_OBJ_BY_NAME_F64:
122            enc->result_.emplace_back(pandasm::Create_ETS_LDOBJ_NAME_64(v0, bcId0));
123            DoSta64(inst->GetDstReg(), enc->result_);
124            break;
125        case compiler::RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_LD_OBJ_BY_NAME_OBJ:
126            enc->result_.emplace_back(pandasm::Create_ETS_LDOBJ_NAME_OBJ(v0, bcId0));
127            DoStaObj(inst->GetDstReg(), enc->result_);
128            break;
129        default:
130            UNREACHABLE();
131    }
132}
133
134static void VisitEtsStObjByName(BytecodeGen *enc, compiler::IntrinsicInst *inst)
135{
136    auto v0 = inst->GetSrcReg(0);
137    auto bcId0 = enc->irInterface_->GetFieldIdByOffset(static_cast<uint32_t>(inst->GetImms()[0]));
138    switch (inst->GetIntrinsicId()) {
139        case compiler::RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_ST_OBJ_BY_NAME_I32:
140        case compiler::RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_ST_OBJ_BY_NAME_I16:
141        case compiler::RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_ST_OBJ_BY_NAME_I8:
142        case compiler::RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_ST_OBJ_BY_NAME_F32:
143            DoLda(inst->GetSrcReg(1U), enc->result_);
144            enc->result_.emplace_back(pandasm::Create_ETS_STOBJ_NAME(v0, bcId0));
145            break;
146        case compiler::RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_ST_OBJ_BY_NAME_I64:
147        case compiler::RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_ST_OBJ_BY_NAME_F64:
148            DoLda64(inst->GetSrcReg(1U), enc->result_);
149            enc->result_.emplace_back(pandasm::Create_ETS_STOBJ_NAME_64(v0, bcId0));
150            break;
151        case compiler::RuntimeInterface::IntrinsicId::INTRINSIC_COMPILER_ETS_ST_OBJ_BY_NAME_OBJ:
152            DoLdaObj(inst->GetSrcReg(1U), enc->result_);
153            enc->result_.emplace_back(pandasm::Create_ETS_STOBJ_NAME_OBJ(v0, bcId0));
154            break;
155        default:
156            UNREACHABLE();
157    }
158}
159
160static void VisitLoadUndefined(GraphVisitor *visitor, Inst *inst)
161{
162    auto *enc = static_cast<BytecodeGen *>(visitor);
163    if (inst->GetDstReg() == compiler::GetAccReg()) {
164        enc->result_.emplace_back(pandasm::Create_ETS_LDUNDEFINED());
165    } else {
166        enc->result_.emplace_back(pandasm::Create_ETS_MOVUNDEFINED(inst->GetDstReg()));
167    }
168}
169
170static void VisitEtsEquals(GraphVisitor *visitor, Inst *inst)
171{
172    auto *enc = static_cast<BytecodeGen *>(visitor);
173    auto v0 = inst->GetSrcReg(0);
174    auto v1 = inst->GetSrcReg(1);
175    enc->result_.emplace_back(pandasm::Create_ETS_EQUALS(v0, v1));
176    DoSta(inst->GetDstReg(), enc->result_);
177}
178