Finish most of the Power 8 VSX instruction decoding
[dyninst.git] / instructionAPI / src / InstructionDecoder-power.h
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
32 #include "InstructionDecoderImpl.h"
33 #include <iostream>
34 #include "Immediate.h"
35 #include "dyn_regs.h"
36 //#define DEBUG_FIELD
37
38 namespace Dyninst {
39     namespace InstructionAPI
40     {
41         struct power_entry;
42
43         class InstructionDecoder_power : public InstructionDecoderImpl
44         {
45             friend struct power_entry;
46             public:
47                 InstructionDecoder_power(Architecture a);
48                 virtual ~InstructionDecoder_power();
49                 virtual void decodeOpcode(InstructionDecoder::buffer& b);
50                 virtual Instruction::Ptr decode(InstructionDecoder::buffer& b);
51                 virtual void setMode(bool) 
52                 {
53                 }
54                 virtual bool decodeOperands(const Instruction* insn_to_complete);
55                 virtual void doDelayedDecode(const Instruction* insn_to_complete);
56                 static bool foundDoubleHummerInsn;
57                 static bool foundQuadInsn;
58                 using InstructionDecoderImpl::makeRegisterExpression;
59             private:
60                 virtual Result_Type makeSizeType(unsigned int opType);
61                 Expression::Ptr makeMemRefIndex(Result_Type size);
62                 Expression::Ptr makeMemRefNonIndex(Result_Type size);
63                 Expression::Ptr makeRAExpr();
64                 Expression::Ptr makeRBExpr();
65                 Expression::Ptr makeRTExpr(); 
66                 Expression::Ptr makeFRAExpr();
67                 Expression::Ptr makeFRBExpr();
68                 Expression::Ptr makeFRCExpr();
69                 Expression::Ptr makeQFRCExpr();
70                 Expression::Ptr makeFRTExpr();
71                 Expression::Ptr makeIFormBranchTarget();
72                 Expression::Ptr makeBFormBranchTarget();
73                 Expression::Ptr makeRAorZeroExpr();
74                 Expression::Ptr makeDorSIExpr();
75                 Expression::Ptr makeBTExpr();
76                 Expression::Ptr makeBAExpr();
77                 Expression::Ptr makeQRBExpr();
78                 Expression::Ptr makeQRTExpr();
79                 Expression::Ptr makeBBExpr();
80                 Expression::Ptr makeCR0Expr();
81                 Expression::Ptr makeBIExpr();
82                 Expression::Ptr makeSHExpr();
83                 Expression::Ptr makeMBExpr();
84                 Expression::Ptr makeMEExpr();
85                 Expression::Ptr makeFLMExpr();
86                 Expression::Ptr makeSPRExpr();
87                 Expression::Ptr makeTOExpr();
88                 Expression::Ptr makeDSExpr();
89                 Expression::Ptr makeQFRAExpr();
90                 template <Result_Type size> void L();
91                 template <Result_Type size> void ST();
92                 template <Result_Type size> void LX();
93                 template <Result_Type size> void STX();
94                 template <Result_Type size> void LU();
95                 template <Result_Type size> void STU();
96                 template <Result_Type size> void LUX();
97                 template <Result_Type size> void STUX();
98                 void LK();
99                 void LI();
100                 void FRT();
101                 void FRS();
102                 void FRT2();
103                 void FRS2();
104                 void QRT();
105                 void QTT();
106                 void QVD();
107                 void QRB();
108                 void QRBS();
109                 void QGPC();
110                 void QFRTS();
111                 void QFRSP();
112                 void QFRTP();
113                 void QFRS();
114                 void QFRSS();
115                 void QFRCP();
116                 void QFRC();
117                 void QFRCS();
118                 void RT();
119                 void RS();
120                 void BD();
121                 void TO();
122                 void RA();
123                 void SI();
124                 void D();
125                 void mainDecode();
126                 void BF();
127                 void UI();
128                 void BO();
129                 void AA() {}
130                 void LL();
131                 void SH();
132                 void Rc();
133                 void RB();
134                 void FRA();
135                 void QFRA();
136                 void FRB();
137                 void FRC();
138                 void BI();
139                 void ME();
140                 void MB();
141                 void BFA();
142                 void BT();
143                 void BA();
144                 void BB();
145                 void OE();
146                 void FXM();
147                 void spr();
148                 void SR();
149                 void NB();
150                 void U();
151                 void FLM();
152                 void FRTP();
153                 void FRTS();
154                 void FRSP();
155                 void FRSS();
156                 void FRAP();
157                 void FRAS();
158                 void QFRAP();
159                 void QFRAS();
160                 void FRBP();
161                 void FRBS();
162                 void FRCP();
163                 void FRCS();
164                 void WC();
165                 void syscall();
166                 void setFPMode();
167                 void L() {}; // non-templated version for some zero fields
168                 void XT();
169                 void XS();
170                 void XA();
171                 void XB();
172                 void VRT();
173                 void VRA();
174                 void VRB();
175                 void VRC();
176                 void UIM();
177                 void SIM();
178                 void DCMX();
179                 void VRS();
180                 void RO();
181                 void R();
182                 void RMC();
183                 void EX();
184                 void SHB();
185                 void SIX();
186                 void PS();
187                 void CY();
188
189
190
191                 const power_entry& extended_op_0();
192                 const power_entry& extended_op_4();
193                 const power_entry& extended_op_19();
194                 const power_entry& extended_op_30();
195                 const power_entry& extended_op_31();
196                 const power_entry& extended_op_57();
197                 const power_entry& extended_op_58();
198                 const power_entry& extended_op_59();
199                 const power_entry& extended_op_60();
200                 const power_entry& extended_op_61();
201                 const power_entry& extended_op_63();
202                 template <int start, int end>
203                 int field(unsigned int raw) {
204 #if defined DEBUG_FIELD
205                     std::cerr << start << "-" << end << ":" << std::dec << (raw >> (31 - (end)) &
206                             (0xFFFFFFFF >> (31 - (end - start)))) << " ";
207 #endif
208                     return (raw >> (31 - (end)) & (0xFFFFFFFF >> (31 - (end - start))));
209                 }
210                 template <int size>
211                 int sign_extend(int in)
212                 {
213                     return (in << (32 - size)) >> (32 - size);
214                 }
215
216                 
217                 template<unsigned int low, unsigned int high, unsigned int base = ppc32::icr0,
218                     unsigned int curCR = high - low>
219                 struct translateBitFieldToCR
220                 {
221                     translateBitFieldToCR(InstructionDecoder_power& dec) :
222                             m_dec(dec) {}
223                     void operator()()
224                     {
225                         (translateBitFieldToCR<low, high - 1, base, curCR - 1>(m_dec))();
226                         if(m_dec.field<high, high>(m_dec.insn))
227                         {
228                             m_dec.insn_in_progress->appendOperand(m_dec.makeRegisterExpression(m_dec.makePowerRegID(
229                                     MachRegister(base), curCR)), !m_dec.isRAWritten, m_dec.isRAWritten);
230                         }
231                     }
232                     InstructionDecoder_power& m_dec;
233                 };
234                 template<unsigned int low, unsigned int high, unsigned int base>
235                         struct translateBitFieldToCR<low, high, base, 0>
236                         {
237                     translateBitFieldToCR(InstructionDecoder_power& dec) :
238                             m_dec(dec) {}
239                     void operator()()
240                     {
241                         if(m_dec.field<high, high>(m_dec.insn))
242                         {
243                             m_dec.insn_in_progress->appendOperand(m_dec.makeRegisterExpression(m_dec.makePowerRegID(
244                                     MachRegister(base), 0)), !m_dec.isRAWritten, m_dec.isRAWritten);
245                         }
246                     }
247                     InstructionDecoder_power& m_dec;
248                 };
249                 
250
251                 template< int lowBit, int highBit>
252                         Expression::Ptr makeBranchTarget()
253                         {
254                             size_t where = insn_in_progress->getOperation().mnemonic.rfind('+');
255                             if(where == std::string::npos) {
256                                 where = insn_in_progress->getOperation().mnemonic.rfind('-');
257                             }
258                             if(where == std::string::npos) {
259                                 where = insn_in_progress->getOperation().mnemonic.size();
260                             }
261                             if(field<31, 31>(insn) == 1)
262                             {
263                                 insn_in_progress->getOperation().mnemonic.insert(where, "l");
264                                 where++;
265                                 insn_in_progress->appendOperand(makeRegisterExpression(ppc32::lr), false, true);
266                             }
267         // absolute address
268                             if(field<30, 30>(insn) == 1)
269                             {
270                                 insn_in_progress->getOperation().mnemonic.insert(where, "a");
271                                 return Immediate::makeImmediate(Result(u32,
272                                         sign_extend<(highBit - lowBit + 1)>(field<lowBit, highBit>(insn)) << 2));
273                             }
274                             else
275                             {
276                                 Expression::Ptr displacement = Immediate::makeImmediate(Result(s32,
277                                         sign_extend<(highBit - lowBit + 1)>(field<lowBit, highBit>(insn)) << 2));
278                                 return makeAddExpression(makeRegisterExpression(ppc32::pc), displacement, s32);
279                             }
280                         }
281                 
282                 MachRegister makePowerRegID(MachRegister base, unsigned int encoding, int field = -1);
283                 MachRegister makePowerRegID(MachRegister base, unsigned int encoding,
284                         unsigned int lowBit, unsigned int highBit);
285                 
286                 Expression::Ptr makeFallThroughExpr();
287
288                 unsigned int insn;
289                 Instruction* insn_in_progress;
290                 bool isRAWritten;
291                 bool invertBranchCondition;
292                 bool isFPInsn;
293                 bool bcIsConditional;
294                 bool findRAAndRS(const struct power_entry*);
295         };
296     }
297 }