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