Modified logic for constructing an AST for a branch instruction.
[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                 std::vector<std::string> condStringMap;
67
68                 #define IS_INSN_LOGICAL_SHIFT(I)                (field<24, 28>(I) == 0x0A)
69                 #define IS_INSN_ADDSUB_EXT(I)                   (field<24, 28>(I) == 0x0B && field<21, 21>(I) == 1)
70                 #define IS_INSN_ADDSUB_SHIFT(I)                 (field<24, 28>(I) == 0x0B && field<21, 21>(I) == 0)
71                 #define IS_INSN_ADDSUB_IMM(I)                   (field<24, 28>(I) == 0x11)
72                 #define IS_INSN_ADDSUB_CARRY(I)                 (field<21, 28>(I) == 0xD0)
73
74                 //----ld/st-----
75                 #define IS_INSN_LDST(I)                 (field<25, 25>(I) == 0x00 && field<27, 27>(I) == 1)
76
77                 #define IS_INSN_LDST_EX(I)              (field<24, 29>(I) == 0x08)
78                 #define IS_INSN_LDST_EX_PAIR(I)         (field<24, 29>(I) == 0x08 && field<15, 15>(I) == 0x01 && field<21, 21>(I) ==0x01)
79
80                 #define IS_INSN_LD_LITERAL(I)           (field<27, 29>(I) == 0x03 && field<24, 25>(I) == 0)
81
82                 #define IS_INSN_LDST_PAIR(I)            (field<27, 29>(I) == 0x05)
83                 #define IS_INSN_LDST_PAIR_PRE(I)        (field<27, 29>(I) == 0x05 && field<23, 25>(I) == 0x03)
84                 #define IS_INSN_LDST_PAIR_OFFSET(I)     (field<27, 29>(I) == 0x05 && field<23, 25>(I) == 0x02)
85                 #define IS_INSN_LDST_PAIR_POST(I)       (field<27, 29>(I) == 0x05 && field<23, 25>(I) == 0x01)
86                 #define IS_INSN_LDST_PAIR_NOALLOC(I)    (field<27, 29>(I) == 0x05 && field<23, 25>(I) == 0x00)
87
88                 #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)
89                 #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)
90                 #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)
91                 #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)
92                 #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)
93                 #define IS_INSN_LDST_UIMM(I)            (field<27, 29>(I) == 0x07 && field<24, 25>(I) == 1)
94
95
96                 #define IS_INSN_LOGICAL_IMM(I)                  (field<23, 28>(I) == 0x24)
97                 #define IS_INSN_BITFIELD(I)                             (field<23, 28>(I) == 0x26)
98                 #define IS_INSN_EXCEPTION(I)                    (field<24, 31>(I) == 0xD4)
99                 #define IS_INSN_FP_COMPARE(I)                   (field<24, 28>(I) == 0x1E && field<21, 21>(I) == 0x1 && field<10, 13>(I) == 0x8)
100                 #define IS_INSN_FP_CONV_FIX(I)                  (field<24, 28>(I) == 0x1E && field<21, 21>(I) == 0x0)
101                 #define IS_INSN_FP_CONV_INT(I)                  (field<24, 28>(I) == 0x1E && field<21, 21>(I) == 0x1 && field<10, 15>(I) == 0x0)
102                 #define IS_SOURCE_GP(I)                                 (field<16, 18>(I) == 0x2  || field<16, 18>(I) == 0x3 || field<16, 18>(I) == 0x7)
103                 #define IS_INSN_FP_IMM(I)                               (field<24, 28>(I) == 0x1E && field<21, 21>(I) == 0x1 && field<10, 12>(I) == 0x4)
104                                 #define IS_INSN_FP_DATAPROC_ONESRC(I)   (field<24, 28>(I) == 0x1E && field<21, 21>(I) == 0x1 && field<10, 14>(I) == 0x10)
105                                 #define IS_INSN_B_UNCOND(I)                             (field<26, 30>(I) == 0x05)
106                 #define IS_INSN_B_UNCOND_REG(I)                 (field<25, 31>(I) == 0x6B)
107                 #define IS_INSN_B_COMPARE(I)                    (field<25, 30>(I) == 0x1A)
108                 #define IS_INSN_B_TEST(I)                               (field<25, 30>(I) == 0x1B)
109                 #define IS_INSN_B_COND(I)                               (field<25, 31>(I) == 0x2A)
110                 #define IS_INSN_PCREL_ADDR(I)                   (field<24, 28>(I) == 0x10)
111                 #define IS_INSN_SYSTEM(I)                               (field<22, 31>(I) == 0x354)
112                 #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))
113
114                 #define IS_FIELD_IMMR(S, E)                             (S == 16 && E == 21)
115                 #define IS_FIELD_IMMS(S, E)                             (S == 10 && E == 15)
116                 #define IS_FIELD_IMMLO(S, E)                    (S == 29 && E == 30)
117                 #define IS_FIELD_IMMHI(S, E)                    (S == 5 && E == 23)
118
119             private:
120                 virtual Result_Type makeSizeType(unsigned int opType);
121
122                                 bool isPstateRead, isPstateWritten;
123                 bool isFPInsn;
124                 bool isSIMDInsn;
125                 bool is64Bit;
126                 bool isValid;
127
128                 void mainDecode();
129                 int findInsnTableIndex(unsigned int);
130                 unsigned int insn;
131                 Instruction* insn_in_progress;
132                 Instruction* invalid_insn;
133
134                 // inherit from ppc is not sematically consistent with aarch64 manual
135                 template <int start, int end>
136                 int field(unsigned int raw)
137                 {
138 #if defined DEBUG_FIELD
139                     std::cerr << start << "-" << end << ":" << std::dec << (raw >> (start) &
140                             (0xFFFFFFFF >> (31 - (end - start)))) << " ";
141 #endif
142                     return (raw >> (start) & (0xFFFFFFFF >> (31 - (end - start))));
143                 }
144
145                 int32_t sign_extend32(int size, int in)
146                 {
147                                         int32_t val = 0|in;
148
149                     return (val << (32 - size)) >> (32 - size);
150                 }
151
152                 int64_t sign_extend64(int size, int in)
153                 {
154                                         int64_t val = 0|in;
155
156                     return (val << (64 - size)) >> (64 - size);
157                 }
158
159                 uint32_t unsign_extend32(int size, int in)
160                 {
161                                         uint32_t mask = ~0;
162
163                     return (mask>>(32-size)) & in;
164                                 }
165
166                 uint64_t unsign_extend64(int size, int in)
167                 {
168                                         uint64_t mask = ~0;
169
170                     return (mask>>(64-size)) & in;
171                                 }
172
173                                 int op1Field, op2Field, crmField;
174                                 void processSystemInsn();
175
176                                 bool hasHw;
177                                 int hwField;
178                                 void processHwFieldInsn(int, int);
179
180                                 bool hasShift;
181                                 int shiftField;
182                                 void processShiftFieldShiftedInsn(int, int);
183                                 void processShiftFieldImmInsn(int, int);
184
185                                 bool hasOption;
186                                 int optionField;
187                                 void processOptionFieldLSRegOffsetInsn();
188
189                                 bool hasN;
190                                 int immr, immrLen;
191                                 int sField, nField, nLen;
192
193                         int immlo, immloLen;
194                                 void makeBranchTarget(bool, bool, int, int);
195                                 Expression::Ptr makeFallThroughExpr();
196
197                 int _szField;
198                 int _typeField;
199
200                 void NOTHING();
201
202                 void set32Mode();
203                                 void setRegWidth();
204                                 void setFPMode();
205                                 void setSIMDMode();
206
207                 bool isSinglePrec();
208
209                                 MachRegister makeAarch64RegID(MachRegister, unsigned int);
210                                 Expression::Ptr makeRdExpr();
211                                 Expression::Ptr makeRnExpr();
212                                 Expression::Ptr makeRmExpr();
213                                 Expression::Ptr makeRaExpr();
214                                 Expression::Ptr makeRsExpr();
215                                 Expression::Ptr makePstateExpr();
216                 Expression::Ptr makePCExpr();
217                                 Expression::Ptr makeOptionExpression(int, int);
218                                 template<typename T, Result_Type rT>
219                                 Expression::Ptr fpExpand(int);
220                 Expression::Ptr makeRtExpr();
221                 Expression::Ptr makeRt2Expr();
222
223                 Expression::Ptr makeMemRefReg();
224                 Expression::Ptr makeMemRefReg_Rm();
225                 Expression::Ptr makeMemRefReg_ext();
226                 Expression::Ptr makeMemRefReg_amount();
227
228                 Expression::Ptr makeMemRefIndexLiteral();
229                 Expression::Ptr makeMemRefIndexUImm();
230                 Expression::Ptr makeMemRefIndexPre();
231                 Expression::Ptr makeMemRefIndexPost();
232                 Expression::Ptr makeMemRefIndex_addOffset9();
233                 Expression::Ptr makeMemRefIndex_offset9();
234
235                 Expression::Ptr makeMemRefPairPre();
236                 Expression::Ptr makeMemRefPairPost();
237                 Expression::Ptr makeMemRefPair_offset7();
238                 Expression::Ptr makeMemRefPair_addOffset7();
239                 Expression::Ptr makeMemRefEx();
240                 Expression::Ptr makeMemRefExPair();
241                 Expression::Ptr makeMemRefExPair2();
242                 //Expression::Ptr makeMemRefPairPre2();
243                 //Expression::Ptr makeMemRefPairPost2();
244                 //Expression::Ptr makeMemRefExPair16B();
245
246
247                 void getMemRefIndexLiteral_OffsetLen(int &, int &);
248                 void getMemRefIndex_SizeSizelen(unsigned int &, unsigned int &);
249                 void getMemRefIndexPrePost_ImmImmlen(unsigned int& , unsigned int& );
250                 void getMemRefPair_ImmImmlen(unsigned int &immVal, unsigned int &immLen);
251
252                 void getMemRefEx_RT(Result_Type &rt);
253                 void getMemRefIndexLiteral_RT(Result_Type &);
254                 void getMemRefExPair_RT(Result_Type &rt);
255                 void getMemRefPair_RT(Result_Type &rt);
256                 void getMemRefIndex_RT(Result_Type &);
257                 void getMemRefIndexUImm_RT(Result_Type &);
258
259                                 void OPRRd();
260                                 void OPRsf();
261                                 template<unsigned int endBit, unsigned int startBit>
262                 void OPRoption();
263                                 void OPRshift();
264                                 void OPRhw();
265                                 template<unsigned int endBit, unsigned int startBit>
266                 void OPRN();
267
268                 //for load store
269                 void LIndex();
270                 void STIndex();
271                                 void OPRRn();
272                 void OPRRnL();
273                 void OPRRnLU();
274                 void OPRRnSU();
275                 void OPRRnS();
276                                 void OPRRnU();
277                                 void OPRRm();
278                                 void OPRRt();
279                                 void OPRRtL();
280                                 void OPRRtS();
281                                 void OPRRt2();
282                                 void OPRRt2L();
283                                 void OPRRt2S();
284
285                                 void OPRop1();
286                                 void OPRop2();
287                                 template<unsigned int endBit, unsigned int startBit>
288                 void OPRcond();
289                                 void OPRnzcv();
290                                 void OPRCRm();
291                                 void OPRCRn();
292                                 template<unsigned int endBit, unsigned int startBit>
293                 void OPRS();
294                                 void OPRRa();
295                                 void OPRo0();
296                                 void OPRb5();
297                                 void OPRb40();
298                                 template<unsigned int endBit, unsigned int startBit>
299                                 void OPRsz();
300                                 void OPRRs();
301                                 template<unsigned int endBit, unsigned int startBit>
302                 void OPRimm();
303                                 void OPRscale();
304                                 template<unsigned int endBit, unsigned int startBit>
305                 void OPRtype();
306
307                 void OPRH() {}
308                 void OPRL() {}
309                 void OPRM() {}
310                 void OPRQ() {}
311                 void OPRa() {}
312                 void OPRb() {}
313                 void OPRc() {}
314                 void OPRd() {}
315                 void OPRe() {}
316                 void OPRf() {}
317                 void OPRg() {}
318                 void OPRh() {}
319                 void OPRopc() {}
320                 void OPRopcode() {}
321                 void OPRlen() {}
322                 template<unsigned int endBit, unsigned int startBit>
323                 void OPRsize() {}
324                 void OPRcmode() {}
325                 void OPRrmode() {}
326                 void OPRop() {}
327         };
328     }
329 }