• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 MAPLEBE_INCLUDE_CG_X86_64_MEMLAYOUT_H
17 #define MAPLEBE_INCLUDE_CG_X86_64_MEMLAYOUT_H
18 
19 #include "memlayout.h"
20 #include "x64_abi.h"
21 
22 namespace maplebe {
23 class X64SymbolAlloc : public SymbolAlloc {
24 public:
25     X64SymbolAlloc() = default;
26 
27     ~X64SymbolAlloc() = default;
28 
SetRegisters(bool isR)29     void SetRegisters(bool isR)
30     {
31         isRegister = isR;
32     }
33 
IsRegister()34     inline bool IsRegister() const
35     {
36         return isRegister;
37     }
38 
39 private:
40     bool isRegister = false;
41 };
42 /*
43  * On X64, stack frames are structured as follows:
44  *
45  * The stack grows downward -- full descending (SP points
46  * to a filled slot).
47  *
48  * Any of the parts of a frame is optional, i.e., it is
49  * possible to write a caller-callee pair in such a way
50  * that the particular part is absent in the frame.
51  *
52  * Before a call is made, the frame looks like:
53  * |                            |
54  * ||----------------------------|
55  * | args passed on the stack   | (we call them up-formals)
56  * ||----------------------------|<- Stack Pointer
57  * |                            |
58  *
59  * Right after a call is made
60  * |                            |
61  * ||----------------------------|
62  * | args passed on the stack   |
63  * ||----------------------------|<- Stack Pointer
64  * | PREV_FP, PREV_LR           |
65  * ||----------------------------|<- Frame Pointer
66  *
67  * After the prologue has run,
68  * |                            |
69  * ||----------------------------|
70  * | args passed on the stack   |
71  * ||----------------------------|
72  * | PREV_FP, PREV_LR           |
73  * ||----------------------------|<- Frame Pointer
74  * | GR Arg Save Area           |
75  * ||----------------------------|
76  * | VR Arg Save Area           |
77  * ||----------------------------|
78  * | callee-saved registers     |
79  * ||----------------------------|
80  * | empty space. should have   |
81  * | at least 16-byte alignment |
82  * ||----------------------------|
83  * | local variables            |
84  * ||----------------------------|<- Stack Pointer
85  * | red zone                   |
86  *
87  * callee-saved registers include
88  *  1. rbx rbp r12 r14 r14 r15
89  *  2. XMM0-XMM7
90  */
91 
92 class X64MemLayout : public MemLayout {
93 public:
X64MemLayout(BECommon & b,MIRFunction & f,MapleAllocator & mallocator)94     X64MemLayout(BECommon &b, MIRFunction &f, MapleAllocator &mallocator)
95         : MemLayout(b, f, mallocator, kX64StackPtrAlignment)
96     {
97     }
98 
99     ~X64MemLayout() override = default;
100 
101     uint32 ComputeStackSpaceRequirementForCall(StmtNode &stmtNode, int32 &aggCopySize, bool isIcall) override;
102     void LayoutStackFrame(int32 &structCopySize, int32 &maxParmStackSize) override;
103 
104     uint64 StackFrameSize() const;
105 
Locals()106     const MemSegment &Locals() const
107     {
108         return segLocals;
109     }
110     /*
111      * "Pseudo-registers can be regarded as local variables of a
112      * primitive type whose addresses are never taken"
113      */
114     virtual void AssignSpillLocationsToPseudoRegisters() override;
115 
GetSizeOfSpillReg()116     uint32 GetSizeOfSpillReg() const
117     {
118         return segSpillReg.GetSize();
119     }
120 
GetSizeOfLocals()121     uint32 GetSizeOfLocals() const
122     {
123         return segLocals.GetSize();
124     }
125 
SetSizeOfGRSaveArea(uint32 sz)126     void SetSizeOfGRSaveArea(uint32 sz)
127     {
128         segGrSaveArea.SetSize(sz);
129     }
130 
GetSizeOfGRSaveArea()131     uint32 GetSizeOfGRSaveArea() const
132     {
133         return segGrSaveArea.GetSize();
134     }
135 
SetSizeOfVRSaveArea(uint32 sz)136     inline void SetSizeOfVRSaveArea(uint32 sz)
137     {
138         segVrSaveArea.SetSize(sz);
139     }
140 
GetSizeOfVRSaveArea()141     uint32 GetSizeOfVRSaveArea() const
142     {
143         return segVrSaveArea.GetSize();
144     }
145 
146     int32 GetGRSaveAreaBaseLoc();
147     int32 GetVRSaveAreaBaseLoc();
148 
149 private:
150     /* Layout function */
151     void LayoutFormalParams();
152     void LayoutLocalVariables();
153 
154     /* util function */
155     void SetSizeAlignForTypeIdx(uint32 typeIdx, uint32 &size, uint32 &align) const;
156     void LayoutReturnRef(int32 &structCopySize, int32 &maxParmStackSize);
157 
158     MemSegment segLocals = MemSegment(kMsLocals); /* these are accessed via Frame Pointer */
159     MemSegment segGrSaveArea = MemSegment(kMsGrSaveArea);
160     MemSegment segVrSaveArea = MemSegment(kMsVrSaveArea);
161 
CreateSymbolAlloc()162     SymbolAlloc *CreateSymbolAlloc() const override
163     {
164         return memAllocator->GetMemPool()->New<X64SymbolAlloc>();
165     }
166 };
167 }  // namespace maplebe
168 #endif  // MAPLEBE_INCLUDE_CG_X86_64_MEMLAYOUT_H
169