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 "x64_optimize_common.h"
17 #include "x64_cgfunc.h"
18 #include "cgbb.h"
19 #include "cg.h"
20
21 namespace maplebe {
ModifyJumpTarget(Operand & targetOperand,BB & bb)22 void X64InsnVisitor::ModifyJumpTarget(Operand &targetOperand, BB &bb)
23 {
24 Insn *jmpInsn = bb.GetLastInsn();
25 if (bb.GetKind() == BB::kBBIgoto) {
26 CHECK_FATAL(targetOperand.IsLabel(), "NIY");
27 CHECK_FATAL(false, "NIY");
28 }
29 jmpInsn->SetOperand(x64::GetJumpTargetIdx(*jmpInsn), targetOperand);
30 }
31
ModifyJumpTarget(LabelIdx targetLabel,BB & bb)32 void X64InsnVisitor::ModifyJumpTarget(LabelIdx targetLabel, BB &bb)
33 {
34 std::string lableName = ".L." + std::to_string(GetCGFunc()->GetUniqueID()) + "__" + std::to_string(targetLabel);
35 ModifyJumpTarget(GetCGFunc()->GetOpndBuilder()->CreateLabel(lableName.c_str(), targetLabel), bb);
36 }
37
ModifyJumpTarget(BB & newTarget,BB & bb)38 void X64InsnVisitor::ModifyJumpTarget(BB &newTarget, BB &bb)
39 {
40 ModifyJumpTarget(newTarget.GetLastInsn()->GetOperand(x64::GetJumpTargetIdx(*newTarget.GetLastInsn())), bb);
41 }
42
CloneInsn(Insn & originalInsn)43 Insn *X64InsnVisitor::CloneInsn(Insn &originalInsn)
44 {
45 MemPool *memPool = const_cast<MemPool *>(CG::GetCurCGFunc()->GetMemoryPool());
46 if (originalInsn.IsTargetInsn()) {
47 if (!originalInsn.IsVectorOp()) {
48 return memPool->Clone<Insn>(originalInsn);
49 } else {
50 auto *insn = memPool->Clone<VectorInsn>(*static_cast<VectorInsn *>(&originalInsn));
51 insn->SetRegSpecList(static_cast<VectorInsn &>(originalInsn).GetRegSpecList());
52 return insn;
53 }
54 } else if (originalInsn.IsCfiInsn()) {
55 return memPool->Clone<cfi::CfiInsn>(*static_cast<cfi::CfiInsn *>(&originalInsn));
56 } else if (originalInsn.IsDbgInsn()) {
57 return memPool->Clone<mpldbg::DbgInsn>(*static_cast<mpldbg::DbgInsn *>(&originalInsn));
58 }
59 if (originalInsn.IsComment()) {
60 return memPool->Clone<Insn>(originalInsn);
61 }
62 CHECK_FATAL(false, "Cannot clone");
63 return nullptr;
64 }
65
66 /*
67 * Precondition: The given insn is a jump instruction.
68 * Get the jump target label operand index from the given instruction.
69 * Note: MOP_jmp_m, MOP_jmp_r is a jump instruction, but the target is unknown at compile time.
70 */
GetJumpLabel(const Insn & insn) const71 LabelIdx X64InsnVisitor::GetJumpLabel(const Insn &insn) const
72 {
73 uint32 operandIdx = x64::GetJumpTargetIdx(insn);
74 if (insn.GetOperand(operandIdx).IsLabelOpnd()) {
75 return static_cast<LabelOperand &>(insn.GetOperand(operandIdx)).GetLabelIndex();
76 }
77 DEBUG_ASSERT(false, "Operand is not label");
78 return 0;
79 }
80
IsCompareInsn(const Insn & insn) const81 bool X64InsnVisitor::IsCompareInsn(const Insn &insn) const
82 {
83 switch (insn.GetMachineOpcode()) {
84 case x64::MOP_cmpb_r_r:
85 case x64::MOP_cmpb_m_r:
86 case x64::MOP_cmpb_i_r:
87 case x64::MOP_cmpb_r_m:
88 case x64::MOP_cmpb_i_m:
89 case x64::MOP_cmpw_r_r:
90 case x64::MOP_cmpw_m_r:
91 case x64::MOP_cmpw_i_r:
92 case x64::MOP_cmpw_r_m:
93 case x64::MOP_cmpw_i_m:
94 case x64::MOP_cmpl_r_r:
95 case x64::MOP_cmpl_m_r:
96 case x64::MOP_cmpl_i_r:
97 case x64::MOP_cmpl_r_m:
98 case x64::MOP_cmpl_i_m:
99 case x64::MOP_cmpq_r_r:
100 case x64::MOP_cmpq_m_r:
101 case x64::MOP_cmpq_i_r:
102 case x64::MOP_cmpq_r_m:
103 case x64::MOP_cmpq_i_m:
104 case x64::MOP_testq_r_r:
105 return true;
106 default:
107 return false;
108 }
109 }
110
IsSimpleJumpInsn(const Insn & insn) const111 bool X64InsnVisitor::IsSimpleJumpInsn(const Insn &insn) const
112 {
113 return (insn.GetMachineOpcode() == x64::MOP_jmpq_l);
114 }
115
IsCompareAndBranchInsn(const Insn & insn) const116 bool X64InsnVisitor::IsCompareAndBranchInsn(const Insn &insn) const
117 {
118 return false;
119 }
120
IsTestAndSetCCInsn(const Insn & insn) const121 bool X64InsnVisitor::IsTestAndSetCCInsn(const Insn &insn) const
122 {
123 return false;
124 }
125
IsTestAndBranchInsn(const Insn & insn) const126 bool X64InsnVisitor::IsTestAndBranchInsn(const Insn &insn) const
127 {
128 return false;
129 }
130
IsAddOrSubInsn(const Insn & insn) const131 bool X64InsnVisitor::IsAddOrSubInsn(const Insn &insn) const
132 {
133 switch (insn.GetMachineOpcode()) {
134 case x64::MOP_addb_r_r:
135 case x64::MOP_addw_r_r:
136 case x64::MOP_addl_r_r:
137 case x64::MOP_addq_r_r:
138 case x64::MOP_addb_m_r:
139 case x64::MOP_addw_m_r:
140 case x64::MOP_addl_m_r:
141 case x64::MOP_addq_m_r:
142 case x64::MOP_addb_i_r:
143 case x64::MOP_addw_i_r:
144 case x64::MOP_addl_i_r:
145 case x64::MOP_addq_i_r:
146 case x64::MOP_addb_r_m:
147 case x64::MOP_addw_r_m:
148 case x64::MOP_addl_r_m:
149 case x64::MOP_addq_r_m:
150 case x64::MOP_addb_i_m:
151 case x64::MOP_addw_i_m:
152 case x64::MOP_addl_i_m:
153 case x64::MOP_addq_i_m:
154 case x64::MOP_subb_r_r:
155 case x64::MOP_subw_r_r:
156 case x64::MOP_subl_r_r:
157 case x64::MOP_subq_r_r:
158 case x64::MOP_subb_m_r:
159 case x64::MOP_subw_m_r:
160 case x64::MOP_subl_m_r:
161 case x64::MOP_subq_m_r:
162 case x64::MOP_subb_i_r:
163 case x64::MOP_subw_i_r:
164 case x64::MOP_subl_i_r:
165 case x64::MOP_subq_i_r:
166 case x64::MOP_subb_r_m:
167 case x64::MOP_subw_r_m:
168 case x64::MOP_subl_r_m:
169 case x64::MOP_subq_r_m:
170 case x64::MOP_subb_i_m:
171 case x64::MOP_subw_i_m:
172 case x64::MOP_subl_i_m:
173 return true;
174 default:
175 return false;
176 }
177 }
178
CreateVregFromReg(const RegOperand & pReg)179 RegOperand *X64InsnVisitor::CreateVregFromReg(const RegOperand &pReg)
180 {
181 return &GetCGFunc()->GetOpndBuilder()->CreateVReg(pReg.GetRegisterNumber(), pReg.GetSize(), pReg.GetRegisterType());
182 }
183
ReTargetSuccBB(BB & bb,LabelIdx newTarget) const184 void X64InsnVisitor::ReTargetSuccBB(BB &bb, LabelIdx newTarget) const
185 {
186 DEBUG_ASSERT(false, "not implement in X86_64");
187 (void)bb;
188 (void)newTarget;
189 return;
190 }
191
FlipIfBB(BB & bb,LabelIdx ftLabel) const192 void X64InsnVisitor::FlipIfBB(BB &bb, LabelIdx ftLabel) const
193 {
194 DEBUG_ASSERT(false, "not implement in X86_64");
195 (void)bb;
196 (void)ftLabel;
197 return;
198 }
199
CreateGotoBBAfterCondBB(BB & bb,BB & fallthru,bool isTargetFallthru) const200 BB *X64InsnVisitor::CreateGotoBBAfterCondBB(BB &bb, BB &fallthru, bool isTargetFallthru) const
201 {
202 DEBUG_ASSERT(false, "not implement in X86_64");
203 (void)bb;
204 (void)fallthru;
205 (void)isTargetFallthru;
206 return nullptr;
207 }
208
ModifyFathruBBToGotoBB(BB & bb,LabelIdx labelIdx) const209 void X64InsnVisitor::ModifyFathruBBToGotoBB(BB &bb, LabelIdx labelIdx) const
210 {
211 DEBUG_ASSERT(false, "not implement in X86_64");
212 (void)bb;
213 return;
214 }
215 } /* namespace maplebe */
216