• 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_AARCH64_AARCH64_MEMLAYOUT_H
17 #define MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_MEMLAYOUT_H
18 
19 #include "memlayout.h"
20 #include "aarch64_abi.h"
21 
22 namespace maplebe {
23 class AArch64SymbolAlloc : public SymbolAlloc {
24 public:
25     AArch64SymbolAlloc() = default;
26 
27     ~AArch64SymbolAlloc() = default;
28 
SetRegisters(AArch64reg r0,AArch64reg r1,AArch64reg r2,AArch64reg r3)29     void SetRegisters(AArch64reg r0, AArch64reg r1, AArch64reg r2, AArch64reg r3)
30     {
31         reg0 = r0;
32         reg1 = r1;
33         reg2 = r2;
34         reg3 = r3;
35     }
36 
IsRegister()37     inline bool IsRegister() const
38     {
39         return reg0 != kRinvalid;
40     }
41 
42 private:
43     AArch64reg reg0 = kRinvalid;
44     AArch64reg reg1 = kRinvalid;
45     AArch64reg reg2 = kRinvalid;
46     AArch64reg reg3 = kRinvalid;
47 };
48 
49 /*
50  * On AArch64, stack frames are structured as follows:
51  *
52  * The stack grows downward -- full descending (SP points
53  * to a filled slot).
54  *
55  * Any of the parts of a frame is optional, i.e., it is
56  * possible to write a caller-callee pair in such a way
57  * that the particular part is absent in the frame.
58  *
59  * Before a call is made, the frame looks like:
60  * |                            |
61  * ||----------------------------|
62  * | args passed on the stack   | (we call them up-formals)
63  * ||----------------------------|<- Stack Pointer
64  * |                            |
65  *
66  * V1.
67  * Right after a call is made
68  * |                            |
69  * ||----------------------------|
70  * | args passed on the stack   |
71  * ||----------------------------|<- Stack Pointer
72  * | PREV_FP, PREV_LR           |
73  * ||----------------------------|<- Frame Pointer
74  *
75  * After the prologue has run,
76  * |                            |
77  * ||----------------------------|
78  * | args passed on the stack   |
79  * ||----------------------------|
80  * | PREV_FP, PREV_LR           |
81  * ||----------------------------|<- Frame Pointer
82  * | callee-saved registers     |
83  * ||----------------------------|
84  * | empty space. should have   |
85  * | at least 16-byte alignment |
86  * ||----------------------------|
87  * | local variables            |
88  * ||----------------------------|
89  * | variable-sized local vars  |
90  * | (VLAs)                     |
91  * ||----------------------------|<- Stack Pointer
92  *
93  * callee-saved registers include
94  *  1. R19-R28
95  *  2. R8 if return value needs to be returned
96  *     thru memory and callee wants to use R8
97  *  3. we don't need to save R19 if it is used
98  *     as base register for PIE.
99  *  4. V8-V15
100  *
101  * V2. (this way, we may be able to save
102  *     on SP modifying instruction)
103  * Right after a call is made
104  * |                            |
105  * ||----------------------------|
106  * | args passed on the stack   |
107  * ||----------------------------|<- Stack Pointer
108  * |                            |
109  * | empty space                |
110  * |                            |
111  * ||----------------------------|
112  * | PREV_FP, PREV_LR           |
113  * ||----------------------------|<- Frame Pointer
114  *
115  * After the prologue has run,
116  * |                            |
117  * ||----------------------------|
118  * | args passed on the stack   |
119  * ||----------------------------|
120  * | callee-saved registers     |
121  * | including those used for   |
122  * | parameter passing          |
123  * ||----------------------------|
124  * | empty space. should have   |
125  * | at least 16-byte alignment |
126  * ||----------------------------|
127  * | local variables            |
128  * ||----------------------------|
129  * | PREV_FP, PREV_LR           |
130  * ||----------------------------|<- Frame Pointer
131  * | variable-sized local vars  |
132  * | (VLAs)                     |
133  * ||----------------------------|
134  * | args to pass through stack |
135  * ||----------------------------|
136  */
137 class AArch64MemLayout : public MemLayout {
138 public:
AArch64MemLayout(BECommon & b,MIRFunction & f,MapleAllocator & mallocator)139     AArch64MemLayout(BECommon &b, MIRFunction &f, MapleAllocator &mallocator)
140         : MemLayout(b, f, mallocator, kAarch64StackPtrAlignment)
141     {
142     }
143 
144     ~AArch64MemLayout() override = default;
145 
146     /*
147      * Returns stack space required for a call
148      * which is used to pass arguments that cannot be
149      * passed through registers
150      */
151     uint32 ComputeStackSpaceRequirementForCall(StmtNode &stmt, int32 &aggCopySize, bool isIcall) override;
152 
153     void LayoutStackFrame(int32 &structCopySize, int32 &maxParmStackSize) override;
154 
AssignSpillLocationsToPseudoRegisters()155     void AssignSpillLocationsToPseudoRegisters() override {};
156 
157     uint64 StackFrameSize() const;
158 
159     uint32 RealStackFrameSize() const;
160 
Locals()161     const MemSegment &Locals() const
162     {
163         return segLocals;
164     }
165 
GetSizeOfSpillReg()166     uint32 GetSizeOfSpillReg() const
167     {
168         return segSpillReg.GetSize();
169     }
170 
GetSizeOfLocals()171     uint32 GetSizeOfLocals() const
172     {
173         return segLocals.GetSize();
174     }
175 
GetSizeOfCold()176     uint32 GetSizeOfCold() const
177     {
178         return segCold.GetSize();
179     }
180 
SetSizeOfGRSaveArea(uint32 sz)181     void SetSizeOfGRSaveArea(uint32 sz)
182     {
183         segGrSaveArea.SetSize(sz);
184     }
185 
GetSizeOfGRSaveArea()186     uint32 GetSizeOfGRSaveArea() const
187     {
188         return segGrSaveArea.GetSize();
189     }
190 
SetSizeOfVRSaveArea(uint32 sz)191     inline void SetSizeOfVRSaveArea(uint32 sz)
192     {
193         segVrSaveArea.SetSize(sz);
194     }
195 
GetSizeOfVRSaveArea()196     uint32 GetSizeOfVRSaveArea() const
197     {
198         return segVrSaveArea.GetSize();
199     }
200 
GetSizeOfRefLocals()201     uint32 GetSizeOfRefLocals() const
202     {
203         return segRefLocals.GetSize();
204     }
205 
206     uint64 GetSizeOfColdToStk() const;
207     bool IsSegMentVaried(const MemSegment *seg) const;
208     int32 GetCalleeSaveBaseLoc() const override;
209 
210 private:
211     MemSegment segRefLocals = MemSegment(kMsRefLocals);
212     /* callee saved register R19-R28 (10) */
213     MemSegment segLocals = MemSegment(kMsLocals); /* these are accessed via Frame Pointer */
214     MemSegment segGrSaveArea = MemSegment(kMsGrSaveArea);
215     MemSegment segVrSaveArea = MemSegment(kMsVrSaveArea);
216     int32 fixStackSize = 0;
217     void SetSizeAlignForTypeIdx(uint32 typeIdx, uint32 &size, uint32 &align) const;
218     void LayoutFormalParams();
219     void LayoutActualParams();
220     void LayoutLocalVariables(std::vector<MIRSymbol *> &tempVar, std::vector<MIRSymbol *> &returnDelays);
221     void LayoutEAVariales(std::vector<MIRSymbol *> &tempVar);
222     void LayoutReturnRef(std::vector<MIRSymbol *> &returnDelays, int32 &structCopySize, int32 &maxParmStackSize);
223     // layout small local near sp, otherwise, above spill region
224     void LayoutLocalsInSize(const MIRSymbol &mirSym);
225 
CreateSymbolAlloc()226     SymbolAlloc *CreateSymbolAlloc() const override
227     {
228         return memAllocator->GetMemPool()->New<AArch64SymbolAlloc>();
229     }
230 };
231 } /* namespace maplebe */
232 
233 #endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_MEMLAYOUT_H */
234