1 /* This file is part of the dynarmic project.
2  * Copyright (c) 2016 MerryMage
3  * SPDX-License-Identifier: 0BSD
4  */
5 #pragma once
6 
7 #include <array>
8 
9 #include "backend/x64/hostloc.h"
10 
11 namespace Dynarmic::Backend::X64 {
12 
13 class BlockOfCode;
14 
15 #ifdef _WIN32
16 
17 constexpr HostLoc ABI_RETURN = HostLoc::RAX;
18 
19 constexpr HostLoc ABI_PARAM1 = HostLoc::RCX;
20 constexpr HostLoc ABI_PARAM2 = HostLoc::RDX;
21 constexpr HostLoc ABI_PARAM3 = HostLoc::R8;
22 constexpr HostLoc ABI_PARAM4 = HostLoc::R9;
23 
24 constexpr std::array<HostLoc, 13> ABI_ALL_CALLER_SAVE = {
25     HostLoc::RAX,
26     HostLoc::RCX,
27     HostLoc::RDX,
28     HostLoc::R8,
29     HostLoc::R9,
30     HostLoc::R10,
31     HostLoc::R11,
32     HostLoc::XMM0,
33     HostLoc::XMM1,
34     HostLoc::XMM2,
35     HostLoc::XMM3,
36     HostLoc::XMM4,
37     HostLoc::XMM5,
38 };
39 
40 constexpr std::array<HostLoc, 18> ABI_ALL_CALLEE_SAVE = {
41     HostLoc::RBX,
42     HostLoc::RSI,
43     HostLoc::RDI,
44     HostLoc::RBP,
45     HostLoc::R12,
46     HostLoc::R13,
47     HostLoc::R14,
48     HostLoc::R15,
49     HostLoc::XMM6,
50     HostLoc::XMM7,
51     HostLoc::XMM8,
52     HostLoc::XMM9,
53     HostLoc::XMM10,
54     HostLoc::XMM11,
55     HostLoc::XMM12,
56     HostLoc::XMM13,
57     HostLoc::XMM14,
58     HostLoc::XMM15,
59 };
60 
61 constexpr size_t ABI_SHADOW_SPACE = 32; // bytes
62 
63 #else
64 
65 constexpr HostLoc ABI_RETURN = HostLoc::RAX;
66 
67 constexpr HostLoc ABI_PARAM1 = HostLoc::RDI;
68 constexpr HostLoc ABI_PARAM2 = HostLoc::RSI;
69 constexpr HostLoc ABI_PARAM3 = HostLoc::RDX;
70 constexpr HostLoc ABI_PARAM4 = HostLoc::RCX;
71 
72 constexpr std::array<HostLoc, 25> ABI_ALL_CALLER_SAVE = {
73     HostLoc::RAX,
74     HostLoc::RCX,
75     HostLoc::RDX,
76     HostLoc::RDI,
77     HostLoc::RSI,
78     HostLoc::R8,
79     HostLoc::R9,
80     HostLoc::R10,
81     HostLoc::R11,
82     HostLoc::XMM0,
83     HostLoc::XMM1,
84     HostLoc::XMM2,
85     HostLoc::XMM3,
86     HostLoc::XMM4,
87     HostLoc::XMM5,
88     HostLoc::XMM6,
89     HostLoc::XMM7,
90     HostLoc::XMM8,
91     HostLoc::XMM9,
92     HostLoc::XMM10,
93     HostLoc::XMM11,
94     HostLoc::XMM12,
95     HostLoc::XMM13,
96     HostLoc::XMM14,
97     HostLoc::XMM15,
98 };
99 
100 constexpr std::array<HostLoc, 6> ABI_ALL_CALLEE_SAVE = {
101     HostLoc::RBX,
102     HostLoc::RBP,
103     HostLoc::R12,
104     HostLoc::R13,
105     HostLoc::R14,
106     HostLoc::R15,
107 };
108 
109 constexpr size_t ABI_SHADOW_SPACE = 0; // bytes
110 
111 #endif
112 
113 static_assert(ABI_ALL_CALLER_SAVE.size() + ABI_ALL_CALLEE_SAVE.size() == 31, "Invalid total number of registers");
114 
115 void ABI_PushCalleeSaveRegistersAndAdjustStack(BlockOfCode& code, size_t frame_size = 0);
116 void ABI_PopCalleeSaveRegistersAndAdjustStack(BlockOfCode& code, size_t frame_size = 0);
117 void ABI_PushCallerSaveRegistersAndAdjustStack(BlockOfCode& code, size_t frame_size = 0);
118 void ABI_PopCallerSaveRegistersAndAdjustStack(BlockOfCode& code, size_t frame_size = 0);
119 
120 void ABI_PushCallerSaveRegistersAndAdjustStackExcept(BlockOfCode& code, HostLoc exception);
121 void ABI_PopCallerSaveRegistersAndAdjustStackExcept(BlockOfCode& code, HostLoc exception);
122 
123 } // namespace Dynarmic::Backend::X64
124