Fixes as part of validation.
[dyninst.git] / instructionAPI / src / InstructionDecoder-aarch64.h
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  *
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  *
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  *
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  *
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  *
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #include "InstructionDecoderImpl.h"
32 #include <iostream>
33 #include "Immediate.h"
34 #include "dyn_regs.h"
35
36 namespace Dyninst {
37     namespace InstructionAPI
38     {
39
40 #if defined(__GNUC__)
41 #define insn_printf(format, ...) \
42         do{ \
43             printf("[%s:%u]insn_debug " format, FILE__, __LINE__, ## __VA_ARGS__); \
44         }while(0)
45 #endif
46
47 #define AARCH64_INSN_LENGTH     32
48
49         struct aarch64_insn_entry;
50                 struct aarch64_mask_entry;
51
52         class InstructionDecoder_aarch64 : public InstructionDecoderImpl
53         {
54             friend struct aarch64_insn_entry;
55                         friend struct aarch64_mask_entry;
56
57             public:
58                 InstructionDecoder_aarch64(Architecture a);
59                 virtual ~InstructionDecoder_aarch64();
60                 virtual void decodeOpcode(InstructionDecoder::buffer& b);
61                 virtual Instruction::Ptr decode(InstructionDecoder::buffer& b);
62                                 virtual void setMode(bool) {}
63                 virtual bool decodeOperands(const Instruction* insn_to_complete);
64                 virtual void doDelayedDecode(const Instruction* insn_to_complete);
65
66                 using InstructionDecoderImpl::makeRegisterExpression;
67
68                 std::vector<std::string> condStringMap = {"eq","ne","cs","cc","mi","pl","vs","vc","hi","ls","ge","lt","gt","le","al","nv"};
69
70                 #define IS_INSN_LOGICAL_SHIFT(I)                (field<24, 28>(I) == 0x0A)
71                 #define IS_INSN_ADDSUB_EXT(I)                   (field<24, 28>(I) == 0x0B && field<21, 21>(I) == 1)
72                 #define IS_INSN_ADDSUB_SHIFT(I)                 (field<24, 28>(I) == 0x0B && field<21, 21>(I) == 0)
73                 #define IS_INSN_ADDSUB_IMM(I)                   (field<24, 28>(I) == 0x11)
74                 #define IS_INSN_ADDSUB_CARRY(I)                 (field<21, 28>(I) == 0xD0)
75
76                 //----ld/st-----
77                 #define IS_INSN_LDST(I)                 (field<25, 25>(I) == 0x00 && field<27, 27>(I) == 1)
78
79                 #define IS_INSN_LDST_EX(I)              (field<24, 29>(I) == 0x08)
80                 #define IS_INSN_LDST_EX_PAIR(I)         (field<24, 29>(I) == 0x08 && field<15, 15>(I) == 0x01 && field<21, 21>(I) ==0x01)
81
82                 #define IS_INSN_LD_LITERAL(I)           (field<27, 29>(I) == 0x03 && field<24, 25>(I) == 0)
83
84                 #define IS_INSN_LDST_PAIR(I)            (field<27, 29>(I) == 0x05)
85                 #define IS_INSN_LDST_PAIR_PRE(I)        (field<27, 29>(I) == 0x05 && field<23, 25>(I) == 0x03)
86                 #define IS_INSN_LDST_PAIR_OFFSET(I)     (field<27, 29>(I) == 0x05 && field<23, 25>(I) == 0x02)
87                 #define IS_INSN_LDST_PAIR_POST(I)       (field<27, 29>(I) == 0x05 && field<23, 25>(I) == 0x01)
88                 #define IS_INSN_LDST_PAIR_NOALLOC(I)    (field<27, 29>(I) == 0x05 && field<23, 25>(I) == 0x00)
89
90                 #define IS_INSN_LDST_UNSCALED(I)        (field<27, 29>(I) == 0x07 && field<24, 25>(I) == 0 && field<21, 21>(I) == 0 && field<10, 11>(I) == 0x00)
91                 #define IS_INSN_LDST_POST(I)            (field<27, 29>(I) == 0x07 && field<24, 25>(I) == 0 && field<21, 21>(I) == 0 && field<10, 11>(I) == 0x01)
92                 #define IS_INSN_LDST_UNPRIV(I)          (field<27, 29>(I) == 0x07 && field<24, 25>(I) == 0 && field<21, 21>(I) == 0 && field<10, 11>(I) == 0x02)
93                 #define IS_INSN_LDST_PRE(I)             (field<27, 29>(I) == 0x07 && field<24, 25>(I) == 0 && field<21, 21>(I) == 0 && field<10, 11>(I) == 0x03)
94                 #define IS_INSN_LDST_REG(I)                 (field<27, 29>(I) == 0x07 && field<24, 25>(I) == 0 && field<21, 21>(I) == 1 && field<10, 11>(I) == 0x02)
95                 #define IS_INSN_LDST_UIMM(I)            (field<27, 29>(I) == 0x07 && field<24, 25>(I) == 1)
96
97
98                 #define IS_INSN_LOGICAL_IMM(I)                  (field<23, 28>(I) == 0x24)
99                 #define IS_INSN_BITFIELD(I)                             (field<23, 28>(I) == 0x26)
100                 #define IS_INSN_EXCEPTION(I)                    (field<24, 31>(I) == 0xD4)
101                 #define IS_INSN_FP_COMPARE(I)                   (field<24, 28>(I) == 0x1E && field<10, 13>(I) == 0x8)
102                 #define IS_INSN_FP_CONV_FIX(I)                  (field<24, 28>(I) == 0x1E && field<21, 21>(I) == 0x0)
103                 #define IS_INSN_FP_CONV_INT(I)                  (field<24, 28>(I) == 0x1E && field<21, 21>(I) == 0x1 && field<10, 15>(I) == 0x0)
104                 #define IS_SOURCE_GP(I)                                 (field<16, 18>(I) == 0x2  || field<16, 18>(I) == 0x3 || field<16, 18>(I) == 0x7)
105                 #define IS_INSN_FP_IMM(I)                               (field<24, 28>(I) == 0x1E && field<10, 15>(I) == 0x0 && field<10, 12>(I) == 0x4)
106                 #define IS_INSN_FP_DATAPROC_ONESRC(I)   (field<24, 31>(I) == 0x1E && field<10, 14>(I) == 0x10)
107                                 #define IS_INSN_B_UNCOND(I)                             (field<26, 30>(I) == 0x05)
108                 #define IS_INSN_B_UNCOND_REG(I)                 (field<25, 31>(I) == 0x6B)
109                 #define IS_INSN_B_COMPARE(I)                    (field<25, 30>(I) == 0x1A)
110                 #define IS_INSN_B_TEST(I)                               (field<25, 30>(I) == 0x1B)
111                 #define IS_INSN_B_COND(I)                               (field<25, 31>(I) == 0x2A)
112                 #define IS_INSN_PCREL_ADDR(I)                   (field<24, 28>(I) == 0x10)
113                 #define IS_INSN_BRANCHING(I)                    (IS_INSN_B_COND(I) || IS_INSN_B_UNCOND(I) || IS_INSN_B_UNCOND_REG(I) || IS_INSN_B_TEST(I) ||                    IS_INSN_B_COMPARE(I))
114
115                 #define IS_FIELD_IMMR(S, E)                             (S == 16 && E == 21)
116                 #define IS_FIELD_IMMS(S, E)                             (S == 10 && E == 15)
117                 #define IS_FIELD_IMMLO(S, E)                    (S == 29 && E == 30)
118                 #define IS_FIELD_IMMHI(S, E)                    (S == 5 && E == 23)
119
120             private:
121                 virtual Result_Type makeSizeType(unsigned int opType);
122
123                                 bool isPstateRead, isPstateWritten;
124                 bool isFPInsn;
125                 bool isSIMDInsn;
126                 bool is64Bit;
127                 bool isValid;
128
129                 void mainDecode();
130                 int findInsnTableIndex(unsigned int);
131                 unsigned int insn;
132                 Instruction* insn_in_progress;
133                 Instruction* invalid_insn;
134
135                 // inherit from ppc is not sematically consistent with aarch64 manual
136                 template <int start, int end>
137                 int field(unsigned int raw)
138                 {
139 #if defined DEBUG_FIELD
140                     std::cerr << start << "-" << end << ":" << std::dec << (raw >> (start) &
141                             (0xFFFFFFFF >> (31 - (end - start)))) << " ";
142 #endif
143                     return (raw >> (start) & (0xFFFFFFFF >> (31 - (end - start))));
144                 }
145
146                 int32_t sign_extend32(int size, int in)
147                 {
148                                         int32_t val = 0|in;
149
150                     return (val << (32 - size)) >> (32 - size);
151                 }
152
153                 int64_t sign_extend64(int size, int in)
154                 {
155                                         int64_t val = 0|in;
156
157                     return (val << (64 - size)) >> (64 - size);
158                 }
159
160                 uint32_t unsign_extend32(int size, int in)
161                 {
162                                         uint32_t mask = ~0;
163
164                     return (mask>>(32-size)) & in;
165                                 }
166
167                 uint64_t unsign_extend64(int size, int in)
168                 {
169                                         uint64_t mask = ~0;
170
171                     return (mask>>(64-size)) & in;
172                                 }
173
174                 bool isSystemInsn;
175                                 int op0Field, op1Field, op2Field, crnField, crmField;
176                                 void processSystemInsn();
177
178                                 bool hasHw;
179                                 int hwField;
180                                 void processHwFieldInsn(int, int);
181
182                                 bool hasShift;
183                                 int shiftField;
184                                 void processShiftFieldShiftedInsn(int, int);
185                                 void processShiftFieldImmInsn(int, int);
186
187                                 bool hasOption;
188                                 int optionField;
189                                 void processOptionFieldLSRegOffsetInsn();
190
191                                 bool hasN;
192                                 int immr, immrLen;
193                                 int sField, nField, nLen;
194
195                         int immlo, immloLen;
196                                 void makeBranchTarget(bool, bool, int, int);
197                                 void makeLinkForBranch();
198                                 Expression::Ptr makeFallThroughExpr();
199
200                 int _szField;
201                 int _typeField;
202
203                 void set32Mode();
204                                 void setRegWidth();
205                                 void setFPMode();
206                                 void setSIMDMode();
207
208                 bool isSinglePrec();
209
210                                 MachRegister makeAarch64RegID(MachRegister, unsigned int);
211                                 Expression::Ptr makeRdExpr();
212                                 Expression::Ptr makeRnExpr();
213                                 Expression::Ptr makeRmExpr();
214                                 Expression::Ptr makeRaExpr();
215                                 Expression::Ptr makeRsExpr();
216                                 Expression::Ptr makePstateExpr();
217                 Expression::Ptr makePCExpr();
218                                 Expression::Ptr makeOptionExpression(int, int);
219                                 template<typename T, Result_Type rT>
220                                 Expression::Ptr fpExpand(int);
221                 Expression::Ptr makeRtExpr();
222                 Expression::Ptr makeRt2Expr();
223
224                 Expression::Ptr makeMemRefReg();
225                 Expression::Ptr makeMemRefReg_Rm();
226                 Expression::Ptr makeMemRefReg_ext();
227                 Expression::Ptr makeMemRefReg_amount();
228
229                 Expression::Ptr makeMemRefIndexLiteral();
230                 Expression::Ptr makeMemRefIndexUImm();
231                 Expression::Ptr makeMemRefIndexPre();
232                 Expression::Ptr makeMemRefIndexPost();
233                 Expression::Ptr makeMemRefIndex_addOffset9();
234                 Expression::Ptr makeMemRefIndex_offset9();
235
236                 Expression::Ptr makeMemRefPairPre();
237                 Expression::Ptr makeMemRefPairPost();
238                 Expression::Ptr makeMemRefPair_offset7();
239                 Expression::Ptr makeMemRefPair_addOffset7();
240                 Expression::Ptr makeMemRefEx();
241                 Expression::Ptr makeMemRefExPair();
242                 Expression::Ptr makeMemRefExPair2();
243                 //Expression::Ptr makeMemRefPairPre2();
244                 //Expression::Ptr makeMemRefPairPost2();
245                 //Expression::Ptr makeMemRefExPair16B();
246
247
248                 void getMemRefIndexLiteral_OffsetLen(int &, int &);
249                 void getMemRefIndex_SizeSizelen(unsigned int &, unsigned int &);
250                 void getMemRefIndexPrePost_ImmImmlen(unsigned int& , unsigned int& );
251                 void getMemRefPair_ImmImmlen(unsigned int &immVal, unsigned int &immLen);
252
253                 void getMemRefEx_RT(Result_Type &rt);
254                 void getMemRefIndexLiteral_RT(Result_Type &);
255                 void getMemRefExPair_RT(Result_Type &rt);
256                 void getMemRefPair_RT(Result_Type &rt);
257                 void getMemRefIndex_RT(Result_Type &);
258                 void getMemRefIndexUImm_RT(Result_Type &);
259
260                                 void OPRRd();
261                                 void OPRsf();
262                                 template<unsigned int endBit, unsigned int startBit>
263                 void OPRoption();
264                                 void OPRshift();
265                                 void OPRhw();
266                                 template<unsigned int endBit, unsigned int startBit>
267                 void OPRN();
268
269                 //for load store
270                 void LIndex();
271                 void STIndex();
272                                 void OPRRn();
273                 void OPRRnL();
274                 void OPRRnLU();
275                 void OPRRnSU();
276                 void OPRRnS();
277                                 void OPRRnU();
278                                 void OPRRm();
279                                 void OPRRt();
280                                 void OPRRtL();
281                                 void OPRRtS();
282                                 void OPRRt2();
283                                 void OPRRt2L();
284                                 void OPRRt2S();
285
286                                 void OPRop1();
287                                 void OPRop2();
288                                 template<unsigned int endBit, unsigned int startBit>
289                 void OPRcond();
290                                 void OPRnzcv();
291                                 void OPRCRm();
292                                 void OPRCRn();
293                                 template<unsigned int endBit, unsigned int startBit>
294                 void OPRS();
295                                 void OPRRa();
296                                 void OPRo0();
297                                 void OPRb5();
298                                 void OPRb40();
299                                 template<unsigned int endBit, unsigned int startBit>
300                                 void OPRsz();
301                                 void OPRRs();
302                                 template<unsigned int endBit, unsigned int startBit>
303                 void OPRimm();
304                                 void OPRscale();
305                                 template<unsigned int endBit, unsigned int startBit>
306                 void OPRtype();
307
308                 void OPRH() {}
309                 void OPRL() {}
310                 void OPRM() {}
311                 void OPRQ() {}
312                 void OPRa() {}
313                 void OPRb() {}
314                 void OPRc() {}
315                 void OPRd() {}
316                 void OPRe() {}
317                 void OPRf() {}
318                 void OPRg() {}
319                 void OPRh() {}
320                 void OPRopc() {}
321                 void OPRopcode() {}
322                 void OPRlen() {}
323                 template<unsigned int endBit, unsigned int startBit>
324                 void OPRsize() {}
325                 void OPRcmode() {}
326                 void OPRrmode() {}
327                 void OPRop() {}
328         };
329     }
330 }