• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #ifndef PANDA_FRAME_INFO_H
17 #define PANDA_FRAME_INFO_H
18 
19 #include "libpandabase/utils/cframe_layout.h"
20 #include "libpandabase/utils/bit_field.h"
21 #include "libpandabase/mem/mem.h"
22 
23 namespace ark::compiler {
24 
25 class Encoder;
26 class Graph;
27 
28 /// This class describes layout of the frame being compiled.
29 class FrameInfo {
30 public:
FrameInfo(uint32_t fields)31     explicit FrameInfo(uint32_t fields) : fields_(fields) {}
32     ~FrameInfo() = default;
33     NO_COPY_SEMANTIC(FrameInfo);
34     NO_MOVE_SEMANTIC(FrameInfo);
35 
36 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
37 #define FRAME_INFO_GET_ATTR(name, var)         \
38     auto Get##name() const                     \
39     {                                          \
40         /* CC-OFFNXT(G.PRE.05) function gen */ \
41         return var;                            \
42     }
43 
44 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
45 #define FRAME_INFO_SET_ATTR(name, var)                            \
46     void Set##name(ssize_t val)                                   \
47     {                                                             \
48         ASSERT(val <= std::numeric_limits<decltype(var)>::max()); \
49         ASSERT(val >= std::numeric_limits<decltype(var)>::min()); \
50         var = val;                                                \
51     }
52 
53 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
54 #define FRAME_INFO_ATTR(name, var) \
55     FRAME_INFO_GET_ATTR(name, var) \
56     FRAME_INFO_SET_ATTR(name, var)
57 
58 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
59 #define FRAME_INFO_GET_FIELD(name, type)                                   \
60     type Get##name() const                                                 \
61     {                                                                      \
62         /* CC-OFFNXT(G.PRE.02, G.PRE.05) function gen, namespace member */ \
63         return name::Get(fields_);                                         \
64     }
65 
66 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
67 #define FRAME_INFO_SET_FIELD(name, type)           \
68     void Set##name(type val)                       \
69     {                                              \
70         /* CC-OFFNXT(G.PRE.02) namespace member */ \
71         name::Set(val, &fields_);                  \
72     }
73 
74 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
75 #define FRAME_INFO_FIELD(name, type) \
76     FRAME_INFO_GET_FIELD(name, type) \
77     FRAME_INFO_SET_FIELD(name, type)
78 
79     FRAME_INFO_ATTR(FrameSize, frameSize_);
80     FRAME_INFO_ATTR(SpillsCount, spillsCount_);
81     FRAME_INFO_ATTR(CallersOffset, callersOffset_);
82     FRAME_INFO_ATTR(CalleesOffset, calleesOffset_);
83     FRAME_INFO_ATTR(FpCallersOffset, fpCallersOffset_);
84     FRAME_INFO_ATTR(FpCalleesOffset, fpCalleesOffset_);
85     FRAME_INFO_FIELD(PositionedCallers, bool);
86     FRAME_INFO_FIELD(PositionedCallees, bool);
87     FRAME_INFO_FIELD(CallersRelativeFp, bool);
88     FRAME_INFO_FIELD(CalleesRelativeFp, bool);
89     // SaveFrameAndLinkRegs - save/restore FP and LR registers in prologue/epilogue.
90     FRAME_INFO_FIELD(SaveFrameAndLinkRegs, bool);
91     // SetupFrame - setup CFrame (aka. 'managed' frame).
92     // Namely, set FP reg, method and flags in prologue.
93     FRAME_INFO_FIELD(SetupFrame, bool);
94     // SaveUnusedCalleeRegs - save/restore used+unused callee-saved registers in prologue/epilogue.
95     FRAME_INFO_FIELD(SaveUnusedCalleeRegs, bool);
96     // AdjustSpReg - sub SP,#framesize in prologue and add SP,#framesize in epilogue.
97     FRAME_INFO_FIELD(AdjustSpReg, bool);
98     FRAME_INFO_FIELD(HasFloatRegs, bool);
99     FRAME_INFO_FIELD(PushCallers, bool);
100 
101     using PositionedCallers = BitField<bool, 0, 1>;
102     using PositionedCallees = PositionedCallers::NextFlag;
103     using CallersRelativeFp = PositionedCallees::NextFlag;
104     using CalleesRelativeFp = CallersRelativeFp::NextFlag;
105     using SaveFrameAndLinkRegs = CalleesRelativeFp::NextFlag;
106     using SetupFrame = SaveFrameAndLinkRegs::NextFlag;
107     using SaveUnusedCalleeRegs = SetupFrame::NextFlag;
108     using AdjustSpReg = SaveUnusedCalleeRegs::NextFlag;
109     using HasFloatRegs = AdjustSpReg::NextFlag;
110     // Whether we need to push callers below stack during calls. Actually it is some kind of workaround, and we need
111     // to rework it and make better solution, e.g allocate size for callers in a frame and save them there.
112     using PushCallers = HasFloatRegs::NextFlag;
113 
114     // The following static 'constructors' are for situations
115     // when we have to generate prologue/epilogue but there is
116     // no codegen at hand (some tests etc.)
117     // 'Leaf' means a prologue for a function which does not call
118     // any other functions (library, runtime etc.)
LeafPrologue()119     static FrameInfo LeafPrologue()
120     {
121         return FrameInfo(AdjustSpReg::Encode(true));
122     }
123 
124     // 'Native' means just a regular prologue, that is used for native functions.
125     // 'Native' is also used for Irtoc.
NativePrologue()126     static FrameInfo NativePrologue()
127     {
128         return FrameInfo(AdjustSpReg::Encode(true) | SaveFrameAndLinkRegs::Encode(true) |
129                          SaveUnusedCalleeRegs::Encode(true));
130     }
131 
132     // 'Full' means NativePrologue + setting up frame (set FP, method and flags),
133     // i.e. a prologue for managed code.
FullPrologue()134     static FrameInfo FullPrologue()
135     {
136         return FrameInfo(AdjustSpReg::Encode(true) | SaveFrameAndLinkRegs::Encode(true) |
137                          SaveUnusedCalleeRegs::Encode(true) | SetupFrame::Encode(true));
138     }
139 
140 #undef FRAME_INFO_GET_ATTR
141 #undef FRAME_INFO_SET_ATTR
142 #undef FRAME_INFO_ATTR
143 #undef FRAME_INFO_GET_FIELD
144 #undef FRAME_INFO_SET_FIELD
145 #undef FRAME_INFO_FIELD
146 
147 private:
148     uint32_t fields_ {0};
149     int32_t frameSize_ {0};
150     int16_t spillsCount_ {0};
151     // Offset to caller registers storage (in words)
152     int16_t callersOffset_ {0};
153     int16_t calleesOffset_ {0};
154     int16_t fpCallersOffset_ {0};
155     int16_t fpCalleesOffset_ {0};
156 };
157 }  // namespace ark::compiler
158 
159 #endif  // PANDA_FRAME_INFO_H
160