Add initial code for power 32 semantics and symbolic expansion for power 64
[dyninst.git] / dataflowAPI / rose / semantics / DispatcherPowerpc.h
1 // Semantics for 32-bit Motorola-IBM PowerPC microprocessors using ROSE instruction semantics API2
2 // This code was derived from $ROSE/projects/assemblyToSourceAst/powerpcInstructionSemantics.h,
3 // which is mostly a copy of $ROSE/projects/SemanticSignatureVectors/powerpcInstructionSemantics.h
4 //
5 // The ROSE style guide indicates that PowerPC, when used as part of a symbol in ROSE source code,
6 // should be capitalized as "Powerpc" (e.g., "DispatcherPowerpc", the same rule that consistently
7 // capitializes x86 as "DispatcherX86").
8
9 #ifndef ROSE_DispatcherPpc_H
10 #define ROSE_DispatcherPpc_H
11
12 #include "BaseSemantics2.h"
13 #include "../SgAsmPowerpcInstruction.h"
14 #include "external/rose/powerpcInstructionEnum.h"
15
16 namespace rose {
17 namespace BinaryAnalysis {
18 namespace InstructionSemantics2 {
19
20 /** Shared-ownership pointer to a PowerPC instruction dispatcher. See @ref heap_object_shared_ownership. */
21 typedef boost::shared_ptr<class DispatcherPowerpc> DispatcherPowerpcPtr;
22
23 class DispatcherPowerpc: public BaseSemantics::Dispatcher {
24 protected:
25     // prototypical constructor
26     DispatcherPowerpc(): BaseSemantics::Dispatcher(32, RegisterDictionary::dictionary_powerpc()) {}
27
28     DispatcherPowerpc(const BaseSemantics::RiscOperatorsPtr &ops, size_t addrWidth, const RegisterDictionary *regs)
29         : BaseSemantics::Dispatcher(ops, addrWidth, regs ? regs : RegisterDictionary::dictionary_powerpc()) {
30         ASSERT_require(32==addrWidth);
31         regcache_init();
32         iproc_init();
33         memory_init();
34     }
35
36     /** Loads the iproc table with instruction processing functors. This normally happens from the constructor. */
37     void iproc_init();
38
39     /** Load the cached register descriptors.  This happens at construction and on set_register_dictionary() calls. */
40     void regcache_init();
41
42     /** Make sure memory is set up correctly. For instance, byte order should be little endian. */
43     void memory_init();
44
45 public:
46     /** Cached register. This register is cached so that there are not so many calls to Dispatcher::findRegister(). The
47      *  register descriptor is updated only when the register dictionary is changed (see set_register_dictionary()).
48      * @{ */
49     RegisterDescriptor REG_IAR, REG_LR, REG_XER, REG_CR, REG_CR0, REG_CTR;
50     /** @}*/
51
52     /** Construct a prototypical dispatcher.  The only thing this dispatcher can be used for is to create another dispatcher
53      *  with the virtual @ref create method. */
54     static DispatcherPowerpcPtr instance() {
55         return DispatcherPowerpcPtr(new DispatcherPowerpc);
56     }
57     
58     /** Constructor. */
59     static DispatcherPowerpcPtr instance(const BaseSemantics::RiscOperatorsPtr &ops, size_t addrWidth,
60                                          const RegisterDictionary *regs=NULL) {
61         return DispatcherPowerpcPtr(new DispatcherPowerpc(ops, addrWidth, regs));
62     }
63
64     /** Virtual constructor. */
65     virtual BaseSemantics::DispatcherPtr create(const BaseSemantics::RiscOperatorsPtr &ops, size_t addrWidth=0,
66                                                 const RegisterDictionary *regs=NULL) const  {
67         if (0==addrWidth)
68             addrWidth = addressWidth();
69         if (!regs)
70             regs = get_register_dictionary();
71         return instance(ops, addrWidth, regs);
72     }
73
74     /** Dynamic cast to a DispatcherPowerpcPtr with assertion. */
75     static DispatcherPowerpcPtr promote(const BaseSemantics::DispatcherPtr &d) {
76         DispatcherPowerpcPtr retval = boost::dynamic_pointer_cast<DispatcherPowerpc>(d);
77         assert(retval!=NULL);
78         return retval;
79     }
80
81     virtual void set_register_dictionary(const RegisterDictionary *regdict) ;
82
83     virtual RegisterDescriptor instructionPointerRegister() const ;
84
85     virtual RegisterDescriptor stackPointerRegister() const ;
86
87     virtual int iproc_key(SgAsmInstruction *insn_) const  {
88         SgAsmPowerpcInstruction *insn = isSgAsmPowerpcInstruction(insn_);
89         assert(insn!=NULL);
90         return insn->get_kind();
91     }
92
93     /** Write status flags for result. */
94     virtual void record(const BaseSemantics::SValuePtr &result);
95 };
96         
97 } // namespace
98 } // namespace
99 } // namespace
100
101 #endif