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