fixed a few bugs after rolling backing to weak solution to aliases
[dyninst.git] / instructionAPI / src / InstructionDecoder-aarch64.C
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 "InstructionDecoder-aarch64.h"
32 #include <boost/assign/list_of.hpp>
33 #include "../../common/src/singleton_object_pool.h"
34
35 namespace Dyninst
36 {
37   namespace InstructionAPI
38   {
39     typedef void (InstructionDecoder_aarch64::*operandFactory)();
40     typedef std::vector<operandFactory> operandSpec;
41     typedef std::vector<aarch64_insn_entry> aarch64_insn_table;
42     typedef std::map<unsigned int, aarch64_mask_entry> aarch64_decoder_table;
43     typedef std::map<unsigned int, unsigned int> branchMap;
44     typedef uint32_t Bits_t;
45
46     std::vector<std::string> InstructionDecoder_aarch64::condStringMap;
47     std::map<unsigned int, MachRegister> InstructionDecoder_aarch64::sysRegMap;
48
49     struct aarch64_insn_entry
50     {
51         aarch64_insn_entry(entryID o, const char* m, operandSpec ops):
52         op(o), mnemonic(m), operands(ops)
53         {
54         }
55
56         aarch64_insn_entry(entryID o, const char* m, operandSpec ops, Bits_t enb, Bits_t mb):
57         op(o), mnemonic(m), operands(ops),_encodingBits(enb), _maskBits(mb)
58         {
59         }
60
61         aarch64_insn_entry():
62         op(aarch64_op_INVALID), mnemonic("INVALID")
63         {
64             operands.reserve(5);
65         }
66
67         aarch64_insn_entry(const aarch64_insn_entry& o) :
68         op(o.op), mnemonic(o.mnemonic), operands(o.operands),
69         _encodingBits(o._encodingBits),_maskBits(o._maskBits)
70         {
71         }
72
73         const aarch64_insn_entry& operator=(const aarch64_insn_entry& rhs)
74         {
75             operands.reserve(rhs.operands.size());
76             op = rhs.op;
77             mnemonic = rhs.mnemonic;
78             operands = rhs.operands;
79             _encodingBits = rhs._encodingBits;
80             _maskBits = rhs._maskBits;
81
82             return *this;
83         }
84
85         entryID op;
86         const char* mnemonic;
87         operandSpec operands;
88
89         Bits_t _encodingBits;
90         Bits_t _maskBits;
91
92         static void buildInsnTable();
93         static bool built_insn_table;
94
95         static aarch64_insn_table main_insn_table;
96     };
97
98     struct aarch64_mask_entry
99     {
100                 aarch64_mask_entry(unsigned int m, branchMap bm, int tabIndex):
101                 mask(m), nodeBranches(bm), insnTableIndices(std::vector<int>()), insnTableIndex(tabIndex)
102                 {
103                 }
104
105                 aarch64_mask_entry(unsigned int m, branchMap bm, std::vector<int> tabIndices):
106                 mask(m), nodeBranches(bm), insnTableIndices(tabIndices), insnTableIndex(0)
107                 {
108                 }
109
110                 aarch64_mask_entry():
111                 mask(0), nodeBranches(branchMap()), insnTableIndices(std::vector<int>()), insnTableIndex(0)
112                 {
113                 }
114
115                 aarch64_mask_entry(const aarch64_mask_entry& e):
116                 mask(e.mask), nodeBranches(e.nodeBranches), insnTableIndices(e.insnTableIndices), insnTableIndex(e.insnTableIndex)
117                 {
118                 }
119
120                 const aarch64_mask_entry& operator=(const aarch64_mask_entry& rhs)
121                 {
122                         mask = rhs.mask;
123                         nodeBranches = rhs.nodeBranches;
124                         insnTableIndices = rhs.insnTableIndices;
125             insnTableIndex = rhs.insnTableIndex;
126
127                         return *this;
128                 }
129
130                 unsigned int mask;
131                 branchMap nodeBranches;
132         std::vector<int> insnTableIndices;
133         int insnTableIndex;
134
135                 static void buildDecoderTable();
136                 static bool built_decoder_table;
137                 static bool isAliasWeakSolution;
138                 static aarch64_decoder_table main_decoder_table;
139         };
140
141     InstructionDecoder_aarch64::InstructionDecoder_aarch64(Architecture a)
142       : InstructionDecoderImpl(a), isPstateRead(false), isPstateWritten(false), isFPInsn(false),isSIMDInsn(false),
143             is64Bit(true), isValid(true), insn(0), insn_in_progress(NULL),
144         hasHw(false), hasShift(false), hasOption(false), hasN(false),
145         immr(0), immrLen(0), sField(0), nField(0), nLen(0),
146         immlo(0), immloLen(0), _szField(-1)
147     {
148         aarch64_insn_entry::buildInsnTable();
149         aarch64_mask_entry::buildDecoderTable();
150         InstructionDecoder_aarch64::buildSysRegMap();
151
152         std::string condArray[16] = {"eq","ne","cs","cc","mi","pl","vs","vc","hi","ls","ge","lt","gt","le","al","nv"};
153         InstructionDecoder_aarch64::condStringMap.assign(&condArray[0], &condArray[0] + 16);
154     }
155
156     InstructionDecoder_aarch64::~InstructionDecoder_aarch64()
157     {
158     }
159
160     void InstructionDecoder_aarch64::decodeOpcode(InstructionDecoder::buffer& b)
161     {
162       b.start += 4;
163     }
164
165     using namespace std;
166     Instruction::Ptr InstructionDecoder_aarch64::decode(InstructionDecoder::buffer& b)
167     {
168         if(b.start > b.end)
169             return Instruction::Ptr();
170
171                 isPstateRead = isPstateWritten = false;
172         isFPInsn = false;
173         isSIMDInsn = false;
174         isValid = true;
175         is64Bit = true;
176
177         hasHw = false;
178         hwField = 0;
179
180         hasShift = false;
181         shiftField = 0;
182
183         hasOption = false;
184         optionField = 0;
185
186         hasN = false;
187         sField = nField = nLen = 0;
188         immr = immrLen = 0;
189
190         op1Field = op2Field = crmField = 0;
191
192         immlo = immloLen = 0;
193
194         _szField = -1;
195
196                 oprRotateAmt = 0;
197                 hasb5 = false;
198
199         insn = b.start[3] << 24 | b.start[2] << 16 |
200         b.start[1] << 8 | b.start[0];
201
202 #if defined(DEBUG_RAW_INSN)
203         cout.width(0);
204         cout << "0x";
205         cout.width(8);
206         cout.fill('0');
207         cout << hex << insn << "\t";
208 #endif
209
210                 mainDecode();
211         b.start += 4;
212
213         return make_shared(insn_in_progress);
214     }
215
216     /* replace this function with a more generic function, which is setRegWidth
217     void InstructionDecoder_aarch64::set32Mode()
218     {
219         // NOTE: is64Bit is set by default.
220                 is64Bit = false;
221     }
222     */
223     void InstructionDecoder_aarch64::NOTHING(){
224     }
225
226     void InstructionDecoder_aarch64::setFPMode()
227     {
228         // NOTE: if it is fp, only isFP is set.
229                 isFPInsn = true;
230     }
231
232      //TODO: consistency issue
233      void InstructionDecoder_aarch64::setSIMDMode()
234     {
235         // NOTE: if it is SIMD insn, both isFP and isSIMD are set.
236                 isFPInsn = true;
237                 isSIMDInsn = true;
238     }
239
240         template<unsigned int endBit, unsigned int startBit>
241     void InstructionDecoder_aarch64::OPRtype(){
242         _typeField = field<startBit, endBit>(insn);
243     }
244
245     bool InstructionDecoder_aarch64::decodeOperands(const Instruction *)
246     {
247                 return false;
248     }
249
250         void InstructionDecoder_aarch64::processHwFieldInsn(int len, int val)
251         {
252                 Result_Type rT = is64Bit?u64:u32;
253
254                 unsigned int shiftAmount = hwField*16;
255
256                 Expression::Ptr lhs = Immediate::makeImmediate(Result(rT, rT==u32?unsign_extend32(len, val):unsign_extend64(len, val)));
257                 Expression::Ptr rhs = Immediate::makeImmediate(Result(u32, unsign_extend32(6, shiftAmount)));
258
259                 insn_in_progress->appendOperand(makeLeftShiftExpression(lhs, rhs, rT), true, false);
260         }
261
262         void InstructionDecoder_aarch64::processShiftFieldShiftedInsn(int len, int val)
263         {
264                 Result_Type rT;
265                 Expression::Ptr lhs, rhs;
266
267                 rT = is64Bit?u64:u32;
268
269             lhs = makeRmExpr();
270             rhs = Immediate::makeImmediate(Result(u32, unsign_extend32(len, val)));
271
272                 switch(shiftField)                                                                                      //add-sub (shifted) and logical (shifted)
273                 {
274                         case 0:insn_in_progress->appendOperand(makeLeftShiftExpression(lhs, rhs, rT), true, false);
275                                    break;
276                         case 1:insn_in_progress->appendOperand(makeRightLogicalShiftExpression(lhs, rhs, rT), true, false);
277                                    break;
278                         case 2:insn_in_progress->appendOperand(makeRightArithmeticShiftExpression(lhs, rhs, rT), true, false);
279                                    break;
280                         case 3:if(IS_INSN_LOGICAL_SHIFT(insn))                                  //logical (shifted) -- not applicable to add-sub (shifted)
281                                                 insn_in_progress->appendOperand(makeRightRotateExpression(lhs, rhs, rT), true, false);
282                                    else
283                                                 isValid = false;
284                                    break;
285                 }
286         }
287
288         void InstructionDecoder_aarch64::processShiftFieldImmInsn(int len, int val)
289         {
290                 if(shiftField == 0 || shiftField == 1)                                          //add-sub (immediate)
291                 {
292                         Result_Type rT = is64Bit?u64:u32;
293
294                         unsigned int shiftAmount = shiftField * 12;
295
296                         Expression::Ptr lhs = Immediate::makeImmediate(Result(rT, rT==u32?unsign_extend32(len, val):unsign_extend64(len, val)));
297                         Expression::Ptr rhs = Immediate::makeImmediate(Result(u32, unsign_extend32(4, shiftAmount)));
298
299                         insn_in_progress->appendOperand(makeLeftShiftExpression(lhs, rhs, rT), true, false);
300                 }
301                 else
302                 {
303                         isValid = false;
304                 }
305
306         }
307
308         Expression::Ptr InstructionDecoder_aarch64::makeOptionExpression(int len, int val)
309         {
310                 MachRegister reg;
311                 int encoding = field<16, 20>(insn);
312
313                 reg = ((optionField & 0x3) == 0x3)?((encoding == 31)?aarch64::zr:aarch64::x0):((encoding == 31)?aarch64::wzr:aarch64::w0);
314                 if(encoding != 31)
315                         reg = makeAarch64RegID(reg, encoding);
316
317                 Expression::Ptr lhs;
318
319                 switch(optionField)
320                 {
321                         case 0:lhs = makeRegisterExpression(reg, u8);
322                                         break;
323                         case 1:lhs = makeRegisterExpression(reg, u16);
324                                         break;
325                         case 2:lhs = makeRegisterExpression(reg, u32);
326                                         break;
327                         case 3:lhs = makeRegisterExpression(reg, u64);
328                                         break;
329                         case 4:lhs = makeRegisterExpression(reg, s8);
330                                         break;
331                         case 5:lhs = makeRegisterExpression(reg, s16);
332                                         break;
333                         case 6:lhs = makeRegisterExpression(reg, s32);
334                                         break;
335                         case 7:lhs = makeRegisterExpression(reg, s64);
336                                         break;
337                         default: assert(!"invalid option field value");
338                 }
339
340                 Result_Type rT = is64Bit?(optionField<4?u64:s64):(optionField<4?u32:s32);
341
342                 return makeLeftShiftExpression(lhs, Immediate::makeImmediate(Result(u32, unsign_extend32(len, val))), rT);
343         }
344
345         void InstructionDecoder_aarch64::processOptionFieldLSRegOffsetInsn()
346         {
347                 if(optionField == 0x3)                  //option = LSL
348                 {
349                         int sizeVal = field<30, 31>(insn), extend;
350
351                         if(field<23, 23>(insn) == 1)
352                                 sizeVal = 4;
353
354                         extend = sField * sizeVal;
355                         int extendSize = 31;
356                         while(extendSize >= 0  && ((extend << (31 - extendSize)) & 0x80000000) == 0)
357                                 extendSize--;
358
359                         //above values need to be used in a dereference expression
360                 }
361                 else
362                 {
363                         //sign-extend
364                         switch(optionField)
365                         {
366                                 case 0x2://UXTW
367                                                  break;
368                                 case 0x6://SXTW
369                                                  break;
370                                 case 0x7://SXTX
371                                                  break;
372                                 default:isValid = false;
373                                                 break;
374                         }
375                 }
376         }
377
378         void InstructionDecoder_aarch64::processSystemInsn()
379         {
380                 int op0Field = field<19, 20>(insn), crnField = field<12, 15>(insn);
381
382                 if(op0Field == 0)
383                 {
384                         if(crnField == 3)                       //clrex, dendBit, dmb, iendBit
385                         {
386                                 Expression::Ptr CRm = Immediate::makeImmediate(Result(u8, unsign_extend32(4, crmField)));
387
388                                 insn_in_progress->appendOperand(CRm, true, false);
389                         }
390                         else if(crnField == 2)                    //hint
391                         {
392                                 int immVal = (crmField << 3)|(op2Field & 7);
393
394                                 Expression::Ptr imm = Immediate::makeImmediate(Result(u8, unsign_extend32(7, immVal)));
395
396                                 insn_in_progress->appendOperand(imm, true, false);
397                         }
398                         else if(crnField == 4)                          //msr (immediate)
399                         {
400                                 int pstatefield = (op1Field << 3) | (op2Field & 7);
401                                 insn_in_progress->appendOperand(Immediate::makeImmediate(Result(u8, unsign_extend32(6, pstatefield))), true, false);
402
403                                 insn_in_progress->appendOperand(Immediate::makeImmediate(Result(u8, unsign_extend32(4, crmField))), true, false);
404
405                                 isPstateWritten = true;
406                         }
407                         else
408                         {
409                                 isValid = false;
410                         }
411                 }
412                 else if(op0Field == 1)                  //sys, sysl
413                 {
414                         insn_in_progress->appendOperand(Immediate::makeImmediate(Result(u8, unsign_extend32(3, op1Field))), true, false);
415                         insn_in_progress->appendOperand(Immediate::makeImmediate(Result(u8, unsign_extend32(4, crnField))), true, false);
416                         insn_in_progress->appendOperand(Immediate::makeImmediate(Result(u8, unsign_extend32(4, crmField))), true, false);
417                         insn_in_progress->appendOperand(Immediate::makeImmediate(Result(u8, unsign_extend32(3, op2Field))), true, false);
418
419                         bool isRtRead = (field<21, 21>(insn) == 0);
420                         insn_in_progress->appendOperand(makeRtExpr(), isRtRead, !isRtRead);
421                 }
422                 else                   //mrs (register), msr
423                 {
424                         bool isRtRead = (field<21, 21>(insn) == 0);
425
426                         unsigned int systemRegEncoding = (op0Field << 14) | (op1Field << 11) | (crnField << 7) | (crmField << 3) | op2Field;
427                         if(InstructionDecoder_aarch64::sysRegMap.count(systemRegEncoding) <= 0)
428                                 assert(!"tried to access system register not accessible in EL0");
429
430                         insn_in_progress->appendOperand(makeRegisterExpression(InstructionDecoder_aarch64::sysRegMap[systemRegEncoding]), !isRtRead, isRtRead);
431                         insn_in_progress->appendOperand(makeRtExpr(), isRtRead, !isRtRead);
432                         if(!isRtRead)
433                             insn_in_progress->m_Operands.reverse();
434                 }
435         }
436
437     Result_Type InstructionDecoder_aarch64::makeSizeType(unsigned int)
438     {
439         assert(0); //not implemented
440         return u32;
441     }
442
443     // ****************
444     // decoding opcodes
445     // ****************
446
447 #define fn(x) (&InstructionDecoder_aarch64::x)
448 #define COMMA   ,
449
450 MachRegister InstructionDecoder_aarch64::makeAarch64RegID(MachRegister base, unsigned int encoding)
451 {
452     return MachRegister(base.val() + encoding);
453 }
454
455 Expression::Ptr InstructionDecoder_aarch64::makeRdExpr()
456 {
457     int encoding  = field<0, 4>(insn);
458         MachRegister reg;
459
460     if( isSIMDInsn ){
461         reg = aarch64::q0;
462         reg = makeAarch64RegID(reg, encoding);
463     } else
464         if(isFPInsn && !((IS_INSN_FP_CONV_FIX(insn) || (IS_INSN_FP_CONV_INT(insn))) && !IS_SOURCE_GP(insn)))
465         {
466
467                 if(IS_INSN_FP_DATAPROC_ONESRC(insn))
468                 {
469                         int opc = field<15, 16>(insn);
470                         switch(opc)
471                         {
472                                 case 0: reg = aarch64::s0;
473                                                 break;
474                                 case 1: reg = aarch64::d0;
475                                                 break;
476                                 case 3: reg = aarch64::h0;
477                                                 break;
478                                 default: assert(!"invalid destination register size");
479                         }
480                 }
481                 else
482                         reg = isSinglePrec()?aarch64::s0:aarch64::d0;
483
484                 reg = makeAarch64RegID(reg, encoding);
485         }
486         else
487         {
488                 reg = is64Bit?((encoding == 31)?aarch64::sp:aarch64::x0):((encoding == 31)?aarch64::wsp:aarch64::w0);
489                 if(encoding != 31)
490                         reg = makeAarch64RegID(reg, encoding);
491         }
492
493         return makeRegisterExpression(reg);
494 }
495
496 void InstructionDecoder_aarch64::OPRRd()
497 {
498     insn_in_progress->appendOperand(makeRdExpr(), false, true);
499 }
500
501 Expression::Ptr InstructionDecoder_aarch64::makeRnExpr()
502 {
503     int encoding  = field<5, 9>(insn);
504         MachRegister reg;
505
506     if( isSIMDInsn && !IS_INSN_LDST(insn) ){
507         reg = aarch64::q0;
508         reg = makeAarch64RegID(reg, encoding);
509     } else
510         if(isFPInsn && !((IS_INSN_FP_CONV_FIX(insn) || (IS_INSN_FP_CONV_INT(insn))) && IS_SOURCE_GP(insn)))
511         {
512                 switch(_typeField)
513                 {
514                     case 0: reg = aarch64::s0;
515                         break;
516                     case 1: reg = aarch64::d0;
517                                 break;
518                     case 3: reg = aarch64::h0;
519                                 break;
520                     default: assert(!"invalid source register size");
521                 }
522                 reg = makeAarch64RegID(reg, encoding);
523         }
524     else if(IS_INSN_LDST(insn)){
525         reg = encoding == 31?aarch64::sp:aarch64::x0;
526                 if(encoding != 31)
527                         reg = makeAarch64RegID(reg, encoding);
528     }
529         else
530         {
531                 reg = is64Bit?((encoding == 31)?aarch64::sp:aarch64::x0):((encoding == 31)?aarch64::wsp:aarch64::w0);
532                 if(encoding != 31)
533                         reg = makeAarch64RegID(reg, encoding);
534         }
535
536         return makeRegisterExpression(reg);
537 }
538
539 Expression::Ptr InstructionDecoder_aarch64::makePCExpr()
540 {
541         MachRegister baseReg = aarch64::pc;
542
543         return makeRegisterExpression(makeAarch64RegID(baseReg, 0));
544 }
545
546 Expression::Ptr InstructionDecoder_aarch64::makePstateExpr()
547 {
548         MachRegister baseReg = aarch64::pstate;
549
550         return makeRegisterExpression(makeAarch64RegID(baseReg, 0));
551 }
552
553
554 void InstructionDecoder_aarch64::getMemRefIndexLiteral_OffsetLen(int &immVal, int &immLen){
555     immVal = field<5, 23>(insn);
556     immVal = immVal << 2; //immVal:00
557     immLen = (23 - 5 + 1) + 2;
558     return;
559 }
560
561 void InstructionDecoder_aarch64::getMemRefIndexLiteral_RT(Result_Type &rt){
562     int size = field<30, 31>(insn);
563     switch(size){
564         case 0x0:
565             rt = u32;
566             break;
567         case 0x1:
568             rt = u64;
569             break;
570         case 0x2:
571             rt = s32;
572             break;
573         case 0x3:
574         default:
575             assert(0);
576             break;
577     }
578     return;
579 }
580
581 // ****************************************
582 // load/store literal
583 // eg: load Xt, <literal>
584 // => offset = signextend(<literal>:00, 64)
585 // load from [PC + offset] to Xt
586 // ****************************************
587 Expression::Ptr InstructionDecoder_aarch64::makeMemRefIndexLiteral()
588 {
589     int immVal, immLen;
590     getMemRefIndexLiteral_OffsetLen(immVal, immLen);
591
592     Expression::Ptr label = Immediate::makeImmediate(Result(s32, sign_extend32(immLen, immVal)));
593
594     Result_Type rt;
595     getMemRefIndexLiteral_RT(rt);
596
597     return makeDereferenceExpression(makeAddExpression(label, makePCExpr(), u64), rt);
598 }
599
600 // TODO potential bug: do we need to distinguish signed and unsigned here?
601 // this funciton is to get the mem ref size
602 // shared by ld/st uimm, post, pre, reg
603 void InstructionDecoder_aarch64::getMemRefIndex_RT(Result_Type &rt){
604     unsigned int opc1 = field<23, 23>(insn);
605     unsigned int size = field<30, 31>(insn);
606
607     if(opc1 == 1){
608         switch(size){
609             case 0:
610                 rt = s8;
611                 break;
612             case 1:
613                 rt = s16;
614                 break;
615             case 2:
616                 rt = s32;
617                 break;
618             case 3:
619                 rt = s64;
620                 break;
621             default:
622                 assert(0);
623                 //should only be 2 or 3
624                 break;
625         }
626     }else{
627         switch(size){
628             case 0:
629                 rt = u8;
630                 break;
631             case 1:
632                 rt = u16;
633                 break;
634             case 2:
635                 rt = u32;
636                 break;
637             case 3:
638                 rt = u64;
639                 break;
640             default:
641                 assert(0);
642                 //should only be 2 or 3
643                 break;
644         }
645     }
646
647     return;
648 }
649
650 void InstructionDecoder_aarch64::getMemRefPair_RT(Result_Type &rt){
651     unsigned int isSigned = field<30,30>(insn);
652     unsigned int size = field<31, 31>(insn);
653
654     // double the width
655     switch(isSigned){
656         case 0:
657             switch(size){
658                 case 0:
659                     //rt = u32;
660                     rt = u64;
661                     break;
662                 case 1:
663                     //rt = u64;
664                     rt = dbl128;
665                     break;
666                 default:
667                     assert(0);
668             }
669             break;
670         case 1:
671             switch(size){
672                 case 0:
673                     //rt = s32;
674                     rt = s64;
675                     break;
676                 case 1:
677                 default:
678                     assert(0);
679             }
680             break;
681         default:
682             assert(0);
683             break;
684     }
685
686     return;
687 }
688
689 void InstructionDecoder_aarch64::getMemRefIndex_SizeSizelen(unsigned int &size, unsigned int &sizeLen){
690     size = field<30, 31>(insn);
691     sizeLen = 31-30+1;
692     return;
693 }
694
695 void InstructionDecoder_aarch64::getMemRefIndexPrePost_ImmImmlen(unsigned int &immVal, unsigned int &immLen){
696     immVal = field<12, 20>(insn);
697     immLen = 20 - 12 + 1;
698     return;
699 }
700
701 void InstructionDecoder_aarch64::getMemRefPair_ImmImmlen(unsigned int &immVal, unsigned int &immLen){
702     immVal = field<15, 21>(insn);
703     immLen = 21-15 + 1;
704     return;
705 }
706
707 // ****************************************
708 // load/store unsigned imm
709 // eg: load Xt, [Xn, #imm]
710 // => offset = unsignextend( imm , 64)
711 // load from [PC + offset] to Xt
712 // ****************************************
713 Expression::Ptr InstructionDecoder_aarch64::makeMemRefIndexUImm()
714 {
715     assert( IS_INSN_LDST_UIMM(insn) );
716
717     int immVal = field<10, 21>(insn);
718     int immLen = 21 - 10 + 1;
719
720     unsigned int size = 0, sizeLen = 0;
721     getMemRefIndex_SizeSizelen(size, sizeLen);
722
723     Expression::Ptr offset = Immediate::makeImmediate( Result(u64, unsign_extend64( immLen+size, immVal<<size) ) );
724
725     /*
726     Expression::Ptr scaleForUImm = Immediate::makeImmediate(Result(u32, unsign_extend32(sizeLen + size, 1<<size)));
727     Expression::Ptr offset = makeMultiplyExpression(imm, scaleForUImm, u64);
728     */
729
730     Result_Type rt;
731     getMemRefIndex_RT(rt);
732     return makeDereferenceExpression( makeAddExpression(makeRnExpr(), offset, u64), rt);
733 }
734
735 Expression::Ptr InstructionDecoder_aarch64::makeMemRefIndex_offset9(){
736     unsigned int immVal = 0, immLen = 0;
737     getMemRefIndexPrePost_ImmImmlen(immVal, immLen);
738     return Immediate::makeImmediate(Result(u32, sign_extend32(immLen, immVal)));
739 }
740
741 // scale = 2 + opc<1>
742 // scale = 1<<scale
743 // LSL(sign_ex(imm7 , 64), scale)
744 Expression::Ptr InstructionDecoder_aarch64::makeMemRefPair_offset7(){
745     /*
746     unsigned int scaleVal = field<31, 31>(insn);
747     unsigned int scaleLen = 8;
748     scaleVal += 2;
749     Expression::Ptr scale = Immediate::makeImmediate(Result(u32, unsign_extend32(scaleLen, 1<<scaleVal)));
750     */
751
752     unsigned int immVal = 0, immLen = 0;
753     getMemRefPair_ImmImmlen(immVal, immLen);
754
755     immVal = is64Bit?immVal<<3:immVal<<2;
756     Expression::Ptr imm7 = Immediate::makeImmediate(Result(u64, sign_extend64(immLen, immVal)));
757
758     //return makeMultiplyExpression(imm7, scale, s64);
759     return imm7;
760 }
761
762 Expression::Ptr InstructionDecoder_aarch64::makeMemRefIndex_addOffset9(){
763     Expression::Ptr offset = makeMemRefIndex_offset9();
764     return makeAddExpression(makeRnExpr(), offset, u64);
765 }
766
767 Expression::Ptr InstructionDecoder_aarch64::makeMemRefPair_addOffset7(){
768     Expression::Ptr offset = makeMemRefPair_offset7();
769     return makeAddExpression(makeRnExpr(), offset, u64);
770 }
771
772 Expression::Ptr InstructionDecoder_aarch64::makeMemRefIndexPre(){
773     Result_Type rt;
774     getMemRefIndex_RT(rt);
775     return makeDereferenceExpression(makeMemRefIndex_addOffset9(), rt);
776 }
777
778 Expression::Ptr InstructionDecoder_aarch64::makeMemRefIndexPost(){
779     Result_Type rt;
780     getMemRefIndex_RT(rt);
781     return makeDereferenceExpression(makeRnExpr(), rt);
782 }
783
784 Expression::Ptr InstructionDecoder_aarch64::makeMemRefPairPre(){
785     Result_Type rt;
786     getMemRefPair_RT(rt);
787     return makeDereferenceExpression(makeMemRefPair_addOffset7(), rt);
788 }
789
790 /*
791 Expression::Ptr InstructionDecoder_aarch64::makeMemRefPairPre2(){
792     // datasize = 64/32 /8;
793     unsigned int opc1 = field<31, 31>(insn);
794     unsigned int sizeVal = 1<<(2+opc1); //4 or 8 bytes
795
796     Expression::Ptr dataSize = Immediate::makeImmediate(Result(u32, unsign_extend32( 32, sizeVal ) ) );
797     Expression::Ptr pair2 = makeAddExpression( makeMemRefPair_addOffset7(), dataSize, u64);
798
799     Result_Type rt;
800     getMemRefPair_RT(rt);
801     return makeDereferenceExpression(pair2, rt);
802 }
803 */
804
805 Expression::Ptr InstructionDecoder_aarch64::makeMemRefPairPost(){
806     Result_Type rt;
807     getMemRefPair_RT(rt);
808     return makeDereferenceExpression(makeRnExpr(), rt);
809 }
810
811 /*
812 Expression::Ptr InstructionDecoder_aarch64::makeMemRefPairPost2(){
813     // datasize = 64/32 /8;
814     unsigned int opc1 = field<31, 31>(insn);
815     unsigned int sizeVal = 1<<(2+opc1); //4 or 8 bytes
816
817     Expression::Ptr dataSize = Immediate::makeImmediate(Result(u32, unsign_extend32( 32, sizeVal ) ) );
818     Expression::Ptr pair2 = makeAddExpression( makeRnExpr(), dataSize, u64);
819
820     Result_Type rt;
821     getMemRefPair_RT(rt);
822     return makeDereferenceExpression(pair2, rt);
823 }
824 */
825
826 void InstructionDecoder_aarch64::getMemRefEx_RT(Result_Type &rt){
827     unsigned int sz = field<30, 31>(insn);
828     switch(sz){
829         case 0x00: //B
830             rt = u8;
831             break;
832         case 0x01: //H
833             rt = u16;
834             break;
835         case 0x02: //32b
836             rt = u32;
837             break;
838         case 0x03: //64b
839             rt = u64;
840             break;
841         default:
842             rt = u64;
843     }
844     return;
845 }
846
847 Expression::Ptr InstructionDecoder_aarch64::makeMemRefEx(){
848     Result_Type rt;
849     getMemRefEx_RT(rt);
850     return makeDereferenceExpression(makeRnExpr(), rt);
851 }
852
853 void InstructionDecoder_aarch64::OPRQ(){
854     _Q = field<30, 30>(insn);
855 }
856
857 void InstructionDecoder_aarch64::OPRL(){
858     _L = field<30, 30>(insn);
859 }
860
861 void InstructionDecoder_aarch64::getMemRefSIMD_MULT_RT(Result_Type &rt){
862     //TODO the width should be much wider
863     rt = dbl128;
864     assert(0);
865 }
866
867 void InstructionDecoder_aarch64::getMemRefSIMD_SING_RT(Result_Type &rt){
868     unsigned int opcode = field<13,14>(insn);
869     unsigned int S = field<12, 12>(insn);
870     unsigned int size = field<10, 11>(insn);
871
872     if(opcode == 0x0){
873         rt = u8;
874     }else
875     if(opcode == 0x2 && (size & 0x1)==0x0){
876         rt = u16;
877     }else
878     if(opcode == 0x4 && size == 0x0){
879         rt = u32;
880     }else
881     if(opcode == 0x4 && S == 0 && size == 0x1){
882         rt = u64;
883     }
884     else
885         assert(0);
886     return;
887 }
888
889 Expression::Ptr InstructionDecoder_aarch64::makeMemRefSIMD_MULT(){
890     Result_Type rt;
891     getMemRefSIMD_MULT_RT(rt);
892     return makeDereferenceExpression(makeRnExpr(), rt);
893 }
894
895 Expression::Ptr InstructionDecoder_aarch64::makeMemRefSIMD_SING(){
896     Result_Type rt;
897     getMemRefSIMD_SING_RT(rt);
898     return makeDereferenceExpression(makeRnExpr(), rt);
899 }
900
901 void InstructionDecoder_aarch64::getMemRefExPair_RT(Result_Type &rt){
902     int size = field<30, 30>(insn);
903     switch(size){
904         case 0:
905             rt = u64;
906             break;
907         case 1:
908             rt = dbl128;
909             break;
910         default:
911             assert(!"should not reach here");
912             break;
913     }
914     return;
915 }
916
917 Expression::Ptr InstructionDecoder_aarch64::makeMemRefExPair(){
918     Result_Type rt;
919     getMemRefExPair_RT(rt);
920     return makeDereferenceExpression(makeRnExpr(), rt);
921 }
922
923 /*
924 Expression::Ptr InstructionDecoder_aarch64::makeMemRefExPair16B(){
925     return makeDereferenceExpression(makeRnExpr(), dbl128);
926 }
927 */
928
929 /*
930 Expression::Ptr InstructionDecoder_aarch64::makeMemRefExPair2(){
931     unsigned int immLen = 4, immVal = 8;
932     Expression::Ptr offset = Immediate::makeImmediate(Result(u32, unsign_extend32(immLen, immVal)));
933     return makeDereferenceExpression(makeAddExpression(makeRnExpr(), offset, u64) , u64);
934 }
935 */
936
937 Expression::Ptr InstructionDecoder_aarch64::makeMemRefReg_Rm(){
938     unsigned int option = field<13, 15>(insn);
939     if((option&2) != 2) assert(0);
940     MachRegister baseReg = ((option & 0x3)==0x2) ? aarch64::w0 : aarch64::x0;
941     unsigned int encoding = field<16, 20>(insn);
942
943         if( encoding == 31 )//zero register
944                 return makeRegisterExpression(makeAarch64RegID(aarch64::zr, 0));
945     else
946         return makeRegisterExpression(makeAarch64RegID(baseReg, encoding));
947 }
948
949 Expression::Ptr InstructionDecoder_aarch64::makeMemRefReg_amount(){
950     unsigned int S =  field<12, 12>(insn);
951     unsigned int amountVal = is64Bit?(S==0?0:2):(S==0?0:3);
952     unsigned int amountLen = 2;
953
954     return Immediate::makeImmediate(Result(u32, unsign_extend32(amountLen, amountVal)) ) ;
955 }
956
957 Expression::Ptr InstructionDecoder_aarch64::makeMemRefReg_ext(){
958
959     int immLen = 2;
960     int immVal = 0; //for amount
961
962     int S = field<12,12>(insn);
963     int size = field<30,31>(insn);
964
965     if( size == 2 ){ //32bit
966         immVal = S==0?0:(S==1?2:-1);
967         if( immVal==-1 ) assert(0);
968     }else if( size == 3 ){ //64bit
969         immVal = S==0?0:(S==1?3:-1);
970         if( immVal==-1) assert(0);
971     }
972     Expression::Ptr ext = makeOptionExpression(immLen, immVal);
973
974     return ext; /*extended ptr*/
975 }
976
977 /**********************
978 // ld/st reg memReg AST:
979 //    memRef
980 //      |
981 //     ADD
982 //    /    \
983 //  [Rn]   EXT
984 //        /   \
985 //      [Rm] [amount]
986 **********************/
987 Expression::Ptr InstructionDecoder_aarch64::makeMemRefReg(){
988
989     Expression::Ptr ext = makeMemRefReg_ext();
990     Expression::Ptr xn = makeRnExpr();
991     Expression::Ptr add = makeAddExpression(xn, ext, u64);
992
993     Result_Type rt;
994     getMemRefIndex_RT(rt);
995     return makeDereferenceExpression(add,rt);
996 }
997
998 void InstructionDecoder_aarch64::LIndex()
999 {
1000     // never be called
1001     if( IS_INSN_LD_LITERAL(insn)){
1002         insn_in_progress->appendOperand(makeMemRefIndexLiteral(), true, false);
1003         return;
1004     }
1005
1006     // ******************
1007     // load register offset
1008     // ******************
1009     else if( IS_INSN_LDST_REG(insn)){
1010         insn_in_progress->appendOperand(makeMemRefReg(), true, false);
1011         return;
1012     }
1013
1014     // ******************
1015     // load unsigned imm
1016     // ******************
1017     else if( IS_INSN_LDST_UIMM(insn)){
1018         insn_in_progress->appendOperand(makeMemRefIndexUImm(), true, false);
1019         return;
1020     }
1021
1022     // ******************
1023     // load pre, unscaled and unprivlidged
1024     // ******************
1025     else if( IS_INSN_LDST_PRE(insn)
1026         || IS_INSN_LDST_UNPRIV(insn)
1027         || IS_INSN_LDST_UNSCALED(insn) ){
1028         insn_in_progress->appendOperand(makeMemRefIndexPre(), true, false);
1029         return;
1030     }
1031
1032     else if( IS_INSN_LDST_POST(insn) ){
1033         insn_in_progress->appendOperand(makeMemRefIndexPost(), true, false);
1034         return;
1035     }
1036
1037     // ****************************
1038     // load PAIR pre, post, offset
1039     // ****************************
1040     else if( IS_INSN_LDST_PAIR_PRE(insn)
1041         || IS_INSN_LDST_PAIR_NOALLOC(insn) ){
1042         insn_in_progress->appendOperand(makeMemRefPairPre(), true, false);
1043         return;
1044     }
1045
1046     else if( IS_INSN_LDST_PAIR_POST(insn)
1047         || IS_INSN_LDST_PAIR_OFFSET(insn) ){
1048         insn_in_progress->appendOperand(makeMemRefPairPost(), true, false);
1049         return;
1050     }
1051
1052     // ****************************
1053     // load exclusive instructions
1054     // ****************************
1055     else if( IS_INSN_LDST_EX(insn) ){
1056         if( !IS_INSN_LDST_EX_PAIR(insn) ){ // Rt2 field == 31, non-pair op
1057             insn_in_progress->appendOperand( makeMemRefEx(), true, false);
1058         } else { // pair
1059             insn_in_progress->appendOperand( makeMemRefExPair(), true, false);
1060         }
1061         return;
1062     }
1063
1064     // ****************************
1065     // load SIMD multiple structures
1066     // ****************************
1067     else if( IS_INSN_LDST_SIMD_MULT(insn) ){
1068         insn_in_progress->appendOperand( makeMemRefSIMD_MULT(), true, false);
1069         return;
1070     }
1071     // ****************************
1072     // load SIMD multiple structures post increment
1073     // ****************************
1074     else if( IS_INSN_LDST_SIMD_MULT_POST(insn) ){
1075         insn_in_progress->appendOperand( makeMemRefSIMD_MULT(), true, false);
1076         return;
1077     }
1078     // ****************************
1079     // load SIMD single structure
1080     // ****************************
1081     else if( IS_INSN_LDST_SIMD_SING(insn) ){
1082         insn_in_progress->appendOperand( makeMemRefSIMD_SING(), true, false);
1083         return;
1084     }
1085     // ****************************
1086     // load SIMD single structure post increment
1087     // ****************************
1088     else if( IS_INSN_LDST_SIMD_SING_POST(insn) ){
1089         insn_in_progress->appendOperand( makeMemRefSIMD_SING(), true, false);
1090         return;
1091     }
1092
1093     assert(0); //un-handled case
1094
1095 }
1096
1097 void InstructionDecoder_aarch64::STIndex()
1098 {
1099     if( IS_INSN_LD_LITERAL(insn))
1100         assert(0); // only load literal, no store literal
1101
1102     // ******************
1103     // ld/st register offset
1104     // ******************
1105     else if( IS_INSN_LDST_REG(insn)){
1106         insn_in_progress->appendOperand(makeMemRefReg(), false, true);
1107         return;
1108     }
1109
1110     else if( IS_INSN_LDST_UIMM(insn)){
1111         insn_in_progress->appendOperand(makeMemRefIndexUImm(), false, true);
1112         return;
1113     }
1114
1115     // ******************
1116     // ld/st pre and post, unscaled and unprivilidged
1117     // ******************
1118     else if( IS_INSN_LDST_PRE(insn)
1119         || IS_INSN_LDST_UNPRIV(insn)
1120         || IS_INSN_LDST_UNSCALED(insn) ){
1121         insn_in_progress->appendOperand(makeMemRefIndexPre(), false, true);
1122         return;
1123     }
1124
1125     else if( IS_INSN_LDST_POST(insn) ){
1126         insn_in_progress->appendOperand(makeMemRefIndexPost(), false, true);
1127         return;
1128     }
1129
1130     // ****************************
1131     // ld/st PAIR pre, post, offset
1132     // ****************************
1133     else if( IS_INSN_LDST_PAIR_PRE(insn)
1134         || IS_INSN_LDST_PAIR_NOALLOC(insn) ){
1135         insn_in_progress->appendOperand(makeMemRefPairPre(), false, true);
1136         return;
1137     }
1138
1139     else if( IS_INSN_LDST_PAIR_POST(insn)
1140         || IS_INSN_LDST_PAIR_OFFSET(insn)) {
1141         insn_in_progress->appendOperand(makeMemRefPairPost(), false, true);
1142         return;
1143     }
1144
1145
1146     // ****************************
1147     // ld/st exclusive instructions
1148     // ****************************
1149     else if( IS_INSN_LDST_EX(insn) ){
1150         if( !IS_INSN_LDST_EX_PAIR(insn) ){ // Rt2 field == 31, non-pair op
1151             insn_in_progress->appendOperand( makeMemRefEx(), false, true);
1152         } else { // pair
1153             insn_in_progress->appendOperand( makeMemRefExPair(), false, true);
1154         }
1155         return;
1156     }
1157
1158     // ****************************
1159     // store SIMD multiple structures
1160     // ****************************
1161     else if( IS_INSN_LDST_SIMD_MULT(insn) ){
1162         insn_in_progress->appendOperand( makeMemRefSIMD_MULT(), false, true);
1163         return;
1164     }
1165     // ****************************
1166     // store SIMD multiple structures post increment
1167     // ****************************
1168     else if( IS_INSN_LDST_SIMD_MULT_POST(insn) ){
1169         insn_in_progress->appendOperand( makeMemRefSIMD_MULT(), false, true);
1170         return;
1171     }
1172     else if( IS_INSN_LDST_SIMD_SING(insn) ){
1173         insn_in_progress->appendOperand( makeMemRefSIMD_SING(), false, true);
1174     }
1175     else if( IS_INSN_LDST_SIMD_SING_POST(insn) ){
1176         insn_in_progress->appendOperand( makeMemRefSIMD_SING(), false, true);
1177         return;
1178     }
1179
1180     assert(0); //un-handled case
1181
1182 }
1183
1184 // This function is for non-writeback
1185 void InstructionDecoder_aarch64::OPRRn()
1186 {
1187         if(IS_INSN_B_UNCOND_REG(insn))                                                                          //unconditional branch (register)
1188         {
1189                 int branchType = field<21, 22>(insn);
1190
1191                 insn_in_progress->appendOperand(makePCExpr(), false, true);
1192                 insn_in_progress->addSuccessor(makeRnExpr(), field<21, 21>(insn) == 1, true, false, false);
1193
1194                 if(branchType == 0x1)
1195                 {
1196                         insn_in_progress->addSuccessor(makeFallThroughExpr(), false, false, false, true);
1197                 }
1198         }
1199         else
1200                 insn_in_progress->appendOperand(makeRnExpr(), true, false);
1201 }
1202
1203 void InstructionDecoder_aarch64::OPRRnL()
1204 {
1205     LIndex();
1206 }
1207
1208 void InstructionDecoder_aarch64::OPRRnS()
1209 {
1210     STIndex();
1211 }
1212
1213 void InstructionDecoder_aarch64::OPRRnU()
1214 {
1215     assert(0);
1216     /* this functions is useless
1217         insn_in_progress->appendOperand(makeRnExpr(), true, true);
1218     */
1219 }
1220
1221 void InstructionDecoder_aarch64::OPRRnLU()
1222 {
1223     if( IS_INSN_LDST_PRE(insn) ){
1224         LIndex();
1225         return;
1226     }
1227
1228     if( IS_INSN_LDST_POST(insn) ){
1229         LIndex();
1230         return;
1231     }
1232
1233     if( IS_INSN_LDST_PAIR_PRE(insn) ){
1234         LIndex();
1235         return;
1236     }
1237
1238     if( IS_INSN_LDST_PAIR_POST(insn) ){
1239         LIndex();
1240         return;
1241     }
1242
1243 }
1244
1245 void InstructionDecoder_aarch64::OPRRnSU()
1246 {
1247     if( IS_INSN_LDST_PRE(insn) ){
1248         STIndex();
1249         return;
1250     }
1251
1252     if( IS_INSN_LDST_POST(insn) ){
1253         STIndex();
1254         return;
1255     }
1256
1257     if( IS_INSN_LDST_PAIR_PRE(insn) ){
1258         STIndex();
1259         return;
1260     }
1261
1262     if( IS_INSN_LDST_PAIR_POST(insn) ){
1263         STIndex();
1264         return;
1265     }
1266 }
1267
1268 unsigned int InstructionDecoder_aarch64::get_SIMD_MULT_POST_imm(){
1269     unsigned int Q = field<30, 30>(insn);
1270     unsigned int rpt = 0, selem = 0;
1271     get_rptselem(rpt, selem);
1272     unsigned int numReg = rpt*selem;
1273     return Q?numReg<<3:numReg<<4;
1274 }
1275
1276 unsigned int InstructionDecoder_aarch64::get_SIMD_SING_POST_imm(){
1277     Result_Type rt;
1278     getMemRefSIMD_SING_RT(rt);
1279     switch(rt){
1280         case u8:
1281             return 1;
1282         case u16:
1283             return 2;
1284         case u32:
1285             return 4;
1286         case u64:
1287             return 8;
1288         default:
1289             assert(0);
1290             return 0;
1291     }
1292     return 0;
1293 }
1294
1295 Expression::Ptr InstructionDecoder_aarch64::makeRmExpr()
1296 {
1297     int encoding  = field<16, 20>(insn);
1298         MachRegister reg;
1299
1300     if( isSIMDInsn ){
1301         if( IS_INSN_LDST_SIMD_MULT_POST(insn) && encoding == 0x1f){
1302             unsigned int immVal = get_SIMD_MULT_POST_imm();
1303             unsigned int immLen = 8; // max #64
1304             return Immediate::makeImmediate( Result(u32, unsign_extend32(immLen, immVal)) );
1305         }
1306         else if(IS_INSN_LDST_SIMD_SING_POST(insn) && encoding == 0x1f ){
1307             unsigned int immVal = get_SIMD_SING_POST_imm();
1308             unsigned int immLen = 4; // max #8
1309             return Immediate::makeImmediate( Result(u32, unsign_extend32(immLen, immVal) ) );
1310         }
1311         else{
1312             reg = aarch64::q0;
1313             reg = makeAarch64RegID(reg, encoding);
1314         }
1315     } else
1316         if(isFPInsn)
1317         {
1318                 reg = isSinglePrec()?aarch64::s0:aarch64::d0;
1319                 reg = makeAarch64RegID(reg, encoding);
1320         }
1321         else
1322         {
1323                 reg = is64Bit?((encoding == 31)?aarch64::zr:aarch64::x0):((encoding == 31)?aarch64::wzr:aarch64::w0);
1324                 if(encoding != 31)
1325                         reg = makeAarch64RegID(reg, encoding);
1326         }
1327
1328         return makeRegisterExpression(reg);
1329 }
1330
1331 void InstructionDecoder_aarch64::OPRRm()
1332 {
1333         if(IS_INSN_LDST_REG(insn) ||
1334            IS_INSN_ADDSUB_EXT(insn) ||
1335            IS_INSN_ADDSUB_SHIFT(insn) ||
1336            IS_INSN_LOGICAL_SHIFT(insn))
1337                 return;
1338
1339         if(IS_INSN_FP_COMPARE(insn) && field<3, 3>(insn) == 1)
1340                 insn_in_progress->appendOperand(Immediate::makeImmediate(Result(isSinglePrec()?sp_float:dp_float, 0.0)), true, false);
1341         else
1342                 insn_in_progress->appendOperand(makeRmExpr(), true, false);
1343 }
1344
1345 void InstructionDecoder_aarch64::OPRsf()
1346 {
1347         if(field<31, 31>(insn) == 0)
1348                 is64Bit = false;
1349 }
1350
1351 template<unsigned int endBit, unsigned int startBit>
1352 void InstructionDecoder_aarch64::OPRoption()
1353 {
1354         hasOption = true;
1355         optionField = field<startBit, endBit>(insn);
1356 }
1357
1358 void InstructionDecoder_aarch64::OPRshift()
1359 {
1360         hasShift = true;
1361         shiftField = field<22, 23>(insn);
1362 }
1363
1364 void InstructionDecoder_aarch64::OPRhw()
1365 {
1366         hasHw = true;
1367         hwField = field<21, 22>(insn);
1368 }
1369
1370 template<unsigned int endBit, unsigned int startBit>
1371 void InstructionDecoder_aarch64::OPRN()
1372 {
1373         hasN = true;
1374         nField = field<startBit, endBit>(insn);
1375         nLen = endBit - startBit + 1;
1376 }
1377
1378 // the call of this function should be generated by decoder gen for ld/st class
1379 // except for ld/st{s, h, w} subclass
1380 void InstructionDecoder_aarch64::setRegWidth(){
1381     //is64Bit is by default set to TRUE
1382     unsigned int opc = 0x3 & field<22, 23>(insn);
1383     unsigned int opc0 = opc & 0x1;
1384     unsigned int opc1 = (opc & 0x2)>>1;
1385     unsigned int sz  = 0x3 & field<30, 31>(insn);
1386
1387     if(IS_INSN_LDST(insn)){
1388         if(   IS_INSN_LDST_UIMM(insn)   || IS_INSN_LDST_UNSCALED(insn)
1389                 || IS_INSN_LDST_UNPRIV(insn) || IS_INSN_LDST_POST(insn)
1390                 || IS_INSN_LDST_PRE(insn)    || IS_INSN_LDST_REG(insn)){
1391                 if(opc1 == 0){
1392                     if(field<30, 31>(insn) != 3)
1393                         is64Bit = false;
1394                     return;
1395                 }else{
1396                     if( sz == 3){
1397                         if( opc0 == 1) assert(!"unallocated insn");
1398                     }
1399                     else{
1400                         if(sz == 2 && opc0 == 1) assert(!"unallocated insn");
1401                         if(opc0 == 1)
1402                             is64Bit = false;
1403                     }
1404                     return;
1405                 }
1406         }
1407         else if(IS_INSN_LDST_EX(insn)){
1408             switch(sz){
1409                 case 2:
1410                 case 0:
1411                 case 1:
1412                     is64Bit = false;
1413                     break;
1414                 case 3:
1415                 default:
1416                     return;
1417             }
1418         }
1419         else if(IS_INSN_LDST_PAIR(insn)){
1420             switch(sz){
1421                 case 0:
1422                     is64Bit = false;
1423                     break;
1424                 case 1:
1425                 case 2:
1426                 case 3:
1427                 default:
1428                     return;
1429             }
1430         }
1431         else if(IS_INSN_LD_LITERAL(insn)){
1432             switch(sz){
1433                 case 0:
1434                     is64Bit = false;
1435                 case 1:
1436                 case 2:
1437                 case 3:
1438                 default:
1439                     return;
1440             }
1441         }
1442         else{
1443             assert(!"not implemented for SIMD");
1444         }
1445     }else{
1446         assert(0);
1447     }
1448     return;
1449 }
1450
1451 Expression::Ptr InstructionDecoder_aarch64::makeRtExpr()
1452 {
1453         int encoding  = field<0, 4>(insn);
1454         MachRegister reg;
1455
1456         if(isFPInsn)
1457         {
1458                 reg = makeAarch64RegID(isSinglePrec()?aarch64::s0:aarch64::d0, encoding);
1459         }
1460         else
1461         {
1462                 reg = is64Bit?((encoding == 31)?aarch64::zr:aarch64::x0):((encoding == 31)?aarch64::wzr:aarch64::w0);
1463                 if(encoding != 31)
1464                         reg = makeAarch64RegID(reg, encoding);
1465         }
1466
1467         return makeRegisterExpression(reg);
1468 }
1469
1470 void InstructionDecoder_aarch64::get_rptselem(unsigned int &rpt, unsigned int &selem){
1471     unsigned opcode = field<12, 15>(insn);
1472     switch(opcode){
1473         case 0x0:
1474             rpt = 1; selem = 4;
1475             break;
1476         case 0x2:
1477             rpt = 4; selem = 1;
1478             break;
1479         case 0x4:
1480             rpt = 1; selem = 3;
1481             break;
1482         case 0x6:
1483             rpt = 3; selem = 1;
1484             break;
1485         case 0x7:
1486             rpt = 1; selem = 1;
1487             break;
1488         case 0x8:
1489             rpt = 1; selem = 2;
1490             break;
1491         case 0xa:
1492             rpt = 2; selem = 1;
1493             break;
1494         default:
1495             assert(!"unallocated encoding");
1496             return;
1497     }
1498     assert(rpt!=0 && selem!=0);
1499     return;
1500 }
1501
1502 void InstructionDecoder_aarch64::OPRRt()
1503 {
1504         int encoding = field<0, 4>(insn);
1505         if(IS_INSN_BRANCHING(insn))
1506         {
1507                 if(encoding == 31)
1508                         insn_in_progress->appendOperand(makeRegisterExpression(is64Bit?aarch64::zr:aarch64::wzr), true, false);
1509                 else
1510                         insn_in_progress->appendOperand(makeRegisterExpression(makeAarch64RegID(is64Bit?aarch64::x0:aarch64::w0, encoding)), true, false);
1511         }
1512 }
1513
1514 void InstructionDecoder_aarch64::OPRRtL()
1515 {
1516         int encoding = field<0, 4>(insn);
1517     if( IS_INSN_LDST_SIMD_MULT(insn) ){
1518         unsigned int rpt, selem;
1519         get_rptselem(rpt, selem);
1520         for(unsigned int it_rpt = 0; it_rpt < rpt; it_rpt++){
1521                         insn_in_progress->appendOperand(makeRegisterExpression(makeAarch64RegID(aarch64::q0, encoding + it_rpt)), false, true);
1522         }
1523     }
1524     else
1525             insn_in_progress->appendOperand(makeRtExpr(), false, true);
1526 }
1527
1528 void InstructionDecoder_aarch64::OPRRtS()
1529 {
1530         int encoding = field<0, 4>(insn);
1531     if( IS_INSN_LDST_SIMD_MULT(insn) ){
1532         unsigned int rpt, selem;
1533         get_rptselem(rpt, selem);
1534         for(unsigned int it_rpt = 0; it_rpt < rpt; it_rpt++){
1535                         insn_in_progress->appendOperand(makeRegisterExpression(makeAarch64RegID(aarch64::q0, encoding + it_rpt)), true, false);
1536         }
1537     }
1538     else
1539             insn_in_progress->appendOperand(makeRtExpr(), true, false);
1540 }
1541
1542 Expression::Ptr InstructionDecoder_aarch64::makeRt2Expr()
1543 {
1544         MachRegister baseReg = isFPInsn?
1545         (isSinglePrec()?aarch64::s0:aarch64::d0):
1546         (is64Bit?aarch64::x0 : aarch64::w0);
1547
1548         return makeRegisterExpression(makeAarch64RegID(baseReg, field<10, 14>(insn)));
1549 }
1550
1551 void InstructionDecoder_aarch64::OPRRt2()
1552 {
1553     assert(0);
1554 }
1555
1556 void InstructionDecoder_aarch64::OPRRt2L()
1557 {
1558         insn_in_progress->appendOperand(makeRt2Expr(), false, true);
1559 }
1560
1561 void InstructionDecoder_aarch64::OPRRt2S()
1562 {
1563         insn_in_progress->appendOperand(makeRt2Expr(), true, false);
1564 }
1565
1566 template<unsigned int endBit, unsigned int startBit>
1567 void InstructionDecoder_aarch64::OPRcond()
1568 {
1569         unsigned char condVal = static_cast<unsigned char>(field<startBit, endBit>(insn));
1570         if(IS_INSN_B_COND(insn))
1571         {
1572                 insn_in_progress->getOperation().mnemonic += ".";
1573                 insn_in_progress->getOperation().mnemonic += condStringMap[condVal];
1574         }
1575         else
1576         {
1577                 Expression::Ptr cond = Immediate::makeImmediate(Result(u8, condVal));
1578                 insn_in_progress->appendOperand(cond, true, false);
1579                 oprRotateAmt++;
1580         }
1581
1582         isPstateRead = true;
1583 }
1584
1585 void InstructionDecoder_aarch64::OPRnzcv()
1586 {
1587         unsigned int nzcvVal = field<0, 3>(insn)<<28;
1588         Expression::Ptr nzcv = Immediate::makeImmediate(Result(u32, nzcvVal));
1589         insn_in_progress->appendOperand(nzcv, true, false);
1590
1591         isPstateWritten = true;
1592         oprRotateAmt++;
1593 }
1594
1595 void InstructionDecoder_aarch64::OPRop1()
1596 {
1597         op1Field = field<16, 18>(insn);
1598 }
1599
1600 void InstructionDecoder_aarch64::OPRop2()
1601 {
1602         op2Field = field<5, 7>(insn);
1603 }
1604
1605 void InstructionDecoder_aarch64::OPRCRm()
1606 {
1607         crmField = field<8 ,11>(insn);
1608 }
1609
1610 void InstructionDecoder_aarch64::OPRCRn()
1611 {
1612 }
1613
1614 template<unsigned int endBit, unsigned int startBit>
1615 void InstructionDecoder_aarch64::OPRS()
1616 {
1617         sField = field<startBit, endBit>(insn);
1618 }
1619
1620 void InstructionDecoder_aarch64::OPRscale()
1621 {
1622         int scaleVal = 64 - field<10, 15>(insn);
1623
1624         Expression::Ptr scale = Immediate::makeImmediate(Result(u32, unsign_extend32(6, scaleVal)));
1625         insn_in_progress->appendOperand(scale, true, false);
1626 }
1627
1628 Expression::Ptr InstructionDecoder_aarch64::makeRaExpr()
1629 {
1630         int encoding  = field<10, 14>(insn);
1631         MachRegister reg;
1632
1633         if(isFPInsn)
1634         {
1635                 reg = makeAarch64RegID(isSinglePrec()?aarch64::s0:aarch64::d0, encoding);
1636         }
1637         else
1638         {
1639                 reg = is64Bit?((encoding == 31)?aarch64::sp:aarch64::x0):((encoding == 31)?aarch64::wsp:aarch64::w0);
1640                 if(encoding != 31)
1641                         reg = makeAarch64RegID(reg, encoding);
1642         }
1643
1644         return makeRegisterExpression(reg);
1645
1646 }
1647
1648 void InstructionDecoder_aarch64::OPRRa()
1649 {
1650         insn_in_progress->appendOperand(makeRaExpr(), true, false);
1651
1652         oprRotateAmt++;
1653 }
1654
1655 void InstructionDecoder_aarch64::OPRo0()
1656 {
1657
1658 }
1659
1660 void InstructionDecoder_aarch64::OPRb5()
1661 {
1662         OPRsf();
1663         hasb5 = true;
1664 }
1665
1666 void InstructionDecoder_aarch64::OPRb40()
1667 {
1668
1669 }
1670
1671 Expression::Ptr InstructionDecoder_aarch64::makeb40Expr()
1672 {
1673         int b40Val = field<19, 23>(insn);
1674         int bitpos = ((is64Bit?1:0)<<5) | b40Val;
1675
1676         return Immediate::makeImmediate(Result(u32, unsign_extend32(6, bitpos)));
1677 }
1678
1679 template<unsigned int endBit, unsigned int startBit>
1680 void InstructionDecoder_aarch64::OPRsz()
1681 {
1682     _szField = field<startBit, endBit>(insn);
1683 }
1684
1685 bool InstructionDecoder_aarch64::isSinglePrec() {
1686     if( isFPInsn && !isSIMDInsn ){
1687         if(_typeField == -1){
1688             //TODO if the type field is not set, do sth else
1689             OPRtype<23, 22>();
1690         }
1691         return _typeField==0?true:false;
1692     }else if( isSIMDInsn ){
1693         assert(0); //not implemeted yet
1694     }
1695     return false;
1696 }
1697
1698 Expression::Ptr InstructionDecoder_aarch64::makeRsExpr()
1699 {
1700         MachRegister baseReg = isFPInsn?
1701         (isSinglePrec()?aarch64::s0:aarch64::d0):
1702         (is64Bit?aarch64::x0:aarch64::w0);
1703
1704     if(IS_INSN_LDST(insn)){
1705         baseReg = aarch64::w0;
1706     }
1707         return makeRegisterExpression(makeAarch64RegID(baseReg, field<16, 20>(insn)));
1708 }
1709
1710 void InstructionDecoder_aarch64::OPRRs()
1711 {
1712         insn_in_progress->appendOperand(makeRsExpr(), false, true);
1713 }
1714
1715 void InstructionDecoder_aarch64::makeBranchTarget(bool branchIsCall, bool bIsConditional, int immVal, int immLen)
1716 {
1717         Expression::Ptr lhs = makePCExpr();
1718
1719         int offset = sign_extend64(immLen + 2, immVal*4);
1720         Expression::Ptr rhs = Immediate::makeImmediate(Result(s64, offset));
1721
1722         insn_in_progress->addSuccessor(makeAddExpression(lhs, rhs, s64), branchIsCall, false, bIsConditional, false);
1723         if(branchIsCall)
1724         {
1725                 insn_in_progress->addSuccessor(makeFallThroughExpr(), false, false, false, true);
1726         }
1727
1728 }
1729
1730 Expression::Ptr InstructionDecoder_aarch64::makeFallThroughExpr()
1731 {
1732         return makeAddExpression(makePCExpr(), Immediate::makeImmediate(Result(u64, unsign_extend64(3, 4))), u64);
1733 }
1734
1735 template<typename T, Result_Type rT>
1736 Expression::Ptr InstructionDecoder_aarch64::fpExpand(int val)
1737 {
1738         int N, E, F;
1739         T frac, expandedImm, sign, exp;
1740
1741         N = (rT == s32)?32:64;
1742         E = (N == 32)?8:11;
1743         F = N - E - 1;
1744
1745         sign = (val & 0x80) >> 7;
1746
1747         int val6 = ((~val) & 0x40) >> 6, val6mask = (1 << (E - 3)) - 1;
1748         exp = (val6 << (E - 1)) | ((val6?val6mask:0) << 2) | ((val & 0x30) >> 4);
1749
1750         frac = (val & 0xF) << (F - 4);
1751
1752         expandedImm = (sign << (E + F)) | (exp << F) | frac;
1753
1754         return Immediate::makeImmediate(Result(rT, expandedImm));
1755 }
1756
1757 template<unsigned int endBit, unsigned int startBit>
1758 void InstructionDecoder_aarch64::OPRimm()
1759 {
1760         int immVal = field<startBit, endBit>(insn);
1761         unsigned int immLen = endBit - startBit + 1;
1762
1763         if(IS_INSN_LDST(insn)){
1764         if(IS_INSN_LD_LITERAL(insn) ){
1765                         Expression::Ptr literal = makeMemRefIndexLiteral();
1766                         insn_in_progress->appendOperand(literal, true, false);
1767         }
1768         else if(IS_INSN_LDST_POST(insn)){
1769                         Expression::Ptr offset = makeMemRefIndex_offset9();
1770                         insn_in_progress->appendOperand(offset, true, false);
1771         }
1772         else if(IS_INSN_LDST_PAIR_POST(insn)
1773                 || IS_INSN_LDST_PAIR_OFFSET(insn) ){
1774                         Expression::Ptr offset = makeMemRefPair_offset7();
1775                         insn_in_progress->appendOperand(offset, true, false);
1776         }
1777                 return;
1778     }
1779
1780         if(hasHw)
1781         {
1782                 processHwFieldInsn(immLen, immVal);
1783         }
1784         else if(hasN)           //logical (immediate), bitfield, extract
1785         {
1786                 if(IS_FIELD_IMMR(startBit, endBit))
1787                 {
1788                         immr = immVal;
1789                         immrLen = immLen;
1790                 }
1791                 else if(IS_FIELD_IMMS(startBit, endBit))
1792                 {
1793                         Expression::Ptr imm;
1794
1795                         if(IS_INSN_LOGICAL_IMM(insn))
1796                         {
1797                                 immVal |= (immr << immLen);
1798                                 immVal |= (nField << (immLen + immrLen));
1799
1800                                 immLen += nLen + immrLen;
1801
1802                                 Result_Type rT = is64Bit?u64:u32;
1803                                 imm = Immediate::makeImmediate(Result(rT, rT==u32?unsign_extend32(immLen, immVal):unsign_extend64(immLen, immVal)));
1804                         }
1805                         else
1806                         {
1807                                 imm = Immediate::makeImmediate(Result(u32, unsign_extend32(immLen, immVal)));
1808                                 oprRotateAmt++;
1809                         }
1810
1811                         insn_in_progress->appendOperand(imm, true, false);
1812                         if(IS_INSN_BITFIELD(insn))
1813                         {
1814                                 imm = Immediate::makeImmediate(Result(u32, unsign_extend32(immrLen, immr)));
1815                                 insn_in_progress->appendOperand(imm, true, false);
1816                                 oprRotateAmt--;
1817                         }
1818                 }
1819                 else
1820                     isValid = false;
1821         }
1822         else if(hasShift)
1823         {
1824                 if(IS_INSN_ADDSUB_SHIFT(insn) || IS_INSN_LOGICAL_SHIFT(insn))   //add-sub shifted | logical shifted
1825                 {
1826                         processShiftFieldShiftedInsn(immLen, immVal);
1827                 }
1828                 else if(IS_INSN_ADDSUB_IMM(insn))               //add-sub (immediate)
1829                 {
1830                         processShiftFieldImmInsn(immLen, immVal);
1831                 }
1832                 else
1833                         isValid = false;
1834         }
1835         else if(hasOption)
1836         {
1837                 if(IS_INSN_ADDSUB_EXT(insn))                                                                            //add-sub extended
1838                 {
1839                     Expression::Ptr expr = makeOptionExpression(immLen, immVal);
1840
1841                     insn_in_progress->appendOperand(expr, true, false);
1842                 }
1843                 else
1844                 {
1845                         isValid = false;
1846                 }
1847         }
1848         else if(IS_INSN_BRANCHING(insn) && !IS_INSN_B_UNCOND_REG(insn))
1849         {               //unconditional branch (immediate), test and branch, compare and branch, conditional branch
1850                 bool bIsConditional = false;
1851                 if(!(IS_INSN_B_UNCOND(insn)))
1852                         bIsConditional = true;
1853
1854                 bool branchIsCall = bIsConditional?false:(field<31, 31>(insn) == 1);
1855
1856                 insn_in_progress->appendOperand(makePCExpr(), false, true);
1857                 makeBranchTarget(branchIsCall, bIsConditional, immVal, immLen);
1858
1859                 if(hasb5)
1860                         insn_in_progress->appendOperand(makeb40Expr(), true, false);
1861
1862                 if(bIsConditional)
1863                         insn_in_progress->addSuccessor(makeFallThroughExpr(), false, false, true, true);
1864         }
1865         else if(IS_INSN_PCREL_ADDR(insn))                                                                       //pc-relative addressing
1866         {
1867                 if(IS_FIELD_IMMLO(startBit, endBit))
1868                 {
1869                         immlo = immVal;
1870                         immloLen = endBit - startBit + 1;
1871                 }
1872                 else if(IS_FIELD_IMMHI(startBit, endBit))
1873                 {
1874                         int page = field<31, 31>(insn);
1875                         int offset = (immVal<<immloLen) | immlo;
1876
1877                         insn_in_progress->appendOperand(makePCExpr(), true, false);
1878                         Expression::Ptr imm = Immediate::makeImmediate(Result(s64, sign_extend64(immloLen + immLen + page*12, offset<<(page*12))));
1879
1880                         insn_in_progress->appendOperand(imm, true, false);
1881                 }
1882                 else
1883                         isValid = false;
1884         }
1885         else if(isFPInsn)
1886         {
1887                 if(isSinglePrec())
1888                         insn_in_progress->appendOperand(fpExpand<int32_t, s32>(immVal), true, false);
1889                 else
1890                         insn_in_progress->appendOperand(fpExpand<int64_t, s64>(immVal), true, false);
1891         }
1892         else if(IS_INSN_EXCEPTION(insn))
1893         {
1894                 Expression::Ptr imm = Immediate::makeImmediate(Result(u16, immVal));
1895                 insn_in_progress->appendOperand(imm, true, false);
1896                 isPstateRead = true;
1897         }
1898         else                                                            //conditional compare (immediate)
1899         {
1900                 Result_Type rT = is64Bit?u64:u32;
1901
1902                 Expression::Ptr imm = Immediate::makeImmediate(Result(rT, rT==u32?unsign_extend32(immLen, immVal):unsign_extend64(immLen, immVal)));
1903                 insn_in_progress->appendOperand(imm, true, false);
1904         }
1905 }
1906
1907         void InstructionDecoder_aarch64::reorderOperands()
1908         {
1909             if(oprRotateAmt)
1910             {
1911                         std::vector<Operand> curOperands;
1912                         insn_in_progress->getOperands(curOperands);
1913
1914                         if(curOperands.empty())
1915                                 assert(!"empty operand list found while re-ordering operands");
1916
1917                         std::swap(curOperands[1], curOperands[3]);
1918
1919                         while(oprRotateAmt--)
1920                                 std::rotate(curOperands.begin(), curOperands.begin()+1, curOperands.begin()+3);
1921
1922                         insn_in_progress->m_Operands.assign(curOperands.begin(), curOperands.end());
1923             }
1924         else if( IS_INSN_LDST_POST(insn) || IS_INSN_LDST_PAIR_POST(insn) ){
1925                 std::vector<Operand> curOperands;
1926                 insn_in_progress->getOperands(curOperands);
1927             std::iter_swap( curOperands.begin(), curOperands.end()-1 );
1928                     insn_in_progress->m_Operands.assign(curOperands.begin(), curOperands.end());
1929         }
1930         else if( IS_INSN_LDST_PAIR(insn) ){
1931                     std::vector<Operand> curOperands;
1932                     insn_in_progress->getOperands(curOperands);
1933             assert(curOperands.size() == 4 || curOperands.size() == 3);
1934             if(curOperands.size() == 3){
1935                 curOperands.insert(curOperands.begin(), curOperands.back());
1936                 curOperands.pop_back();
1937             }else if(curOperands.size() == 4){
1938                 std::iter_swap( curOperands.begin(), curOperands.end()-1 );
1939             }
1940                     insn_in_progress->m_Operands.assign(curOperands.begin(), curOperands.end());
1941         }
1942         else if( IS_INSN_LDST_EX_PAIR(insn) ){
1943                     std::vector<Operand> curOperands;
1944                     insn_in_progress->getOperands(curOperands);
1945             if(curOperands.size() == 3) {
1946                 curOperands.insert(curOperands.begin(), curOperands.back());
1947                 curOperands.pop_back();
1948             }
1949             else if( curOperands.size() == 4) {
1950                 curOperands.insert(curOperands.begin()+1, curOperands.back());
1951                 curOperands.pop_back();
1952             }
1953                     insn_in_progress->m_Operands.assign(curOperands.begin(), curOperands.end());
1954         }
1955         else if( IS_INSN_ST_EX(insn) ){
1956                     std::vector<Operand> curOperands;
1957                     insn_in_progress->getOperands(curOperands);
1958             if(curOperands.size() == 3){
1959                 curOperands.insert(curOperands.begin()+1, curOperands.back());
1960                 curOperands.pop_back();
1961                         insn_in_progress->m_Operands.assign(curOperands.begin(), curOperands.end());
1962             }
1963             else
1964                         insn_in_progress->m_Operands.reverse();
1965         }
1966             else
1967                     insn_in_progress->m_Operands.reverse();
1968         }
1969
1970
1971 using namespace boost::assign;
1972
1973 #include "aarch64_opcode_tables.C"
1974
1975         void InstructionDecoder_aarch64::doDelayedDecode(const Instruction *insn_to_complete)
1976     {
1977                 int insn_table_index = findInsnTableIndex(0);
1978                 aarch64_insn_entry *insn_table_entry = &aarch64_insn_entry::main_insn_table[insn_table_index];
1979
1980                 insn = insn_to_complete->m_RawInsn.small_insn;
1981                 insn_in_progress = const_cast<Instruction*>(insn_to_complete);
1982
1983         for(operandSpec::const_iterator fn = insn_table_entry->operands.begin(); fn != insn_table_entry->operands.end(); fn++)
1984         {
1985                         std::mem_fun(*fn)(this);
1986                 }
1987
1988                 reorderOperands();
1989
1990                 if(IS_INSN_SYSTEM(insn))
1991                 {
1992                         processSystemInsn();
1993                 }
1994
1995                 if(isPstateWritten || isPstateRead)
1996                         insn_in_progress->appendOperand(makePstateExpr(), isPstateRead, isPstateWritten);
1997
1998                 if(!isValid)
1999                 {
2000                         insn_in_progress->getOperation().mnemonic = INVALID_ENTRY.mnemonic;
2001                         insn_in_progress->getOperation().operationID = INVALID_ENTRY.op;
2002                         insn_in_progress->m_Operands.clear();
2003                         insn_in_progress->m_Successors.clear();
2004                 }
2005     }
2006         int InstructionDecoder_aarch64::findInsnTableIndex(unsigned int decoder_table_index)
2007         {
2008                 aarch64_mask_entry *cur_entry = &aarch64_mask_entry::main_decoder_table[decoder_table_index];
2009                 unsigned int cur_mask = cur_entry->mask;
2010
2011                 if(cur_mask == 0)
2012                 {
2013                         if(cur_entry->insnTableIndices.size() == 1)
2014                                 return cur_entry->insnTableIndices[0];
2015
2016                         int insn_table_index = -1;
2017                         for(std::vector<int>::iterator itr = cur_entry->insnTableIndices.begin(); itr != cur_entry->insnTableIndices.end(); itr++)
2018                         {
2019                                 aarch64_insn_entry *nextEntry = &aarch64_insn_entry::main_insn_table[*itr];
2020                                 if((insn & nextEntry->_maskBits) == nextEntry->_encodingBits)
2021                                 {
2022                                         insn_table_index = *itr;
2023                                         break;
2024                                 }
2025                         }
2026
2027                         if(insn_table_index == -1)
2028                                 assert(!"no instruction table entry found for current instruction");
2029                         else
2030                                 return insn_table_index;
2031                 }
2032
2033                 unsigned int insn_iter_index = 0, map_key_index = 0, branch_map_key = 0;
2034                 branchMap cur_branches = cur_entry->nodeBranches;
2035
2036                 while(insn_iter_index < AARCH64_INSN_LENGTH)
2037                 {
2038                         if(((cur_mask>>insn_iter_index) & 1) == 1)
2039                         {
2040                                 branch_map_key = branch_map_key | (((insn>>insn_iter_index) & 1)<<map_key_index);
2041                                 map_key_index++;
2042                         }
2043                         insn_iter_index++;
2044                 }
2045
2046                 if(cur_branches.count(branch_map_key) <= 0)
2047                         branch_map_key = 0;
2048
2049                 return findInsnTableIndex(cur_branches[branch_map_key]);
2050         }
2051
2052         void InstructionDecoder_aarch64::setFlags()
2053         {
2054                 isPstateWritten = true;
2055         }
2056
2057     void InstructionDecoder_aarch64::mainDecode()
2058     {
2059                 int insn_table_index = findInsnTableIndex(0);
2060                 aarch64_insn_entry *insn_table_entry = &aarch64_insn_entry::main_insn_table[insn_table_index];
2061
2062         insn_in_progress = makeInstruction(insn_table_entry->op, insn_table_entry->mnemonic, 4, reinterpret_cast<unsigned char*>(&insn));
2063         //insn_printf("ARM: %s\n", insn_table_entry->mnemonic);
2064
2065         if(IS_INSN_BRANCHING(insn))
2066         {
2067             // decode control-flow operands immediately; we're all but guaranteed to need them
2068             doDelayedDecode(insn_in_progress);
2069         }
2070
2071         //insn_in_progress->arch_decoded_from = m_Arch;
2072         insn_in_progress->arch_decoded_from = Arch_aarch64;
2073         return;
2074     }
2075   };
2076 };
2077
2078
2079