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