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 #include "mir_function.h"
17 #include "opcode_info.h"
18 #include "mir_pragma.h"
19 #include "mir_builder.h"
20 #include "bin_mplt.h"
21 #include <sstream>
22 #include <vector>
23
24 using namespace std;
25 namespace maple {
OutputInfoVector(const MIRInfoVector & infoVector,const MapleVector<bool> & infoVectorIsString)26 void BinaryMplExport::OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector<bool> &infoVectorIsString)
27 {
28 if (!mod.IsWithDbgInfo()) {
29 Write(0);
30 return;
31 }
32 WriteNum(infoVector.size());
33 for (uint32 i = 0; i < infoVector.size(); i++) {
34 OutputStr(infoVector[i].first);
35 WriteNum(infoVectorIsString[i] ? 1 : 0);
36 if (!infoVectorIsString[i]) {
37 WriteNum(infoVector[i].second);
38 } else {
39 OutputStr(GStrIdx(infoVector[i].second));
40 }
41 }
42 }
43
OutputFuncIdInfo(MIRFunction * func)44 void BinaryMplExport::OutputFuncIdInfo(MIRFunction *func)
45 {
46 WriteNum(kBinFuncIdInfoStart);
47 WriteNum(func->GetPuidxOrigin()); // the funcid
48 OutputInfoVector(func->GetInfoVector(), func->InfoIsString());
49 if (mod.GetFlavor() == kFlavorLmbc) {
50 WriteNum(func->GetFrameSize());
51 }
52 }
53
OutputBaseNode(const BaseNode * b)54 void BinaryMplExport::OutputBaseNode(const BaseNode *b)
55 {
56 Write(static_cast<uint8>(b->GetOpCode()));
57 Write(static_cast<uint8>(b->GetPrimType()));
58 }
59
OutputLocalSymbol(MIRSymbol * sym)60 void BinaryMplExport::OutputLocalSymbol(MIRSymbol *sym)
61 {
62 CHECK_FATAL(sym != nullptr, "null ptr");
63 std::unordered_map<const MIRSymbol *, int64>::iterator it = localSymMark.find(sym);
64 if (it != localSymMark.end()) {
65 WriteNum(-(it->second));
66 return;
67 }
68
69 WriteNum(kBinSymbol);
70 OutputStr(sym->GetNameStrIdx());
71 WriteNum(sym->GetSKind());
72 WriteNum(sym->GetStorageClass());
73 size_t mark = localSymMark.size();
74 localSymMark[sym] = static_cast<int64>(mark);
75 OutputTypeAttrs(sym->GetAttrs());
76 WriteNum(static_cast<int64>(sym->GetIsTmp()));
77 if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) {
78 OutputSrcPos(sym->GetSrcPosition());
79 }
80 OutputType(sym->GetTyIdx());
81 if (sym->GetSKind() == kStPreg) {
82 OutputPreg(sym->GetPreg());
83 } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) {
84 OutputConst(sym->GetKonst());
85 } else if (sym->GetSKind() == kStFunc) {
86 OutputFuncViaSym(sym->GetFunction()->GetPuidx());
87 } else {
88 CHECK_FATAL(false, "should not used");
89 }
90 }
91
OutputPreg(MIRPreg * preg)92 void BinaryMplExport::OutputPreg(MIRPreg *preg)
93 {
94 if (preg->GetPregNo() < 0) {
95 WriteNum(kBinSpecialReg);
96 Write(static_cast<uint8>(-preg->GetPregNo()));
97 return;
98 }
99 std::unordered_map<const MIRPreg *, int64>::iterator it = localPregMark.find(preg);
100 if (it != localPregMark.end()) {
101 WriteNum(-(it->second));
102 return;
103 }
104
105 WriteNum(kBinPreg);
106 Write(static_cast<uint8>(preg->GetPrimType()));
107 size_t mark = localPregMark.size();
108 localPregMark[preg] = static_cast<int>(mark);
109 }
110
OutputLabel(LabelIdx lidx)111 void BinaryMplExport::OutputLabel(LabelIdx lidx)
112 {
113 std::unordered_map<LabelIdx, int64>::iterator it = labelMark.find(lidx);
114 if (it != labelMark.end()) {
115 WriteNum(-(it->second));
116 return;
117 }
118
119 WriteNum(kBinLabel);
120 size_t mark = labelMark.size();
121 labelMark[lidx] = static_cast<int64>(mark);
122 }
123
OutputLocalTypeNameTab(const MIRTypeNameTable * typeNameTab)124 void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab)
125 {
126 WriteNum(kBinTypenameStart);
127 WriteNum(static_cast<int64>(typeNameTab->Size()));
128 for (std::pair<GStrIdx, TyIdx> it : typeNameTab->GetGStrIdxToTyIdxMap()) {
129 OutputStr(it.first);
130 OutputType(it.second);
131 }
132 }
133
OutputFormalsStIdx(MIRFunction * func)134 void BinaryMplExport::OutputFormalsStIdx(MIRFunction *func)
135 {
136 WriteNum(kBinFormalStart);
137 WriteNum(func->GetFormalDefVec().size());
138 for (FormalDef formalDef : func->GetFormalDefVec()) {
139 OutputLocalSymbol(formalDef.formalSym);
140 }
141 }
142
OutputAliasMap(MapleMap<GStrIdx,MIRAliasVars> & aliasVarMap)143 void BinaryMplExport::OutputAliasMap(MapleMap<GStrIdx, MIRAliasVars> &aliasVarMap)
144 {
145 WriteNum(kBinAliasMapStart);
146 WriteInt(static_cast<int32>(aliasVarMap.size()));
147 for (std::pair<GStrIdx, MIRAliasVars> it : aliasVarMap) {
148 OutputStr(it.first);
149 OutputStr(it.second.mplStrIdx);
150 OutputType(it.second.tyIdx);
151 OutputStr(it.second.sigStrIdx);
152 }
153 }
154
OutputFuncViaSym(PUIdx puIdx)155 void BinaryMplExport::OutputFuncViaSym(PUIdx puIdx)
156 {
157 MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx);
158 MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx());
159 OutputSymbol(funcSt);
160 }
161
162 static SrcPosition lastOutputSrcPosition;
163
OutputSrcPos(const SrcPosition & pos)164 void BinaryMplExport::OutputSrcPos(const SrcPosition &pos)
165 {
166 if (!mod.IsWithDbgInfo()) {
167 return;
168 }
169 if (pos.FileNum() == 0 || pos.LineNum() == 0) { // error case, so output 0
170 WriteNum(lastOutputSrcPosition.RawData());
171 WriteNum(lastOutputSrcPosition.LineNum());
172 return;
173 }
174 WriteNum(pos.RawData());
175 WriteNum(pos.LineNum());
176 lastOutputSrcPosition = pos;
177 }
178
OutputReturnValues(const CallReturnVector * retv)179 void BinaryMplExport::OutputReturnValues(const CallReturnVector *retv)
180 {
181 WriteNum(kBinReturnvals);
182 WriteNum(static_cast<int64>(retv->size()));
183 for (uint32 i = 0; i < retv->size(); i++) {
184 RegFieldPair rfp = (*retv)[i].second;
185 if (rfp.IsReg()) {
186 MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rfp.GetPregIdx());
187 OutputPreg(preg);
188 } else {
189 WriteNum(0);
190 WriteNum((rfp.GetFieldID()));
191 OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol((*retv)[i].first));
192 }
193 }
194 }
195
196 } // namespace maple
197