Finish most of the Power 8 VSX instruction decoding
[dyninst.git] / instructionAPI / src / InstructionDecoder-power.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-power.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_power::*operandFactory)();
40       typedef std::vector< operandFactory > operandSpec;
41       typedef const power_entry&(InstructionDecoder_power::*nextTableFunc)();
42       typedef std::map<unsigned int, power_entry> power_table;
43       bool InstructionDecoder_power::foundDoubleHummerInsn = false;
44       bool InstructionDecoder_power::foundQuadInsn = false;
45       struct power_entry
46       {
47         power_entry(entryID o, const char* m, nextTableFunc next, operandSpec ops) :
48                 op(o), mnemonic(m), next_table(next), operands(ops)
49                 {}
50         power_entry() :
51                         op(power_op_INVALID), mnemonic("INVALID"), next_table(NULL)
52                         {
53                             operands.reserve(5);
54                         }
55         power_entry(const power_entry& o) :
56                 op(o.op), mnemonic(o.mnemonic), next_table(o.next_table), operands(o.operands)
57                 {}
58                 const power_entry& operator=(const power_entry& rhs)
59                 {
60                     operands.reserve(rhs.operands.size());
61                     op = rhs.op;
62                     mnemonic = rhs.mnemonic;
63                     next_table = rhs.next_table;
64                     operands = rhs.operands;
65                     return *this;
66                 }
67                 entryID op;
68                 const char* mnemonic;
69                 nextTableFunc next_table;
70                 operandSpec operands;
71                 static void buildTables();
72                 static bool built_tables;
73                 static std::vector<power_entry> main_opcode_table;
74                 static power_table extended_op_0;
75                 static power_table extended_op_4;
76                 static power_table extended_op_19;
77                 static power_table extended_op_30;
78                 static power_table extended_op_31;
79                 static power_table extended_op_57;
80                 static power_table extended_op_58;
81                 static power_table extended_op_59;
82                 static power_table extended_op_60;
83                 static power_table extended_op_61;
84                 static power_table extended_op_63;
85       };
86
87     InstructionDecoder_power::InstructionDecoder_power(Architecture a)
88       : InstructionDecoderImpl(a),
89         insn(0), insn_in_progress(NULL),
90         isRAWritten(false), invertBranchCondition(false),
91         isFPInsn(false), bcIsConditional(false)
92     {
93         power_entry::buildTables();
94     }
95     InstructionDecoder_power::~InstructionDecoder_power()
96     {
97     }
98     void InstructionDecoder_power::decodeOpcode(InstructionDecoder::buffer& b)
99     {
100       b.start += 4;
101     }
102
103     void InstructionDecoder_power::FRTP()
104     {
105         FRT();
106         FRTS();
107     }
108     void InstructionDecoder_power::FRTS()
109     {
110         isFPInsn = true;
111         MachRegister regID = makePowerRegID(ppc32::fsr0, field<6, 10>(insn));
112         insn_in_progress->appendOperand(makeRegisterExpression(regID), false, true);
113         isRAWritten = false;
114         foundDoubleHummerInsn = true;
115     }
116     void InstructionDecoder_power::QFRTP()
117     {
118         QRT();
119         QFRTS();
120     }
121     void InstructionDecoder_power::QFRTS()
122     {
123         isFPInsn = true;
124         MachRegister regID = makePowerRegID(ppc64::fsr0, field<6, 10>(insn));
125         insn_in_progress->appendOperand(makeRegisterExpression(regID), false, true);
126         isRAWritten = false;
127         foundQuadInsn = true;
128     }
129     void InstructionDecoder_power::FRSP()
130     {
131         FRS();
132         FRSS();
133     }
134     void InstructionDecoder_power::FRSS()
135     {
136         isFPInsn = true;
137         MachRegister regID = makePowerRegID(ppc32::fsr0, field<6, 10>(insn));
138         insn_in_progress->appendOperand(makeRegisterExpression(regID), true, false);
139         isRAWritten = true;
140         foundDoubleHummerInsn = true;
141     }
142     void InstructionDecoder_power::QFRSP()
143     {
144         QFRS();
145         QFRSS();
146     }
147     void InstructionDecoder_power::QFRSS()
148     {
149         isFPInsn = true;
150         MachRegister regID = makePowerRegID(ppc64::fsr0, field<6, 10>(insn));
151         insn_in_progress->appendOperand(makeRegisterExpression(regID), true, false);
152         isRAWritten = true;
153         foundQuadInsn = true;
154     }
155     void InstructionDecoder_power::FRAP()
156     {
157         FRA();
158         FRAS();
159     }
160     void InstructionDecoder_power::FRAS()
161     {
162         isFPInsn = true;
163         MachRegister regID = makePowerRegID(ppc32::fsr0, field<11, 15>(insn));
164         insn_in_progress->appendOperand(makeRegisterExpression(regID), !isRAWritten, isRAWritten);
165         foundDoubleHummerInsn = true;
166     }
167     void InstructionDecoder_power::QFRAP()
168     {
169         QFRA();
170         QFRAS();
171     }
172     void InstructionDecoder_power::QFRAS()
173     {
174         isFPInsn = true;
175         MachRegister regID = makePowerRegID(ppc64::fsr0, field<11, 15>(insn));
176         insn_in_progress->appendOperand(makeRegisterExpression(regID), !isRAWritten, isRAWritten);
177         foundQuadInsn = true;
178     }
179     void InstructionDecoder_power::FRBP()
180     {
181         FRB();
182         FRBS();
183     }
184     void InstructionDecoder_power::QRB()
185     {
186         insn_in_progress->appendOperand(makeQRBExpr(), true, false);
187         QRBS();
188     }
189     void InstructionDecoder_power::QRBS()
190     {
191         isFPInsn = true;
192         MachRegister regID = makePowerRegID(ppc64::fsr0, field<16, 20>(insn));
193         insn_in_progress->appendOperand(makeRegisterExpression(regID), true, false);
194         foundQuadInsn = true;
195     }
196     void InstructionDecoder_power::FRBS()
197     {
198         isFPInsn = true;
199         MachRegister regID = makePowerRegID(ppc32::fsr0, field<16, 20>(insn));
200         insn_in_progress->appendOperand(makeRegisterExpression(regID), true, false);
201         foundDoubleHummerInsn = true;
202     }
203     void InstructionDecoder_power::FRCP()
204     {
205         FRC();
206         FRCS();
207     }
208     void InstructionDecoder_power::FRCS()
209     {
210         isFPInsn = true;
211         MachRegister regID = makePowerRegID(ppc32::fsr0, field<21, 25>(insn));
212         insn_in_progress->appendOperand(makeRegisterExpression(regID), true, false);
213         foundDoubleHummerInsn = true;
214     }
215
216     void InstructionDecoder_power::QFRCP()
217     {
218         QFRC();
219         QFRCS();
220     }
221     void InstructionDecoder_power::QFRCS()
222     {
223         isFPInsn = true;
224         MachRegister regID = makePowerRegID(ppc64::fsr0, field<21, 25>(insn));
225         insn_in_progress->appendOperand(makeRegisterExpression(regID), true, false);
226         foundQuadInsn = true;
227     }
228
229     Expression::Ptr InstructionDecoder_power::makeFallThroughExpr()
230     {
231         return makeAddExpression(makeRegisterExpression(ppc32::pc), Immediate::makeImmediate(Result(u32, 4)), u32);
232     }
233     void InstructionDecoder_power::LI()
234     {
235         insn_in_progress->addSuccessor(makeIFormBranchTarget(), field<31, 31>(insn) == 1, false, false, false);
236     }
237     void InstructionDecoder_power::BD()
238     {
239         insn_in_progress->addSuccessor(makeBFormBranchTarget(), field<31, 31>(insn) == 1, false, bcIsConditional, false);
240         if(bcIsConditional)
241         {
242             insn_in_progress->addSuccessor(makeFallThroughExpr(), false, false, false, true);
243         }
244     }
245     
246     using namespace std;
247     Instruction::Ptr InstructionDecoder_power::decode(InstructionDecoder::buffer& b)
248     {
249       if(b.start > b.end) return Instruction::Ptr();
250       isRAWritten = false;
251       isFPInsn = false;
252       bcIsConditional = false;
253       insn = *((const uint32_t*)b.start);
254 #if defined(DEBUG_RAW_INSN)        
255         cout.width(0);
256         cout << "0x";
257         cout.width(8);
258         cout.fill('0');
259         cout << hex << insn << "\t";
260 #endif
261         mainDecode();
262         b.start += 4;
263         return make_shared(insn_in_progress);
264     }
265
266     bool InstructionDecoder_power::decodeOperands(const Instruction*)
267     {
268       assert(!"not implemented");
269       return false;
270     }
271     void InstructionDecoder_power::OE()
272     {
273         if(field<21, 21>(insn))
274         {
275             // overflow and summary overflow bits; do we want full bit detail?
276             insn_in_progress->appendOperand(makeRegisterExpression(ppc32::xer), false, true);
277             insn_in_progress->getOperation().mnemonic += "o";
278         }
279     }
280     template <Result_Type size>
281     void InstructionDecoder_power::L()
282     {
283         insn_in_progress->appendOperand(makeMemRefNonIndex(size), true, false);
284     }
285     template <Result_Type size>
286     void InstructionDecoder_power::ST()
287     {
288         insn_in_progress->appendOperand(makeMemRefNonIndex(size), false, true);
289     }
290     template <Result_Type size>
291     void InstructionDecoder_power::LX()
292     {
293         insn_in_progress->appendOperand(makeMemRefIndex(size), true, false);
294     }
295     template <Result_Type size>
296     void InstructionDecoder_power::STX()
297     {
298         insn_in_progress->appendOperand(makeMemRefIndex(size), false, true);
299     }
300     template <Result_Type size>
301     void InstructionDecoder_power::LU()
302     {
303         L<size>();
304         insn_in_progress->appendOperand(makeRAExpr(), false, true, true);
305     }
306     template <Result_Type size>
307     void InstructionDecoder_power::STU()
308     {
309         ST<size>();
310         insn_in_progress->appendOperand(makeRAExpr(), false, true, true);
311     }
312     template <Result_Type size>
313     void InstructionDecoder_power::LUX()
314     {
315         LX<size>();
316         insn_in_progress->appendOperand(makeRAExpr(), false, true, true);
317     }
318     template <Result_Type size>
319     void InstructionDecoder_power::STUX()
320     {
321         STX<size>();
322         insn_in_progress->appendOperand(makeRAExpr(), false, true, true);
323     }
324     void InstructionDecoder_power::LK()
325     {
326     }
327     
328     Expression::Ptr InstructionDecoder_power::makeMemRefIndex(Result_Type size)
329     {
330       return makeDereferenceExpression(makeAddExpression(makeRAorZeroExpr(), makeRBExpr(), s32), size);
331     }
332     Expression::Ptr InstructionDecoder_power::makeDSExpr()
333     {
334         return Immediate::makeImmediate(Result(s32, sign_extend<14>(field<16,29>(insn)) << 2));
335     }
336     Expression::Ptr InstructionDecoder_power::makeMemRefNonIndex(Result_Type size)
337     {
338         if(field<0,5>(insn) == 31 && (field<21,30>(insn) == 597 || field<21, 30>(insn) == 725))
339         {
340             return makeDereferenceExpression(makeRAorZeroExpr(), size);
341         }
342         if(size == u64 || size == s64 || size == dbl128 || field<0,5>(insn) == 58)
343         {
344             return makeDereferenceExpression(makeAddExpression(makeRAorZeroExpr(), makeDSExpr(), s32), size);
345         }
346         return makeDereferenceExpression(makeAddExpression(makeRAorZeroExpr(), makeDorSIExpr(), s32), size);
347     }
348     Expression::Ptr InstructionDecoder_power::makeRAExpr()
349     {
350         return makeRegisterExpression(makePowerRegID(ppc32::r0, field<11, 15>(insn)));
351     }
352     void InstructionDecoder_power::RA()
353     {
354         if(insn_in_progress->getOperation().getID() == power_op_addi)
355         {
356             if(field<11,15>(insn) == 0)
357             {
358                 insn_in_progress->getOperation().mnemonic = "li";
359                 insn_in_progress->appendOperand(makeRAorZeroExpr(), !isRAWritten, isRAWritten);
360                 return;
361             }
362         }
363         if(insn_in_progress->getOperation().getID() == power_op_addis)
364         {
365             if(field<11,15>(insn) == 0)
366             {
367                 insn_in_progress->getOperation().mnemonic = "lis";
368                 insn_in_progress->appendOperand(makeRAorZeroExpr(), !isRAWritten, isRAWritten);
369                 return;
370             }
371         }
372         insn_in_progress->appendOperand(makeRAExpr(), !isRAWritten, isRAWritten);
373     }
374     Expression::Ptr InstructionDecoder_power::makeRBExpr()
375     {
376         return makeRegisterExpression(makePowerRegID(ppc32::r0, field<16, 20>(insn)));
377     }
378     Expression::Ptr InstructionDecoder_power::makeFRAExpr()
379     {
380         isFPInsn = true;
381         return makeRegisterExpression(makePowerRegID(ppc32::fpr0, field<11, 15>(insn)));
382     }
383     Expression::Ptr InstructionDecoder_power::makeQFRAExpr()
384     {
385         isFPInsn = true;
386         return makeRegisterExpression(makePowerRegID(ppc64::fpr0, field<11, 15>(insn)));
387     }
388     Expression::Ptr InstructionDecoder_power::makeFRBExpr()
389     {
390         isFPInsn = true;
391         return makeRegisterExpression(makePowerRegID(ppc32::fpr0, field<16, 20>(insn)));
392     }
393     Expression::Ptr InstructionDecoder_power::makeFRCExpr()
394     {
395         isFPInsn = true;
396         return makeRegisterExpression(makePowerRegID(ppc32::fpr0, field<21, 25>(insn)));
397     }
398     Expression::Ptr InstructionDecoder_power::makeQFRCExpr()
399     {
400         isFPInsn = true;
401         return makeRegisterExpression(makePowerRegID(ppc64::fpr0, field<21, 25>(insn)));
402     }
403     Expression::Ptr InstructionDecoder_power::makeQRBExpr()
404     {
405         isFPInsn = true;
406         return makeRegisterExpression(makePowerRegID(ppc64::fpr0, field<16, 20>(insn)));
407     }
408     Expression::Ptr InstructionDecoder_power::makeQRTExpr()
409     {
410         isFPInsn = true;
411         return makeRegisterExpression(makePowerRegID(ppc64::fpr0, field<6, 10>(insn)));
412     }
413     void InstructionDecoder_power::QRT()
414     {
415         insn_in_progress->appendOperand(makeQRTExpr(), false, true);
416     }
417     Expression::Ptr InstructionDecoder_power::makeFRTExpr()
418     {
419         isFPInsn = true;
420         return makeRegisterExpression(makePowerRegID(ppc32::fpr0, field<6, 10>(insn)));
421     }
422     void InstructionDecoder_power::FRT()
423     {
424         insn_in_progress->appendOperand(makeFRTExpr(), false, true);
425     }
426     void InstructionDecoder_power::FRS()
427     {
428         insn_in_progress->appendOperand(makeFRTExpr(), true, false);
429     }
430     void InstructionDecoder_power::QFRS()
431     {
432         insn_in_progress->appendOperand(makeQRTExpr(), true, false);
433     }
434     void InstructionDecoder_power::FRT2()
435     {
436         MachRegister firstRegID = makePowerRegID(ppc32::fpr0, field<6,10>(insn));
437         MachRegister secondRegID = makePowerRegID(ppc32::fpr0, field<6,10>(insn) + 1);
438         insn_in_progress->appendOperand(makeRegisterExpression(firstRegID), false, true);
439         insn_in_progress->appendOperand(makeRegisterExpression(secondRegID), false, true);
440     }
441     void InstructionDecoder_power::FRS2()
442     {
443         MachRegister firstRegID = makePowerRegID(ppc32::fpr0, field<6,10>(insn));
444         MachRegister secondRegID = makePowerRegID(ppc32::fpr0, field<6,10>(insn) + 1);
445         insn_in_progress->appendOperand(makeRegisterExpression(firstRegID), true, false);
446         insn_in_progress->appendOperand(makeRegisterExpression(secondRegID), true, false);
447     }
448     void InstructionDecoder_power::RT()
449     {
450         insn_in_progress->appendOperand(makeRTExpr(), false, true);
451     }
452     void InstructionDecoder_power::RS()
453     {
454         insn_in_progress->appendOperand(makeRTExpr(), true, false);
455         isRAWritten = true;
456     }
457     Expression::Ptr InstructionDecoder_power::makeRTExpr()
458     {
459         return makeRegisterExpression(makePowerRegID(ppc32::r0, field<6, 10>(insn)));
460     }
461     Expression::Ptr InstructionDecoder_power::makeIFormBranchTarget()
462     {
463         return makeBranchTarget<6, 29>();
464     }
465     Expression::Ptr InstructionDecoder_power::makeBFormBranchTarget()
466     {
467         return makeBranchTarget<16, 29>();
468     }
469     Expression::Ptr InstructionDecoder_power::makeRAorZeroExpr()
470     {
471         if(field<11, 15>(insn) == 0)
472         {
473             return Immediate::makeImmediate(Result(u32, 0));
474         }
475         else
476         {
477             return makeRAExpr();
478         }
479     } 
480     Expression::Ptr InstructionDecoder_power::makeDorSIExpr()
481     {
482         return Immediate::makeImmediate(Result(s16, field<16, 31>(insn)));
483     }
484     void InstructionDecoder_power::SI()
485     {
486         insn_in_progress->appendOperand(makeDorSIExpr(), true, false);
487     }
488     void InstructionDecoder_power::D()
489     {
490         SI();
491     }
492
493
494     /***** BEGIN: For new vector instructions *****/
495     void InstructionDecoder_power::XT()
496     {
497         // TODO: Format DQ has a different encoding.
498         //       The single T bit is at bit 28, instaed of bit 31.
499         unsigned id = field<6, 10>(insn) + 32 * field<31, 31>(insn);
500         insn_in_progress->appendOperand(
501                         makeRegisterExpression(makePowerRegID(ppc64::vsr0, id)),
502                         false, 
503                         true);
504     }
505     void InstructionDecoder_power::XS()
506     {
507         // TODO: Format DQ has a different encoding.
508         //       The single T bit is at bit 28, instaed of bit 31.
509         unsigned id = field<6, 10>(insn) + 32 * field<31, 31>(insn);
510         insn_in_progress->appendOperand(
511                         makeRegisterExpression(makePowerRegID(ppc64::vsr0, id)),
512                         true, 
513                         false);
514     }
515     void InstructionDecoder_power::XA()
516     {
517         unsigned id = field<11, 15>(insn) + 32 * field<29, 29>(insn);
518         insn_in_progress->appendOperand(
519                         makeRegisterExpression(makePowerRegID(ppc64::vsr0, id)),
520                         true, 
521                         false);
522     }
523     void InstructionDecoder_power::XB()
524     {
525         unsigned id = field<16, 20>(insn) + 32 * field<30, 30>(insn);
526         insn_in_progress->appendOperand(
527                         makeRegisterExpression(makePowerRegID(ppc64::vsr0, id)),
528                         true, 
529                         false);
530     }
531     void InstructionDecoder_power::VRT()
532     {
533         unsigned id = field<6, 10>(insn) + 32;
534         insn_in_progress->appendOperand(
535                         makeRegisterExpression(makePowerRegID(ppc64::vsr0, id)),
536                         false, 
537                         true);
538     }
539     void InstructionDecoder_power::VRS()
540     {
541         unsigned id = field<6, 10>(insn) + 32;
542         insn_in_progress->appendOperand(
543                         makeRegisterExpression(makePowerRegID(ppc64::vsr0, id)),
544                         true, 
545                         false);
546     }
547     void InstructionDecoder_power::VRA()
548     {
549         unsigned id = field<11, 15>(insn) + 32;
550         insn_in_progress->appendOperand(
551                         makeRegisterExpression(makePowerRegID(ppc64::vsr0, id)),
552                         true, 
553                         false);
554     }
555     void InstructionDecoder_power::VRB()
556     {
557         unsigned id = field<16, 20>(insn) + 32 ;
558         insn_in_progress->appendOperand(
559                         makeRegisterExpression(makePowerRegID(ppc64::vsr0, id)),
560                         true, 
561                         false);
562     }
563     void InstructionDecoder_power::VRC()
564     {
565         unsigned id = field<21, 25>(insn) + 32 ;
566         insn_in_progress->appendOperand(
567                         makeRegisterExpression(makePowerRegID(ppc64::vsr0, id)),
568                         true, 
569                         false);
570     }
571
572     void InstructionDecoder_power::UIM()
573     {
574         fprintf(stderr, "Unimplemented operand type UIM. Please create an issue at https://github.com/dyninst/dyninst/issues\n");
575     }
576     void InstructionDecoder_power::SIM()
577     {
578         fprintf(stderr, "Unimplemented operand type SIM. Please create an issue at https://github.com/dyninst/dyninst/issues\n");
579     }
580
581     void InstructionDecoder_power::DCMX()
582     {
583         fprintf(stderr, "Unimplemented operand type DCMX. Please create an issue at https://github.com/dyninst/dyninst/issues\n");
584     }
585     void InstructionDecoder_power::RO()
586     {
587         fprintf(stderr, "Unimplemented operand type RO. Please create an issue at https://github.com/dyninst/dyninst/issues\n");
588     }
589     void InstructionDecoder_power::R()
590     {
591         fprintf(stderr, "Unimplemented operand type R. Please create an issue at https://github.com/dyninst/dyninst/issues\n");
592     }
593     void InstructionDecoder_power::RMC()
594     {
595         fprintf(stderr, "Unimplemented operand type RMC. Please create an issue at https://github.com/dyninst/dyninst/issues\n");
596     }
597     void InstructionDecoder_power::EX()
598     {
599         fprintf(stderr, "Unimplemented operand type EX. Please create an issue at https://github.com/dyninst/dyninst/issues\n");
600     }
601     void InstructionDecoder_power::SHB()
602     {
603         fprintf(stderr, "Unimplemented operand type SHB. Please create an issue at https://github.com/dyninst/dyninst/issues\n");
604     }
605     void InstructionDecoder_power::PS()
606     {
607         fprintf(stderr, "Unimplemented operand type PS. Please create an issue at https://github.com/dyninst/dyninst/issues\n");
608     }
609     void InstructionDecoder_power::CY()
610     {
611         fprintf(stderr, "Unimplemented operand type CY. Please create an issue at https://github.com/dyninst/dyninst/issues\n");
612     }
613
614     /***** END: For new vector instructions *****/
615
616     Expression::Ptr InstructionDecoder_power::makeBTExpr()
617     {
618         return makeRegisterExpression(makePowerRegID(ppc32::cr0, field<6, 10>(insn) >> 2));
619     }
620     Expression::Ptr InstructionDecoder_power::makeBAExpr()
621     {
622         return makeRegisterExpression(makePowerRegID(ppc32::cr0, field<11, 15>(insn) >> 2));
623     }
624     Expression::Ptr InstructionDecoder_power::makeBBExpr()
625     {
626         return makeRegisterExpression(makePowerRegID(ppc32::cr0, field<16, 20>(insn) >> 2));
627     }
628     Expression::Ptr InstructionDecoder_power::makeCR0Expr()
629     {
630         return makeRegisterExpression(ppc32::cr0);
631     }
632     Expression::Ptr InstructionDecoder_power::makeBIExpr()
633     {
634         switch(field<11, 15>(insn) & 0x03)
635         {
636             case 0:
637                 insn_in_progress->getOperation().mnemonic += (invertBranchCondition ? "ge" : "lt");
638                 break;
639             case 1:
640                 insn_in_progress->getOperation().mnemonic += (invertBranchCondition ? "le" : "gt");
641                 break;
642             case 2:
643                 insn_in_progress->getOperation().mnemonic += (invertBranchCondition ? "ne" : "eq");
644                 break;
645             case 3:
646                 insn_in_progress->getOperation().mnemonic += (invertBranchCondition ? "ns" : "so");
647                 break;
648             default:
649                 assert(!"can't happen");
650                 break;
651         } 
652         return makeRegisterExpression(makePowerRegID(ppc32::cr0, field<11, 15>(insn) >> 2));
653     }
654     
655     Result_Type InstructionDecoder_power::makeSizeType(unsigned int)
656     {
657       assert(!"not implemented");
658       return u32;
659     }
660     Expression::Ptr InstructionDecoder_power::makeSHExpr()
661     {
662         // For sradi instruction, the SH field is bit30 || bit16-20
663         if (field<0,5>(insn) == 31 && field<21,29>(insn) == 413) {
664             unsigned shift = ((field<30, 30>(insn)) << 5) | (field<16,20>(insn));
665             return Immediate::makeImmediate(Result(u32, shift));
666         }
667         return Immediate::makeImmediate(Result(u32, (field<16, 20>(insn))));
668     }
669     Expression::Ptr InstructionDecoder_power::makeMBExpr()
670     {
671         return Immediate::makeImmediate(Result(u8, field<21, 25>(insn)));
672     }
673     Expression::Ptr InstructionDecoder_power::makeMEExpr()
674     {
675         return Immediate::makeImmediate(Result(u8, field<26, 30>(insn)));
676     }
677     Expression::Ptr InstructionDecoder_power::makeFLMExpr()
678     {
679         return Immediate::makeImmediate(Result(u32, field<7, 14>(insn)));
680     }
681     Expression::Ptr InstructionDecoder_power::makeTOExpr()
682     {
683         return Immediate::makeImmediate(Result(u32, field<6, 10>(insn)));
684     }
685     void InstructionDecoder_power::TO()
686     {
687         insn_in_progress->appendOperand(makeTOExpr(), true, false);
688     }
689     Expression::Ptr InstructionDecoder_power::makeSPRExpr()
690     {
691         int sprIDlo = field<11, 15>(insn);
692         int sprIDhi = field<16, 20>(insn);
693         int sprID = (sprIDhi << 5) + sprIDlo;
694
695         // This is mftb, which is equivalent to mfspr Rx, 268 
696         if (field<0,5>(insn) == 31 && field<21,30>(insn) == 371) {
697             sprID = 268;
698         }
699         return makeRegisterExpression(makePowerRegID(ppc32::mq, sprID));
700     }
701
702     void InstructionDecoder_power::setFPMode()
703     {
704         isFPInsn = true;
705     }
706     void InstructionDecoder_power::doDelayedDecode(const Instruction* insn_to_complete)
707     {
708
709                                 /* Yuhan's notes for implementation
710                                          For all instructions in opcode 60, the extended opcode is 21-29th bit.
711                                          special case for opcode 60: (Opcode table on Page 1190)
712                           I. Decision Tree:
713                                   (1) For XX4 format, the 26&27 bits are 1. (only for opcde "xxsel" P773)
714                             (2) Two special XX3 cases: 0..00 010.. & 0..01 010.., started from 21th bit. (manual 1208)
715                                   (3) Other instruction are all implemented normally, 
716                                     the "." bits are treated as 0 and 1 respectively in the opcode table
717                                 II. The Rc bit for opcode 60 is the 21st bit
718
719                            **   There are 2 XX1 instructions, the last bit of the extended opcodes are ignored (30th bit, which are both 0).
720                                 */
721         isRAWritten = false;
722         isFPInsn = false;
723         bcIsConditional = false;
724         insn = insn_to_complete->m_RawInsn.small_insn;
725         const power_entry* current = &power_entry::main_opcode_table[field<0,5>(insn)];
726         while(current->next_table)
727         {
728             current = &(std::mem_fun(current->next_table)(this));
729         }
730         if (findRAAndRS(current)) {
731             isRAWritten = true;
732         }
733         insn_in_progress = const_cast<Instruction*>(insn_to_complete);
734         if(current->op == power_op_b ||
735            current->op == power_op_bc ||
736            current->op == power_op_bclr ||
737            current->op == power_op_bcctr)
738         {
739             insn_in_progress->appendOperand(makeRegisterExpression(ppc32::pc), false, true);
740         }
741         
742         for(operandSpec::const_iterator curFn = current->operands.begin();
743             curFn != current->operands.end();
744             ++curFn)
745         {
746             std::mem_fun(*curFn)(this);
747         }
748         if(current->op == power_op_bclr)
749         {
750           // blrl is in practice a return-and-link, not a call-through-LR
751           // so we'll treat it as such
752             insn_in_progress->addSuccessor(makeRegisterExpression(ppc32::lr),
753                                            /*field<31,31>(insn) == 1*/ false, true, 
754                                            bcIsConditional, false);
755             if(bcIsConditional)
756             {
757                 insn_in_progress->addSuccessor(makeFallThroughExpr(), false, false, false, true);
758             }
759         }
760         if(current->op == power_op_bcctr)
761         {
762             insn_in_progress->addSuccessor(makeRegisterExpression(ppc32::ctr),
763                                            field<31,31>(insn) == 1, true, bcIsConditional, false);
764             if(bcIsConditional)
765             {
766                 insn_in_progress->addSuccessor(makeFallThroughExpr(), false, false, false, true);
767             }
768         }
769         if(current->op == power_op_addic_rc ||
770            current->op == power_op_andi_rc ||
771            current->op == power_op_andis_rc ||
772            current->op == power_op_stwcx_rc ||
773            current->op == power_op_stdcx_rc)
774         {
775             insn_in_progress->appendOperand(makeCR0Expr(), false, true);
776         }
777
778         return;
779     }
780     MachRegister InstructionDecoder_power::makePowerRegID(MachRegister base, unsigned int encoding, int field)
781     {
782         if(field != -1)
783         {
784             return makePowerRegID(base, encoding, field * 4, field * 4 + 3);
785         }
786         return makePowerRegID(base, encoding, 0, 31);
787     }
788     MachRegister InstructionDecoder_power::makePowerRegID(MachRegister base, unsigned int encoding,
789                                                          unsigned int, unsigned int)
790     {
791         return MachRegister(base.val() + encoding);
792     }
793
794 #define fn(x) (&InstructionDecoder_power::x)
795
796 using namespace boost::assign;
797     
798 #include "power_opcode_tables.C"
799
800
801     const power_entry& InstructionDecoder_power::extended_op_0()
802     {
803         unsigned int xo = field<26, 30>(insn);
804         if(xo <= 31)
805         {
806             return power_entry::extended_op_0[xo];
807         }
808         return power_entry::extended_op_0[field<21, 30>(insn)];
809     }
810
811     const power_entry& InstructionDecoder_power::extended_op_4()
812     {
813         return power_entry::extended_op_4[field<26, 30>(insn)];
814     }
815     const power_entry& InstructionDecoder_power::extended_op_19()
816     {
817         return power_entry::extended_op_19[field<21, 30>(insn)];
818     }
819     const power_entry& InstructionDecoder_power::extended_op_30()
820     {
821         return power_entry::extended_op_30[field<27, 29>(insn)];
822     }
823     const power_entry& InstructionDecoder_power::extended_op_31()
824     {
825         // sradi is a special instruction. Its xop is from 21 to 29 and its xop value is 413
826         if (field<21,29>(insn) == 413) {
827             return power_entry::extended_op_31[413];
828         }
829         const power_entry& xoform_entry = power_entry::extended_op_31[field<22, 30>(insn)];
830         if(find(xoform_entry.operands.begin(), xoform_entry.operands.end(), &InstructionDecoder_power::OE)
831            != xoform_entry.operands.end())
832         {
833             return xoform_entry;
834         }
835         return power_entry::extended_op_31[field<21, 30>(insn)];
836     }
837     // extended_op_57 needs revisiting
838     const power_entry& InstructionDecoder_power::extended_op_57()
839     {
840         return power_entry::extended_op_57[field<30, 31>(insn)];
841     }
842     const power_entry& InstructionDecoder_power::extended_op_58()
843     {
844         return power_entry::extended_op_58[field<30, 31>(insn)];
845     }
846     const power_entry& InstructionDecoder_power::extended_op_59()
847     {
848         return power_entry::extended_op_59[field<26, 30>(insn)];
849     }
850     // extended_op_60 needs revisiting
851     const power_entry& InstructionDecoder_power::extended_op_60()
852     {
853         unsigned int xo = field<21, 29>(insn);
854         return power_entry::extended_op_60[xo];
855     }
856     // extended_op_61 needs revisiting
857     const power_entry& InstructionDecoder_power::extended_op_61()
858     {
859         unsigned int xo = field<26, 30>(insn);
860         if(xo <= 31)
861         {
862             power_table::const_iterator found = power_entry::extended_op_61.find(xo);
863             if(found != power_entry::extended_op_61.end())
864                 return found->second;
865         }
866         return power_entry::extended_op_61[field<21, 30>(insn)];
867     }
868
869     const power_entry& InstructionDecoder_power::extended_op_63()
870     {
871         unsigned int xo = field<26, 30>(insn);
872         if(xo <= 31)
873         {
874             power_table::const_iterator found = power_entry::extended_op_63.find(xo);
875             if(found != power_entry::extended_op_63.end())
876                 return found->second;
877         }
878         return power_entry::extended_op_63[field<21, 30>(insn)];
879     }
880     
881     void InstructionDecoder_power::BF()
882     {
883         MachRegister base_reg = isFPInsn ? ppc32::fpscw0 : ppc32::cr0;
884         Expression::Ptr condReg = makeRegisterExpression(makePowerRegID(base_reg, field<6, 10>(insn) >> 2));
885         insn_in_progress->appendOperand(condReg, false, true);
886         return;
887     }
888     void InstructionDecoder_power::QTT()
889     {
890         Expression::Ptr imm = Immediate::makeImmediate(Result(u8, field<21, 24>(insn)));
891         insn_in_progress->appendOperand(imm, true, false);
892         return;
893     }
894     void InstructionDecoder_power::QVD()
895     {
896         Expression::Ptr imm = Immediate::makeImmediate(Result(u8, field<21, 22>(insn)));
897         insn_in_progress->appendOperand(imm, true, false);
898         return;
899     }
900     void InstructionDecoder_power::QGPC()
901     {
902         Expression::Ptr imm = Immediate::makeImmediate(Result(u8, field<11, 22>(insn)));
903         insn_in_progress->appendOperand(imm, true, false);
904         return;
905     }
906     void InstructionDecoder_power::UI()
907     {
908         Expression::Ptr imm = Immediate::makeImmediate(Result(u32, field<16, 31>(insn)));
909         insn_in_progress->appendOperand(imm, true, false);
910         return;
911     }
912     void InstructionDecoder_power::BO()
913     {
914         bcIsConditional = true;
915 #if defined(DEBUG_BO_FIELD)        
916         cout << "BO: " << field<6,6>(insn) << field<7,7>(insn) << field<8,8>(insn) << field<9,9>(insn) << field<10,10>(insn)
917                 << endl;
918 #endif
919         invertBranchCondition = false;
920         if(!field<8, 8>(insn))
921         {
922             Expression::Ptr ctr = makeRegisterExpression(makePowerRegID(ppc32::ctr, 0));
923             if(field<9, 9>(insn))
924             {
925                 insn_in_progress->getOperation().mnemonic = "bdz";
926             }
927             else
928             {
929                 insn_in_progress->getOperation().mnemonic = "bdn";
930             }
931             insn_in_progress->appendOperand(ctr, true, true);
932         }
933         if(!(field<6, 6>(insn)))
934         {
935             invertBranchCondition = !field<7,7>(insn);
936             if(insn_in_progress->getOperation().mnemonic == "bc")
937             {
938                 insn_in_progress->getOperation().mnemonic = "b";            
939             }
940             insn_in_progress->appendOperand(makeBIExpr(), true, false);
941         }
942         if(field<8,8>(insn) && field<6,6>(insn))
943         {
944             size_t found = insn_in_progress->getOperation().mnemonic.rfind("c");
945             if(found != std::string::npos)
946             {
947                 insn_in_progress->getOperation().mnemonic.erase(found, 1);
948             }
949             bcIsConditional = false;
950         }
951         else
952         {
953             bool taken = (field<6,6>(insn) && field<8,8>(insn)) || field<16,16>(insn);
954                         taken ^= field<10,10>(insn) ? true : false;
955             insn_in_progress->getOperation().mnemonic += (taken ? "+" : "-");
956         }
957 #if defined(DEBUG_BO_FIELD)
958         cout << "bcIsConditional = " << (bcIsConditional ? "true" : "false") << endl;
959 #endif
960         return;
961     }
962     void InstructionDecoder_power::syscall()
963     {
964         insn_in_progress->appendOperand(makeRegisterExpression(ppc32::msr), true, true);
965         insn_in_progress->appendOperand(makeRegisterExpression(ppc32::srr0), false, true);
966         insn_in_progress->appendOperand(makeRegisterExpression(ppc32::srr1), false, true);
967         insn_in_progress->appendOperand(makeRegisterExpression(ppc32::pc), true, true);
968         insn_in_progress->appendOperand(makeRegisterExpression(ppc32::ivpr), false, true);
969         insn_in_progress->appendOperand(makeRegisterExpression(ppc32::ivor8), false, true);
970         return;
971     }
972     void InstructionDecoder_power::LL()
973     {
974         LI();
975         return;
976     }
977     void InstructionDecoder_power::SH()
978     {
979         insn_in_progress->appendOperand(makeSHExpr(), true, false);
980         return;
981     }
982     void InstructionDecoder_power::Rc()
983     {
984         if(field<31, 31>(insn))
985         {
986             if(isFPInsn)
987             {
988                 insn_in_progress->appendOperand(makeRegisterExpression(ppc32::fpscw), false, true, true);
989             }
990             else
991             {
992                 insn_in_progress->appendOperand(makeCR0Expr(), false, true);
993             }
994             insn_in_progress->getOperation().mnemonic += ".";
995         }
996         return;
997     }
998     void InstructionDecoder_power::RB()
999     {
1000         if(insn_in_progress->getOperation().getID() == power_op_or)
1001         {
1002             if(field<16,20>(insn) == field<6,10>(insn))
1003             {
1004                 insn_in_progress->getOperation().mnemonic = "mr";
1005             }
1006         }
1007         else if(insn_in_progress->getOperation().getID() == power_op_nor)
1008         {
1009             if(field<16,20>(insn) == field<6,10>(insn))
1010             {
1011                 insn_in_progress->getOperation().mnemonic = "not";
1012             }
1013         }
1014         insn_in_progress->appendOperand(makeRBExpr(), true, false);
1015         return;
1016     }
1017     void InstructionDecoder_power::FRA()
1018     {
1019         insn_in_progress->appendOperand(makeFRAExpr(), !isRAWritten, isRAWritten);
1020         return;
1021     }
1022     void InstructionDecoder_power::QFRA()
1023     {
1024         insn_in_progress->appendOperand(makeQFRAExpr(), !isRAWritten, isRAWritten);
1025         return;
1026     }
1027     void InstructionDecoder_power::FRB()
1028     {
1029         insn_in_progress->appendOperand(makeFRBExpr(), true, false);
1030         return;
1031     }
1032     void InstructionDecoder_power::FRC()
1033     {
1034         insn_in_progress->appendOperand(makeFRCExpr(), true, false);
1035         return;
1036     }
1037     void InstructionDecoder_power::QFRC()
1038     {
1039         insn_in_progress->appendOperand(makeQFRCExpr(), true, false);
1040         return;
1041     }
1042     void InstructionDecoder_power::BI()
1043     {
1044         return;
1045     }
1046     void InstructionDecoder_power::ME()
1047     {
1048         insn_in_progress->appendOperand(makeMEExpr(), true, false);
1049         return;
1050     }
1051     void InstructionDecoder_power::MB()
1052     {
1053         insn_in_progress->appendOperand(makeMBExpr(), true, false);
1054         return;
1055     }
1056     void InstructionDecoder_power::BFA()
1057     {
1058         Expression::Ptr condReg = makeRegisterExpression(makePowerRegID(ppc32::cr0, field<11, 15>(insn) >> 2));
1059         insn_in_progress->appendOperand(condReg, true, false);
1060         return;
1061     }
1062     void InstructionDecoder_power::BT()
1063     {
1064         insn_in_progress->appendOperand(makeBTExpr(), false, true);
1065         return;
1066     }
1067     void InstructionDecoder_power::BA()
1068     {
1069         insn_in_progress->appendOperand(makeBAExpr(), true, false);
1070         return;
1071     }
1072     void InstructionDecoder_power::BB()
1073     {
1074         insn_in_progress->appendOperand(makeBBExpr(), true, false);
1075         return;
1076     }
1077
1078     void InstructionDecoder_power::FXM()
1079     {
1080         (translateBitFieldToCR<12, 19, ppc32::icr0, 7>(*this))();
1081         return;
1082     }
1083     void InstructionDecoder_power::spr()
1084     {
1085         insn_in_progress->appendOperand(makeSPRExpr(), !isRAWritten, isRAWritten);
1086         return;
1087     }
1088     void InstructionDecoder_power::SR()
1089     {
1090         insn_in_progress->appendOperand(makeRegisterExpression(makePowerRegID(ppc32::seg0, field<11, 15>(insn) >> 2)),
1091                                         true, true);
1092         return;
1093     }
1094     void InstructionDecoder_power::NB()
1095     {
1096         insn_in_progress->appendOperand(Immediate::makeImmediate(Result(u8, field<16, 20>(insn))), true, false);
1097         return;
1098     }
1099     void InstructionDecoder_power::U()
1100     {
1101         insn_in_progress->appendOperand(Immediate::makeImmediate(Result(u8, field<16, 20>(insn) >> 1)), true, false);
1102         return;
1103     }
1104     void InstructionDecoder_power::FLM()
1105     {
1106         isRAWritten = true;
1107         (translateBitFieldToCR<7, 14, ppc32::ifpscw0, 7>(*this))();
1108         return;
1109     }
1110      void InstructionDecoder_power::WC()
1111     {
1112         insn_in_progress->appendOperand(Immediate::makeImmediate(Result(u8, field<9, 10>(insn))), true, false);
1113         return;
1114     }
1115    
1116     bool InstructionDecoder_power::findRAAndRS(const power_entry* cur) {
1117         bool findRA = false;
1118         bool findRS = false;
1119         for (auto oit = cur->operands.begin(); oit != cur->operands.end(); ++oit) {
1120             if ((*oit) == &InstructionDecoder_power::RA) findRA = true;
1121             if ((*oit) == &InstructionDecoder_power::RS) findRS = true;
1122         }
1123         return findRA && findRS;
1124     }
1125
1126     void InstructionDecoder_power::mainDecode()
1127     {
1128         const power_entry* current = &power_entry::main_opcode_table[field<0,5>(insn)];
1129         while(current->next_table)
1130         {
1131             current = &(std::mem_fun(current->next_table)(this));
1132         }
1133         insn_in_progress = makeInstruction(current->op, current->mnemonic, 4, reinterpret_cast<unsigned char*>(&insn));
1134         if(current->op == power_op_b ||
1135           current->op == power_op_bc ||
1136           current->op == power_op_bclr ||
1137           current->op == power_op_bcctr)
1138         {
1139             // decode control-flow operands immediately; we're all but guaranteed to need them
1140             doDelayedDecode(insn_in_progress);
1141         }
1142         // FIXME in parsing
1143         insn_in_progress->arch_decoded_from = m_Arch;
1144         //insn_in_progress->arch_decoded_from = Arch_ppc32;
1145         if(field<0,5>(insn) == 0x04) {
1146             insn_in_progress->m_InsnOp->isVectorInsn = true;
1147         }
1148         return;
1149     }
1150   };
1151 };
1152
1153
1154
1155