SymEval for POWER: WIP
[dyninst.git] / symEval / rose / powerpcInstructionSemantics.h
1 #ifndef ROSE_POWERPCINSTRUCTIONSEMANTICS_H
2 #define ROSE_POWERPCINSTRUCTIONSEMANTICS_H
3
4 //#include "rose.h"
5 #include "semanticsModule.h"
6 #include <cassert>
7 #include <cstdio>
8 #include <iostream>
9 #include "integerOps.h"
10
11 #include "SgAsmExpression.h"
12 #include "SgAsmPowerpcInstruction.h"
13 #include "conversions.h"
14
15 #ifdef Word
16 #error "Having a macro called \"Word\" conflicts with powerpcInstructionSemantics.h"
17 #endif
18
19 template <typename Policy, template <size_t> class WordType>
20 struct PowerpcInstructionSemantics {
21 #define Word(Len) WordType<(Len)>
22   Policy& policy;
23
24   PowerpcInstructionSemantics(Policy& policy): policy(policy) {}
25
26   template <size_t Len>
27   Word(Len) number(uintmax_t v) {
28     return policy.template number<Len>(v);
29   }
30
31   template <size_t From, size_t To, size_t Len>
32   Word(To - From) extract(Word(Len) w) {
33     return policy.template extract<From, To>(w);
34   }
35
36   template <size_t From, size_t To>
37   Word(To) signExtend(Word(From) w) {
38     return policy.template signExtend<From, To>(w);
39   }
40
41   template <size_t Len> // In bits
42   Word(Len) readMemory(const Word(32)& addr, Word(1) cond) {
43     return policy.template readMemory<Len>(addr, cond);
44   }
45
46   template <size_t Len>
47   void writeMemory(const Word(32)& addr, const Word(Len)& data, Word(1) cond) {
48     policy.template writeMemory<Len>(addr, data, cond);
49   }
50
51 // DQ (10/20/2008): changed name of function from templated read version.
52   Word(32) read32(SgAsmExpression* e) {
53  // This function does the address evaluation.
54
55     ROSE_ASSERT(e != NULL);
56  // printf ("In read32(): e = %p = %s \n",e,e->class_name().c_str());
57
58     switch (e->variantT()) {
59
60    // DQ (10/26/2008): Don't we need to handle the case of a SgAsmMemoryReferenceExpression
61    // so that readEffectiveAddress() will operate properly!
62
63       case V_SgAsmBinaryAdd:
64          {
65            SgAsmBinaryAdd* binaryAdd = isSgAsmBinaryAdd(e);
66            Word(32) lhs_value = read32(binaryAdd->get_lhs());
67            Word(32) rhs_value = read32(binaryAdd->get_rhs());
68            return policy.add(lhs_value,rhs_value);
69          }
70
71       case V_SgAsmMemoryReferenceExpression:
72          {
73            return readMemory<32>(readEffectiveAddress(e),policy.true_());
74          }
75
76       case V_SgAsmByteValueExpression: {
77         uint64_t val = isSgAsmByteValueExpression(e)->get_value();
78         return number<32>(val);
79       }
80       case V_SgAsmWordValueExpression: {
81         uint64_t val = isSgAsmWordValueExpression(e)->get_value();
82         return number<32>(val);
83       }
84       case V_SgAsmDoubleWordValueExpression: {
85         uint64_t val = isSgAsmDoubleWordValueExpression(e)->get_value();
86         return number<32>(val);
87       }
88       case V_SgAsmQuadWordValueExpression: {
89         uint64_t val = isSgAsmQuadWordValueExpression(e)->get_value();
90         return number<32>(val & 0xFFFFFFFFULL);
91       }
92       case V_SgAsmPowerpcRegisterReferenceExpression: {
93         SgAsmPowerpcRegisterReferenceExpression* ref = isSgAsmPowerpcRegisterReferenceExpression(e);
94         ROSE_ASSERT(ref != NULL);
95         switch(ref->get_register_class())
96            {
97              case powerpc_regclass_gpr:
98                 {
99                   Word(32) val = policy.readGPR(ref->get_register_number());
100                   return val;
101                 }
102               
103              case powerpc_regclass_spr:
104                 {
105                // printf ("Need support for reading SPR in policy! \n");
106                // ROSE_ASSERT(false);
107                // printf ("ref->get_register_number() = %d \n",ref->get_register_number());
108                   Word(32) val = policy.readSPR(ref->get_register_number());
109                   return val;
110                 }
111               
112              default:
113                 {
114                   fprintf(stderr, "Bad register class %s\n", regclassToString(ref->get_register_class())); abort();
115                 }
116            }
117         
118       }
119       default: fprintf(stderr, "Bad variant %s in read32\n", e->class_name().c_str()); abort();
120     }
121   }
122
123   Word(32) readEffectiveAddress(SgAsmExpression* expr) {
124     assert (isSgAsmMemoryReferenceExpression(expr));
125
126  // This must be a SgAsmExpression that is supported by read32(), else it will be an error.
127  // The case of "D(RA)" as an operand is such a case...(the type is a SgAsmBinaryAdd).
128     return read32(isSgAsmMemoryReferenceExpression(expr)->get_address());
129   }
130
131
132   Word(16) read16(SgAsmExpression* e) {
133     ROSE_ASSERT(e != NULL);
134
135     switch (e->variantT()) {
136
137       case V_SgAsmMemoryReferenceExpression:
138          {
139            return readMemory<16>(readEffectiveAddress(e),policy.true_());
140          }
141
142       default: fprintf(stderr, "Bad variant %s in read16\n", e->class_name().c_str()); abort();
143     }
144   }
145
146
147   Word(8) read8(SgAsmExpression* e) {
148     ROSE_ASSERT(e != NULL);
149
150     switch (e->variantT()) {
151
152       case V_SgAsmMemoryReferenceExpression:
153          {
154            return readMemory<8>(readEffectiveAddress(e),policy.true_());
155          }
156
157       default: fprintf(stderr, "Bad variant %s in read8\n", e->class_name().c_str()); abort();
158     }
159   }
160
161
162
163   void write8(SgAsmExpression* e, const Word(8)& value) {
164     switch (e->variantT()) {
165       case V_SgAsmMemoryReferenceExpression: {
166         writeMemory<8>(readEffectiveAddress(e), value, policy.true_());
167         break;
168       }
169       default: fprintf(stderr, "Bad variant %s in write8\n", e->class_name().c_str()); abort();
170     }
171   }
172
173   void write16(SgAsmExpression* e, const Word(16)& value) {
174     switch (e->variantT()) {
175       case V_SgAsmMemoryReferenceExpression: {
176         writeMemory<16>(readEffectiveAddress(e), value, policy.true_());
177         break;
178       }
179       default: fprintf(stderr, "Bad variant %s in write16\n", e->class_name().c_str()); abort();
180     }
181   }
182
183   void write32(SgAsmExpression* e, const Word(32)& value) {
184     switch (e->variantT()) {
185       case V_SgAsmMemoryReferenceExpression: {
186         writeMemory<32>(readEffectiveAddress(e), value, policy.true_());
187         break;
188       }
189       case V_SgAsmPowerpcRegisterReferenceExpression: {
190         SgAsmPowerpcRegisterReferenceExpression* ref = isSgAsmPowerpcRegisterReferenceExpression(e);
191         switch(ref->get_register_class())
192            {
193              case powerpc_regclass_gpr:
194                 {
195                   policy.writeGPR(ref->get_register_number(),value);
196                   break;
197                 }
198               
199              case powerpc_regclass_spr:
200                 {
201                // printf ("Need support for writing SPR in policy! \n");
202                // ROSE_ASSERT(false);
203
204                   policy.writeSPR(ref->get_register_number(),value);
205                 }
206               
207              default:
208                 {
209                   fprintf(stderr, "Bad register class %s\n", regclassToString(ref->get_register_class())); abort();
210                 }
211            }
212         
213          break;
214       }
215       default: fprintf(stderr, "Bad variant %s in write32\n", e->class_name().c_str()); abort();
216     }
217   }
218
219
220 void record( Word(32) result )
221    {
222      Word(3) c = policy.ite(
223                     policy.equalToZero(result),
224                     number<3>(1),
225                     policy.ite(
226                        extract<31,32>(result),
227                        number<3>(4),
228                        number<3>(2)));
229
230   // This should be a helper function!
231      Word(1) SO = extract<31,32>(policy.readSPR(powerpc_spr_xer));
232
233   // Put "SO" into the lower bits, and "c" into the higher order bits
234      policy.writeCRField(0,policy.concat(SO,c));
235    }
236
237 uint32_t 
238 build_mask(uint8_t mb_value, uint8_t me_value)
239    {
240   // Builds mask of 1's from the bit value starting at mb_value to me_value.
241   // See page 71 of PowerPC manual.
242
243      uint32_t mask = 0;
244      if (mb_value <= me_value)
245         {
246        // PowerPC counts bits from the left.
247           for(int i=mb_value; i <= me_value;  i++)
248                mask |= (1 << (31- i));
249         }
250        else
251         {
252           for(int i=mb_value; i <= 31;  i++)
253                mask |= (1 << (31- i));
254           for(int i=0; i <= me_value; i++)
255                mask |= (1 << (31- i));
256         }
257
258      return mask;
259    }
260       
261
262
263   void translate(SgAsmPowerpcInstruction* insn) {
264     policy.writeIP(policy.template number<32>((unsigned int)(insn->get_address() + 4)));
265     PowerpcInstructionKind kind = insn->get_kind();
266     const SgAsmExpressionPtrList& operands = insn->get_operandList()->get_operands();
267     switch (kind) {
268
269 // General questions:
270 //    1) What is the role of the SgAsmExpression's vs. uint32_t vs. Word(32).
271 //    2) The write32() uses the readEffectiveAddress() to write to memory, but
272 //       when the address is a computed value (e.g. "D(RA)" it is not clear 
273 //       where this should be evaluated, unless we should be generating a
274 //       
275
276       case powerpc_or:
277          {
278            ROSE_ASSERT(operands.size() == 3);
279            write32(operands[0], policy.or_(read32(operands[1]),read32(operands[2])));
280            break;
281          }
282
283       case powerpc_or_record:
284          {
285            ROSE_ASSERT(operands.size() == 3);
286            Word(32) result = policy.or_(read32(operands[1]),read32(operands[2]));
287            write32(operands[0], result);
288            record(result);
289            break;
290          }
291
292       case powerpc_ori:
293          {
294            ROSE_ASSERT(operands.size() == 3);
295            write32(operands[0], policy.or_(read32(operands[1]),read32(operands[2])));
296            break;
297          }
298
299       case powerpc_oris:
300          {
301            ROSE_ASSERT(operands.size() == 3);
302            write32(operands[0], policy.or_(read32(operands[1]),policy.concat(number<16>(0),extract<0,16>(read32(operands[2])))));
303            break;
304          }
305
306       case powerpc_xor:
307          {
308            ROSE_ASSERT(operands.size() == 3);
309            write32(operands[0], policy.xor_(read32(operands[1]),read32(operands[2])));
310            break;
311          }
312
313       case powerpc_xori:
314          {
315            ROSE_ASSERT(operands.size() == 3);
316            write32(operands[0], policy.xor_(read32(operands[1]),read32(operands[2])));
317            break;
318          }
319
320       case powerpc_xoris:
321          {
322            ROSE_ASSERT(operands.size() == 3);
323            write32(operands[0], policy.xor_(read32(operands[1]),policy.concat(number<16>(0),extract<0,16>(read32(operands[2])))));
324            break;
325          }
326
327       case powerpc_rlwinm:
328          {
329            ROSE_ASSERT(operands.size() == 5);
330            Word(32) RS = read32(operands[1]);
331            Word(5) SH = extract<0, 5>(read32(operands[2]));
332
333            SgAsmByteValueExpression* MB = isSgAsmByteValueExpression(operands[3]);
334            ROSE_ASSERT(MB != NULL);
335            int mb_value = MB->get_value();
336
337            SgAsmByteValueExpression* ME = isSgAsmByteValueExpression(operands[4]);
338            ROSE_ASSERT(ME != NULL);
339
340            int me_value = ME->get_value();
341            uint32_t mask = build_mask(mb_value,me_value);
342
343            Word(32) rotatedReg = policy.rotateLeft(RS,SH);
344            Word(32) bitMask = number<32>(mask);
345
346            write32(operands[0],policy.and_(rotatedReg,bitMask));
347            break;
348          }
349
350       case powerpc_rlwimi:
351          {
352            ROSE_ASSERT(operands.size() == 5);
353            Word(32) RS = read32(operands[0]);
354            Word(32) RA = read32(operands[1]);
355            Word(5) SH = extract<0, 5>(read32(operands[2]));
356
357            SgAsmByteValueExpression* MB = isSgAsmByteValueExpression(operands[3]);
358            ROSE_ASSERT(MB != NULL);
359            int mb_value = MB->get_value();
360
361            SgAsmByteValueExpression* ME = isSgAsmByteValueExpression(operands[4]);
362            ROSE_ASSERT(ME != NULL);
363
364            int me_value = ME->get_value();
365            uint32_t mask = build_mask(mb_value,me_value);
366
367            Word(32) rotatedReg = policy.rotateLeft(RS,SH);
368            Word(32) bitMask = number<32>(mask);
369
370            write32(operands[0],policy.or_(policy.and_(rotatedReg,bitMask),policy.and_(RA,policy.invert(bitMask))));
371            break;
372          }
373
374       case powerpc_addi:
375          {
376            ROSE_ASSERT(operands.size() == 3);
377            Word(32) RA = read32(operands[1]);
378
379         // The disassembler should have built this as a DWord with a sign extended value
380            Word(32) signExtended_SI = signExtend<16,32>(extract<0,16>(read32(operands[2])));
381
382         // "ite" is "if then else"
383         // Word(32) result = policy.ite(policy.equalToZero(RA), signExtended_SI, policy.add(RA,signExtended_SI));
384            write32(operands[0], policy.add(RA,signExtended_SI));
385            break;
386          }
387
388       case powerpc_stwu:
389       case powerpc_stwux: // implemented as a memory reference instead of a 3 operand instruction.
390          {
391            ROSE_ASSERT(operands.size() == 2);
392            SgAsmMemoryReferenceExpression* memoryReference = isSgAsmMemoryReferenceExpression(operands[1]);
393            SgAsmBinaryAdd* binaryAdd = isSgAsmBinaryAdd(memoryReference->get_address());
394            ROSE_ASSERT(binaryAdd != NULL);
395
396            SgAsmExpression* RA = binaryAdd->get_lhs();
397
398            Word(32) effectiveAddress = readEffectiveAddress(operands[1]);
399            writeMemory(effectiveAddress,read32(operands[0]),policy.true_());
400            write32(RA,effectiveAddress);
401            break;
402          }
403
404       case powerpc_and:
405          {
406            ROSE_ASSERT(operands.size() == 3);
407            write32(operands[0], policy.and_(read32(operands[1]),read32(operands[2])));
408            break;
409          }
410
411       case powerpc_mfspr:
412          {
413            ROSE_ASSERT(operands.size() == 2);
414
415         // This is only a valid instruction if bits 0-4 or SPR are: 1, 8, or 9.  Should we be checking 
416         // this here or in the disassembler?
417            write32(operands[0],read32(operands[1]));
418            break;
419          }
420
421       case powerpc_mtspr:
422          {
423            ROSE_ASSERT(operands.size() == 2);
424
425         // This is only a valid instruction if bits 0-4 or SPR are: 1, 8, or 9.  Should we be checking 
426         // this here or in the disassembler?
427            write32(operands[0],read32(operands[1]));
428            break;
429          }
430
431       case powerpc_stw:
432       case powerpc_stwx:
433          {
434            ROSE_ASSERT(operands.size() == 2);
435            write32(operands[1],read32(operands[0]));
436            break;
437          }
438
439       case powerpc_stb:
440          {
441            ROSE_ASSERT(operands.size() == 2);
442            write8(operands[1],extract<0,8>(read32(operands[0])));
443            break;
444          }
445
446       case powerpc_sth:
447          {
448            ROSE_ASSERT(operands.size() == 2);
449            write16(operands[1],extract<0,16>(read32(operands[0])));
450            break;
451          }
452
453       case powerpc_addis:
454          {
455            ROSE_ASSERT(operands.size() == 3);
456            write32(operands[0], policy.add(read32(operands[1]),policy.concat(number<16>(0),extract<0,16>(read32(operands[2])))));
457            break;
458          }
459
460       case powerpc_lwzu:
461          {
462            ROSE_ASSERT(operands.size() == 2);
463            SgAsmMemoryReferenceExpression* memoryReference = isSgAsmMemoryReferenceExpression(operands[1]);
464            SgAsmBinaryAdd* binaryAdd = isSgAsmBinaryAdd(memoryReference->get_address());
465            ROSE_ASSERT(binaryAdd != NULL);
466
467            SgAsmExpression* RA = binaryAdd->get_lhs();
468
469            Word(32) effectiveAddress = readEffectiveAddress(operands[1]);
470            write32(operands[0],readMemory<32>(effectiveAddress,policy.true_()));
471            write32(RA,effectiveAddress);
472            break;
473          }
474
475       case powerpc_add:
476          {
477            ROSE_ASSERT(operands.size() == 3);
478            write32(operands[0], policy.add(read32(operands[1]),read32(operands[2])));
479            break;
480          }
481
482       case powerpc_bl:
483          {
484            ROSE_ASSERT(operands.size() == 1);
485            policy.writeSPR(powerpc_spr_lr,number<32>(insn->get_address() + 4));
486            policy.writeIP(read32(operands[0]));
487            break;
488          }
489
490       case powerpc_b:
491          {
492            ROSE_ASSERT(operands.size() == 1);
493            policy.writeIP(read32(operands[0]));
494            break;
495          }
496
497       case powerpc_lwz:
498       case powerpc_lwzx:
499          {
500            ROSE_ASSERT(operands.size() == 2);
501            write32(operands[0],read32(operands[1]));
502            break;
503          }
504
505       case powerpc_addc:
506          {
507            ROSE_ASSERT(operands.size() == 3);
508            Word(32) carries = number<32>(0);
509            Word(32) result = policy.addWithCarries(read32(operands[1]),read32(operands[2]),policy.false_(),carries);
510
511         // Policy class bit numbering is opposite ordering from powerpc (based on x86).
512            Word(1)  carry_out = extract<31,32>(carries);
513            write32(operands[0], result);
514
515         // This should be a helper function to read/write CA (and other flags)
516         // The value 0xDFFFFFFFU is the mask for the Carry (CA) flag
517            policy.writeSPR(powerpc_spr_xer,policy.or_(policy.and_(policy.readSPR(powerpc_spr_xer),number<32>(0xDFFFFFFFU)),policy.ite(carry_out,number<32>(0x20000000U),number<32>(0x0))));
518            break;
519          }
520
521       case powerpc_addic:
522          {
523            ROSE_ASSERT(operands.size() == 3);
524            Word(32) carries = number<32>(0);
525            Word(32) result = policy.addWithCarries(read32(operands[1]),signExtend<16,32>(extract<0,16>(read32(operands[2]))),policy.false_(),carries);
526
527         // Policy class bit numbering is opposite ordering from powerpc (based on x86).
528            Word(1)  carry_out = extract<31,32>(carries);
529            write32(operands[0], result);
530
531         // This should be a helper function to read/write CA (and other flags)
532         // The value 0xDFFFFFFFU is the mask for the Carry (CA) flag
533            policy.writeSPR(powerpc_spr_xer,policy.or_(policy.and_(policy.readSPR(powerpc_spr_xer),number<32>(0xDFFFFFFFU)),policy.ite(carry_out,number<32>(0x20000000U),number<32>(0x0))));
534            break;
535          }
536
537       case powerpc_addic_record:
538          {
539            ROSE_ASSERT(operands.size() == 3);
540            Word(32) carries = number<32>(0);
541            Word(32) result = policy.addWithCarries(read32(operands[1]),signExtend<16,32>(extract<0,16>(read32(operands[2]))),policy.false_(),carries);
542
543         // Policy class bit numbering is opposite ordering from powerpc (based on x86).
544            Word(1)  carry_out = extract<31,32>(carries);
545            write32(operands[0], result);
546
547         // This should be a helper function to read/write CA (and other flags)
548         // The value 0xDFFFFFFFU is the mask for the Carry (CA) flag
549            policy.writeSPR(powerpc_spr_xer,policy.or_(policy.and_(policy.readSPR(powerpc_spr_xer),number<32>(0xDFFFFFFFU)),policy.ite(carry_out,number<32>(0x20000000U),number<32>(0x0))));
550
551            record(result);
552            break;
553          }
554
555       case powerpc_subfe:
556          {
557            ROSE_ASSERT(operands.size() == 3);
558
559         // This should be a helper function to read CA (and other flags)
560            Word(1)  carry_in = extract<29,30>(policy.readSPR(powerpc_spr_xer));
561
562            Word(32) carries = number<32>(0);
563            Word(32) result = policy.addWithCarries(policy.invert(read32(operands[1])),read32(operands[2]),carry_in,carries);
564
565         // Policy class bit numbering is opposite ordering from powerpc (based on x86).
566            Word(1)  carry_out = extract<31,32>(carries);
567            write32(operands[0], result);
568
569         // This should be a helper function to read/write CA (and other flags)
570         // The value 0xDFFFFFFFU is the mask for the Carry (CA) flag
571            policy.writeSPR(powerpc_spr_xer,policy.or_(policy.and_(policy.readSPR(powerpc_spr_xer),number<32>(0xDFFFFFFFU)),policy.ite(carry_out,number<32>(0x20000000U),number<32>(0x0))));
572            break;
573          }
574
575       case powerpc_subfc:
576          {
577            ROSE_ASSERT(operands.size() == 3);
578            Word(32) carries = number<32>(0);
579            Word(32) result = policy.addWithCarries(policy.invert(read32(operands[1])),read32(operands[2]),policy.true_(),carries);
580
581         // Policy class bit numbering is opposite ordering from powerpc (based on x86).
582            Word(1)  carry_out = extract<31,32>(carries);
583            write32(operands[0], result);
584
585         // This should be a helper function to read/write CA (and other flags)
586         // The value 0xDFFFFFFFU is the mask for the Carry (CA) flag
587            policy.writeSPR(powerpc_spr_xer,policy.or_(policy.and_(policy.readSPR(powerpc_spr_xer),number<32>(0xDFFFFFFFU)),policy.ite(carry_out,number<32>(0x20000000U),number<32>(0x0))));
588            break;
589          }
590
591       case powerpc_subfic:
592          {
593            ROSE_ASSERT(operands.size() == 3);
594            Word(32) carries = number<32>(0);
595
596         // To do the subtraction we invert the first operand and add.  To add "1" we set the carry in to true.
597            Word(32) result = policy.addWithCarries(policy.invert(read32(operands[1])),signExtend<16,32>(extract<0,16>(read32(operands[2]))),policy.true_(),carries);
598
599         // Policy class bit numbering is opposite ordering from powerpc (based on x86).
600            Word(1)  carry_out = extract<31,32>(carries);
601            write32(operands[0], result);
602
603         // This should be a helper function to read/write CA (and other flags)
604         // The value 0xDFFFFFFFU is the mask for the Carry (CA) flag
605            policy.writeSPR(powerpc_spr_xer,policy.or_(policy.and_(policy.readSPR(powerpc_spr_xer),number<32>(0xDFFFFFFFU)),policy.ite(carry_out,number<32>(0x20000000U),number<32>(0x0))));
606            break;
607          }
608
609       case powerpc_lbz:
610       case powerpc_lbzx:
611          {
612            ROSE_ASSERT(operands.size() == 2);
613            write32(operands[0],policy.concat(read8(operands[1]),number<24>(0)));
614            break;
615          }
616
617       case powerpc_lha:
618       case powerpc_lhax:
619          {
620            ROSE_ASSERT(operands.size() == 2);
621            write32(operands[0],signExtend<16,32>(read16(operands[1])));
622            break;
623          }
624
625       case powerpc_lhz:
626       case powerpc_lhzx:
627          {
628            ROSE_ASSERT(operands.size() == 2);
629            write32(operands[0],policy.concat(read16(operands[1]),number<16>(0)));
630            break;
631          }
632
633       case powerpc_cmpli:
634          {
635            ROSE_ASSERT(operands.size() == 4);
636         // For 32-bit case we can ignore value of L
637  
638            Word(32) RA = read32(operands[2]);
639            Word(32) UI = read32(operands[3]);
640
641            Word(32) carries = number<32>(0);
642
643         // Need to check if policy.false_() or policy.true_() should be used!
644         // policy.invert(RA) yields "(-RA)-1"
645         // Check if UI + (-RA) - 1 >= 0, test for UI > RA
646            policy.addWithCarries(policy.invert(RA),UI,policy.false_(),carries);
647
648            Word(3)  c = policy.ite(
649                            policy.equalToZero(policy.xor_(RA,UI)),
650                            number<3>(1),
651                            policy.ite(
652                               extract<31,32>(carries),
653                                  number<3>(4),
654                                  number<3>(2)));
655
656            SgAsmPowerpcRegisterReferenceExpression* bf = isSgAsmPowerpcRegisterReferenceExpression(operands[0]);
657            ROSE_ASSERT(bf != NULL);
658            ROSE_ASSERT(bf->get_register_class() == powerpc_regclass_cr);
659            ROSE_ASSERT(bf->get_conditionRegisterGranularity() == powerpc_condreggranularity_field);
660
661         // This should be a helper function!
662            Word(1) SO = extract<31,32>(policy.readSPR(powerpc_spr_xer));
663            
664
665            policy.writeCRField(bf->get_register_number(),policy.concat(SO,c));
666            break;
667          }
668
669       case powerpc_cmpl:
670          {
671         // This is same as powerpc_cmpli (UI --> RB)
672
673            ROSE_ASSERT(operands.size() == 4);
674         // For 32-bit case we can ignore value of L
675  
676            Word(32) RA = read32(operands[2]);
677            Word(32) RB = read32(operands[3]);
678
679            Word(32) carries = number<32>(0);
680
681         // Need to check if policy.false_() or policy.true_() should be used!
682         // policy.invert(RA) yields "(-RA)-1"
683         // Check if UI + (-RA) - 1 >= 0, test for UI > RA
684            policy.addWithCarries(policy.invert(RA),RB,policy.false_(),carries);
685
686            Word(3)  c = policy.ite(
687                            policy.equalToZero(policy.xor_(RA,RB)),
688                            number<3>(1),
689                            policy.ite(
690                               extract<31,32>(carries),
691                                  number<3>(4),
692                                  number<3>(2)));
693
694            SgAsmPowerpcRegisterReferenceExpression* bf = isSgAsmPowerpcRegisterReferenceExpression(operands[0]);
695            ROSE_ASSERT(bf != NULL);
696            ROSE_ASSERT(bf->get_register_class() == powerpc_regclass_cr);
697            ROSE_ASSERT(bf->get_conditionRegisterGranularity() == powerpc_condreggranularity_field);
698
699         // This should be a helper function!
700            Word(1) SO = extract<31,32>(policy.readSPR(powerpc_spr_xer));
701            
702
703            policy.writeCRField(bf->get_register_number(),policy.concat(SO,c));
704            break;
705          }
706
707       case powerpc_bc:
708          {
709            ROSE_ASSERT(operands.size() == 3);
710            SgAsmByteValueExpression* byteValue = isSgAsmByteValueExpression(operands[0]);
711            ROSE_ASSERT(byteValue != NULL);
712            uint8_t boConstant = byteValue->get_value();
713
714         // bool BO_4 = boConstant & 0x1;
715            bool BO_3 = boConstant & 0x2;
716            bool BO_2 = boConstant & 0x4;
717            bool BO_1 = boConstant & 0x8;
718            bool BO_0 = boConstant & 0x10;
719
720            if (!BO_2) 
721               {
722                 policy.writeSPR(powerpc_spr_ctr,policy.add(policy.readSPR(powerpc_spr_ctr),number<32>(-1)));
723               }
724
725            Word(1) CTR_ok = BO_2 ? policy.true_() : BO_3 ? policy.equalToZero(policy.readSPR(powerpc_spr_ctr)) : policy.invert(policy.equalToZero(policy.readSPR(powerpc_spr_ctr)));
726
727            SgAsmPowerpcRegisterReferenceExpression* BI = isSgAsmPowerpcRegisterReferenceExpression(operands[1]);
728            ROSE_ASSERT(BI != NULL);
729            ROSE_ASSERT(BI->get_register_class() == powerpc_regclass_cr);
730            ROSE_ASSERT(BI->get_conditionRegisterGranularity() == powerpc_condreggranularity_bit);
731
732         // This needs a collection of helpfer functions!
733            int bi_value = BI->get_register_number();
734            Word(4) CR_field = policy.readCRField(bi_value/4);
735            Word(1) CR_bi = extract<0,1>(policy.shiftRight(CR_field,number<2>(3 - bi_value % 4)));
736            Word(1) COND_ok = BO_0 ? policy.true_() : BO_1 ? CR_bi : policy.invert(CR_bi);
737            policy.writeIP(policy.ite(policy.and_(CTR_ok,COND_ok),read32(operands[2]),policy.readIP()));
738            break;
739          }
740
741       case powerpc_subf:
742          {
743            ROSE_ASSERT(operands.size() == 3);
744            write32(operands[0], policy.add(policy.negate(read32(operands[1])),read32(operands[2])));
745            break;
746          }
747
748       case powerpc_subf_record:
749          {
750            ROSE_ASSERT(operands.size() == 3);
751
752            Word(32) result = policy.add(policy.negate(read32(operands[1])),read32(operands[2]));
753            write32(operands[0],result);
754
755            record(result);
756            break;
757          }
758
759       case powerpc_bclr:
760          {
761            ROSE_ASSERT(operands.size() == 3);
762            SgAsmByteValueExpression* byteValue = isSgAsmByteValueExpression(operands[0]);
763            ROSE_ASSERT(byteValue != NULL);
764            uint8_t boConstant = byteValue->get_value();
765
766         // bool BO_4 = boConstant & 0x1;
767            bool BO_3 = boConstant & 0x2;
768            bool BO_2 = boConstant & 0x4;
769            bool BO_1 = boConstant & 0x8;
770            bool BO_0 = boConstant & 0x10;
771
772            if (!BO_2) 
773               {
774                 policy.writeSPR(powerpc_spr_ctr,policy.add(policy.readSPR(powerpc_spr_ctr),number<32>(-1)));
775               }
776
777            Word(1) CTR_ok = BO_2 ? policy.true_() : BO_3 ? policy.equalToZero(policy.readSPR(powerpc_spr_ctr)) : policy.invert(policy.equalToZero(policy.readSPR(powerpc_spr_ctr)));
778
779            SgAsmPowerpcRegisterReferenceExpression* BI = isSgAsmPowerpcRegisterReferenceExpression(operands[1]);
780            ROSE_ASSERT(BI != NULL);
781            ROSE_ASSERT(BI->get_register_class() == powerpc_regclass_cr);
782            ROSE_ASSERT(BI->get_conditionRegisterGranularity() == powerpc_condreggranularity_bit);
783
784         // This needs a collection of helpfer functions!
785            int bi_value = BI->get_register_number();
786            Word(4) CR_field = policy.readCRField(bi_value/4);
787            Word(1) CR_bi = extract<0,1>(policy.shiftRight(CR_field,number<2>(3 - bi_value % 4)));
788            Word(1) COND_ok = BO_0 ? policy.true_() : BO_1 ? CR_bi : policy.invert(CR_bi);
789            policy.writeIP(policy.ite(policy.and_(CTR_ok,COND_ok),policy.and_(policy.readSPR(powerpc_spr_lr),number<32>(0xFFFFFFFC)),policy.readIP()));
790            break;
791          }
792
793       case powerpc_cmpi:
794          {
795            ROSE_ASSERT(operands.size() == 4);
796         // For 32-bit case we can ignore value of L
797  
798            Word(32) RA = read32(operands[2]);
799            Word(32) SI = policy.signExtend<16,32>(extract<0,16>(read32(operands[3])));
800
801            Word(32) carries = number<32>(0);
802
803         // Need to check if policy.false_() or policy.true_() should be used!
804         // Bias both sides and use unsigned compare.
805         // policy.invert(policy.xor_(RA,number<32>(0x80000000U))) yields "(RA+bias)-1"
806         // Check if UI + (-RA) - 1 >= 0, test for UI > RA
807            policy.addWithCarries(policy.invert(policy.xor_(RA,number<32>(0x80000000U))),policy.xor_(SI,number<32>(0x80000000U)),policy.false_(),carries);
808
809            Word(3)  c = policy.ite(
810                            policy.equalToZero(policy.xor_(RA,SI)),
811                            number<3>(1),
812                            policy.ite(
813                               extract<31,32>(carries),
814                                  number<3>(4),
815                                  number<3>(2)));
816
817            SgAsmPowerpcRegisterReferenceExpression* bf = isSgAsmPowerpcRegisterReferenceExpression(operands[0]);
818            ROSE_ASSERT(bf != NULL);
819            ROSE_ASSERT(bf->get_register_class() == powerpc_regclass_cr);
820            ROSE_ASSERT(bf->get_conditionRegisterGranularity() == powerpc_condreggranularity_field);
821
822         // This should be a helper function!
823            Word(1) SO = extract<31,32>(policy.readSPR(powerpc_spr_xer));
824
825            policy.writeCRField(bf->get_register_number(),policy.concat(SO,c));
826            break;
827          }
828
829       case powerpc_mulhwu:
830          {
831            ROSE_ASSERT(operands.size() == 3);
832            write32(operands[0], extract<32,64>(policy.unsignedMultiply(read32(operands[1]),read32(operands[2]))));
833            break;
834          }
835
836       case powerpc_mulhw:
837          {
838            ROSE_ASSERT(operands.size() == 3);
839            write32(operands[0], extract<32,64>(policy.signedMultiply(read32(operands[1]),read32(operands[2]))));
840            break;
841          }
842
843       case powerpc_mullw:
844          {
845            ROSE_ASSERT(operands.size() == 3);
846            write32(operands[0], extract<0,32>(policy.signedMultiply(read32(operands[1]),read32(operands[2]))));
847            break;
848          }
849
850       case powerpc_mulli:
851          {
852            ROSE_ASSERT(operands.size() == 3);
853            write32(operands[0], extract<0,32>(policy.signedMultiply(read32(operands[1]),read32(operands[2]))));
854            break;
855          }
856
857       case powerpc_divw:
858          {
859            ROSE_ASSERT(operands.size() == 3);
860            write32(operands[0], policy.signedDivide(read32(operands[1]),read32(operands[2])));
861            break;
862          }
863
864       case powerpc_divwu:
865          {
866            ROSE_ASSERT(operands.size() == 3);
867            write32(operands[0], policy.unsignedDivide(read32(operands[1]),read32(operands[2])));
868            break;
869          }
870
871       case powerpc_cmp:
872          {
873            ROSE_ASSERT(operands.size() == 4);
874         // For 32-bit case we can ignore value of L
875  
876            Word(32) RA = read32(operands[2]);
877            Word(32) RB = read32(operands[3]);
878
879            Word(32) carries = number<32>(0);
880
881         // Need to check if policy.false_() or policy.true_() should be used!
882         // Bias both sides and use unsigned compare.
883         // policy.invert(policy.xor_(RA,number<32>(0x80000000U))) yields "(RA+bias)-1"
884         // Check if UI + (-RA) - 1 >= 0, test for UI > RA
885            policy.addWithCarries(policy.invert(policy.xor_(RA,number<32>(0x80000000U))),policy.xor_(RB,number<32>(0x80000000U)),policy.false_(),carries);
886
887            Word(3)  c = policy.ite(
888                            policy.equalToZero(policy.xor_(RA,RB)),
889                            number<3>(1),
890                            policy.ite(
891                               extract<31,32>(carries),
892                                  number<3>(4),
893                                  number<3>(2)));
894
895            SgAsmPowerpcRegisterReferenceExpression* bf = isSgAsmPowerpcRegisterReferenceExpression(operands[0]);
896            ROSE_ASSERT(bf != NULL);
897            ROSE_ASSERT(bf->get_register_class() == powerpc_regclass_cr);
898            ROSE_ASSERT(bf->get_conditionRegisterGranularity() == powerpc_condreggranularity_field);
899
900         // This should be a helper function!
901            Word(1) SO = extract<31,32>(policy.readSPR(powerpc_spr_xer));
902
903            policy.writeCRField(bf->get_register_number(),policy.concat(SO,c));
904            break;
905          }
906
907       case powerpc_addze:
908          {
909            ROSE_ASSERT(operands.size() == 2);
910
911         // This should be a helper function to read CA (and other flags)
912            Word(1)  carry_in = extract<29,30>(policy.readSPR(powerpc_spr_xer));
913
914            Word(32) carries = number<32>(0);
915            Word(32) result = policy.addWithCarries(read32(operands[1]),number<32>(0x0),carry_in,carries);
916
917         // Policy class bit numbering is opposite ordering from powerpc (based on x86).
918            Word(1)  carry_out = extract<31,32>(carries);
919            write32(operands[0], result);
920
921         // This should be a helper function to read/write CA (and other flags)
922         // The value 0xDFFFFFFFU is the mask for the Carry (CA) flag
923            policy.writeSPR(powerpc_spr_xer,policy.or_(policy.and_(policy.readSPR(powerpc_spr_xer),number<32>(0xDFFFFFFFU)),policy.ite(carry_out,number<32>(0x20000000U),number<32>(0x0))));
924            break;
925          }
926
927       case powerpc_addme:
928          {
929            ROSE_ASSERT(operands.size() == 2);
930
931         // This should be a helper function to read CA (and other flags)
932            Word(1)  carry_in = extract<29,30>(policy.readSPR(powerpc_spr_xer));
933
934            Word(32) carries = number<32>(0);
935            Word(32) result = policy.addWithCarries(read32(operands[1]),number<32>(0xFFFFFFFFU),carry_in,carries);
936
937         // Policy class bit numbering is opposite ordering from powerpc (based on x86).
938            Word(1)  carry_out = extract<31,32>(carries);
939            write32(operands[0], result);
940
941         // This should be a helper function to read/write CA (and other flags)
942         // The value 0xDFFFFFFFU is the mask for the Carry (CA) flag
943            policy.writeSPR(powerpc_spr_xer,policy.or_(policy.and_(policy.readSPR(powerpc_spr_xer),number<32>(0xDFFFFFFFU)),policy.ite(carry_out,number<32>(0x20000000U),number<32>(0x0))));
944            break;
945          }
946
947       case powerpc_adde:
948          {
949            ROSE_ASSERT(operands.size() == 3);
950
951         // This should be a helper function to read CA (and other flags)
952            Word(1)  carry_in = extract<29,30>(policy.readSPR(powerpc_spr_xer));
953
954            Word(32) carries = number<32>(0);
955            Word(32) result = policy.addWithCarries(read32(operands[1]),read32(operands[2]),carry_in,carries);
956
957         // Policy class bit numbering is opposite ordering from powerpc (based on x86).
958            Word(1)  carry_out = extract<31,32>(carries);
959            write32(operands[0], result);
960
961         // This should be a helper function to read/write CA (and other flags)
962         // The value 0xDFFFFFFFU is the mask for the Carry (CA) flag
963            policy.writeSPR(powerpc_spr_xer,policy.or_(policy.and_(policy.readSPR(powerpc_spr_xer),number<32>(0xDFFFFFFFU)),policy.ite(carry_out,number<32>(0x20000000U),number<32>(0x0))));
964            break;
965          }
966
967       case powerpc_andi_record:
968          {
969            ROSE_ASSERT(operands.size() == 3);
970
971            Word(32) result = policy.and_(read32(operands[1]),read32(operands[2]));
972            write32(operands[0],result);
973
974            record(result);
975            break;
976          }
977
978       case powerpc_andis_record:
979          {
980            ROSE_ASSERT(operands.size() == 3);
981
982            Word(32) result = policy.and_(read32(operands[1]),policy.concat(number<16>(0),extract<0,16>(read32(operands[2]))));
983            write32(operands[0],result);
984
985            record(result);
986            break;
987          }
988
989       case powerpc_neg:
990          {
991            ROSE_ASSERT(operands.size() == 2);
992            write32(operands[0], policy.negate(read32(operands[1])));
993            break;
994          }
995
996       case powerpc_srawi:
997          {
998            ROSE_ASSERT(operands.size() == 3);
999  
1000            Word(32) RS = read32(operands[1]);
1001
1002         // An alternative might be: uint8_t sh_value = read32(operands[1]);
1003            Word(5) SH = extract<0, 5>(read32(operands[2]));
1004
1005            Word(1) negative = extract<31,32>(RS);
1006            Word(32) mask = policy.invert(policy.shiftLeft(number<32>(-1),SH));
1007            Word(1) hasValidBits = policy.invert(policy.equalToZero(policy.and_(RS,mask)));
1008            Word(1)  carry_out = policy.and_(hasValidBits,negative);
1009
1010            write32(operands[0],policy.shiftRightArithmetic(RS,SH));
1011            policy.writeSPR(powerpc_spr_xer,policy.or_(policy.and_(policy.readSPR(powerpc_spr_xer),number<32>(0xDFFFFFFFU)),policy.ite(carry_out,number<32>(0x20000000U),number<32>(0x0))));
1012            break;
1013          }
1014
1015       case powerpc_bcctrl:
1016          {
1017            ROSE_ASSERT(operands.size() == 3);
1018            SgAsmByteValueExpression* byteValue = isSgAsmByteValueExpression(operands[0]);
1019            ROSE_ASSERT(byteValue != NULL);
1020            uint8_t boConstant = byteValue->get_value();
1021
1022            bool BO_1 = boConstant & 0x8;
1023            bool BO_0 = boConstant & 0x10;
1024
1025            SgAsmPowerpcRegisterReferenceExpression* BI = isSgAsmPowerpcRegisterReferenceExpression(operands[1]);
1026            ROSE_ASSERT(BI != NULL);
1027            ROSE_ASSERT(BI->get_register_class() == powerpc_regclass_cr);
1028            ROSE_ASSERT(BI->get_conditionRegisterGranularity() == powerpc_condreggranularity_bit);
1029
1030         // This needs a collection of helpfer functions!
1031            int bi_value = BI->get_register_number();
1032            Word(4) CR_field = policy.readCRField(bi_value/4);
1033            Word(1) CR_bi = extract<0,1>(policy.shiftRight(CR_field,number<2>(3 - bi_value % 4)));
1034            Word(1) COND_ok = BO_0 ? policy.true_() : BO_1 ? CR_bi : policy.invert(CR_bi);
1035
1036         // Write the incremented IP value to the link register so that function can return.
1037            policy.writeSPR(powerpc_spr_lr,policy.readIP());
1038
1039            policy.writeIP(policy.ite(COND_ok,policy.and_(policy.readSPR(powerpc_spr_ctr),number<32>(0xFFFFFFFC)),policy.readIP()));
1040
1041            break;
1042          }
1043
1044       case powerpc_sc:
1045          {
1046            ROSE_ASSERT(operands.size() == 1);
1047            SgAsmByteValueExpression* bv = isSgAsmByteValueExpression(operands[0]);
1048            ROSE_ASSERT (bv);
1049            policy.systemCall(bv->get_value());
1050            break;
1051          }
1052
1053       case powerpc_stmw:
1054          {
1055            ROSE_ASSERT(operands.size() == 2);
1056
1057            Word(32) effectiveAddress = readEffectiveAddress(operands[1]);
1058
1059            SgAsmPowerpcRegisterReferenceExpression* RS = isSgAsmPowerpcRegisterReferenceExpression(operands[0]);
1060            ROSE_ASSERT(RS != NULL);
1061            ROSE_ASSERT(RS->get_register_class() == powerpc_regclass_gpr);
1062
1063            uint8_t r = RS->get_register_number();
1064            uint32_t offset = 0;
1065
1066            while (r <= 31)
1067               {
1068                 writeMemory<32>(policy.add(effectiveAddress,number<32>(offset)),policy.readGPR(r),policy.true_());
1069                 offset += 4;
1070                 ++r;
1071               }
1072            break;
1073          }
1074
1075       case powerpc_lmw:
1076          {
1077            ROSE_ASSERT(operands.size() == 2);
1078
1079            Word(32) effectiveAddress = readEffectiveAddress(operands[1]);
1080
1081            SgAsmPowerpcRegisterReferenceExpression* RT = isSgAsmPowerpcRegisterReferenceExpression(operands[0]);
1082            ROSE_ASSERT(RT != NULL);
1083            ROSE_ASSERT(RT->get_register_class() == powerpc_regclass_gpr);
1084
1085            uint8_t r = RT->get_register_number();
1086            uint32_t offset = 0;
1087
1088            while (r <= 31)
1089               {
1090                 policy.writeGPR(r, readMemory<32>(policy.add(effectiveAddress,number<32>(offset)),policy.true_()));
1091                 offset += 4;
1092                 ++r;
1093               }
1094            break;
1095          }
1096
1097       case powerpc_cntlzw:
1098          {
1099            ROSE_ASSERT(operands.size() == 2);
1100            Word(32) RS = read32(operands[1]);
1101
1102         // Using xor to do the subtract from 31
1103            Word(32) result = policy.ite(policy.equalToZero(RS),number<32>(32),policy.xor_(policy.mostSignificantSetBit(RS),number<32>(31)));
1104
1105            write32(operands[0],result);
1106            break;
1107          }
1108
1109       case powerpc_mfcr:
1110          {
1111            ROSE_ASSERT(operands.size() == 1);
1112            write32(operands[0],policy.readCR());
1113            break;
1114          }
1115
1116       case powerpc_slw:
1117          {
1118            ROSE_ASSERT(operands.size() == 3);
1119            Word(6) shiftCount = extract<0,6>(read32(operands[2]));
1120            write32(operands[0], policy.ite(extract<5,6>(shiftCount),number<32>(0),policy.shiftLeft(read32(operands[1]),extract<0,5>(shiftCount))));
1121            break;
1122          }
1123
1124       case powerpc_srw:
1125          {
1126            ROSE_ASSERT(operands.size() == 3);
1127            Word(6) shiftCount = extract<0,6>(read32(operands[2]));
1128            write32(operands[0], policy.ite(extract<5,6>(shiftCount),number<32>(0),policy.shiftRight(read32(operands[1]),extract<0,5>(shiftCount))));
1129            break;
1130          }
1131
1132          default: fprintf(stderr, "Bad instruction\n"); abort();
1133     }
1134   }
1135
1136   void processInstruction(SgAsmPowerpcInstruction* insn) {
1137     ROSE_ASSERT (insn);
1138     policy.startInstruction(insn);
1139     translate(insn);
1140     policy.finishInstruction(insn);
1141   }
1142
1143
1144 };
1145
1146 #undef Word
1147
1148 #endif // ROSE_POWERPCINSTRUCTIONSEMANTICS_H