• 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_isa.h"
17 #include "insn.h"
18 
19 namespace maplebe {
20 /*
21  * Get the ldp/stp corresponding to ldr/str
22  * mop : a ldr or str machine operator
23  */
GetMopPair(MOperator mop,bool isIncludeStrbStrh)24 MOperator GetMopPair(MOperator mop, bool isIncludeStrbStrh)
25 {
26     switch (mop) {
27         case MOP_xldr:
28             return MOP_xldp;
29         case MOP_wldr:
30             return MOP_wldp;
31         case MOP_xstr:
32             return MOP_xstp;
33         case MOP_wstr:
34             return MOP_wstp;
35         case MOP_dldr:
36             return MOP_dldp;
37         case MOP_qldr:
38             return MOP_qldp;
39         case MOP_sldr:
40             return MOP_sldp;
41         case MOP_dstr:
42             return MOP_dstp;
43         case MOP_sstr:
44             return MOP_sstp;
45         case MOP_qstr:
46             return MOP_qstp;
47         case MOP_wstrb:
48             return isIncludeStrbStrh ? MOP_wstrh : MOP_undef;
49         case MOP_wstrh:
50             return isIncludeStrbStrh ? MOP_wstr : MOP_undef;
51         default:
52             DEBUG_ASSERT(false, "should not run here");
53             return MOP_undef;
54     }
55 }
56 namespace AArch64isa {
FlipConditionOp(MOperator flippedOp)57 MOperator FlipConditionOp(MOperator flippedOp)
58 {
59     switch (flippedOp) {
60         case AArch64MopT::MOP_beq:
61             return AArch64MopT::MOP_bne;
62         case AArch64MopT::MOP_bge:
63             return AArch64MopT::MOP_blt;
64         case AArch64MopT::MOP_bgt:
65             return AArch64MopT::MOP_ble;
66         case AArch64MopT::MOP_bhi:
67             return AArch64MopT::MOP_bls;
68         case AArch64MopT::MOP_bhs:
69             return AArch64MopT::MOP_blo;
70         case AArch64MopT::MOP_ble:
71             return AArch64MopT::MOP_bgt;
72         case AArch64MopT::MOP_blo:
73             return AArch64MopT::MOP_bhs;
74         case AArch64MopT::MOP_bls:
75             return AArch64MopT::MOP_bhi;
76         case AArch64MopT::MOP_blt:
77             return AArch64MopT::MOP_bge;
78         case AArch64MopT::MOP_bne:
79             return AArch64MopT::MOP_beq;
80         case AArch64MopT::MOP_bpl:
81             return AArch64MopT::MOP_bmi;
82         case AArch64MopT::MOP_xcbnz:
83             return AArch64MopT::MOP_xcbz;
84         case AArch64MopT::MOP_wcbnz:
85             return AArch64MopT::MOP_wcbz;
86         case AArch64MopT::MOP_xcbz:
87             return AArch64MopT::MOP_xcbnz;
88         case AArch64MopT::MOP_wcbz:
89             return AArch64MopT::MOP_wcbnz;
90         case AArch64MopT::MOP_wtbnz:
91             return AArch64MopT::MOP_wtbz;
92         case AArch64MopT::MOP_wtbz:
93             return AArch64MopT::MOP_wtbnz;
94         case AArch64MopT::MOP_xtbnz:
95             return AArch64MopT::MOP_xtbz;
96         case AArch64MopT::MOP_xtbz:
97             return AArch64MopT::MOP_xtbnz;
98         default:
99             break;
100     }
101     return AArch64MopT::MOP_undef;
102 }
103 
GetJumpTargetIdx(const Insn & insn)104 uint32 GetJumpTargetIdx(const Insn &insn)
105 {
106     MOperator curMop = insn.GetMachineOpcode();
107     switch (curMop) {
108         /* unconditional jump */
109         case MOP_xuncond: {
110             return kInsnFirstOpnd;
111         }
112         case MOP_xbr: {
113             DEBUG_ASSERT(insn.GetOperandSize() == 2, "ERR");  // must have 2
114             return kInsnSecondOpnd;
115         }
116             /* conditional jump */
117         case MOP_bmi:
118         case MOP_bvc:
119         case MOP_bls:
120         case MOP_blt:
121         case MOP_ble:
122         case MOP_blo:
123         case MOP_beq:
124         case MOP_bpl:
125         case MOP_bhs:
126         case MOP_bvs:
127         case MOP_bhi:
128         case MOP_bgt:
129         case MOP_bge:
130         case MOP_bne:
131         case MOP_wcbz:
132         case MOP_xcbz:
133         case MOP_wcbnz:
134         case MOP_xcbnz: {
135             return kInsnSecondOpnd;
136         }
137         case MOP_wtbz:
138         case MOP_xtbz:
139         case MOP_wtbnz:
140         case MOP_xtbnz: {
141             return kInsnThirdOpnd;
142         }
143         default:
144             CHECK_FATAL(false, "Not a jump insn");
145     }
146     return kInsnFirstOpnd;
147 }
148 
149 // This api is only used for cgir verify, implemented by calling the memopndofst interface.
GetMemOpndOffsetValue(Operand * o)150 int64 GetMemOpndOffsetValue(Operand *o)
151 {
152     auto *memOpnd = static_cast<MemOperand *>(o);
153     CHECK_FATAL(memOpnd != nullptr, "memOpnd should not be nullptr");
154     // kBOR memOpnd has no offsetvalue, so return 0 for verify.
155     // todo: AArch64AddressingMode is different from BiShengC
156     if (memOpnd->GetAddrMode() == MemOperand::kAddrModeBOrX) {
157         return 0;
158     }
159     // Offset value of kBOI & kLo12Li can be got.
160     OfstOperand *ofStOpnd = memOpnd->GetOffsetImmediate();
161     int64 offsetValue = ofStOpnd ? ofStOpnd->GetOffsetValue() : 0LL;
162     return offsetValue;
163 }
164 
IsSub(const Insn & insn)165 bool IsSub(const Insn &insn)
166 {
167     MOperator curMop = insn.GetMachineOpcode();
168     switch (curMop) {
169         case MOP_xsubrrr:
170         case MOP_xsubrrrs:
171         case MOP_xsubrri24:
172         case MOP_xsubrri12:
173         case MOP_wsubrrr:
174         case MOP_wsubrrrs:
175         case MOP_wsubrri24:
176         case MOP_wsubrri12:
177             return true;
178         default:
179             return false;
180     }
181 }
182 
GetMopSub2Subs(const Insn & insn)183 MOperator GetMopSub2Subs(const Insn &insn)
184 {
185     MOperator curMop = insn.GetMachineOpcode();
186     switch (curMop) {
187         case MOP_xsubrrr:
188             return MOP_xsubsrrr;
189         case MOP_xsubrrrs:
190             return MOP_xsubsrrrs;
191         case MOP_xsubrri24:
192             return MOP_xsubsrri24;
193         case MOP_xsubrri12:
194             return MOP_xsubsrri12;
195         case MOP_wsubrrr:
196             return MOP_wsubsrrr;
197         case MOP_wsubrrrs:
198             return MOP_wsubsrrrs;
199         case MOP_wsubrri24:
200             return MOP_wsubsrri24;
201         case MOP_wsubrri12:
202             return MOP_wsubsrri12;
203         default:
204             return curMop;
205     }
206 }
207 
208 // Returns the number of trailing 0-bits in x, starting at the least significant bit position.
209 // If x is 0, the result is -1.
GetTail0BitNum(int64 val)210 int32 GetTail0BitNum(int64 val)
211 {
212     uint32 bitNum = 0;
213     for (; bitNum < k64BitSize; bitNum++) {
214         if (((1ULL << bitNum) & static_cast<uint64>(val)) != 0) {
215             break;
216         }
217     }
218     if (bitNum == k64BitSize) {
219         return -1;
220     }
221     return static_cast<int32>(bitNum);
222 }
223 
224 // Returns the number of leading 0-bits in x, starting at the most significant bit position.
225 // If x is 0, the result is -1.
GetHead0BitNum(int64 val)226 int32 GetHead0BitNum(int64 val)
227 {
228     uint32 bitNum = 0;
229     for (; bitNum < k64BitSize; bitNum++) {
230         if (((0x8000000000000000ULL >> bitNum) & static_cast<uint64>(val)) != 0) {
231             break;
232         }
233     }
234     if (bitNum == k64BitSize) {
235         return -1;
236     }
237     return static_cast<int32>(bitNum);
238 }
239 } /* namespace AArch64isa */
240 } /* namespace maplebe */
241