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