• 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 "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