Update Examples in dataflowAPI (#700)
[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 #if defined(__GNUC__)
40 #define insn_printf(format, ...) \
41         do{ \
42             printf("[%s:%u]insn_debug " format, FILE__, __LINE__, ## __VA_ARGS__); \
43         }while(0)
44 #endif
45
46 #define AARCH64_INSN_LENGTH    32
47
48         struct aarch64_insn_entry;
49         struct aarch64_mask_entry;
50
51         class InstructionDecoder_aarch64 : public InstructionDecoderImpl {
52             friend struct aarch64_insn_entry;
53             friend struct aarch64_mask_entry;
54
55         public:
56             InstructionDecoder_aarch64(Architecture a);
57
58             virtual ~InstructionDecoder_aarch64();
59
60             virtual void decodeOpcode(InstructionDecoder::buffer &b);
61
62             virtual Instruction decode(InstructionDecoder::buffer &b);
63
64             virtual void setMode(bool) { }
65
66             virtual bool decodeOperands(const Instruction *insn_to_complete);
67
68             virtual void doDelayedDecode(const Instruction *insn_to_complete);
69
70             static const std::array<std::string, 16> condNames;
71             static MachRegister sysRegMap(unsigned int);
72             static const char* bitfieldInsnAliasMap(entryID);
73             static const char* condInsnAliasMap(entryID);
74
75 #define    IS_INSN_LOGICAL_SHIFT(I)        (field<24, 28>(I) == 0x0A)
76 #define    IS_INSN_ADDSUB_EXT(I)            (field<24, 28>(I) == 0x0B && field<21, 21>(I) == 1)
77 #define    IS_INSN_ADDSUB_SHIFT(I)            (field<24, 28>(I) == 0x0B && field<21, 21>(I) == 0)
78 #define    IS_INSN_ADDSUB_IMM(I)            (field<24, 28>(I) == 0x11)
79
80             //----ld/st-----
81 #define IS_INSN_LDST(I)                 (field<25, 25>(I) == 0x00 && field<27, 27>(I) == 1)
82
83 #define IS_INSN_LDST_EX(I)              (field<24, 29>(I) == 0x08)
84 #define IS_INSN_ST_EX(I)                (field<24, 29>(I) == 0x08 && field<22, 22>(I) == 0)
85 #define IS_INSN_LDST_EX_PAIR(I)         (field<24, 29>(I) == 0x08 && field<21, 21>(I) ==0x01)
86
87 #define IS_INSN_LD_LITERAL(I)           (field<27, 29>(I) == 0x03 && field<24, 25>(I) == 0)
88
89 #define IS_INSN_LDST_PAIR(I)            (field<27, 29>(I) == 0x05 && field<25, 25>(I) == 0)
90 #define IS_INSN_LDST_PAIR_PRE(I)        (field<27, 29>(I) == 0x05 && field<23, 25>(I) == 0x03)
91 #define IS_INSN_LDST_PAIR_OFFSET(I)     (field<27, 29>(I) == 0x05 && field<23, 25>(I) == 0x02)
92 #define IS_INSN_LDST_PAIR_POST(I)       (field<27, 29>(I) == 0x05 && field<23, 25>(I) == 0x01)
93 #define IS_INSN_LDST_PAIR_NOALLOC(I)    (field<27, 29>(I) == 0x05 && field<23, 25>(I) == 0x00)
94
95 #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)
96 #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)
97 #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)
98 #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)
99 #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)
100 #define IS_INSN_LDST_UIMM(I)            (field<27, 29>(I) == 0x07 && field<24, 25>(I) == 1)
101
102 #define IS_INSN_LDST_SIMD_MULT(I)       (field<31, 31>(I) == 0x00 && field<23, 29>(I) == 0x18 && field<16, 21>(I) == 0)
103 #define IS_INSN_LDST_SIMD_MULT_POST(I)  (field<31, 31>(I) == 0x00 && field<23, 29>(I) == 0x19 && field<21, 21>(I) == 0)
104 #define IS_INSN_LDST_SIMD_SING(I)       (field<31, 31>(I) == 0x00 && field<23, 29>(I) == 0x1a && field<16, 20>(I) == 0)
105 #define IS_INSN_LDST_SIMD_SING_POST(I)  (field<31, 31>(I) == 0x00 && field<23, 29>(I) == 0x1b)
106
107 #define    IS_INSN_LOGICAL_IMM(I)            (field<23, 28>(I) == 0x24)
108 #define    IS_INSN_BITFIELD(I)                (field<23, 28>(I) == 0x26)
109 #define    IS_INSN_EXCEPTION(I)            (field<24, 31>(I) == 0xD4)
110 #define    IS_INSN_FP_COMPARE(I)            (field<24, 28>(I) == 0x1E && field<21, 21>(I) == 0x1 && field<10, 13>(I) == 0x8)
111 #define    IS_INSN_FP_CONV_FIX(I)            (field<24, 28>(I) == 0x1E && field<21, 21>(I) == 0x0)
112 #define    IS_INSN_FP_CONV_INT(I)            (field<24, 28>(I) == 0x1E && field<21, 21>(I) == 0x1 && field<10, 15>(I) == 0x0)
113 #define    IS_SOURCE_GP(I)                    (field<16, 18>(I) == 0x2  || field<16, 18>(I) == 0x3 || field<16, 18>(I) == 0x7)
114 #define    IS_INSN_FP_DATAPROC_ONESRC(I)    (field<24, 28>(I) == 0x1E && field<21, 21>(I) == 0x1 && field<10, 14>(I) == 0x10)
115 #define    IS_INSN_B_UNCOND(I)                (field<26, 30>(I) == 0x05)
116 #define    IS_INSN_B_UNCOND_REG(I)            (field<25, 31>(I) == 0x6B)
117 #define    IS_INSN_B_COMPARE(I)            (field<25, 30>(I) == 0x1A)
118 #define    IS_INSN_COND_SELECT(I)           (field<21, 28>(I) == 0xD4)
119 #define    IS_INSN_B_TEST(I)                (field<25, 30>(I) == 0x1B)
120 #define    IS_INSN_B_COND(I)                (field<25, 31>(I) == 0x2A)
121 #define    IS_INSN_PCREL_ADDR(I)            (field<24, 28>(I) == 0x10)
122 #define    IS_INSN_SYSTEM(I)                (field<22, 31>(I) == 0x354)
123 #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))
124
125 #define IS_INSN_SIMD_3SAME(I)           (field<31, 31>(I) == 0x0 && field<24, 28>(I) == 0xE && field<21, 21>(I) == 0x1 && field<10, 10>(I) == 0x1)
126 #define IS_INSN_SIMD_3DIFF(I)           (field<31, 31>(I) == 0x0 && field<24, 28>(I) == 0xe && field<21, 21>(I) == 0x1 && field<10, 11>(I) == 0x0)
127 #define IS_INSN_SIMD_2REG_MISC(I)       (field<31, 31>(I) == 0x0 && field<24, 28>(I) == 0xe && field<17, 21>(I) == 0x10 && field<10, 11>(I) == 0x2)
128 #define IS_INSN_SIMD_ACROSS(I)          (field<31, 31>(I) == 0x0 && field<24, 28>(I) == 0xe && field<17, 21>(I) == 0x18 && field<10, 11>(I) == 0x2)
129 #define IS_INSN_SIMD_COPY(I)            (field<31, 31>(I) == 0x0 && field<21, 28>(I) == 0x70 && field<15,15>(I) == 0x0 && field<10, 10>(I) == 0x1)
130 #define IS_INSN_SIMD_VEC_INDEX(I)       (field<31, 31>(I) == 0x0 && field<24, 28>(I) == 0xf && field<10, 10>(I) == 0x0)
131 #define IS_INSN_SIMD_MOD_IMM(I)         (field<31, 31>(I) == 0x0 && field<19, 28>(I) == 0x1e0 && field<10, 10>(I) == 0x1)
132 #define IS_INSN_SIMD_SHIFT_IMM(I)       (field<31, 31>(I) == 0x0 && field<23, 28>(I) == 0x1e && field<19, 22>(I) != 0x0 && field<10, 10>(I) == 0x1)
133 #define IS_INSN_SIMD_TAB_LOOKUP(I)      (field<31, 31>(I) == 0x0 && field<24, 29>(I) == 0xe && field<21, 21>(I) == 0x0 && field<15, 15>(I) == 0x0 && field<10, 11>(I) == 0x0)
134 #define IS_INSN_SIMD_EXTR(I)            (field<31, 31>(I) == 0x0 && field<24, 29>(I) == 0x2e && field<21, 21>(I) == 0x0 && field<15, 15>(I) == 0x0 && field<10, 10>(I) == 0x0)
135 #define IS_INSN_SCALAR_3SAME(I)         (field<30, 31>(I) == 0x1 && field<24, 28>(I) == 0x1e && field<21, 21>(I) == 0x1 && field<10, 10>(I) == 0x1)
136 #define IS_INSN_SCALAR_3DIFF(I)         (field<30, 31>(I) == 0x1 && field<24, 28>(I) == 0x1e && field<21, 21>(I) == 0x1 && field<10, 11>(I) == 0x0)
137 #define IS_INSN_SCALAR_2REG_MISC(I)     (field<30, 31>(I) == 0x1 && field<24, 28>(I) == 0x1e && field<17, 21>(I) == 0x10 && field<10, 11>(I) == 0x2)
138 #define IS_INSN_SCALAR_PAIR(I)          (field<30, 31>(I) == 0x1 && field<24, 28>(I) == 0x1e && field<17, 21>(I) == 0x18 && field<10, 11>(I) == 0x2)
139 #define IS_INSN_SCALAR_COPY(I)          (field<30, 31>(I) == 0x1 && field<21, 28>(I) == 0xf0 && field<15, 15>(I) == 0x0 && field<10, 10>(I) == 0x1)
140 #define IS_INSN_SCALAR_INDEX(I)         (field<30, 31>(I) == 0x1 && field<24, 28>(I) == 0x1f && field<10, 10>(I) == 0x0)
141 #define IS_INSN_SCALAR_SHIFT_IMM(I)     (field<30, 31>(I) == 0x1 && field<23, 28>(I) == 0x3e && field<10, 10>(I) == 0x1)
142
143 #define IS_INSN_CRYPT_3REG_SHA(I)       (field<24, 31>(I) == 0x5E && field<21, 21>(I) == 0 && field<15, 15>(I) == 0 && field<10, 11>(I) == 0)
144 #define IS_INSN_CRYPT_2REG_SHA(I)       (field<24, 31>(I) == 0x5E && field<17, 21>(I) == 0x14 && field<10, 11>(I) == 0x2)
145
146 #define    IS_FIELD_IMMR(S, E)                (S == 16 && E == 21)
147 #define    IS_FIELD_IMMS(S, E)                (S == 10 && E == 15)
148 #define    IS_FIELD_IMMLO(S, E)            (S == 29 && E == 30)
149 #define    IS_FIELD_IMMHI(S, E)            (S == 5 && E == 23)
150
151         private:
152             virtual Result_Type makeSizeType(unsigned int opType);
153
154             bool isPstateRead, isPstateWritten;
155             bool isFPInsn, isSIMDInsn;
156             bool skipRn, skipRm;
157             bool is64Bit;
158             bool isValid;
159
160             void mainDecode();
161
162             int findInsnTableIndex(unsigned int);
163
164             /*members for handling operand re-ordering, will be removed later once a generic operand ordering method is incorporated*/
165             int oprRotateAmt;
166             bool hasb5;
167
168             void reorderOperands();
169
170             unsigned int insn;
171             Instruction *insn_in_progress;
172
173             template<int start, int end>
174             int field(unsigned int raw) {
175 #if defined DEBUG_FIELD
176                 std::cerr << start << "-" << end << ":" << std::dec << (raw >> (start) &
177                         (0xFFFFFFFF >> (31 - (end - start)))) << " ";
178 #endif
179                 return (raw >> (start) & (0xFFFFFFFF >> (31 - (end - start))));
180             }
181
182             int32_t sign_extend32(int size, int in) {
183                 int32_t val = 0 | in;
184
185                 return (val << (32 - size)) >> (32 - size);
186             }
187
188             int64_t sign_extend64(int size, int in) {
189                 int64_t val = 0 | in;
190
191                 return (val << (64 - size)) >> (64 - size);
192             }
193
194             uint32_t unsign_extend32(int size, int in) {
195                 uint32_t mask = ~0;
196
197                 return (mask >> (32 - size)) & in;
198             }
199
200             uint64_t unsign_extend64(int size, int in) {
201                 uint64_t mask = ~0;
202
203                 return (mask >> (64 - size)) & in;
204             }
205
206             int highest_set_bit(int32_t val) {
207                 for (int bit_index = 31; bit_index >= 0; bit_index--)
208                     if (((static_cast<uint32_t>(val) >> bit_index) & 0x1) == 0x1)
209                         return bit_index + 1;
210
211                 return -1;
212             }
213
214             int lowest_set_bit(int32_t val) {
215                 for (int bit_index = 0; bit_index <= 31; bit_index++)
216                     if (((static_cast<uint32_t>(val) >> bit_index) & 0x1) == 0x1)
217                         return bit_index + 1;
218
219                 return -1;
220             }
221
222             int op1Field, op2Field, crmField;
223
224             void processSystemInsn();
225
226             bool hasHw;
227             int hwField;
228
229             void processHwFieldInsn(int, int);
230
231             bool hasShift;
232             int shiftField;
233
234             void processShiftFieldShiftedInsn(int, int);
235
236             void processShiftFieldImmInsn(int, int);
237
238             bool hasOption;
239             int optionField;
240
241             void processOptionFieldLSRegOffsetInsn();
242
243             bool hasN;
244             int immr, immrLen;
245             int sField, nField, nLen;
246
247             int immlo, immloLen;
248
249             void makeBranchTarget(bool, bool, int, int);
250
251             Expression::Ptr makeFallThroughExpr();
252
253             int _szField, size;
254             int _typeField;
255             int cmode;
256             int op;
257             int simdAlphabetImm;
258
259             void processAlphabetImm();
260
261             void NOTHING();
262
263             void set32Mode();
264
265             void setRegWidth();
266
267             void setFPMode();
268
269             void setSIMDMode();
270
271             bool isSinglePrec();
272
273             bool fix_bitfieldinsn_alias(int, int);
274             void fix_condinsn_alias_and_cond(int &);
275             void modify_mnemonic_simd_upperhalf_insns();
276             bool pre_process_checks(const aarch64_insn_entry &);
277
278             MachRegister makeAarch64RegID(MachRegister, unsigned int);
279
280             MachRegister getLoadStoreSimdRegister(int encoding);
281
282             Expression::Ptr makeRdExpr();
283
284             Expression::Ptr makeRnExpr();
285
286             Expression::Ptr makeRmExpr();
287
288             Expression::Ptr makeRaExpr();
289
290             Expression::Ptr makeRsExpr();
291
292             Expression::Ptr makePstateExpr();
293
294             Expression::Ptr makePCExpr();
295
296             Expression::Ptr makeb40Expr();
297
298             Expression::Ptr makeOptionExpression(int, int);
299
300             template<typename T, Result_Type rT>
301             Expression::Ptr fpExpand(int);
302
303             Expression::Ptr makeRtExpr();
304
305             Expression::Ptr makeRt2Expr();
306
307             Expression::Ptr makeMemRefReg();
308
309             Expression::Ptr makeMemRefReg_Rm();
310
311             Expression::Ptr makeMemRefReg_ext();
312
313             Expression::Ptr makeMemRefReg_amount();
314
315             Expression::Ptr makeMemRefIndexLiteral();
316
317             Expression::Ptr makeMemRefIndexUImm();
318
319             Expression::Ptr makeMemRefIndexPre();
320
321             Expression::Ptr makeMemRefIndexPost();
322
323             Expression::Ptr makeMemRefIndex_addOffset9();
324
325             Expression::Ptr makeMemRefIndex_offset9();
326
327             Expression::Ptr makeMemRefPairPre();
328
329             Expression::Ptr makeMemRefPairPost();
330
331             Expression::Ptr makeMemRefPair_offset7();
332
333             Expression::Ptr makeMemRefPair_addOffset7();
334
335             Expression::Ptr makeMemRefEx();
336
337             Expression::Ptr makeMemRefExPair();
338
339             Expression::Ptr makeMemRefExPair2();
340
341             Expression::Ptr makeMemRefSIMD_MULT();
342
343             Expression::Ptr makeMemRefSIMD_SING();
344
345             template<typename T>
346             Expression::Ptr makeLogicalImm(int immr, int imms, int immsLen, Result_Type rT);
347
348
349             void getMemRefIndexLiteral_OffsetLen(int &, int &);
350
351             void getMemRefIndex_SizeSizelen(unsigned int &, unsigned int &);
352
353             void getMemRefIndexPrePost_ImmImmlen(unsigned int &, unsigned int &);
354
355             void getMemRefPair_ImmImmlen(unsigned int &immVal, unsigned int &immLen);
356
357             void getMemRefEx_RT(Result_Type &rt);
358
359             void getMemRefIndexLiteral_RT(Result_Type &);
360
361             void getMemRefExPair_RT(Result_Type &rt);
362
363             void getMemRefPair_RT(Result_Type &rt);
364
365             void getMemRefIndex_RT(Result_Type &);
366
367             void getMemRefIndexUImm_RT(Result_Type &);
368
369             unsigned int getMemRefSIMD_MULT_T();
370
371             unsigned int getMemRefSIMD_SING_T();
372
373             void getMemRefSIMD_MULT_RT(Result_Type &);
374
375             void getMemRefSIMD_SING_RT(Result_Type &);
376
377             unsigned int get_SIMD_MULT_POST_imm();
378
379             unsigned int get_SIMD_SING_POST_imm();
380
381             void OPRRd();
382
383             void OPRsf();
384
385             template<unsigned int endBit, unsigned int startBit>
386             void OPRoption();
387
388             void OPRshift();
389
390             void OPRhw();
391
392             template<unsigned int endBit, unsigned int startBit>
393             void OPRN();
394
395             //for load store
396             void LIndex();
397
398             void STIndex();
399
400             void OPRRn();
401
402             void OPRRnL();
403
404             void OPRRnLU();
405
406             void OPRRnSU();
407
408             void OPRRnS();
409
410             void OPRRnU();
411
412             void OPRRm();
413
414             void OPRRt();
415
416             void OPRRtL();
417
418             void OPRRtS();
419
420             void OPRRt2();
421
422             void OPRRt2L();
423
424             void OPRRt2S();
425
426             void OPRop1();
427
428             void OPRop2();
429
430             template<unsigned int endBit, unsigned int startBit>
431             void OPRcond();
432
433             void OPRnzcv();
434
435             void OPRCRm();
436
437             void OPRCRn();
438
439             template<unsigned int endBit, unsigned int startBit>
440             void OPRS();
441
442             void OPRRa();
443
444             void OPRo0();
445
446             void OPRb5();
447
448             void OPRb40();
449
450             template<unsigned int endBit, unsigned int startBit>
451             void OPRsz();
452
453             void OPRRs();
454
455             template<unsigned int endBit, unsigned int startBit>
456             void OPRimm();
457
458             void OPRscale();
459
460             template<unsigned int endBit, unsigned int startBit>
461             void OPRtype();
462
463             void OPRQ();
464
465             void OPRL();
466
467             //void OPRR();
468             void OPRH() { }
469
470             void OPRM() { }
471
472             void OPRa();
473
474             void OPRb();
475
476             void OPRc();
477
478             void OPRd();
479
480             void OPRe();
481
482             void OPRf();
483
484             void OPRg();
485
486             void OPRh();
487
488             void OPRopc();
489
490             void OPRopcode() { }
491
492             void OPRlen();
493
494             template<unsigned int endBit, unsigned int startBit>
495             void OPRsize();
496
497             void OPRcmode();
498
499             void OPRrmode() { }
500
501             void OPRop();
502
503             void setFlags();
504
505             unsigned int _Q;
506             unsigned int _L;
507             unsigned int _R;
508
509             void getSIMD_MULT_RptSelem(unsigned int &rpt, unsigned int &selem);
510
511             unsigned int getSIMD_SING_selem();
512         };
513     }
514 }