All AVX and AVX2 Series instructions (included 4 op) decoded
[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 "Immediate.h"
33 #include <boost/assign/list_of.hpp>
34 #include "../../common/src/singleton_object_pool.h"
35
36 namespace Dyninst
37 {
38   namespace InstructionAPI
39   {
40       typedef void (InstructionDecoder_power::*operandFactory)();
41       typedef std::vector< operandFactory > operandSpec;
42       typedef const power_entry&(InstructionDecoder_power::*nextTableFunc)();
43       typedef std::map<unsigned int, power_entry> power_table;
44       bool InstructionDecoder_power::foundDoubleHummerInsn = false;
45       bool InstructionDecoder_power::foundQuadInsn = false;
46       struct power_entry
47       {
48         power_entry(entryID o, const char* m, nextTableFunc next, operandSpec ops) :
49                 op(o), mnemonic(m), next_table(next), operands(ops)
50                 {}
51         power_entry() :
52                         op(power_op_INVALID), mnemonic("INVALID"), next_table(NULL)
53                         {
54                             operands.reserve(5);
55                         }
56         power_entry(const power_entry& o) :
57                 op(o.op), mnemonic(o.mnemonic), next_table(o.next_table), operands(o.operands)
58                 {}
59                 const power_entry& operator=(const power_entry& rhs)
60                 {
61                     operands.reserve(rhs.operands.size());
62                     op = rhs.op;
63                     mnemonic = rhs.mnemonic;
64                     next_table = rhs.next_table;
65                     operands = rhs.operands;
66                     return *this;
67                 }
68                 entryID op;
69                 const char* mnemonic;
70                 nextTableFunc next_table;
71                 operandSpec operands;
72                 static void buildTables();
73                 static bool built_tables;
74                 static std::vector<power_entry> main_opcode_table;
75                 static power_table extended_op_0;
76                 static power_table extended_op_4;
77                 static power_table extended_op_19;
78                 static power_table extended_op_30;
79                 static power_table extended_op_31;
80                 static power_table extended_op_58;
81                 static power_table extended_op_59;
82                 static power_table extended_op_63;
83       };
84
85     InstructionDecoder_power::InstructionDecoder_power(Architecture a)
86       : InstructionDecoderImpl(a),
87         insn(0), insn_in_progress(NULL),
88         isRAWritten(false), invertBranchCondition(false),
89         isFPInsn(false), bcIsConditional(false)
90     {
91         power_entry::buildTables();
92     }
93     InstructionDecoder_power::~InstructionDecoder_power()
94     {
95     }
96     void InstructionDecoder_power::decodeOpcode(InstructionDecoder::buffer& b)
97     {
98       b.start += 4;
99     }
100
101     void InstructionDecoder_power::FRTP()
102     {
103         FRT();
104         FRTS();
105     }
106     void InstructionDecoder_power::FRTS()
107     {
108         isFPInsn = true;
109         MachRegister regID = makePowerRegID(ppc32::fsr0, field<6, 10>(insn));
110         insn_in_progress->appendOperand(makeRegisterExpression(regID), false, true);
111         isRAWritten = false;
112         foundDoubleHummerInsn = true;
113     }
114     void InstructionDecoder_power::QFRTP()
115     {
116         QRT();
117         QFRTS();
118     }
119     void InstructionDecoder_power::QFRTS()
120     {
121         isFPInsn = true;
122         MachRegister regID = makePowerRegID(ppc64::fsr0, field<6, 10>(insn));
123         insn_in_progress->appendOperand(makeRegisterExpression(regID), false, true);
124         isRAWritten = false;
125         foundQuadInsn = true;
126     }
127     void InstructionDecoder_power::FRSP()
128     {
129         FRS();
130         FRSS();
131     }
132     void InstructionDecoder_power::FRSS()
133     {
134         isFPInsn = true;
135         MachRegister regID = makePowerRegID(ppc32::fsr0, field<6, 10>(insn));
136         insn_in_progress->appendOperand(makeRegisterExpression(regID), true, false);
137         isRAWritten = true;
138         foundDoubleHummerInsn = true;
139     }
140     void InstructionDecoder_power::QFRSP()
141     {
142         QFRS();
143         QFRSS();
144     }
145     void InstructionDecoder_power::QFRSS()
146     {
147         isFPInsn = true;
148         MachRegister regID = makePowerRegID(ppc64::fsr0, field<6, 10>(insn));
149         insn_in_progress->appendOperand(makeRegisterExpression(regID), true, false);
150         isRAWritten = true;
151         foundQuadInsn = true;
152     }
153     void InstructionDecoder_power::FRAP()
154     {
155         FRA();
156         FRAS();
157     }
158     void InstructionDecoder_power::FRAS()
159     {
160         isFPInsn = true;
161         MachRegister regID = makePowerRegID(ppc32::fsr0, field<11, 15>(insn));
162         insn_in_progress->appendOperand(makeRegisterExpression(regID), !isRAWritten, isRAWritten);
163         foundDoubleHummerInsn = true;
164     }
165     void InstructionDecoder_power::QFRAP()
166     {
167         QFRA();
168         QFRAS();
169     }
170     void InstructionDecoder_power::QFRAS()
171     {
172         isFPInsn = true;
173         MachRegister regID = makePowerRegID(ppc64::fsr0, field<11, 15>(insn));
174         insn_in_progress->appendOperand(makeRegisterExpression(regID), !isRAWritten, isRAWritten);
175         foundQuadInsn = true;
176     }
177     void InstructionDecoder_power::FRBP()
178     {
179         FRB();
180         FRBS();
181     }
182     void InstructionDecoder_power::QRB()
183     {
184         insn_in_progress->appendOperand(makeQRBExpr(), true, false);
185         QRBS();
186     }
187     void InstructionDecoder_power::QRBS()
188     {
189         isFPInsn = true;
190         MachRegister regID = makePowerRegID(ppc64::fsr0, field<16, 20>(insn));
191         insn_in_progress->appendOperand(makeRegisterExpression(regID), true, false);
192         foundQuadInsn = true;
193     }
194     void InstructionDecoder_power::FRBS()
195     {
196         isFPInsn = true;
197         MachRegister regID = makePowerRegID(ppc32::fsr0, field<16, 20>(insn));
198         insn_in_progress->appendOperand(makeRegisterExpression(regID), true, false);
199         foundDoubleHummerInsn = true;
200     }
201     void InstructionDecoder_power::FRCP()
202     {
203         FRC();
204         FRCS();
205     }
206     void InstructionDecoder_power::FRCS()
207     {
208         isFPInsn = true;
209         MachRegister regID = makePowerRegID(ppc32::fsr0, field<21, 25>(insn));
210         insn_in_progress->appendOperand(makeRegisterExpression(regID), true, false);
211         foundDoubleHummerInsn = true;
212     }
213
214     void InstructionDecoder_power::QFRCP()
215     {
216         QFRC();
217         QFRCS();
218     }
219     void InstructionDecoder_power::QFRCS()
220     {
221         isFPInsn = true;
222         MachRegister regID = makePowerRegID(ppc64::fsr0, field<21, 25>(insn));
223         insn_in_progress->appendOperand(makeRegisterExpression(regID), true, false);
224         foundQuadInsn = true;
225     }
226
227     Expression::Ptr InstructionDecoder_power::makeFallThroughExpr()
228     {
229         return makeAddExpression(makeRegisterExpression(ppc32::pc), Immediate::makeImmediate(Result(u32, 4)), u32);
230     }
231     void InstructionDecoder_power::LI()
232     {
233         insn_in_progress->addSuccessor(makeIFormBranchTarget(), field<31, 31>(insn) == 1, false, false, false);
234     }
235     void InstructionDecoder_power::BD()
236     {
237         insn_in_progress->addSuccessor(makeBFormBranchTarget(), field<31, 31>(insn) == 1, false, bcIsConditional, false);
238         if(bcIsConditional)
239         {
240             insn_in_progress->addSuccessor(makeFallThroughExpr(), false, false, false, true);
241         }
242     }
243     
244     using namespace std;
245     Instruction::Ptr InstructionDecoder_power::decode(InstructionDecoder::buffer& b)
246     {
247       if(b.start > b.end) return Instruction::Ptr();
248       isRAWritten = false;
249       isFPInsn = false;
250       bcIsConditional = false;
251       insn = b.start[0] << 24 | b.start[1] << 16 |
252       b.start[2] << 8 | b.start[3];
253 #if defined(DEBUG_RAW_INSN)        
254         cout.width(0);
255         cout << "0x";
256         cout.width(8);
257         cout.fill('0');
258         cout << hex << insn << "\t";
259 #endif
260         mainDecode();
261         b.start += 4;
262         return make_shared(insn_in_progress);
263     }
264
265     bool InstructionDecoder_power::decodeOperands(const Instruction*)
266     {
267       assert(!"not implemented");
268       return false;
269     }
270     void InstructionDecoder_power::OE()
271     {
272         if(field<21, 21>(insn))
273         {
274             // overflow and summary overflow bits; do we want full bit detail?
275             insn_in_progress->appendOperand(makeRegisterExpression(ppc32::xer), false, true);
276             insn_in_progress->getOperation().mnemonic += "o";
277         }
278     }
279     template <Result_Type size>
280     void InstructionDecoder_power::L()
281     {
282         insn_in_progress->appendOperand(makeMemRefNonIndex(size), true, false);
283     }
284     template <Result_Type size>
285     void InstructionDecoder_power::ST()
286     {
287         insn_in_progress->appendOperand(makeMemRefNonIndex(size), false, true);
288     }
289     template <Result_Type size>
290     void InstructionDecoder_power::LX()
291     {
292         insn_in_progress->appendOperand(makeMemRefIndex(size), true, false);
293     }
294     template <Result_Type size>
295     void InstructionDecoder_power::STX()
296     {
297         insn_in_progress->appendOperand(makeMemRefIndex(size), false, true);
298     }
299     template <Result_Type size>
300     void InstructionDecoder_power::LU()
301     {
302         L<size>();
303         insn_in_progress->appendOperand(makeRAExpr(), false, true);
304     }
305     template <Result_Type size>
306     void InstructionDecoder_power::STU()
307     {
308         ST<size>();
309         insn_in_progress->appendOperand(makeRAExpr(), false, true);
310     }
311     template <Result_Type size>
312     void InstructionDecoder_power::LUX()
313     {
314         LX<size>();
315         insn_in_progress->appendOperand(makeRAExpr(), false, true);
316     }
317     template <Result_Type size>
318     void InstructionDecoder_power::STUX()
319     {
320         STX<size>();
321         insn_in_progress->appendOperand(makeRAExpr(), false, true);
322     }
323     void InstructionDecoder_power::LK()
324     {
325     }
326     
327     Expression::Ptr InstructionDecoder_power::makeMemRefIndex(Result_Type size)
328     {
329       return makeDereferenceExpression(makeAddExpression(makeRAorZeroExpr(), makeRBExpr(), s32), size);
330     }
331     Expression::Ptr InstructionDecoder_power::makeDSExpr()
332     {
333         return Immediate::makeImmediate(Result(s32, sign_extend<14>(field<16,29>(insn)) << 2));
334     }
335     Expression::Ptr InstructionDecoder_power::makeMemRefNonIndex(Result_Type size)
336     {
337         if(field<0,5>(insn) == 31 && (field<21,30>(insn) == 597 || field<21, 30>(insn) == 725))
338         {
339             return makeDereferenceExpression(makeRAorZeroExpr(), size);
340         }
341         if(size == u64 || size == s64 || size == dbl128 || field<0,5>(insn) == 58)
342         {
343             return makeDereferenceExpression(makeAddExpression(makeRAorZeroExpr(), makeDSExpr(), s32), size);
344         }
345         return makeDereferenceExpression(makeAddExpression(makeRAorZeroExpr(), makeDorSIExpr(), s32), size);
346     }
347     Expression::Ptr InstructionDecoder_power::makeRAExpr()
348     {
349         return makeRegisterExpression(makePowerRegID(ppc32::r0, field<11, 15>(insn)));
350     }
351     void InstructionDecoder_power::RA()
352     {
353         if(insn_in_progress->getOperation().getID() == power_op_addi)
354         {
355             if(field<11,15>(insn) == 0)
356             {
357                 insn_in_progress->getOperation().mnemonic = "li";
358                 insn_in_progress->appendOperand(makeRAorZeroExpr(), !isRAWritten, isRAWritten);
359                 return;
360             }
361         }
362         if(insn_in_progress->getOperation().getID() == power_op_addis)
363         {
364             if(field<11,15>(insn) == 0)
365             {
366                 insn_in_progress->getOperation().mnemonic = "lis";
367                 insn_in_progress->appendOperand(makeRAorZeroExpr(), !isRAWritten, isRAWritten);
368                 return;
369             }
370         }
371         insn_in_progress->appendOperand(makeRAExpr(), !isRAWritten, isRAWritten);
372     }
373     Expression::Ptr InstructionDecoder_power::makeRBExpr()
374     {
375         return makeRegisterExpression(makePowerRegID(ppc32::r0, field<16, 20>(insn)));
376     }
377     Expression::Ptr InstructionDecoder_power::makeFRAExpr()
378     {
379         isFPInsn = true;
380         return makeRegisterExpression(makePowerRegID(ppc32::fpr0, field<11, 15>(insn)));
381     }
382     Expression::Ptr InstructionDecoder_power::makeQFRAExpr()
383     {
384         isFPInsn = true;
385         return makeRegisterExpression(makePowerRegID(ppc64::fpr0, field<11, 15>(insn)));
386     }
387     Expression::Ptr InstructionDecoder_power::makeFRBExpr()
388     {
389         isFPInsn = true;
390         return makeRegisterExpression(makePowerRegID(ppc32::fpr0, field<16, 20>(insn)));
391     }
392     Expression::Ptr InstructionDecoder_power::makeFRCExpr()
393     {
394         isFPInsn = true;
395         return makeRegisterExpression(makePowerRegID(ppc32::fpr0, field<21, 25>(insn)));
396     }
397     Expression::Ptr InstructionDecoder_power::makeQFRCExpr()
398     {
399         isFPInsn = true;
400         return makeRegisterExpression(makePowerRegID(ppc64::fpr0, field<21, 25>(insn)));
401     }
402     Expression::Ptr InstructionDecoder_power::makeQRBExpr()
403     {
404         isFPInsn = true;
405         return makeRegisterExpression(makePowerRegID(ppc64::fpr0, field<16, 20>(insn)));
406     }
407     Expression::Ptr InstructionDecoder_power::makeQRTExpr()
408     {
409         isFPInsn = true;
410         return makeRegisterExpression(makePowerRegID(ppc64::fpr0, field<6, 10>(insn)));
411     }
412     void InstructionDecoder_power::QRT()
413     {
414         insn_in_progress->appendOperand(makeQRTExpr(), false, true);
415     }
416     Expression::Ptr InstructionDecoder_power::makeFRTExpr()
417     {
418         isFPInsn = true;
419         return makeRegisterExpression(makePowerRegID(ppc32::fpr0, field<6, 10>(insn)));
420     }
421     void InstructionDecoder_power::FRT()
422     {
423         insn_in_progress->appendOperand(makeFRTExpr(), false, true);
424     }
425     void InstructionDecoder_power::FRS()
426     {
427         insn_in_progress->appendOperand(makeFRTExpr(), true, false);
428     }
429     void InstructionDecoder_power::QFRS()
430     {
431         insn_in_progress->appendOperand(makeQRTExpr(), true, false);
432     }
433     void InstructionDecoder_power::FRT2()
434     {
435         MachRegister firstRegID = makePowerRegID(ppc32::fpr0, field<6,10>(insn));
436         MachRegister secondRegID = makePowerRegID(ppc32::fpr0, field<6,10>(insn) + 1);
437         insn_in_progress->appendOperand(makeRegisterExpression(firstRegID), false, true);
438         insn_in_progress->appendOperand(makeRegisterExpression(secondRegID), false, true);
439     }
440     void InstructionDecoder_power::FRS2()
441     {
442         MachRegister firstRegID = makePowerRegID(ppc32::fpr0, field<6,10>(insn));
443         MachRegister secondRegID = makePowerRegID(ppc32::fpr0, field<6,10>(insn) + 1);
444         insn_in_progress->appendOperand(makeRegisterExpression(firstRegID), true, false);
445         insn_in_progress->appendOperand(makeRegisterExpression(secondRegID), true, false);
446     }
447     void InstructionDecoder_power::RT()
448     {
449         insn_in_progress->appendOperand(makeRTExpr(), false, true);
450     }
451     void InstructionDecoder_power::RS()
452     {
453         insn_in_progress->appendOperand(makeRTExpr(), true, false);
454         isRAWritten = true;
455     }
456     Expression::Ptr InstructionDecoder_power::makeRTExpr()
457     {
458         return makeRegisterExpression(makePowerRegID(ppc32::r0, field<6, 10>(insn)));
459     }
460     Expression::Ptr InstructionDecoder_power::makeIFormBranchTarget()
461     {
462         return makeBranchTarget<6, 29>();
463     }
464     Expression::Ptr InstructionDecoder_power::makeBFormBranchTarget()
465     {
466         return makeBranchTarget<16, 29>();
467     }
468     Expression::Ptr InstructionDecoder_power::makeRAorZeroExpr()
469     {
470         if(field<11, 15>(insn) == 0)
471         {
472             return Immediate::makeImmediate(Result(u32, 0));
473         }
474         else
475         {
476             return makeRAExpr();
477         }
478     } 
479     Expression::Ptr InstructionDecoder_power::makeDorSIExpr()
480     {
481         return Immediate::makeImmediate(Result(s16, field<16, 31>(insn)));
482     }
483     void InstructionDecoder_power::SI()
484     {
485         insn_in_progress->appendOperand(makeDorSIExpr(), true, false);
486     }
487     void InstructionDecoder_power::D()
488     {
489         SI();
490     }
491     Expression::Ptr InstructionDecoder_power::makeBTExpr()
492     {
493         return makeRegisterExpression(makePowerRegID(ppc32::cr0, field<6, 10>(insn) >> 2));
494     }
495     Expression::Ptr InstructionDecoder_power::makeBAExpr()
496     {
497         return makeRegisterExpression(makePowerRegID(ppc32::cr0, field<11, 15>(insn) >> 2));
498     }
499     Expression::Ptr InstructionDecoder_power::makeBBExpr()
500     {
501         return makeRegisterExpression(makePowerRegID(ppc32::cr0, field<16, 20>(insn) >> 2));
502     }
503     Expression::Ptr InstructionDecoder_power::makeCR0Expr()
504     {
505         return makeRegisterExpression(ppc32::cr0);
506     }
507     Expression::Ptr InstructionDecoder_power::makeBIExpr()
508     {
509         switch(field<11, 15>(insn) & 0x03)
510         {
511             case 0:
512                 insn_in_progress->getOperation().mnemonic += (invertBranchCondition ? "ge" : "lt");
513                 break;
514             case 1:
515                 insn_in_progress->getOperation().mnemonic += (invertBranchCondition ? "le" : "gt");
516                 break;
517             case 2:
518                 insn_in_progress->getOperation().mnemonic += (invertBranchCondition ? "ne" : "eq");
519                 break;
520             case 3:
521                 insn_in_progress->getOperation().mnemonic += (invertBranchCondition ? "ns" : "so");
522                 break;
523             default:
524                 assert(!"can't happen");
525                 break;
526         } 
527         return makeRegisterExpression(makePowerRegID(ppc32::cr0, field<11, 15>(insn) >> 2));
528     }
529     
530     Result_Type InstructionDecoder_power::makeSizeType(unsigned int)
531     {
532       assert(!"not implemented");
533       return u32;
534     }
535     Expression::Ptr InstructionDecoder_power::makeSHExpr()
536     {
537         return Immediate::makeImmediate(Result(u32, (field<16, 20>(insn))));
538     }
539     Expression::Ptr InstructionDecoder_power::makeMBExpr()
540     {
541         return Immediate::makeImmediate(Result(u8, field<21, 25>(insn)));
542     }
543     Expression::Ptr InstructionDecoder_power::makeMEExpr()
544     {
545         return Immediate::makeImmediate(Result(u8, field<26, 30>(insn)));
546     }
547     Expression::Ptr InstructionDecoder_power::makeFLMExpr()
548     {
549         return Immediate::makeImmediate(Result(u32, field<7, 14>(insn)));
550     }
551     Expression::Ptr InstructionDecoder_power::makeTOExpr()
552     {
553         return Immediate::makeImmediate(Result(u32, field<6, 10>(insn)));
554     }
555     void InstructionDecoder_power::TO()
556     {
557         insn_in_progress->appendOperand(makeTOExpr(), true, false);
558     }
559     Expression::Ptr InstructionDecoder_power::makeSPRExpr()
560     {
561         int sprIDlo = field<11, 15>(insn);
562         int sprIDhi = field<16, 20>(insn);
563         int sprID = (sprIDhi << 5) + sprIDlo;
564         return makeRegisterExpression(makePowerRegID(ppc32::mq, sprID));
565     }
566
567     void InstructionDecoder_power::setFPMode()
568     {
569         isFPInsn = true;
570     }
571     void InstructionDecoder_power::doDelayedDecode(const Instruction* insn_to_complete)
572     {
573         isRAWritten = false;
574         isFPInsn = false;
575         bcIsConditional = false;
576         insn = insn_to_complete->m_RawInsn.small_insn;
577         const power_entry* current = &power_entry::main_opcode_table[field<0,5>(insn)];
578         while(current->next_table)
579         {
580             current = &(std::mem_fun(current->next_table)(this));
581         }
582         insn_in_progress = const_cast<Instruction*>(insn_to_complete);
583         if(current->op == power_op_b ||
584            current->op == power_op_bc ||
585            current->op == power_op_bclr ||
586            current->op == power_op_bcctr)
587         {
588             insn_in_progress->appendOperand(makeRegisterExpression(ppc32::pc), false, true);
589         }
590         
591         for(operandSpec::const_iterator curFn = current->operands.begin();
592             curFn != current->operands.end();
593             ++curFn)
594         {
595             std::mem_fun(*curFn)(this);
596         }
597         if(current->op == power_op_bclr)
598         {
599           // blrl is in practice a return-and-link, not a call-through-LR
600           // so we'll treat it as such
601             insn_in_progress->addSuccessor(makeRegisterExpression(ppc32::lr),
602                                            /*field<31,31>(insn) == 1*/ false, true, 
603                                            bcIsConditional, false);
604             if(bcIsConditional)
605             {
606                 insn_in_progress->addSuccessor(makeFallThroughExpr(), false, false, false, true);
607             }
608         }
609         if(current->op == power_op_bcctr)
610         {
611             insn_in_progress->addSuccessor(makeRegisterExpression(ppc32::ctr),
612                                            field<31,31>(insn) == 1, true, bcIsConditional, false);
613             if(bcIsConditional)
614             {
615                 insn_in_progress->addSuccessor(makeFallThroughExpr(), false, false, false, true);
616             }
617         }
618         if(current->op == power_op_addic_rc ||
619            current->op == power_op_andi_rc ||
620            current->op == power_op_andis_rc ||
621            current->op == power_op_stwcx_rc ||
622            current->op == power_op_stdcx_rc)
623         {
624             insn_in_progress->appendOperand(makeCR0Expr(), false, true);
625         }
626
627         return;
628     }
629     MachRegister InstructionDecoder_power::makePowerRegID(MachRegister base, unsigned int encoding, int field)
630     {
631         if(field != -1)
632         {
633             return makePowerRegID(base, encoding, field * 4, field * 4 + 3);
634         }
635         return makePowerRegID(base, encoding, 0, 31);
636     }
637     MachRegister InstructionDecoder_power::makePowerRegID(MachRegister base, unsigned int encoding,
638                                                          unsigned int, unsigned int)
639     {
640         return MachRegister(base.val() + encoding);
641     }
642
643 #define fn(x) (&InstructionDecoder_power::x)
644
645 using namespace boost::assign;
646     
647 #include "power_opcode_tables.C"
648
649
650     const power_entry& InstructionDecoder_power::extended_op_0()
651     {
652         unsigned int xo = field<26, 30>(insn);
653         if(xo <= 31)
654         {
655             return power_entry::extended_op_0[xo];
656         }
657         return power_entry::extended_op_0[field<21, 30>(insn)];
658     }
659
660     const power_entry& InstructionDecoder_power::extended_op_4()
661     {
662         return power_entry::extended_op_4[field<26, 30>(insn)];
663     }
664     const power_entry& InstructionDecoder_power::extended_op_19()
665     {
666         return power_entry::extended_op_19[field<21, 30>(insn)];
667     }
668     const power_entry& InstructionDecoder_power::extended_op_30()
669     {
670         return power_entry::extended_op_30[field<27, 29>(insn)];
671     }
672     const power_entry& InstructionDecoder_power::extended_op_31()
673     {
674         const power_entry& xoform_entry = power_entry::extended_op_31[field<22, 30>(insn)];
675         if(find(xoform_entry.operands.begin(), xoform_entry.operands.end(), &InstructionDecoder_power::OE)
676            != xoform_entry.operands.end())
677         {
678             return xoform_entry;
679         }
680         return power_entry::extended_op_31[field<21, 30>(insn)];
681     }
682     const power_entry& InstructionDecoder_power::extended_op_58()
683     {
684         return power_entry::extended_op_58[field<30, 31>(insn)];
685     }
686     const power_entry& InstructionDecoder_power::extended_op_59()
687     {
688         return power_entry::extended_op_59[field<26, 30>(insn)];
689     }
690     const power_entry& InstructionDecoder_power::extended_op_63()
691     {
692         unsigned int xo = field<26, 30>(insn);
693         if(xo <= 31)
694         {
695             power_table::const_iterator found = power_entry::extended_op_63.find(xo);
696             if(found != power_entry::extended_op_63.end())
697                 return found->second;
698         }
699         return power_entry::extended_op_63[field<21, 30>(insn)];
700     }
701     
702     void InstructionDecoder_power::BF()
703     {
704         MachRegister base_reg = isFPInsn ? ppc32::fpscw0 : ppc32::cr0;
705         Expression::Ptr condReg = makeRegisterExpression(makePowerRegID(base_reg, field<6, 10>(insn) >> 2));
706         insn_in_progress->appendOperand(condReg, false, true);
707         return;
708     }
709     void InstructionDecoder_power::QTT()
710     {
711         Expression::Ptr imm = Immediate::makeImmediate(Result(u8, field<21, 24>(insn)));
712         insn_in_progress->appendOperand(imm, true, false);
713         return;
714     }
715     void InstructionDecoder_power::QVD()
716     {
717         Expression::Ptr imm = Immediate::makeImmediate(Result(u8, field<21, 22>(insn)));
718         insn_in_progress->appendOperand(imm, true, false);
719         return;
720     }
721     void InstructionDecoder_power::QGPC()
722     {
723         Expression::Ptr imm = Immediate::makeImmediate(Result(u8, field<11, 22>(insn)));
724         insn_in_progress->appendOperand(imm, true, false);
725         return;
726     }
727     void InstructionDecoder_power::UI()
728     {
729         Expression::Ptr imm = Immediate::makeImmediate(Result(u32, field<16, 31>(insn)));
730         insn_in_progress->appendOperand(imm, true, false);
731         return;
732     }
733     void InstructionDecoder_power::BO()
734     {
735         bcIsConditional = true;
736 #if defined(DEBUG_BO_FIELD)        
737         cout << "BO: " << field<6,6>(insn) << field<7,7>(insn) << field<8,8>(insn) << field<9,9>(insn) << field<10,10>(insn)
738                 << endl;
739 #endif
740         invertBranchCondition = false;
741         if(!field<8, 8>(insn))
742         {
743             Expression::Ptr ctr = makeRegisterExpression(makePowerRegID(ppc32::ctr, 0));
744             if(field<9, 9>(insn))
745             {
746                 insn_in_progress->getOperation().mnemonic = "bdz";
747             }
748             else
749             {
750                 insn_in_progress->getOperation().mnemonic = "bdn";
751             }
752             insn_in_progress->appendOperand(ctr, true, true);
753         }
754         if(!(field<6, 6>(insn)))
755         {
756             invertBranchCondition = !field<7,7>(insn);
757             if(insn_in_progress->getOperation().mnemonic == "bc")
758             {
759                 insn_in_progress->getOperation().mnemonic = "b";            
760             }
761             insn_in_progress->appendOperand(makeBIExpr(), true, false);
762         }
763         if(field<8,8>(insn) && field<6,6>(insn))
764         {
765             size_t found = insn_in_progress->getOperation().mnemonic.rfind("c");
766             if(found != std::string::npos)
767             {
768                 insn_in_progress->getOperation().mnemonic.erase(found, 1);
769             }
770             bcIsConditional = false;
771         }
772         else
773         {
774             bool taken = (field<6,6>(insn) && field<8,8>(insn)) || field<16,16>(insn);
775                         taken ^= field<10,10>(insn) ? true : false;
776             insn_in_progress->getOperation().mnemonic += (taken ? "+" : "-");
777         }
778 #if defined(DEBUG_BO_FIELD)
779         cout << "bcIsConditional = " << (bcIsConditional ? "true" : "false") << endl;
780 #endif
781         return;
782     }
783     void InstructionDecoder_power::syscall()
784     {
785         insn_in_progress->appendOperand(makeRegisterExpression(ppc32::msr), true, true);
786         insn_in_progress->appendOperand(makeRegisterExpression(ppc32::srr0), false, true);
787         insn_in_progress->appendOperand(makeRegisterExpression(ppc32::srr1), false, true);
788         insn_in_progress->appendOperand(makeRegisterExpression(ppc32::pc), true, true);
789         insn_in_progress->appendOperand(makeRegisterExpression(ppc32::ivpr), false, true);
790         insn_in_progress->appendOperand(makeRegisterExpression(ppc32::ivor8), false, true);
791         return;
792     }
793     void InstructionDecoder_power::LL()
794     {
795         LI();
796         return;
797     }
798     void InstructionDecoder_power::SH()
799     {
800         insn_in_progress->appendOperand(makeSHExpr(), true, false);
801         return;
802     }
803     void InstructionDecoder_power::Rc()
804     {
805         if(field<31, 31>(insn))
806         {
807             if(isFPInsn)
808             {
809                 insn_in_progress->appendOperand(makeRegisterExpression(ppc32::fpscw), false, true);
810             }
811             else
812             {
813                 insn_in_progress->appendOperand(makeCR0Expr(), false, true);
814             }
815             insn_in_progress->getOperation().mnemonic += ".";
816         }
817         return;
818     }
819     void InstructionDecoder_power::RB()
820     {
821         if(insn_in_progress->getOperation().getID() == power_op_or)
822         {
823             if(field<16,20>(insn) == field<6,10>(insn))
824             {
825                 insn_in_progress->getOperation().mnemonic = "mr";
826             }
827         }
828         else if(insn_in_progress->getOperation().getID() == power_op_nor)
829         {
830             if(field<16,20>(insn) == field<6,10>(insn))
831             {
832                 insn_in_progress->getOperation().mnemonic = "not";
833             }
834         }
835         insn_in_progress->appendOperand(makeRBExpr(), true, false);
836         return;
837     }
838     void InstructionDecoder_power::FRA()
839     {
840         insn_in_progress->appendOperand(makeFRAExpr(), !isRAWritten, isRAWritten);
841         return;
842     }
843     void InstructionDecoder_power::QFRA()
844     {
845         insn_in_progress->appendOperand(makeQFRAExpr(), !isRAWritten, isRAWritten);
846         return;
847     }
848     void InstructionDecoder_power::FRB()
849     {
850         insn_in_progress->appendOperand(makeFRBExpr(), true, false);
851         return;
852     }
853     void InstructionDecoder_power::FRC()
854     {
855         insn_in_progress->appendOperand(makeFRCExpr(), true, false);
856         return;
857     }
858     void InstructionDecoder_power::QFRC()
859     {
860         insn_in_progress->appendOperand(makeQFRCExpr(), true, false);
861         return;
862     }
863     void InstructionDecoder_power::BI()
864     {
865         return;
866     }
867     void InstructionDecoder_power::ME()
868     {
869         insn_in_progress->appendOperand(makeMEExpr(), true, false);
870         return;
871     }
872     void InstructionDecoder_power::MB()
873     {
874         insn_in_progress->appendOperand(makeMBExpr(), true, false);
875         return;
876     }
877     void InstructionDecoder_power::BFA()
878     {
879         Expression::Ptr condReg = makeRegisterExpression(makePowerRegID(ppc32::cr0, field<11, 15>(insn) >> 2));
880         insn_in_progress->appendOperand(condReg, true, false);
881         return;
882     }
883     void InstructionDecoder_power::BT()
884     {
885         insn_in_progress->appendOperand(makeBTExpr(), false, true);
886         return;
887     }
888     void InstructionDecoder_power::BA()
889     {
890         insn_in_progress->appendOperand(makeBAExpr(), true, false);
891         return;
892     }
893     void InstructionDecoder_power::BB()
894     {
895         insn_in_progress->appendOperand(makeBBExpr(), true, false);
896         return;
897     }
898
899     void InstructionDecoder_power::FXM()
900     {
901         (translateBitFieldToCR<12, 19, ppc32::icr0, 7>(*this))();
902         return;
903     }
904     void InstructionDecoder_power::spr()
905     {
906         insn_in_progress->appendOperand(makeSPRExpr(), !isRAWritten, isRAWritten);
907         return;
908     }
909     void InstructionDecoder_power::SR()
910     {
911         insn_in_progress->appendOperand(makeRegisterExpression(makePowerRegID(ppc32::seg0, field<11, 15>(insn) >> 2)),
912                                         true, true);
913         return;
914     }
915     void InstructionDecoder_power::NB()
916     {
917         insn_in_progress->appendOperand(Immediate::makeImmediate(Result(u8, field<16, 20>(insn))), true, false);
918         return;
919     }
920     void InstructionDecoder_power::U()
921     {
922         insn_in_progress->appendOperand(Immediate::makeImmediate(Result(u8, field<16, 20>(insn) >> 1)), true, false);
923         return;
924     }
925     void InstructionDecoder_power::FLM()
926     {
927         isRAWritten = true;
928         (translateBitFieldToCR<7, 14, ppc32::ifpscw0, 7>(*this))();
929         return;
930     }
931
932     void InstructionDecoder_power::mainDecode()
933     {
934         const power_entry* current = &power_entry::main_opcode_table[field<0,5>(insn)];
935         while(current->next_table)
936         {
937             current = &(std::mem_fun(current->next_table)(this));
938         }
939         insn_in_progress = makeInstruction(current->op, current->mnemonic, 4, reinterpret_cast<unsigned char*>(&insn));
940         if(current->op == power_op_b ||
941           current->op == power_op_bc ||
942           current->op == power_op_bclr ||
943           current->op == power_op_bcctr)
944         {
945             // decode control-flow operands immediately; we're all but guaranteed to need them
946             doDelayedDecode(insn_in_progress);
947         }
948         // FIXME in parsing
949         //insn_in_progress->arch_decoded_from = m_Arch; 
950         insn_in_progress->arch_decoded_from = Arch_ppc32; 
951         return;
952     }
953   };
954 };
955
956
957
958