• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "aarch64_cg.h"
17 #include "aarch64_mop_split.h"
18 #include "aarch64_mop_valid.h"
19 
20 namespace maplebe {
21 #define DEFINE_MOP(...) {__VA_ARGS__},
22 const InsnDesc AArch64CG::kMd[kMopLast] = {
23 #include "abstract_mmir.def"
24 #include "aarch64_md.def"
25 };
26 #undef DEFINE_MOP
27 
28 std::array<std::array<const std::string, kAllRegNum>, kIntRegTypeNum> AArch64CG::intRegNames = {
29     std::array<const std::string, kAllRegNum> {
30         "err",   "err0",  "err1",  "err2",  "err3",  "err4",         "err5",  "err6",  "err7",
31         "err8",  "err9",  "err10", "err11", "err12", "err13",        "err14", "err15", "err16",
32         "err17", "err18", "err19", "err20", "err21", "err22",        "err23", "err24", "err25",
33         "err26", "err27", "err28", "err",   "err",   "err",          "errsp", "errzr", /* x29 is fp */
34         "b0",    "b1",    "b2",    "b3",    "b4",    "b5",           "b6",    "b7",    "b8",
35         "b9",    "b10",   "b11",   "b12",   "b13",   "b14",          "b15",   "b16",   "b17",
36         "b18",   "b19",   "b20",   "b21",   "b22",   "b23",          "b24",   "b25",   "b26",
37         "b27",   "b28",   "b29",   "b30",   "b31",   "errMaxRegNum", "rflag"},
38     std::array<const std::string, kAllRegNum> {
39         "err",   "err0",  "err1",  "err2",  "err3",  "err4",         "err5",  "err6",  "err7",
40         "err8",  "err9",  "err10", "err11", "err12", "err13",        "err14", "err15", "err16",
41         "err17", "err18", "err19", "err20", "err21", "err22",        "err23", "err24", "err25",
42         "err26", "err27", "err28", "err29", "err30", "err31",        "errsp", "errzr", /* x29 is fp */
43         "h0",    "h1",    "h2",    "h3",    "h4",    "h5",           "h6",    "h7",    "h8",
44         "h9",    "h10",   "h11",   "h12",   "h13",   "h14",          "h15",   "h16",   "h17",
45         "h18",   "h19",   "h20",   "h21",   "h22",   "h23",          "h24",   "h25",   "h26",
46         "h27",   "h28",   "h29",   "h30",   "h31",   "errMaxRegNum", "rflag"},
47     std::array<const std::string, kAllRegNum> {
48         "err", "w0",  "w1",  "w2",  "w3",  "w4",  "w5",  "w6",  "w7",           "w8",   "w9",  "w10",
49         "w11", "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19",          "w20",  "w21", "w22",
50         "w23", "w24", "w25", "w26", "w27", "w28", "w29", "err", "err",          "wsp",  "wzr", /* x29 is fp */
51         "s0",  "s1",  "s2",  "s3",  "s4",  "s5",  "s6",  "s7",  "s8",           "s9",   "s10", "s11",
52         "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20",          "s21",  "s22", "s23",
53         "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", "errMaxRegNum", "rflag"},
54     std::array<const std::string, kAllRegNum> {
55         "err",  "x0",  "x1",  "x2",  "x3",  "x4",  "x5",  "x6",  "x7",  "x8",  "x9",
56         "x10",  "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20",
57         "x21",  "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x29" /* use X40 when debug */,
58         "sp",   "xzr", /* x29 is fp */
59         "d0",   "d1",  "d2",  "d3",  "d4",  "d5",  "d6",  "d7",  "d8",  "d9",  "d10",
60         "d11",  "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21",
61         "d22",  "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", "errMaxRegNum",
62         "rflag"},
63     std::array<const std::string, kAllRegNum> {
64         "err",  "x0",  "x1",  "x2",  "x3",  "x4",  "x5",  "x6",  "x7",  "x8",  "x9",
65         "x10",  "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20",
66         "x21",  "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x29" /* use X40 when debug */,
67         "sp",   "xzr", /* x29 is fp */
68         "q0",   "q1",  "q2",  "q3",  "q4",  "q5",  "q6",  "q7",  "q8",  "q9",  "q10",
69         "q11",  "q12", "q13", "q14", "q15", "q16", "q17", "q18", "q19", "q20", "q21",
70         "q22",  "q23", "q24", "q25", "q26", "q27", "q28", "q29", "q30", "q31", "errMaxRegNum",
71         "rflag"}};
72 
73 std::array<const std::string, kAllRegNum> AArch64CG::vectorRegNames = {
74     "err", "err0", "err1", "err2", "err3", "err4", "err5", "err6", "err7", "err8", "err9", "err10", "err11", "err12",
75     "err13", "err14", "err15", "err16", "err17", "err18", "err19", "err20", "err21", "err22",
76     /* x29 is fp, err40 is fp before RA */
77     "err23", "err24", "err25", "err26", "err27", "err28", "err29", "err30", "errsp", "errzr", "err40", "v0", "v1", "v2",
78     "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19",
79     "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", "errMaxRegNum", "rflag"};
80 
IsExclusiveFunc(MIRFunction & mirFunc)81 bool AArch64CG::IsExclusiveFunc(MIRFunction &mirFunc)
82 {
83     const std::string &funcName = mirFunc.GetName();
84     for (const auto &it : ehExclusiveNameVec) {
85         if (it.compare(funcName) == 0) {
86             return true;
87         }
88     }
89     return false;
90 }
91 
IsTargetInsn(MOperator mOp) const92 bool AArch64CG::IsTargetInsn(MOperator mOp) const
93 {
94     return (mOp > MOP_undef && mOp <= MOP_nop);
95 }
IsClinitInsn(MOperator mOp) const96 bool AArch64CG::IsClinitInsn(MOperator mOp) const
97 {
98     return (mOp == MOP_clinit || mOp == MOP_clinit_tail || mOp == MOP_adrp_ldr);
99 }
IsPseudoInsn(MOperator mOp) const100 bool AArch64CG::IsPseudoInsn(MOperator mOp) const
101 {
102     return (mOp >= MOP_pseudo_param_def_x && mOp < MOP_nop);
103 }
104 
IsEffectiveCopy(Insn & insn) const105 bool AArch64CG::IsEffectiveCopy(Insn &insn) const
106 {
107     MOperator mOp = insn.GetMachineOpcode();
108     if (mOp >= MOP_xmovrr && mOp <= MOP_xvmovrv) {
109         return true;
110     }
111     if ((mOp >= MOP_xaddrrr && mOp <= MOP_ssub) || (mOp >= MOP_xlslrri6 && mOp <= MOP_wlsrrrr)) {
112         Operand &opnd2 = insn.GetOperand(kInsnThirdOpnd);
113         if (opnd2.IsIntImmediate()) {
114             auto &immOpnd = static_cast<ImmOperand &>(opnd2);
115             if (immOpnd.IsZero()) {
116                 return true;
117             }
118         }
119     }
120     if (mOp > MOP_xmulrrr && mOp <= MOP_xvmuld) {
121         Operand &opnd2 = insn.GetOperand(kInsnThirdOpnd);
122         if (opnd2.IsIntImmediate()) {
123             auto &immOpnd = static_cast<ImmOperand &>(opnd2);
124             if (immOpnd.GetValue() == 1) {
125                 return true;
126             }
127         }
128     }
129     return false;
130 }
131 
DumpTargetOperand(Operand & opnd,const OpndDesc & opndDesc) const132 void AArch64CG::DumpTargetOperand(Operand &opnd, const OpndDesc &opndDesc) const
133 {
134     A64OpndDumpVisitor visitor(opndDesc);
135     opnd.Accept(visitor);
136 }
137 
EmitGCTIBLabel(GCTIBKey * key,const std::string & gcTIBName,std::vector<uint64> & bitmapWords,uint32 rcHeader)138 void AArch64CG::EmitGCTIBLabel(GCTIBKey *key, const std::string &gcTIBName,
139                                std::vector<uint64> &bitmapWords, uint32 rcHeader)
140 {
141     GCTIBPattern *ptn = memPool->New<GCTIBPattern>(*key, *memPool);
142     (void)keyPatternMap.insert(std::make_pair(key, ptn));
143     (void)symbolPatternMap.insert(std::make_pair(gcTIBName, ptn));
144 
145     /* Emit GCTIB pattern */
146     std::string ptnString = "\t.type " + ptn->GetName() + ", %object\n" + "\t.data\n" + "\t.align 3\n";
147     MIRSymbol *gcTIBSymbol = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(
148         GlobalTables::GetStrTable().GetStrIdxFromName(gcTIBName));
149     if (gcTIBSymbol != nullptr && gcTIBSymbol->GetStorageClass() == kScFstatic) {
150         ptnString += "\t.local ";
151     } else {
152         ptnString += "\t.global ";
153     }
154 
155     Emit([&ptnString, ptn, rcHeader, &bitmapWords](Emitter *emitter) {
156         emitter->Emit(ptnString);
157         emitter->Emit(ptn->GetName());
158         emitter->Emit("\n");
159 
160         /* Emit the GCTIB pattern label for the class */
161         emitter->Emit(ptn->GetName());
162         emitter->Emit(":\n");
163 
164         emitter->Emit("\t.long ");
165         emitter->EmitHexUnsigned(rcHeader);
166         emitter->Emit("\n");
167 
168         /* generate n_bitmap word */
169         emitter->Emit("\t.long "); /* AArch64-specific. Generate a 64-bit value. */
170         emitter->EmitDecUnsigned(bitmapWords.size());
171         emitter->Emit("\n");
172 
173         /* Emit each bitmap word */
174         for (const auto &bitmapWord : bitmapWords) {
175             emitter->Emit("\t.quad "); /* AArch64-specific. Generate a 64-bit value. */
176             emitter->EmitHexUnsigned(bitmapWord);
177             emitter->Emit("\n");
178         }
179     });
180     if (gcTIBSymbol != nullptr && gcTIBSymbol->GetStorageClass() != kScFstatic) {
181         /* add local symbol REF_XXX to every global GCTIB symbol */
182         CreateRefSymForGlobalPtn(*ptn);
183         keyPatternMap[key] = ptn;
184     }
185 }
186 
187 /*
188  * Add local symbol REF_XXX to global GCTIB symbol,
189  * and replace the global GCTIBPattern in keyPatternMap.
190  */
CreateRefSymForGlobalPtn(GCTIBPattern & ptn) const191 void AArch64CG::CreateRefSymForGlobalPtn(GCTIBPattern &ptn) const
192 {
193     const std::string &refPtnString = REF_PREFIX_STR + ptn.GetName();
194     const std::string &ptnString = "\t.type " + refPtnString + ", %object\n" + "\t.data\n" + "\t.align 3\n" +
195                                    "\t.local " + refPtnString + "\n" + refPtnString + ":\n" + "\t.quad " +
196                                    ptn.GetName() + "\n";
197     Emit([&ptnString](Emitter *emitter) {
198         emitter->Emit(ptnString);
199     });
200     ptn.SetName(refPtnString);
201 }
202 
203 #ifdef ARK_LITECG_DEBUG
FindGCTIBPatternName(const std::string & name) const204 std::string AArch64CG::FindGCTIBPatternName(const std::string &name) const
205 {
206     auto iter = symbolPatternMap.find(name);
207     if (iter == symbolPatternMap.end()) {
208         CHECK_FATAL(false, "No GCTIB pattern found for symbol: %s", name.c_str());
209     }
210     return iter->second->GetName();
211 }
212 #endif
213 
EnrollTargetPhases(MaplePhaseManager * pm) const214 void AArch64CG::EnrollTargetPhases(MaplePhaseManager *pm) const
215 {
216     CGOptions::DisableCGSSA();
217 #include "aarch64_phases.def"
218 }
219 
CreatePhiOperand(MemPool & mp,MapleAllocator & mAllocator)220 PhiOperand &AArch64CG::CreatePhiOperand(MemPool &mp, MapleAllocator &mAllocator)
221 {
222     return *mp.New<PhiOperand>(mAllocator);
223 }
224 } /* namespace maplebe */
225