• 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_args.h"
17 
18 namespace maplebe {
19 using namespace maple;
20 
Run()21 void AArch64MoveRegArgs::Run()
22 {
23     BB *formerCurBB = aarFunc->GetCurBB();
24     MoveVRegisterArgs();
25     MoveRegisterArgs();
26     aarFunc->SetCurBB(*formerCurBB);
27 }
28 
MoveRegisterArgs() const29 void AArch64MoveRegArgs::MoveRegisterArgs() const
30 {
31     aarFunc->GetDummyBB()->ClearInsns();
32     aarFunc->SetCurBB(*aarFunc->GetDummyBB());
33 
34     auto &mirFunc = aarFunc->GetFunction();
35     CCImpl &parmlocator =
36         *static_cast<AArch64CGFunc *>(cgFunc)->GetOrCreateLocator(CCImpl::GetCallConvKind(cgFunc->GetFunction()));
37     CCLocInfo ploc;
38     for (uint32 i = 0; i < mirFunc.GetFormalCount(); ++i) {
39         MIRType *ty = mirFunc.GetNthParamType(i);
40         parmlocator.LocateNextParm(*ty, ploc, i == 0, mirFunc.GetMIRFuncType());
41         if (ploc.reg0 == kRinvalid) {
42             continue;
43         }
44         auto *sym = mirFunc.GetFormal(i);
45         if (sym->IsPreg()) {
46             continue;
47         }
48         auto *symLoc = aarFunc->GetMemlayout()->GetSymAllocInfo(sym->GetStIndex());
49         auto *baseOpnd = aarFunc->GetBaseReg(*symLoc);
50         auto offset = aarFunc->GetBaseOffset(*symLoc);
51         auto generateStrInsn = [this, baseOpnd, &offset, sym, symLoc](AArch64reg reg, PrimType primType) {
52             RegOperand &regOpnd = aarFunc->GetOrCreatePhysicalRegisterOperand(reg, GetPrimTypeBitSize(primType),
53                                                                               aarFunc->GetRegTyFromPrimTy(primType));
54             OfstOperand &ofstOpnd =
55                 aarFunc->CreateOfstOpnd(static_cast<uint64>(static_cast<int64>(offset)), k32BitSize);
56             AArch64MemLayout *memLayout = static_cast<AArch64MemLayout *>(aarFunc->GetMemlayout());
57             if (memLayout->IsSegMentVaried(symLoc->GetMemSegment())) {
58                 ofstOpnd.SetVary(kUnAdjustVary);
59             }
60             auto *memOpnd = aarFunc->CreateMemOperand(GetPrimTypeBitSize(primType), *baseOpnd, ofstOpnd, false);
61 
62             MOperator mOp = aarFunc->PickStInsn(GetPrimTypeBitSize(primType), primType);
63             Insn &insn = aarFunc->GetInsnBuilder()->BuildInsn(mOp, regOpnd, *memOpnd);
64             if (aarFunc->GetCG()->GenerateVerboseCG()) {
65                 insn.SetComment(std::string("store param: ").append(sym->GetName()));
66             }
67             aarFunc->GetCurBB()->AppendInsn(insn);
68             offset += static_cast<int32>(GetPrimTypeSize(primType));
69         };
70         generateStrInsn(static_cast<AArch64reg>(ploc.GetReg0()), ploc.GetPrimTypeOfReg0());
71         if (ploc.GetReg1() != kRinvalid) {
72             generateStrInsn(static_cast<AArch64reg>(ploc.GetReg1()), ploc.GetPrimTypeOfReg1());
73         }
74         if (ploc.GetReg2() != kRinvalid) {
75             generateStrInsn(static_cast<AArch64reg>(ploc.GetReg2()), ploc.GetPrimTypeOfReg2());
76         }
77         if (ploc.GetReg3() != kRinvalid) {
78             generateStrInsn(static_cast<AArch64reg>(ploc.GetReg3()), ploc.GetPrimTypeOfReg3());
79         }
80     }
81 
82     aarFunc->GetFirstBB()->InsertAtBeginning(*aarFunc->GetDummyBB());
83 }
84 
MoveLocalRefVarToRefLocals(MIRSymbol & mirSym) const85 void AArch64MoveRegArgs::MoveLocalRefVarToRefLocals(MIRSymbol &mirSym) const
86 {
87     AArch64CGFunc *aarFunc = static_cast<AArch64CGFunc *>(cgFunc);
88     PrimType stype = mirSym.GetType()->GetPrimType();
89     uint32 byteSize = GetPrimTypeSize(stype);
90     uint32 bitSize = byteSize * kBitsPerByte;
91     MemOperand &memOpnd = aarFunc->GetOrCreateMemOpnd(mirSym, 0, bitSize, true);
92     RegOperand *regOpnd = nullptr;
93     if (mirSym.IsPreg()) {
94         PregIdx pregIdx = aarFunc->GetFunction().GetPregTab()->GetPregIdxFromPregno(
95             static_cast<uint32>(mirSym.GetPreg()->GetPregNo()));
96         regOpnd = &aarFunc->GetOrCreateVirtualRegisterOperand(aarFunc->GetVirtualRegNOFromPseudoRegIdx(pregIdx));
97     } else {
98         regOpnd = &aarFunc->GetOrCreateVirtualRegisterOperand(aarFunc->NewVReg(kRegTyInt, k8ByteSize));
99     }
100     Insn &insn =
101         aarFunc->GetInsnBuilder()->BuildInsn(aarFunc->PickLdInsn(GetPrimTypeBitSize(stype), stype), *regOpnd, memOpnd);
102     MemOperand &memOpnd1 = aarFunc->GetOrCreateMemOpnd(mirSym, 0, bitSize, false);
103     Insn &insn1 =
104         aarFunc->GetInsnBuilder()->BuildInsn(aarFunc->PickStInsn(GetPrimTypeBitSize(stype), stype), *regOpnd, memOpnd1);
105     aarFunc->GetCurBB()->InsertInsnBegin(insn1);
106     aarFunc->GetCurBB()->InsertInsnBegin(insn);
107 }
108 
LoadStackArgsToVReg(MIRSymbol & mirSym) const109 void AArch64MoveRegArgs::LoadStackArgsToVReg(MIRSymbol &mirSym) const
110 {
111     AArch64CGFunc *aarFunc = static_cast<AArch64CGFunc *>(cgFunc);
112     PrimType stype = mirSym.GetType()->GetPrimType();
113     uint32 byteSize = GetPrimTypeSize(stype);
114     uint32 bitSize = byteSize * kBitsPerByte;
115     MemOperand &memOpnd = aarFunc->GetOrCreateMemOpnd(mirSym, 0, bitSize);
116     PregIdx pregIdx =
117         aarFunc->GetFunction().GetPregTab()->GetPregIdxFromPregno(static_cast<uint32>(mirSym.GetPreg()->GetPregNo()));
118     RegOperand &dstRegOpnd =
119         aarFunc->GetOrCreateVirtualRegisterOperand(aarFunc->GetVirtualRegNOFromPseudoRegIdx(pregIdx));
120     Insn &insn = aarFunc->GetInsnBuilder()->BuildInsn(aarFunc->PickLdInsn(GetPrimTypeBitSize(stype), stype), dstRegOpnd,
121                                                       memOpnd);
122 
123     if (aarFunc->GetCG()->GenerateVerboseCG()) {
124         std::string key = "param: %%";
125         key += std::to_string(mirSym.GetPreg()->GetPregNo());
126         DEBUG_ASSERT(mirSym.GetStorageClass() == kScFormal, "vreg parameters should be kScFormal type.");
127         insn.SetComment(key);
128     }
129 
130     aarFunc->GetCurBB()->InsertInsnBegin(insn);
131 }
132 
MoveArgsToVReg(const CCLocInfo & ploc,MIRSymbol & mirSym) const133 void AArch64MoveRegArgs::MoveArgsToVReg(const CCLocInfo &ploc, MIRSymbol &mirSym) const
134 {
135     // when args parameter type i128, reg1 will be used.
136     // but, i128 is not supported in back-end
137     CHECK_FATAL(ploc.reg2 == kRinvalid, "NIY");
138     RegType regType = (ploc.reg0 < V0) ? kRegTyInt : kRegTyFloat;
139     PrimType sType = mirSym.GetType()->GetPrimType();
140     uint32 byteSize = GetPrimTypeSize(sType);
141     uint32 srcBitSize = ((byteSize < k4ByteSize) ? k4ByteSize : byteSize) * kBitsPerByte;
142     PregIdx pregIdx =
143         aarFunc->GetFunction().GetPregTab()->GetPregIdxFromPregno(static_cast<uint32>(mirSym.GetPreg()->GetPregNo()));
144     RegOperand &dstRegOpnd =
145         aarFunc->GetOrCreateVirtualRegisterOperand(aarFunc->GetVirtualRegNOFromPseudoRegIdx(pregIdx));
146     dstRegOpnd.SetSize(srcBitSize);
147     RegOperand &srcRegOpnd =
148         aarFunc->GetOrCreatePhysicalRegisterOperand(static_cast<AArch64reg>(ploc.reg0), srcBitSize, regType);
149     DEBUG_ASSERT(mirSym.GetStorageClass() == kScFormal, "should be args");
150     MOperator mOp = aarFunc->PickMovBetweenRegs(sType, sType);
151     Insn &insn = CreateMoveArgsToVRegInsn(mOp, dstRegOpnd, srcRegOpnd, sType);
152     if (aarFunc->GetCG()->GenerateVerboseCG()) {
153         std::string str = "param: %%";
154         str += std::to_string(mirSym.GetPreg()->GetPregNo());
155         insn.SetComment(str);
156     }
157     aarFunc->GetCurBB()->InsertInsnBegin(insn);
158 }
159 
CreateMoveArgsToVRegInsn(MOperator mOp,RegOperand & destOpnd,RegOperand & srcOpnd,PrimType primType) const160 Insn &AArch64MoveRegArgs::CreateMoveArgsToVRegInsn(MOperator mOp, RegOperand &destOpnd, RegOperand &srcOpnd,
161                                                    PrimType primType) const
162 {
163     if (mOp == MOP_wmovrr || mOp == MOP_xmovrr) {
164         /* callee ensure the validbit of parameters of function */
165         switch (primType) {
166             case PTY_u1: {
167                 ImmOperand &lsbOpnd = aarFunc->CreateImmOperand(maplebe::k0BitSize, srcOpnd.GetSize(), false);
168                 ImmOperand &widthOpnd = aarFunc->CreateImmOperand(maplebe::k1BitSize, srcOpnd.GetSize(), false);
169                 bool is64Bit = (srcOpnd.GetSize() == maplebe::k64BitSize);
170                 return aarFunc->GetInsnBuilder()->BuildInsn(is64Bit ? MOP_xubfxrri6i6 : MOP_wubfxrri5i5, destOpnd,
171                                                             srcOpnd, lsbOpnd, widthOpnd);
172             }
173             case PTY_u8:
174             case PTY_i8:
175                 return aarFunc->GetInsnBuilder()->BuildInsn(MOP_xuxtb32, destOpnd, srcOpnd);
176             case PTY_u16:
177             case PTY_i16:
178                 return aarFunc->GetInsnBuilder()->BuildInsn(MOP_xuxth32, destOpnd, srcOpnd);
179             case PTY_u32:
180             case PTY_i32: {
181                 destOpnd.SetValidBitsNum(maplebe::k64BitSize);
182                 return aarFunc->GetInsnBuilder()->BuildInsn(MOP_xuxtw64, destOpnd, srcOpnd);
183             }
184             default:
185                 return aarFunc->GetInsnBuilder()->BuildInsn(mOp, destOpnd, srcOpnd);
186         }
187     } else {
188         return aarFunc->GetInsnBuilder()->BuildInsn(mOp, destOpnd, srcOpnd);
189     }
190 }
191 
MoveVRegisterArgs()192 void AArch64MoveRegArgs::MoveVRegisterArgs()
193 {
194     aarFunc->GetDummyBB()->ClearInsns();
195     aarFunc->SetCurBB(*aarFunc->GetDummyBB());
196     CCImpl &parmlocator =
197         *static_cast<AArch64CGFunc *>(cgFunc)->GetOrCreateLocator(CCImpl::GetCallConvKind(cgFunc->GetFunction()));
198     CCLocInfo ploc;
199 
200     auto &mirFunc = aarFunc->GetFunction();
201     for (size_t i = 0; i < mirFunc.GetFormalCount(); ++i) {
202         MIRType *ty = mirFunc.GetNthParamType(i);
203         parmlocator.LocateNextParm(*ty, ploc, (i == 0), mirFunc.GetMIRFuncType());
204         MIRSymbol *sym = mirFunc.GetFormal(i);
205 
206         /* load locarefvar formals to store in the reflocals. */
207         if (mirFunc.GetNthParamAttr(i).GetAttr(ATTR_localrefvar) && ploc.reg0 == kRinvalid) {
208             MoveLocalRefVarToRefLocals(*sym);
209         }
210 
211         if (!sym->IsPreg()) {
212             continue;
213         }
214 
215         if (ploc.reg0 == kRinvalid) {
216             /* load stack parameters to the vreg. */
217             LoadStackArgsToVReg(*sym);
218         } else {
219             MoveArgsToVReg(ploc, *sym);
220         }
221     }
222 
223     aarFunc->GetFirstBB()->InsertAtBeginning(*aarFunc->GetDummyBB());
224 }
225 } /* namespace maplebe */
226