1/*
2 * Copyright (c) 2022-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#include "ecmascript/compiler/assembler/x64/extended_assembler_x64.h"
17#include "ecmascript/deoptimizer/calleeReg.h"
18#include "ecmascript/frames.h"
19
20namespace panda::ecmascript::x64 {
21Register ExtendedAssembler::ghcJSCallDispacherArgs_[JS_CALL_DISPATCHER_ARGS_COUNT] = {
22    r13, rbp, r12, rbx, r14, rsi, rdi, r8, r9
23};
24Register ExtendedAssembler::cppJSCallDispacherArgs_[JS_CALL_DISPATCHER_ARGS_COUNT] = {
25    rdi, rbp, rsi, rdx, rcx, r8, r9, rInvalid, rInvalid
26};
27
28void ExtendedAssembler::PushAlignBytes()
29{
30    Subq(8, rsp);  // 8: 8 bytes
31}
32
33void ExtendedAssembler::PopAlignBytes()
34{
35    Addq(8, rsp);  // 8: 8 bytes
36}
37
38// c++ calling convention
39void ExtendedAssembler::PushCppCalleeSaveRegisters()
40{
41    Pushq(r12);
42    Pushq(r13);
43    Pushq(r14);
44    Pushq(r15);
45    Pushq(rbx);
46}
47
48void ExtendedAssembler::PopCppCalleeSaveRegisters()
49{
50    Popq(rbx);
51    Popq(r15);
52    Popq(r14);
53    Popq(r13);
54    Popq(r12);
55}
56
57void ExtendedAssembler::UpdateCalleeSaveRegisters()
58{
59    Addq(8 * 5, rsp);  // 8: 8 bytes, 5: number of CalleeSaveRegisters
60}
61
62void ExtendedAssembler::PushGhcCalleeSaveRegisters()
63{
64    Pushq(r10);
65    Pushq(r11);
66    Pushq(r12);
67    Pushq(r13);
68    Pushq(r15);
69}
70
71void ExtendedAssembler::PopGhcCalleeSaveRegisters()
72{
73    Popq(r15);
74    Popq(r13);
75    Popq(r12);
76    Popq(r11);
77    Popq(r10);
78}
79
80void ExtendedAssembler::CallAssemblerStub(int id, bool isTail)
81{
82    Label *target = module_->GetFunctionLabel(id);
83    isTail ? Jmp(target) : Callq(target);
84}
85
86void ExtendedAssembler::BindAssemblerStub(int id)
87{
88    Label *target = module_->GetFunctionLabel(id);
89    Bind(target);
90    auto callSigns = module_->GetCSigns();
91    auto cs = callSigns[id];
92    isGhcCallingConv_ = cs->GetCallConv() ==
93        kungfu::CallSignature::CallConv::GHCCallConv;
94}
95
96void ExtendedAssembler::PushArgc(int32_t argc, Register tempArgcRegister)
97{
98    Movabs(JSTaggedValue(argc).GetRawData(), tempArgcRegister);
99    Pushq(tempArgcRegister);
100}
101
102void ExtendedAssembler::PushArgc(Register argcRegister, Register tempArgcRegister)
103{
104    Movabs(JSTaggedValue::TAG_INT, tempArgcRegister);
105    Orq(argcRegister, tempArgcRegister);
106    Pushq(tempArgcRegister);
107}
108}  // panda::ecmascript::x64