1/*
2 * Copyright (c) 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
16#ifndef ECMASCRIPT_COMPILER_ASSEMBLER_AARCH64_MACRO_ASSEMBLER_AARCH64_H
17#define ECMASCRIPT_COMPILER_ASSEMBLER_AARCH64_MACRO_ASSEMBLER_AARCH64_H
18
19#include "ecmascript/compiler/assembler/macro_assembler.h"
20#include "ecmascript/compiler/assembler/aarch64/assembler_aarch64.h"
21
22namespace panda::ecmascript::kungfu {
23class MacroAssemblerAArch64 : public MacroAssembler {
24public:
25    MacroAssemblerAArch64() : MacroAssembler(), assembler(&chunk) {}
26    ~MacroAssemblerAArch64() = default;
27    uint8_t *GetBegin() const override
28    {
29        return assembler.GetBegin();
30    }
31
32    size_t GetBufferCurrentSize() const override
33    {
34        return assembler.GetCurrentPosition();
35    }
36
37    void SetBaselineFlag()
38    {
39        assembler.SetDoCodeSign();
40    }
41
42    void Move(const StackSlotOperand &dstStackSlot, Immediate value) override;
43    void Move(const StackSlotOperand &dstStackSlot, const StackSlotOperand &srcStackSlot) override;
44    void Cmp(const StackSlotOperand &stackSlot, Immediate value) override;
45    void Bind(JumpLabel &label) override;
46    void Jz(JumpLabel &label) override;
47    void Jnz(JumpLabel &label) override;
48    void Jump(JumpLabel &label) override;
49    void SaveReturnRegister(const StackSlotOperand &dstStackSlot) override;
50    void CallBuiltin(Address funcAddress,
51                     const std::vector<MacroParameter> &parameters) override;
52
53private:
54    aarch64::AssemblerAarch64 assembler;
55    const uint32_t PARAM_REGISTER_COUNT = 8;
56    const std::vector<aarch64::Register> registerParamVec {
57        aarch64::Register(aarch64::X0), aarch64::Register(aarch64::X1), aarch64::Register(aarch64::X2),
58        aarch64::Register(aarch64::X3), aarch64::Register(aarch64::X4), aarch64::Register(aarch64::X5),
59        aarch64::Register(aarch64::X6), aarch64::Register(aarch64::X7) };
60    const aarch64::Register GLUE_REGISTER = aarch64::Register(aarch64::X19);   // same with ghc callconv
61    const aarch64::Register LOCAL_SCOPE_REGISTER = aarch64::Register(aarch64::X11);
62    const aarch64::Register RETURN_REGISTER = aarch64::Register(aarch64::X0);
63    void MovParameterIntoParamReg(MacroParameter param, aarch64::Register paramReg);
64    void PickLoadStoreInsn(aarch64::Register reg, aarch64::MemoryOperand memOpnd, bool isLoad = true);
65    bool IsMoveWidableImmediate(uint64_t val, uint32_t bitLen);
66    bool IsBitmaskImmediate(uint64_t val, uint32_t bitLen);
67    bool BetterUseMOVZ(uint64_t val);
68    bool IsSingleInstructionMovable(uint64_t imm, uint32_t size);
69    void CopyImm(aarch64::Register destReg, int64_t imm, uint32_t size);
70    void CopyImmSize64(aarch64::Register destReg, uint64_t srcVal);
71};
72}  // namespace panda::ecmascript::kungfu
73#endif  // ECMASCRIPT_COMPILER_ASSEMBLER_AARCH64_MACRO_ASSEMBLER_AARCH64_H
74