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 "cg_irbuilder.h"
17 #include "cg.h"
18
19 namespace maplebe {
BuildInsn(MOperator opCode,const InsnDesc & idesc)20 Insn &InsnBuilder::BuildInsn(MOperator opCode, const InsnDesc &idesc)
21 {
22 auto *newInsn = mp->New<Insn>(*mp, opCode);
23 newInsn->SetInsnDescrption(idesc);
24 newInsn->SetDebugComment(currDedugComment);
25 IncreaseInsnNum();
26 return *newInsn;
27 }
28
BuildInsn(MOperator opCode,Operand & o0)29 Insn &InsnBuilder::BuildInsn(MOperator opCode, Operand &o0)
30 {
31 const InsnDesc &tMd = Globals::GetInstance()->GetTarget()->GetTargetMd(opCode);
32 return BuildInsn(opCode, tMd).AddOpndChain(o0);
33 }
BuildInsn(MOperator opCode,Operand & o0,Operand & o1)34 Insn &InsnBuilder::BuildInsn(MOperator opCode, Operand &o0, Operand &o1)
35 {
36 const InsnDesc &tMd = Globals::GetInstance()->GetTarget()->GetTargetMd(opCode);
37 return BuildInsn(opCode, tMd).AddOpndChain(o0).AddOpndChain(o1);
38 }
BuildInsn(MOperator opCode,Operand & o0,Operand & o1,Operand & o2)39 Insn &InsnBuilder::BuildInsn(MOperator opCode, Operand &o0, Operand &o1, Operand &o2)
40 {
41 const InsnDesc &tMd = Globals::GetInstance()->GetTarget()->GetTargetMd(opCode);
42 return BuildInsn(opCode, tMd).AddOpndChain(o0).AddOpndChain(o1).AddOpndChain(o2);
43 }
44
BuildInsn(MOperator opCode,Operand & o0,Operand & o1,Operand & o2,Operand & o3)45 Insn &InsnBuilder::BuildInsn(MOperator opCode, Operand &o0, Operand &o1, Operand &o2, Operand &o3)
46 {
47 const InsnDesc &tMd = Globals::GetInstance()->GetTarget()->GetTargetMd(opCode);
48 return BuildInsn(opCode, tMd).AddOpndChain(o0).AddOpndChain(o1).AddOpndChain(o2).AddOpndChain(o3);
49 }
50
BuildInsn(MOperator opCode,Operand & o0,Operand & o1,Operand & o2,Operand & o3,Operand & o4)51 Insn &InsnBuilder::BuildInsn(MOperator opCode, Operand &o0, Operand &o1, Operand &o2, Operand &o3, Operand &o4)
52 {
53 const InsnDesc &tMd = Globals::GetInstance()->GetTarget()->GetTargetMd(opCode);
54 Insn &nI = BuildInsn(opCode, tMd);
55 return nI.AddOpndChain(o0).AddOpndChain(o1).AddOpndChain(o2).AddOpndChain(o3).AddOpndChain(o4);
56 }
57
BuildInsn(MOperator opCode,std::vector<Operand * > & opnds)58 Insn &InsnBuilder::BuildInsn(MOperator opCode, std::vector<Operand *> &opnds)
59 {
60 const InsnDesc &tMd = Globals::GetInstance()->GetTarget()->GetTargetMd(opCode);
61 Insn &nI = BuildInsn(opCode, tMd);
62 for (auto *opnd : opnds) {
63 nI.AddOperand(*opnd);
64 }
65 return nI;
66 }
67
BuildCfiInsn(MOperator opCode)68 Insn &InsnBuilder::BuildCfiInsn(MOperator opCode)
69 {
70 auto *nI = mp->New<cfi::CfiInsn>(*mp, opCode);
71 IncreaseInsnNum();
72 return *nI;
73 }
74
CreateImm(uint32 size,int64 value,MemPool * mp)75 ImmOperand &OperandBuilder::CreateImm(uint32 size, int64 value, MemPool *mp)
76 {
77 return mp ? *mp->New<ImmOperand>(value, size, false) : *alloc.New<ImmOperand>(value, size, false);
78 }
79
CreateImm(uint32 size,int64 value,bool isSigned,MemPool * mp)80 ImmOperand &OperandBuilder::CreateImm(uint32 size, int64 value, bool isSigned, MemPool *mp)
81 {
82 return mp ? *mp->New<ImmOperand>(value, size, isSigned) : *alloc.New<ImmOperand>(value, size, isSigned);
83 }
84
CreateImm(const MIRSymbol & symbol,int64 offset,int32 relocs,MemPool * mp)85 ImmOperand &OperandBuilder::CreateImm(const MIRSymbol &symbol, int64 offset, int32 relocs, MemPool *mp)
86 {
87 return mp ? *mp->New<ImmOperand>(symbol, offset, relocs, false)
88 : *alloc.New<ImmOperand>(symbol, offset, relocs, false);
89 }
90
CreateOfst(int64 offset,uint32 size,MemPool * mp)91 OfstOperand &OperandBuilder::CreateOfst(int64 offset, uint32 size, MemPool *mp)
92 {
93 return mp ? *mp->New<OfstOperand>(offset, size) : *alloc.New<OfstOperand>(offset, size);
94 }
95
CreateMem(uint32 size,MemPool * mp)96 MemOperand &OperandBuilder::CreateMem(uint32 size, MemPool *mp)
97 {
98 return mp ? *mp->New<MemOperand>(size) : *alloc.New<MemOperand>(size);
99 }
100
CreateMem(RegOperand & baseOpnd,int64 offset,uint32 size,MemPool * mp)101 MemOperand &OperandBuilder::CreateMem(RegOperand &baseOpnd, int64 offset, uint32 size, MemPool *mp)
102 {
103 OfstOperand &ofstOperand = CreateOfst(offset, baseOpnd.GetSize());
104 if (mp != nullptr) {
105 return *mp->New<MemOperand>(&baseOpnd, &ofstOperand, size);
106 }
107 return *alloc.New<MemOperand>(&baseOpnd, &ofstOperand, size);
108 }
109
CreateMem(uint32 size,RegOperand & baseOpnd,ImmOperand & ofstOperand,MemPool * mp)110 MemOperand &OperandBuilder::CreateMem(uint32 size, RegOperand &baseOpnd, ImmOperand &ofstOperand, MemPool *mp)
111 {
112 if (mp != nullptr) {
113 return *mp->New<MemOperand>(size, &baseOpnd, nullptr, &ofstOperand, nullptr);
114 }
115 return *alloc.New<MemOperand>(size, &baseOpnd, nullptr, &ofstOperand, nullptr);
116 }
117
CreateMem(uint32 size,RegOperand & baseOpnd,ImmOperand & ofstOperand,const MIRSymbol & symbol,MemPool * mp)118 MemOperand &OperandBuilder::CreateMem(uint32 size, RegOperand &baseOpnd, ImmOperand &ofstOperand,
119 const MIRSymbol &symbol, MemPool *mp)
120 {
121 if (mp != nullptr) {
122 return *mp->New<MemOperand>(MemOperand::kAddrModeLo12Li, size, baseOpnd, nullptr, &ofstOperand, &symbol);
123 }
124 return *alloc.New<MemOperand>(MemOperand::kAddrModeLo12Li, size, baseOpnd, nullptr, &ofstOperand, &symbol);
125 }
126
CreateBitShift(BitShiftOperand::ShiftOp op,uint32 amount,uint32 bitLen,MemPool * mp)127 BitShiftOperand &OperandBuilder::CreateBitShift(BitShiftOperand::ShiftOp op, uint32 amount, uint32 bitLen, MemPool *mp)
128 {
129 if (mp != nullptr) {
130 return *mp->New<BitShiftOperand>(op, amount, bitLen);
131 }
132 return *alloc.New<BitShiftOperand>(op, amount, bitLen);
133 }
134
CreateVReg(uint32 size,RegType type,MemPool * mp)135 RegOperand &OperandBuilder::CreateVReg(uint32 size, RegType type, MemPool *mp)
136 {
137 regno_t vRegNO = virtualReg.GetNextVregNO(type, size / k8BitSize);
138 RegOperand &rp = mp ? *mp->New<RegOperand>(vRegNO, size, type) : *alloc.New<RegOperand>(vRegNO, size, type);
139 maplebe::VregInfo::vRegOperandTable[vRegNO] = &rp;
140 return rp;
141 }
142
CreateVReg(regno_t vRegNO,uint32 size,RegType type,MemPool * mp)143 RegOperand &OperandBuilder::CreateVReg(regno_t vRegNO, uint32 size, RegType type, MemPool *mp)
144 {
145 RegOperand &rp = mp ? *mp->New<RegOperand>(vRegNO, size, type) : *alloc.New<RegOperand>(vRegNO, size, type);
146 maplebe::VregInfo::vRegOperandTable[vRegNO] = &rp;
147 return rp;
148 }
149
CreatePReg(regno_t pRegNO,uint32 size,RegType type,MemPool * mp)150 RegOperand &OperandBuilder::CreatePReg(regno_t pRegNO, uint32 size, RegType type, MemPool *mp)
151 {
152 return mp ? *mp->New<RegOperand>(pRegNO, size, type) : *alloc.New<RegOperand>(pRegNO, size, type);
153 }
154
CreateList(MemPool * mp)155 ListOperand &OperandBuilder::CreateList(MemPool *mp)
156 {
157 return mp ? *mp->New<ListOperand>(alloc) : *alloc.New<ListOperand>(alloc);
158 }
159
CreateFuncNameOpnd(MIRSymbol & symbol,MemPool * mp)160 FuncNameOperand &OperandBuilder::CreateFuncNameOpnd(MIRSymbol &symbol, MemPool *mp)
161 {
162 return mp ? *mp->New<FuncNameOperand>(symbol) : *alloc.New<FuncNameOperand>(symbol);
163 }
164
CreateLabel(const char * parent,LabelIdx idx,MemPool * mp)165 LabelOperand &OperandBuilder::CreateLabel(const char *parent, LabelIdx idx, MemPool *mp)
166 {
167 return mp ? *mp->New<LabelOperand>(parent, idx, *mp) : *alloc.New<LabelOperand>(parent, idx, *alloc.GetMemPool());
168 }
169 } // namespace maplebe
170