/src/capstonev5/arch/PowerPC/PPCInstPrinter.c
Line  | Count  | Source  | 
1  |  | //===-- PPCInstPrinter.cpp - Convert PPC MCInst to assembly syntax --------===//  | 
2  |  | //  | 
3  |  | //                     The LLVM Compiler Infrastructure  | 
4  |  | //  | 
5  |  | // This file is distributed under the University of Illinois Open Source  | 
6  |  | // License. See LICENSE.TXT for details.  | 
7  |  | //  | 
8  |  | //===----------------------------------------------------------------------===//  | 
9  |  | //  | 
10  |  | // This class prints an PPC MCInst to a .s file.  | 
11  |  | //  | 
12  |  | //===----------------------------------------------------------------------===//  | 
13  |  |  | 
14  |  | /* Capstone Disassembly Engine */  | 
15  |  | /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */  | 
16  |  |  | 
17  |  | #ifdef CAPSTONE_HAS_POWERPC  | 
18  |  |  | 
19  |  | #include <stdio.h>  | 
20  |  | #include <stdlib.h>  | 
21  |  | #include <string.h>  | 
22  |  |  | 
23  |  | #include "PPCInstPrinter.h"  | 
24  |  | #include "PPCPredicates.h"  | 
25  |  | #include "../../MCInst.h"  | 
26  |  | #include "../../utils.h"  | 
27  |  | #include "../../SStream.h"  | 
28  |  | #include "../../MCRegisterInfo.h"  | 
29  |  | #include "../../MathExtras.h"  | 
30  |  | #include "PPCMapping.h"  | 
31  |  |  | 
32  |  | #ifndef CAPSTONE_DIET  | 
33  |  | static const char *getRegisterName(unsigned RegNo);  | 
34  |  | #endif  | 
35  |  |  | 
36  |  | static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);  | 
37  |  | static void printInstruction(MCInst *MI, SStream *O);  | 
38  |  | static void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O);  | 
39  |  | static char *printAliasInstr(MCInst *MI, SStream *OS, MCRegisterInfo *MRI);  | 
40  |  | static char *printAliasBcc(MCInst *MI, SStream *OS, void *info);  | 
41  |  | static void printCustomAliasOperand(MCInst *MI, unsigned OpIdx,  | 
42  |  |     unsigned PrintMethodIdx, SStream *OS);  | 
43  |  |  | 
44  |  | #if 0  | 
45  |  | static void printRegName(SStream *OS, unsigned RegNo)  | 
46  |  | { | 
47  |  |   char *RegName = getRegisterName(RegNo);  | 
48  |  |  | 
49  |  |   if (RegName[0] == 'q' /* QPX */) { | 
50  |  |     // The system toolchain on the BG/Q does not understand QPX register names  | 
51  |  |     // in .cfi_* directives, so print the name of the floating-point  | 
52  |  |     // subregister instead.  | 
53  |  |     RegName[0] = 'f';  | 
54  |  |   }  | 
55  |  |  | 
56  |  |   SStream_concat0(OS, RegName);  | 
57  |  | }  | 
58  |  | #endif  | 
59  |  |  | 
60  |  | static void set_mem_access(MCInst *MI, bool status)  | 
61  | 31.4k  | { | 
62  | 31.4k  |   if (MI->csh->detail != CS_OPT_ON)  | 
63  | 0  |     return;  | 
64  |  |  | 
65  | 31.4k  |   MI->csh->doing_mem = status;  | 
66  |  |  | 
67  | 31.4k  |   if (status) { | 
68  | 15.7k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_MEM;  | 
69  | 15.7k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.base = PPC_REG_INVALID;  | 
70  | 15.7k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.disp = 0;  | 
71  | 15.7k  |   } else { | 
72  |  |     // done, create the next operand slot  | 
73  | 15.7k  |     MI->flat_insn->detail->ppc.op_count++;  | 
74  | 15.7k  |   }  | 
75  | 31.4k  | }  | 
76  |  |  | 
77  |  | void PPC_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)  | 
78  | 131k  | { | 
79  | 131k  |   if (((cs_struct *)ud)->detail != CS_OPT_ON)  | 
80  | 0  |     return;  | 
81  |  |  | 
82  |  |   // check if this insn has branch hint  | 
83  | 131k  |   if (strrchr(insn->mnemonic, '+') != NULL && !strstr(insn_asm, ".+")) { | 
84  | 3.23k  |     insn->detail->ppc.bh = PPC_BH_PLUS;  | 
85  | 128k  |   } else if (strrchr(insn->mnemonic, '-') != NULL) { | 
86  | 1.99k  |     insn->detail->ppc.bh = PPC_BH_MINUS;  | 
87  | 1.99k  |   }  | 
88  |  |  | 
89  | 131k  |   if (strrchr(insn->mnemonic, '.') != NULL) { | 
90  | 9.45k  |     insn->detail->ppc.update_cr0 = true;  | 
91  | 9.45k  |   }  | 
92  | 131k  | }  | 
93  |  |  | 
94  |  | #define GET_INSTRINFO_ENUM  | 
95  |  | #include "PPCGenInstrInfo.inc"  | 
96  |  |  | 
97  |  | #define GET_REGINFO_ENUM  | 
98  |  | #include "PPCGenRegisterInfo.inc"  | 
99  |  |  | 
100  |  | static void op_addBC(MCInst *MI, unsigned int bc)  | 
101  | 3.13k  | { | 
102  | 3.13k  |   if (MI->csh->detail) { | 
103  | 3.13k  |     MI->flat_insn->detail->ppc.bc = (ppc_bc)bc;  | 
104  | 3.13k  |   }  | 
105  | 3.13k  | }  | 
106  |  |  | 
107  | 913  | #define CREQ (0)  | 
108  | 1.22k  | #define CRGT (1)  | 
109  | 1.52k  | #define CRLT (2)  | 
110  | 956  | #define CRUN (3)  | 
111  |  |  | 
112  |  | static int getBICRCond(int bi)  | 
113  | 4.62k  | { | 
114  | 4.62k  |   return (bi - PPC_CR0EQ) >> 3;  | 
115  | 4.62k  | }  | 
116  |  |  | 
117  |  | static int getBICR(int bi)  | 
118  | 4.62k  | { | 
119  | 4.62k  |   return ((bi - PPC_CR0EQ) & 7) + PPC_CR0;  | 
120  | 4.62k  | }  | 
121  |  |  | 
122  |  | static void op_addReg(MCInst *MI, unsigned int reg)  | 
123  | 1.25k  | { | 
124  | 1.25k  |   if (MI->csh->detail) { | 
125  | 1.25k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_REG;  | 
126  | 1.25k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].reg = reg;  | 
127  | 1.25k  |     MI->flat_insn->detail->ppc.op_count++;  | 
128  | 1.25k  |   }  | 
129  | 1.25k  | }  | 
130  |  |  | 
131  |  | static void add_CRxx(MCInst *MI, ppc_reg reg)  | 
132  | 1.46k  | { | 
133  | 1.46k  |   if (MI->csh->detail) { | 
134  | 1.46k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_REG;  | 
135  | 1.46k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].reg = reg;  | 
136  | 1.46k  |     MI->flat_insn->detail->ppc.op_count++;  | 
137  | 1.46k  |   }  | 
138  | 1.46k  | }  | 
139  |  |  | 
140  |  | static char *printAliasBcc(MCInst *MI, SStream *OS, void *info)  | 
141  | 129k  | { | 
142  | 129k  | #define GETREGCLASS_CONTAIN(_class, _reg) MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, _class), MCOperand_getReg(MCInst_getOperand(MI, _reg)))  | 
143  | 129k  |   SStream ss;  | 
144  | 129k  |   const char *opCode;  | 
145  | 129k  |   char *tmp, *AsmMnem, *AsmOps, *c;  | 
146  | 129k  |   int OpIdx, PrintMethodIdx;  | 
147  | 129k  |   int decCtr = false, needComma = false;  | 
148  | 129k  |   MCRegisterInfo *MRI = (MCRegisterInfo *)info;  | 
149  |  |  | 
150  | 129k  |   SStream_Init(&ss);  | 
151  |  |  | 
152  | 129k  |   switch (MCInst_getOpcode(MI)) { | 
153  | 122k  |     default: return NULL;  | 
154  | 2.09k  |     case PPC_gBC:  | 
155  | 2.09k  |          opCode = "b%s";  | 
156  | 2.09k  |          break;  | 
157  | 1.62k  |     case PPC_gBCA:  | 
158  | 1.62k  |          opCode = "b%sa";  | 
159  | 1.62k  |          break;  | 
160  | 124  |     case PPC_gBCCTR:  | 
161  | 124  |          opCode = "b%sctr";  | 
162  | 124  |          break;  | 
163  | 47  |     case PPC_gBCCTRL:  | 
164  | 47  |          opCode = "b%sctrl";  | 
165  | 47  |          break;  | 
166  | 1.53k  |     case PPC_gBCL:  | 
167  | 1.53k  |          opCode = "b%sl";  | 
168  | 1.53k  |          break;  | 
169  | 2.04k  |     case PPC_gBCLA:  | 
170  | 2.04k  |          opCode = "b%sla";  | 
171  | 2.04k  |          break;  | 
172  | 80  |     case PPC_gBCLR:  | 
173  | 80  |          opCode = "b%slr";  | 
174  | 80  |          break;  | 
175  | 84  |     case PPC_gBCLRL:  | 
176  | 84  |          opCode = "b%slrl";  | 
177  | 84  |          break;  | 
178  | 129k  |   }  | 
179  |  |  | 
180  | 7.63k  |   if (MCInst_getNumOperands(MI) == 3 &&  | 
181  | 7.63k  |       MCOperand_isImm(MCInst_getOperand(MI, 0)) &&  | 
182  | 7.63k  |       (MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 0) &&  | 
183  | 7.63k  |       (MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 1)) { | 
184  | 1.28k  |     SStream_concat(&ss, opCode, "dnzf");  | 
185  | 1.28k  |     decCtr = true;  | 
186  | 1.28k  |   }  | 
187  |  |  | 
188  | 7.63k  |   if (MCInst_getNumOperands(MI) == 3 &&  | 
189  | 7.63k  |       MCOperand_isImm(MCInst_getOperand(MI, 0)) &&  | 
190  | 7.63k  |       (MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 2) &&  | 
191  | 6.34k  |       (MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 3)) { | 
192  | 517  |     SStream_concat(&ss, opCode, "dzf");  | 
193  | 517  |     decCtr = true;  | 
194  | 517  |   }  | 
195  |  |  | 
196  | 7.63k  |   if (MCInst_getNumOperands(MI) == 3 &&  | 
197  | 7.63k  |       MCOperand_isImm(MCInst_getOperand(MI, 0)) &&  | 
198  | 7.63k  |       (MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 4) &&  | 
199  | 5.83k  |       (MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 7) &&  | 
200  | 796  |       MCOperand_isReg(MCInst_getOperand(MI, 1)) &&  | 
201  | 796  |       GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1)) { | 
202  | 796  |     int cr = getBICRCond(MCOperand_getReg(MCInst_getOperand(MI, 1)));  | 
203  |  |  | 
204  | 796  |     switch(cr) { | 
205  | 96  |       case CREQ:  | 
206  | 96  |         SStream_concat(&ss, opCode, "ne");  | 
207  | 96  |         break;  | 
208  | 302  |       case CRGT:  | 
209  | 302  |         SStream_concat(&ss, opCode, "le");  | 
210  | 302  |         break;  | 
211  | 226  |       case CRLT:  | 
212  | 226  |         SStream_concat(&ss, opCode, "ge");  | 
213  | 226  |         break;  | 
214  | 172  |       case CRUN:  | 
215  | 172  |         SStream_concat(&ss, opCode, "ns");  | 
216  | 172  |         break;  | 
217  | 796  |     }  | 
218  |  |  | 
219  | 796  |     if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 6)  | 
220  | 210  |       SStream_concat0(&ss, "-");  | 
221  |  |  | 
222  | 796  |     if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 7)  | 
223  | 339  |       SStream_concat0(&ss, "+");  | 
224  |  |  | 
225  | 796  |     decCtr = false;  | 
226  | 796  |   }  | 
227  |  |  | 
228  | 7.63k  |   if (MCInst_getNumOperands(MI) == 3 &&  | 
229  | 7.63k  |       MCOperand_isImm(MCInst_getOperand(MI, 0)) &&  | 
230  | 7.63k  |       (MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 8) &&  | 
231  | 5.03k  |       (MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 9)) { | 
232  | 556  |     SStream_concat(&ss, opCode, "dnzt");  | 
233  | 556  |     decCtr = true;  | 
234  | 556  |   }  | 
235  |  |  | 
236  | 7.63k  |   if (MCInst_getNumOperands(MI) == 3 &&  | 
237  | 7.63k  |       MCOperand_isImm(MCInst_getOperand(MI, 0)) &&  | 
238  | 7.63k  |       (MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 10) &&  | 
239  | 4.48k  |       (MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 11)) { | 
240  | 781  |     SStream_concat(&ss, opCode, "dzt");  | 
241  | 781  |     decCtr = true;  | 
242  | 781  |   }  | 
243  |  |  | 
244  | 7.63k  |   if (MCInst_getNumOperands(MI) == 3 &&  | 
245  | 7.63k  |       MCOperand_isImm(MCInst_getOperand(MI, 0)) &&  | 
246  | 7.63k  |       (MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 12) &&  | 
247  | 3.69k  |       (MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 15) &&  | 
248  | 689  |       MCOperand_isReg(MCInst_getOperand(MI, 1)) &&  | 
249  | 689  |       GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1)) { | 
250  | 689  |     int cr = getBICRCond(MCOperand_getReg(MCInst_getOperand(MI, 1)));  | 
251  |  |  | 
252  | 689  |     switch(cr) { | 
253  | 227  |       case CREQ:  | 
254  | 227  |         SStream_concat(&ss, opCode, "eq");  | 
255  | 227  |         break;  | 
256  | 174  |       case CRGT:  | 
257  | 174  |         SStream_concat(&ss, opCode, "gt");  | 
258  | 174  |         break;  | 
259  | 213  |       case CRLT:  | 
260  | 213  |         SStream_concat(&ss, opCode, "lt");  | 
261  | 213  |         break;  | 
262  | 75  |       case CRUN:  | 
263  | 75  |         SStream_concat(&ss, opCode, "so");  | 
264  | 75  |         break;  | 
265  | 689  |     }  | 
266  |  |  | 
267  | 689  |     if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 14)  | 
268  | 234  |       SStream_concat0(&ss, "-");  | 
269  |  |  | 
270  | 689  |     if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 15)  | 
271  | 218  |       SStream_concat0(&ss, "+");  | 
272  |  |  | 
273  | 689  |     decCtr = false;  | 
274  | 689  |   }  | 
275  |  |  | 
276  | 7.63k  |   if (MCInst_getNumOperands(MI) == 3 &&  | 
277  | 7.63k  |       MCOperand_isImm(MCInst_getOperand(MI, 0)) &&  | 
278  | 7.63k  |       ((MCOperand_getImm(MCInst_getOperand(MI, 0)) & 0x12)== 16)) { | 
279  | 1.15k  |     SStream_concat(&ss, opCode, "dnz");  | 
280  |  |  | 
281  | 1.15k  |     if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 24)  | 
282  | 343  |       SStream_concat0(&ss, "-");  | 
283  |  |  | 
284  | 1.15k  |     if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 25)  | 
285  | 247  |       SStream_concat0(&ss, "+");  | 
286  |  |  | 
287  | 1.15k  |     needComma = false;  | 
288  | 1.15k  |   }  | 
289  |  |  | 
290  | 7.63k  |   if (MCInst_getNumOperands(MI) == 3 &&  | 
291  | 7.63k  |       MCOperand_isImm(MCInst_getOperand(MI, 0)) &&  | 
292  | 7.63k  |       ((MCOperand_getImm(MCInst_getOperand(MI, 0)) & 0x12)== 18)) { | 
293  | 1.85k  |     SStream_concat(&ss, opCode, "dz");  | 
294  |  |  | 
295  | 1.85k  |     if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 26)  | 
296  | 915  |       SStream_concat0(&ss, "-");  | 
297  |  |  | 
298  | 1.85k  |     if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 27)  | 
299  | 304  |       SStream_concat0(&ss, "+");  | 
300  |  |  | 
301  | 1.85k  |     needComma = false;  | 
302  | 1.85k  |   }  | 
303  |  |  | 
304  | 7.63k  |   if (MCOperand_isReg(MCInst_getOperand(MI, 1)) &&  | 
305  | 7.63k  |       GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1) &&  | 
306  | 7.63k  |       MCOperand_isImm(MCInst_getOperand(MI, 0)) &&  | 
307  | 7.63k  |       (MCOperand_getImm(MCInst_getOperand(MI, 0)) < 16)) { | 
308  | 4.62k  |     int cr = getBICR(MCOperand_getReg(MCInst_getOperand(MI, 1)));  | 
309  |  |  | 
310  | 4.62k  |     if (decCtr) { | 
311  | 3.13k  |       int cd;  | 
312  | 3.13k  |       needComma = true;  | 
313  | 3.13k  |       SStream_concat0(&ss, " ");  | 
314  |  |  | 
315  | 3.13k  |       if (cr > PPC_CR0) { | 
316  | 1.66k  |         SStream_concat(&ss, "4*cr%d+", cr - PPC_CR0);  | 
317  | 1.66k  |       }  | 
318  |  |  | 
319  | 3.13k  |       cd = getBICRCond(MCOperand_getReg(MCInst_getOperand(MI, 1)));  | 
320  | 3.13k  |       switch(cd) { | 
321  | 590  |         case CREQ:  | 
322  | 590  |           SStream_concat0(&ss, "eq");  | 
323  | 590  |           if (cr <= PPC_CR0)  | 
324  | 276  |             add_CRxx(MI, PPC_REG_CR0EQ);  | 
325  | 590  |           op_addBC(MI, PPC_BC_EQ);  | 
326  | 590  |           break;  | 
327  | 753  |         case CRGT:  | 
328  | 753  |           SStream_concat0(&ss, "gt");  | 
329  | 753  |           if (cr <= PPC_CR0)  | 
330  | 417  |             add_CRxx(MI, PPC_REG_CR0GT);  | 
331  | 753  |           op_addBC(MI, PPC_BC_GT);  | 
332  | 753  |           break;  | 
333  | 1.08k  |         case CRLT:  | 
334  | 1.08k  |           SStream_concat0(&ss, "lt");  | 
335  | 1.08k  |           if (cr <= PPC_CR0)  | 
336  | 523  |             add_CRxx(MI, PPC_REG_CR0LT);  | 
337  | 1.08k  |           op_addBC(MI, PPC_BC_LT);  | 
338  | 1.08k  |           break;  | 
339  | 709  |         case CRUN:  | 
340  | 709  |           SStream_concat0(&ss, "so");  | 
341  | 709  |           if (cr <= PPC_CR0)  | 
342  | 253  |             add_CRxx(MI, PPC_REG_CR0UN);  | 
343  | 709  |           op_addBC(MI, PPC_BC_SO);  | 
344  | 709  |           break;  | 
345  | 3.13k  |       }  | 
346  |  |  | 
347  | 3.13k  |       if (cr > PPC_CR0) { | 
348  | 1.66k  |         if (MI->csh->detail) { | 
349  | 1.66k  |           MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_REG;  | 
350  | 1.66k  |           MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 1));  | 
351  | 1.66k  |           MI->flat_insn->detail->ppc.op_count++;  | 
352  | 1.66k  |         }  | 
353  | 1.66k  |       }  | 
354  | 3.13k  |     } else { | 
355  | 1.48k  |       if (cr > PPC_CR0) { | 
356  | 1.25k  |         needComma = true;  | 
357  | 1.25k  |         SStream_concat(&ss, " cr%d", cr - PPC_CR0);  | 
358  | 1.25k  |         op_addReg(MI, PPC_REG_CR0 + cr - PPC_CR0);  | 
359  | 1.25k  |       }  | 
360  | 1.48k  |     }  | 
361  | 4.62k  |   }  | 
362  |  |  | 
363  | 7.63k  |   if (MCOperand_isImm(MCInst_getOperand(MI, 2)) &&  | 
364  | 7.63k  |       MCOperand_getImm(MCInst_getOperand(MI, 2)) != 0) { | 
365  | 7.12k  |     if (needComma)  | 
366  | 4.19k  |       SStream_concat0(&ss, ",");  | 
367  |  |  | 
368  | 7.12k  |     SStream_concat0(&ss, " $\xFF\x03\x01");  | 
369  | 7.12k  |   }  | 
370  |  |  | 
371  | 7.63k  |   tmp = cs_strdup(ss.buffer);  | 
372  | 7.63k  |   AsmMnem = tmp;  | 
373  | 47.6k  |   for(AsmOps = tmp; *AsmOps; AsmOps++) { | 
374  | 47.3k  |     if (*AsmOps == ' ' || *AsmOps == '\t') { | 
375  | 7.31k  |       *AsmOps = '\0';  | 
376  | 7.31k  |       AsmOps++;  | 
377  | 7.31k  |       break;  | 
378  | 7.31k  |     }  | 
379  | 47.3k  |   }  | 
380  |  |  | 
381  | 7.63k  |   SStream_concat0(OS, AsmMnem);  | 
382  | 7.63k  |   if (*AsmOps) { | 
383  | 7.31k  |     SStream_concat0(OS, "\t");  | 
384  | 42.8k  |     for (c = AsmOps; *c; c++) { | 
385  | 35.5k  |       if (*c == '$') { | 
386  | 7.12k  |         c += 1;  | 
387  | 7.12k  |         if (*c == (char)0xff) { | 
388  | 7.12k  |           c += 1;  | 
389  | 7.12k  |           OpIdx = *c - 1;  | 
390  | 7.12k  |           c += 1;  | 
391  | 7.12k  |           PrintMethodIdx = *c - 1;  | 
392  | 7.12k  |           printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, OS);  | 
393  | 7.12k  |         } else  | 
394  | 0  |           printOperand(MI, *c - 1, OS);  | 
395  | 28.4k  |       } else { | 
396  | 28.4k  |         SStream_concat1(OS, *c);  | 
397  | 28.4k  |       }  | 
398  | 35.5k  |     }  | 
399  | 7.31k  |   }  | 
400  |  |  | 
401  | 7.63k  |   return tmp;  | 
402  | 7.63k  | }  | 
403  |  |  | 
404  |  | static bool isBOCTRBranch(unsigned int op)  | 
405  | 129k  | { | 
406  | 129k  |   return ((op >= PPC_BDNZ) && (op <= PPC_BDZp));  | 
407  | 129k  | }  | 
408  |  |  | 
409  |  | void PPC_printInst(MCInst *MI, SStream *O, void *Info)  | 
410  | 131k  | { | 
411  | 131k  |   char *mnem;  | 
412  | 131k  |   unsigned int opcode = MCInst_getOpcode(MI);  | 
413  | 131k  |   memset(O->buffer, 0, sizeof(O->buffer));  | 
414  |  |  | 
415  |  |   // printf("opcode = %u\n", opcode); | 
416  |  |  | 
417  |  |   // Check for slwi/srwi mnemonics.  | 
418  | 131k  |   if (opcode == PPC_RLWINM) { | 
419  | 2.33k  |     unsigned char SH = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 2));  | 
420  | 2.33k  |     unsigned char MB = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 3));  | 
421  | 2.33k  |     unsigned char ME = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 4));  | 
422  | 2.33k  |     bool useSubstituteMnemonic = false;  | 
423  |  |  | 
424  | 2.33k  |     if (SH <= 31 && MB == 0 && ME == (31 - SH)) { | 
425  | 538  |       SStream_concat0(O, "slwi\t");  | 
426  | 538  |       MCInst_setOpcodePub(MI, PPC_INS_SLWI);  | 
427  | 538  |       useSubstituteMnemonic = true;  | 
428  | 538  |     }  | 
429  |  |  | 
430  | 2.33k  |     if (SH <= 31 && MB == (32 - SH) && ME == 31) { | 
431  | 369  |       SStream_concat0(O, "srwi\t");  | 
432  | 369  |       MCInst_setOpcodePub(MI, PPC_INS_SRWI);  | 
433  | 369  |       useSubstituteMnemonic = true;  | 
434  | 369  |       SH = 32 - SH;  | 
435  | 369  |     }  | 
436  |  |  | 
437  | 2.33k  |     if (useSubstituteMnemonic) { | 
438  | 907  |       printOperand(MI, 0, O);  | 
439  | 907  |       SStream_concat0(O, ", ");  | 
440  | 907  |       printOperand(MI, 1, O);  | 
441  |  |  | 
442  | 907  |       if (SH > HEX_THRESHOLD)  | 
443  | 370  |         SStream_concat(O, ", 0x%x", (unsigned int)SH);  | 
444  | 537  |       else  | 
445  | 537  |         SStream_concat(O, ", %u", (unsigned int)SH);  | 
446  |  |  | 
447  | 907  |       if (MI->csh->detail) { | 
448  | 907  |         cs_ppc *ppc = &MI->flat_insn->detail->ppc;  | 
449  |  |  | 
450  | 907  |         ppc->operands[ppc->op_count].type = PPC_OP_IMM;  | 
451  | 907  |         ppc->operands[ppc->op_count].imm = SH;  | 
452  | 907  |         ++ppc->op_count;  | 
453  | 907  |       }  | 
454  |  |  | 
455  | 907  |       return;  | 
456  | 907  |     }  | 
457  | 2.33k  |   }  | 
458  |  |  | 
459  | 130k  |   if ((opcode == PPC_OR || opcode == PPC_OR8) &&  | 
460  | 139  |       MCOperand_getReg(MCInst_getOperand(MI, 1)) == MCOperand_getReg(MCInst_getOperand(MI, 2))) { | 
461  | 66  |     SStream_concat0(O, "mr\t");  | 
462  | 66  |     MCInst_setOpcodePub(MI, PPC_INS_MR);  | 
463  |  |  | 
464  | 66  |     printOperand(MI, 0, O);  | 
465  | 66  |     SStream_concat0(O, ", ");  | 
466  | 66  |     printOperand(MI, 1, O);  | 
467  |  |  | 
468  | 66  |     return;  | 
469  | 66  |   }  | 
470  |  |  | 
471  | 130k  |   if (opcode == PPC_RLDICR ||  | 
472  | 129k  |       opcode == PPC_RLDICR_32) { | 
473  | 808  |     unsigned char SH = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 2));  | 
474  | 808  |     unsigned char ME = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 3));  | 
475  |  |  | 
476  |  |     // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH  | 
477  | 808  |     if (63 - SH == ME) { | 
478  | 260  |       SStream_concat0(O, "sldi\t");  | 
479  | 260  |       MCInst_setOpcodePub(MI, PPC_INS_SLDI);  | 
480  |  |  | 
481  | 260  |       printOperand(MI, 0, O);  | 
482  | 260  |       SStream_concat0(O, ", ");  | 
483  | 260  |       printOperand(MI, 1, O);  | 
484  |  |  | 
485  | 260  |       if (SH > HEX_THRESHOLD)  | 
486  | 194  |         SStream_concat(O, ", 0x%x", (unsigned int)SH);  | 
487  | 66  |       else  | 
488  | 66  |         SStream_concat(O, ", %u", (unsigned int)SH);  | 
489  |  |  | 
490  | 260  |       if (MI->csh->detail) { | 
491  | 260  |         cs_ppc *ppc = &MI->flat_insn->detail->ppc;  | 
492  |  |  | 
493  | 260  |         ppc->operands[ppc->op_count].type = PPC_OP_IMM;  | 
494  | 260  |         ppc->operands[ppc->op_count].imm = SH;  | 
495  | 260  |         ++ppc->op_count;  | 
496  | 260  |       }  | 
497  |  |  | 
498  |  |  | 
499  | 260  |       return;  | 
500  | 260  |     }  | 
501  | 808  |   }  | 
502  |  |  | 
503  |  |   // dcbt[st] is printed manually here because:  | 
504  |  |   //  1. The assembly syntax is different between embedded and server targets  | 
505  |  |   //  2. We must print the short mnemonics for TH == 0 because the  | 
506  |  |   //     embedded/server syntax default will not be stable across assemblers  | 
507  |  |   //  The syntax for dcbt is:  | 
508  |  |   //    dcbt ra, rb, th [server]  | 
509  |  |   //    dcbt th, ra, rb [embedded]  | 
510  |  |   //  where th can be omitted when it is 0. dcbtst is the same.  | 
511  | 130k  |   if (opcode == PPC_DCBT || opcode == PPC_DCBTST) { | 
512  | 301  |     unsigned char TH = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 0));  | 
513  |  |  | 
514  | 301  |     SStream_concat0(O, "dcbt");  | 
515  | 301  |     MCInst_setOpcodePub(MI, PPC_INS_DCBT);  | 
516  |  |  | 
517  | 301  |     if (opcode == PPC_DCBTST) { | 
518  | 198  |       SStream_concat0(O, "st");  | 
519  | 198  |       MCInst_setOpcodePub(MI, PPC_INS_DCBTST);  | 
520  | 198  |     }  | 
521  |  |  | 
522  | 301  |     if (TH == 16) { | 
523  | 66  |       SStream_concat0(O, "t");  | 
524  | 66  |       MCInst_setOpcodePub(MI, PPC_INS_DCBTSTT);  | 
525  | 66  |     }  | 
526  |  |  | 
527  | 301  |     SStream_concat0(O, "\t");  | 
528  |  |  | 
529  | 301  |     if (MI->csh->mode & CS_MODE_BOOKE && TH != 0 && TH != 16) { | 
530  | 0  |       if (TH > HEX_THRESHOLD)  | 
531  | 0  |         SStream_concat(O, "0x%x, ", (unsigned int)TH);  | 
532  | 0  |       else  | 
533  | 0  |         SStream_concat(O, "%u, ", (unsigned int)TH);  | 
534  |  | 
  | 
535  | 0  |       if (MI->csh->detail) { | 
536  | 0  |         cs_ppc *ppc = &MI->flat_insn->detail->ppc;  | 
537  |  | 
  | 
538  | 0  |         ppc->operands[ppc->op_count].type = PPC_OP_IMM;  | 
539  | 0  |         ppc->operands[ppc->op_count].imm = TH;  | 
540  | 0  |         ++ppc->op_count;  | 
541  | 0  |       }  | 
542  | 0  |     }  | 
543  |  |  | 
544  | 301  |     printOperand(MI, 1, O);  | 
545  | 301  |     SStream_concat0(O, ", ");  | 
546  | 301  |     printOperand(MI, 2, O);  | 
547  |  |  | 
548  | 301  |     if (!(MI->csh->mode & CS_MODE_BOOKE) && TH != 0 && TH != 16) { | 
549  | 134  |       if (TH > HEX_THRESHOLD)  | 
550  | 68  |         SStream_concat(O, ", 0x%x", (unsigned int)TH);  | 
551  | 66  |       else  | 
552  | 66  |         SStream_concat(O, ", %u", (unsigned int)TH);  | 
553  |  |  | 
554  | 134  |       if (MI->csh->detail) { | 
555  | 134  |         cs_ppc *ppc = &MI->flat_insn->detail->ppc;  | 
556  |  |  | 
557  | 134  |         ppc->operands[ppc->op_count].type = PPC_OP_IMM;  | 
558  | 134  |         ppc->operands[ppc->op_count].imm = TH;  | 
559  | 134  |         ++ppc->op_count;  | 
560  | 134  |       }  | 
561  | 134  |     }  | 
562  |  |  | 
563  | 301  |     return;  | 
564  | 301  |   }  | 
565  |  |  | 
566  | 130k  |   if (opcode == PPC_DCBF) { | 
567  | 363  |     unsigned char L = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 0));  | 
568  |  |  | 
569  | 363  |     if (!L || L == 1 || L == 3) { | 
570  | 292  |       SStream_concat0(O, "dcbf");  | 
571  | 292  |       MCInst_setOpcodePub(MI, PPC_INS_DCBF);  | 
572  |  |  | 
573  | 292  |       if (L == 1 || L == 3) { | 
574  | 171  |         SStream_concat0(O, "l");  | 
575  | 171  |         MCInst_setOpcodePub(MI, PPC_INS_DCBFL);  | 
576  | 171  |       }  | 
577  |  |  | 
578  | 292  |       if (L == 3) { | 
579  | 67  |         SStream_concat0(O, "p");  | 
580  | 67  |         MCInst_setOpcodePub(MI, PPC_INS_DCBFLP);  | 
581  | 67  |       }  | 
582  |  |  | 
583  | 292  |       SStream_concat0(O, "\t");  | 
584  |  |  | 
585  | 292  |       printOperand(MI, 1, O);  | 
586  | 292  |       SStream_concat0(O, ", ");  | 
587  | 292  |       printOperand(MI, 2, O);  | 
588  |  |  | 
589  | 292  |       return;  | 
590  | 292  |     }  | 
591  | 363  |   }  | 
592  |  |  | 
593  | 129k  |   if (opcode == PPC_B || opcode == PPC_BA || opcode == PPC_BL ||  | 
594  | 128k  |       opcode == PPC_BLA) { | 
595  | 1.27k  |     int64_t bd = MCOperand_getImm(MCInst_getOperand(MI, 0));  | 
596  | 1.27k  |     bd = SignExtend64(bd, 24);  | 
597  | 1.27k  |     MCOperand_setImm(MCInst_getOperand(MI, 0), bd);  | 
598  | 1.27k  |   }  | 
599  |  |  | 
600  | 129k  |   if (opcode == PPC_gBC || opcode == PPC_gBCA || opcode == PPC_gBCL ||  | 
601  | 124k  |       opcode == PPC_gBCLA) { | 
602  | 7.29k  |     int64_t bd = MCOperand_getImm(MCInst_getOperand(MI, 2));  | 
603  | 7.29k  |     bd = SignExtend64(bd, 14);  | 
604  | 7.29k  |     MCOperand_setImm(MCInst_getOperand(MI, 2), bd);  | 
605  | 7.29k  |   }  | 
606  |  |  | 
607  | 129k  |   if (isBOCTRBranch(MCInst_getOpcode(MI))) { | 
608  | 1.10k  |     if (MCOperand_isImm(MCInst_getOperand(MI,0))) { | 
609  | 803  |       int64_t bd = MCOperand_getImm(MCInst_getOperand(MI, 0));  | 
610  | 803  |       bd = SignExtend64(bd, 14);  | 
611  | 803  |       MCOperand_setImm(MCInst_getOperand(MI, 0), bd);  | 
612  | 803  |     }  | 
613  | 1.10k  |   }  | 
614  |  |  | 
615  | 129k  |   mnem = printAliasBcc(MI, O, Info);  | 
616  | 129k  |   if (!mnem)  | 
617  | 122k  |     mnem = printAliasInstr(MI, O, Info);  | 
618  |  |  | 
619  | 129k  |   if (mnem != NULL) { | 
620  | 50.5k  |     if (strlen(mnem) > 0) { | 
621  |  |       // check to remove the last letter of ('.', '-', '+') | 
622  | 50.5k  |       if (mnem[strlen(mnem) - 1] == '-' || mnem[strlen(mnem) - 1] == '+' || mnem[strlen(mnem) - 1] == '.')  | 
623  | 3.73k  |         mnem[strlen(mnem) - 1] = '\0';  | 
624  |  |  | 
625  | 50.5k  |             MCInst_setOpcodePub(MI, PPC_map_insn(mnem));  | 
626  |  |  | 
627  | 50.5k  |             if (MI->csh->detail) { | 
628  | 50.5k  |         struct ppc_alias alias;  | 
629  |  |  | 
630  | 50.5k  |         if (PPC_alias_insn(mnem, &alias)) { | 
631  | 1.48k  |           MI->flat_insn->detail->ppc.bc = (ppc_bc)alias.cc;  | 
632  | 1.48k  |         }  | 
633  | 50.5k  |             }  | 
634  | 50.5k  |     }  | 
635  |  |  | 
636  | 50.5k  |     cs_mem_free(mnem);  | 
637  | 50.5k  |   } else  | 
638  | 79.2k  |     printInstruction(MI, O);  | 
639  |  |  | 
640  | 129k  |   const char *mnem_end = strchr(O->buffer, ' ');  | 
641  | 129k  |   unsigned mnem_len = 0;  | 
642  | 129k  |   if (mnem_end)  | 
643  | 123k  |     mnem_len = mnem_end - O->buffer;  | 
644  | 129k  |   if (!mnem_end || mnem_len >= sizeof(MI->flat_insn->mnemonic))  | 
645  | 6.54k  |     mnem_len = sizeof(MI->flat_insn->mnemonic) - 1;  | 
646  |  |  | 
647  | 129k  |   memset(MI->flat_insn->mnemonic, 0, sizeof(MI->flat_insn->mnemonic));  | 
648  | 129k  |   memcpy(MI->flat_insn->mnemonic, O->buffer, mnem_len);  | 
649  | 129k  | }  | 
650  |  |  | 
651  |  | // FIXME  | 
652  |  | enum ppc_bc_hint { | 
653  |  |   PPC_BC_LT_MINUS = (0 << 5) | 14,  | 
654  |  |   PPC_BC_LE_MINUS = (1 << 5) |  6,  | 
655  |  |   PPC_BC_EQ_MINUS = (2 << 5) | 14,  | 
656  |  |   PPC_BC_GE_MINUS = (0 << 5) |  6,  | 
657  |  |   PPC_BC_GT_MINUS = (1 << 5) | 14,  | 
658  |  |   PPC_BC_NE_MINUS = (2 << 5) |  6,  | 
659  |  |   PPC_BC_UN_MINUS = (3 << 5) | 14,  | 
660  |  |   PPC_BC_NU_MINUS = (3 << 5) |  6,  | 
661  |  |   PPC_BC_LT_PLUS  = (0 << 5) | 15,  | 
662  |  |   PPC_BC_LE_PLUS  = (1 << 5) |  7,  | 
663  |  |   PPC_BC_EQ_PLUS  = (2 << 5) | 15,  | 
664  |  |   PPC_BC_GE_PLUS  = (0 << 5) |  7,  | 
665  |  |   PPC_BC_GT_PLUS  = (1 << 5) | 15,  | 
666  |  |   PPC_BC_NE_PLUS  = (2 << 5) |  7,  | 
667  |  |   PPC_BC_UN_PLUS  = (3 << 5) | 15,  | 
668  |  |   PPC_BC_NU_PLUS  = (3 << 5) |  7,  | 
669  |  | };  | 
670  |  |  | 
671  |  | // FIXME  | 
672  |  | // normalize CC to remove _MINUS & _PLUS  | 
673  |  | static int cc_normalize(int cc)  | 
674  | 0  | { | 
675  | 0  |   switch(cc) { | 
676  | 0  |     default: return cc;  | 
677  | 0  |     case PPC_BC_LT_MINUS: return PPC_BC_LT;  | 
678  | 0  |     case PPC_BC_LE_MINUS: return PPC_BC_LE;  | 
679  | 0  |     case PPC_BC_EQ_MINUS: return PPC_BC_EQ;  | 
680  | 0  |     case PPC_BC_GE_MINUS: return PPC_BC_GE;  | 
681  | 0  |     case PPC_BC_GT_MINUS: return PPC_BC_GT;  | 
682  | 0  |     case PPC_BC_NE_MINUS: return PPC_BC_NE;  | 
683  | 0  |     case PPC_BC_UN_MINUS: return PPC_BC_UN;  | 
684  | 0  |     case PPC_BC_NU_MINUS: return PPC_BC_NU;  | 
685  | 0  |     case PPC_BC_LT_PLUS : return PPC_BC_LT;  | 
686  | 0  |     case PPC_BC_LE_PLUS : return PPC_BC_LE;  | 
687  | 0  |     case PPC_BC_EQ_PLUS : return PPC_BC_EQ;  | 
688  | 0  |     case PPC_BC_GE_PLUS : return PPC_BC_GE;  | 
689  | 0  |     case PPC_BC_GT_PLUS : return PPC_BC_GT;  | 
690  | 0  |     case PPC_BC_NE_PLUS : return PPC_BC_NE;  | 
691  | 0  |     case PPC_BC_UN_PLUS : return PPC_BC_UN;  | 
692  | 0  |     case PPC_BC_NU_PLUS : return PPC_BC_NU;  | 
693  | 0  |   }  | 
694  | 0  | }  | 
695  |  |  | 
696  |  | static void printPredicateOperand(MCInst *MI, unsigned OpNo,  | 
697  |  |     SStream *O, const char *Modifier)  | 
698  | 0  | { | 
699  | 0  |   unsigned Code = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
700  |  | 
  | 
701  | 0  |   MI->flat_insn->detail->ppc.bc = (ppc_bc)cc_normalize(Code);  | 
702  |  | 
  | 
703  | 0  |   if (!strcmp(Modifier, "cc")) { | 
704  | 0  |     switch ((ppc_predicate)Code) { | 
705  | 0  |       default:  // unreachable  | 
706  | 0  |       case PPC_PRED_LT_MINUS:  | 
707  | 0  |       case PPC_PRED_LT_PLUS:  | 
708  | 0  |       case PPC_PRED_LT:  | 
709  | 0  |         SStream_concat0(O, "lt");  | 
710  | 0  |         return;  | 
711  | 0  |       case PPC_PRED_LE_MINUS:  | 
712  | 0  |       case PPC_PRED_LE_PLUS:  | 
713  | 0  |       case PPC_PRED_LE:  | 
714  | 0  |         SStream_concat0(O, "le");  | 
715  | 0  |         return;  | 
716  | 0  |       case PPC_PRED_EQ_MINUS:  | 
717  | 0  |       case PPC_PRED_EQ_PLUS:  | 
718  | 0  |       case PPC_PRED_EQ:  | 
719  | 0  |         SStream_concat0(O, "eq");  | 
720  | 0  |         return;  | 
721  | 0  |       case PPC_PRED_GE_MINUS:  | 
722  | 0  |       case PPC_PRED_GE_PLUS:  | 
723  | 0  |       case PPC_PRED_GE:  | 
724  | 0  |         SStream_concat0(O, "ge");  | 
725  | 0  |         return;  | 
726  | 0  |       case PPC_PRED_GT_MINUS:  | 
727  | 0  |       case PPC_PRED_GT_PLUS:  | 
728  | 0  |       case PPC_PRED_GT:  | 
729  | 0  |         SStream_concat0(O, "gt");  | 
730  | 0  |         return;  | 
731  | 0  |       case PPC_PRED_NE_MINUS:  | 
732  | 0  |       case PPC_PRED_NE_PLUS:  | 
733  | 0  |       case PPC_PRED_NE:  | 
734  | 0  |         SStream_concat0(O, "ne");  | 
735  | 0  |         return;  | 
736  | 0  |       case PPC_PRED_UN_MINUS:  | 
737  | 0  |       case PPC_PRED_UN_PLUS:  | 
738  | 0  |       case PPC_PRED_UN:  | 
739  | 0  |         SStream_concat0(O, "un");  | 
740  | 0  |         return;  | 
741  | 0  |       case PPC_PRED_NU_MINUS:  | 
742  | 0  |       case PPC_PRED_NU_PLUS:  | 
743  | 0  |       case PPC_PRED_NU:  | 
744  | 0  |         SStream_concat0(O, "nu");  | 
745  | 0  |         return;  | 
746  | 0  |       case PPC_PRED_BIT_SET:  | 
747  | 0  |       case PPC_PRED_BIT_UNSET:  | 
748  |  |         // llvm_unreachable("Invalid use of bit predicate code"); | 
749  | 0  |         SStream_concat0(O, "invalid-predicate");  | 
750  | 0  |         return;  | 
751  | 0  |     }  | 
752  | 0  |   }  | 
753  |  |  | 
754  | 0  |   if (!strcmp(Modifier, "pm")) { | 
755  | 0  |     switch ((ppc_predicate)Code) { | 
756  | 0  |       case PPC_PRED_LT:  | 
757  | 0  |       case PPC_PRED_LE:  | 
758  | 0  |       case PPC_PRED_EQ:  | 
759  | 0  |       case PPC_PRED_GE:  | 
760  | 0  |       case PPC_PRED_GT:  | 
761  | 0  |       case PPC_PRED_NE:  | 
762  | 0  |       case PPC_PRED_UN:  | 
763  | 0  |       case PPC_PRED_NU:  | 
764  | 0  |         return;  | 
765  | 0  |       case PPC_PRED_LT_MINUS:  | 
766  | 0  |       case PPC_PRED_LE_MINUS:  | 
767  | 0  |       case PPC_PRED_EQ_MINUS:  | 
768  | 0  |       case PPC_PRED_GE_MINUS:  | 
769  | 0  |       case PPC_PRED_GT_MINUS:  | 
770  | 0  |       case PPC_PRED_NE_MINUS:  | 
771  | 0  |       case PPC_PRED_UN_MINUS:  | 
772  | 0  |       case PPC_PRED_NU_MINUS:  | 
773  | 0  |         SStream_concat0(O, "-");  | 
774  | 0  |         return;  | 
775  | 0  |       case PPC_PRED_LT_PLUS:  | 
776  | 0  |       case PPC_PRED_LE_PLUS:  | 
777  | 0  |       case PPC_PRED_EQ_PLUS:  | 
778  | 0  |       case PPC_PRED_GE_PLUS:  | 
779  | 0  |       case PPC_PRED_GT_PLUS:  | 
780  | 0  |       case PPC_PRED_NE_PLUS:  | 
781  | 0  |       case PPC_PRED_UN_PLUS:  | 
782  | 0  |       case PPC_PRED_NU_PLUS:  | 
783  | 0  |         SStream_concat0(O, "+");  | 
784  | 0  |         return;  | 
785  | 0  |       case PPC_PRED_BIT_SET:  | 
786  | 0  |       case PPC_PRED_BIT_UNSET:  | 
787  |  |         // llvm_unreachable("Invalid use of bit predicate code"); | 
788  | 0  |         SStream_concat0(O, "invalid-predicate");  | 
789  | 0  |         return;  | 
790  | 0  |       default:  // unreachable  | 
791  | 0  |         return;  | 
792  | 0  |     }  | 
793  |  |     // llvm_unreachable("Invalid predicate code"); | 
794  | 0  |   }  | 
795  |  |  | 
796  |  |   //assert(StringRef(Modifier) == "reg" &&  | 
797  |  |   //    "Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!");  | 
798  | 0  |   printOperand(MI, OpNo + 1, O);  | 
799  | 0  | }  | 
800  |  |  | 
801  |  | static void printATBitsAsHint(MCInst *MI, unsigned OpNo, SStream *O)  | 
802  | 0  | { | 
803  | 0  |   unsigned Code = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
804  |  | 
  | 
805  | 0  |   if (Code == 2) { | 
806  | 0  |     SStream_concat0(O, "-");  | 
807  | 0  |   } else if (Code == 3) { | 
808  | 0  |     SStream_concat0(O, "+");  | 
809  | 0  |   }  | 
810  | 0  | }  | 
811  |  |  | 
812  |  | static void printU1ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
813  | 1.22k  | { | 
814  | 1.22k  |   unsigned int Value = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
815  |  |  | 
816  |  |   // assert(Value <= 1 && "Invalid u1imm argument!");  | 
817  |  |  | 
818  | 1.22k  |   printUInt32(O, Value);  | 
819  |  |  | 
820  | 1.22k  |   if (MI->csh->detail) { | 
821  | 1.22k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
822  | 1.22k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;  | 
823  | 1.22k  |     MI->flat_insn->detail->ppc.op_count++;  | 
824  | 1.22k  |   }  | 
825  | 1.22k  | }  | 
826  |  |  | 
827  |  | static void printU2ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
828  | 2.04k  | { | 
829  | 2.04k  |   unsigned int Value = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
830  |  |   //assert(Value <= 3 && "Invalid u2imm argument!");  | 
831  |  |  | 
832  | 2.04k  |   printUInt32(O, Value);  | 
833  |  |  | 
834  | 2.04k  |   if (MI->csh->detail) { | 
835  | 2.04k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
836  | 2.04k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;  | 
837  | 2.04k  |     MI->flat_insn->detail->ppc.op_count++;  | 
838  | 2.04k  |   }  | 
839  | 2.04k  | }  | 
840  |  |  | 
841  |  | static void printU3ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
842  | 152  | { | 
843  | 152  |   unsigned int Value = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
844  |  |   //assert(Value <= 8 && "Invalid u3imm argument!");  | 
845  |  |  | 
846  | 152  |   printUInt32(O, Value);  | 
847  |  |  | 
848  | 152  |   if (MI->csh->detail) { | 
849  | 152  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
850  | 152  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;  | 
851  | 152  |     MI->flat_insn->detail->ppc.op_count++;  | 
852  | 152  |   }  | 
853  | 152  | }  | 
854  |  |  | 
855  |  | static void printU4ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
856  | 822  | { | 
857  | 822  |   unsigned int Value = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
858  |  |   //assert(Value <= 15 && "Invalid u4imm argument!");  | 
859  |  |  | 
860  | 822  |   printUInt32(O, Value);  | 
861  |  |  | 
862  | 822  |   if (MI->csh->detail) { | 
863  | 822  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
864  | 822  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;  | 
865  | 822  |     MI->flat_insn->detail->ppc.op_count++;  | 
866  | 822  |   }  | 
867  | 822  | }  | 
868  |  |  | 
869  |  | static void printS5ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
870  | 66  | { | 
871  | 66  |   int Value = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
872  | 66  |   Value = SignExtend32(Value, 5);  | 
873  |  |  | 
874  | 66  |   printInt32(O, Value);  | 
875  |  |  | 
876  | 66  |   if (MI->csh->detail) { | 
877  | 66  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
878  | 66  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;  | 
879  | 66  |     MI->flat_insn->detail->ppc.op_count++;  | 
880  | 66  |   }  | 
881  | 66  | }  | 
882  |  |  | 
883  |  | static void printU5ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
884  | 15.7k  | { | 
885  | 15.7k  |   unsigned int Value = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
886  |  |  | 
887  |  |   //assert(Value <= 31 && "Invalid u5imm argument!");  | 
888  | 15.7k  |   printUInt32(O, Value);  | 
889  |  |  | 
890  | 15.7k  |   if (MI->csh->detail) { | 
891  | 15.7k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
892  | 15.7k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;  | 
893  | 15.7k  |     MI->flat_insn->detail->ppc.op_count++;  | 
894  | 15.7k  |   }  | 
895  | 15.7k  | }  | 
896  |  |  | 
897  |  | static void printU6ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
898  | 4.15k  | { | 
899  | 4.15k  |   unsigned int Value = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
900  |  |  | 
901  |  |   //assert(Value <= 63 && "Invalid u6imm argument!");  | 
902  | 4.15k  |   printUInt32(O, Value);  | 
903  |  |  | 
904  | 4.15k  |   if (MI->csh->detail) { | 
905  | 4.15k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
906  | 4.15k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;  | 
907  | 4.15k  |     MI->flat_insn->detail->ppc.op_count++;  | 
908  | 4.15k  |   }  | 
909  | 4.15k  | }  | 
910  |  |  | 
911  |  | static void printU7ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
912  | 210  | { | 
913  | 210  |   unsigned int Value = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
914  |  |  | 
915  |  |   //assert(Value <= 127 && "Invalid u7imm argument!");  | 
916  | 210  |   printUInt32(O, Value);  | 
917  |  |  | 
918  | 210  |   if (MI->csh->detail) { | 
919  | 210  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
920  | 210  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;  | 
921  | 210  |     MI->flat_insn->detail->ppc.op_count++;  | 
922  | 210  |   }  | 
923  | 210  | }  | 
924  |  |  | 
925  |  | // Operands of BUILD_VECTOR are signed and we use this to print operands  | 
926  |  | // of XXSPLTIB which are unsigned. So we simply truncate to 8 bits and  | 
927  |  | // print as unsigned.  | 
928  |  | static void printU8ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
929  | 88  | { | 
930  | 88  |   unsigned int Value = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
931  |  |  | 
932  | 88  |   printUInt32(O, Value);  | 
933  |  |  | 
934  | 88  |   if (MI->csh->detail) { | 
935  | 88  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
936  | 88  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;  | 
937  | 88  |     MI->flat_insn->detail->ppc.op_count++;  | 
938  | 88  |   }  | 
939  | 88  | }  | 
940  |  |  | 
941  |  | static void printU10ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
942  | 68  | { | 
943  | 68  |   unsigned int Value = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
944  |  |  | 
945  |  |   //assert(Value <= 1023 && "Invalid u10imm argument!");  | 
946  | 68  |   printUInt32(O, Value);  | 
947  |  |  | 
948  | 68  |   if (MI->csh->detail) { | 
949  | 68  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
950  | 68  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;  | 
951  | 68  |     MI->flat_insn->detail->ppc.op_count++;  | 
952  | 68  |   }  | 
953  | 68  | }  | 
954  |  |  | 
955  |  | static void printS12ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
956  | 0  | { | 
957  | 0  |   if (MCOperand_isImm(MCInst_getOperand(MI, OpNo))) { | 
958  | 0  |     int Imm = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
959  | 0  |     Imm = SignExtend32(Imm, 12);  | 
960  |  | 
  | 
961  | 0  |     printInt32(O, Imm);  | 
962  |  | 
  | 
963  | 0  |     if (MI->csh->detail) { | 
964  | 0  |       if (MI->csh->doing_mem) { | 
965  | 0  |                 MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.disp = Imm;  | 
966  | 0  |       } else { | 
967  | 0  |                 MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
968  | 0  |                 MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Imm;  | 
969  | 0  |                 MI->flat_insn->detail->ppc.op_count++;  | 
970  | 0  |             }  | 
971  | 0  |     }  | 
972  | 0  |   } else  | 
973  | 0  |     printOperand(MI, OpNo, O);  | 
974  | 0  | }  | 
975  |  |  | 
976  |  | static void printU12ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
977  | 1.01k  | { | 
978  | 1.01k  |   unsigned short Value = (unsigned short)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
979  |  |  | 
980  |  |   // assert(Value <= 4095 && "Invalid u12imm argument!");  | 
981  |  |  | 
982  | 1.01k  |   printUInt32(O, Value);  | 
983  |  |  | 
984  | 1.01k  |   if (MI->csh->detail) { | 
985  | 1.01k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
986  | 1.01k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;  | 
987  | 1.01k  |     MI->flat_insn->detail->ppc.op_count++;  | 
988  | 1.01k  |   }  | 
989  | 1.01k  | }  | 
990  |  |  | 
991  |  | static void printS16ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
992  | 28.2k  | { | 
993  | 28.2k  |   if (MCOperand_isImm(MCInst_getOperand(MI, OpNo))) { | 
994  | 28.2k  |     short Imm = (short)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
995  | 28.2k  |     printInt32(O, Imm);  | 
996  |  |  | 
997  | 28.2k  |     if (MI->csh->detail) { | 
998  | 28.2k  |       if (MI->csh->doing_mem) { | 
999  | 15.7k  |                 MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.disp = Imm;  | 
1000  | 15.7k  |       } else { | 
1001  | 12.5k  |                 MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
1002  | 12.5k  |                 MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Imm;  | 
1003  | 12.5k  |                 MI->flat_insn->detail->ppc.op_count++;  | 
1004  | 12.5k  |             }  | 
1005  | 28.2k  |     }  | 
1006  | 28.2k  |   } else  | 
1007  | 0  |     printOperand(MI, OpNo, O);  | 
1008  | 28.2k  | }  | 
1009  |  |  | 
1010  |  | static void printU16ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
1011  | 6.51k  | { | 
1012  | 6.51k  |   if (MCOperand_isImm(MCInst_getOperand(MI, OpNo))) { | 
1013  | 6.51k  |     unsigned short Imm = (unsigned short)MCOperand_getImm(MCInst_getOperand(MI, OpNo));  | 
1014  | 6.51k  |     printUInt32(O, Imm);  | 
1015  |  |  | 
1016  | 6.51k  |     if (MI->csh->detail) { | 
1017  | 6.51k  |       MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
1018  | 6.51k  |       MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Imm;  | 
1019  | 6.51k  |       MI->flat_insn->detail->ppc.op_count++;  | 
1020  | 6.51k  |     }  | 
1021  | 6.51k  |   } else  | 
1022  | 0  |     printOperand(MI, OpNo, O);  | 
1023  | 6.51k  | }  | 
1024  |  |  | 
1025  |  | static void printBranchOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
1026  | 7.77k  | { | 
1027  | 7.77k  |   if (!MCOperand_isImm(MCInst_getOperand(MI, OpNo))) { | 
1028  | 0  |     printOperand(MI, OpNo, O);  | 
1029  |  | 
  | 
1030  | 0  |     return;  | 
1031  | 0  |   }  | 
1032  |  |  | 
1033  |  |   // Branches can take an immediate operand.  This is used by the branch  | 
1034  |  |   // selection pass to print .+8, an eight byte displacement from the PC.  | 
1035  |  |   // O << ".+";  | 
1036  | 7.77k  |   printAbsBranchOperand(MI, OpNo, O);  | 
1037  | 7.77k  | }  | 
1038  |  |  | 
1039  |  | static void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
1040  | 9.19k  | { | 
1041  | 9.19k  |   int64_t imm;  | 
1042  |  |  | 
1043  | 9.19k  |   if (!MCOperand_isImm(MCInst_getOperand(MI, OpNo))) { | 
1044  | 0  |     printOperand(MI, OpNo, O);  | 
1045  |  | 
  | 
1046  | 0  |     return;  | 
1047  | 0  |   }  | 
1048  |  |  | 
1049  | 9.19k  |   imm = SignExtend32(MCOperand_getImm(MCInst_getOperand(MI, OpNo)) * 4, 32);  | 
1050  |  |   //imm = MCOperand_getImm(MCInst_getOperand(MI, OpNo)) * 4;  | 
1051  |  |  | 
1052  | 9.19k  |   if (!PPC_abs_branch(MI->csh, MCInst_getOpcode(MI))) { | 
1053  | 4.11k  |     imm += MI->address;  | 
1054  | 4.11k  |   }  | 
1055  |  |  | 
1056  | 9.19k  |   printUInt64(O, imm);  | 
1057  |  |  | 
1058  | 9.19k  |   if (MI->csh->detail) { | 
1059  | 9.19k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
1060  | 9.19k  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = imm;  | 
1061  | 9.19k  |     MI->flat_insn->detail->ppc.op_count++;  | 
1062  | 9.19k  |   }  | 
1063  | 9.19k  | }  | 
1064  |  |  | 
1065  |  | static void printcrbitm(MCInst *MI, unsigned OpNo, SStream *O)  | 
1066  | 826  | { | 
1067  | 826  |   unsigned RegNo;  | 
1068  | 826  |   unsigned CCReg = MCOperand_getReg(MCInst_getOperand(MI, OpNo));  | 
1069  |  |  | 
1070  | 826  |   switch (CCReg) { | 
1071  | 0  |     default: // llvm_unreachable("Unknown CR register"); | 
1072  | 132  |     case PPC_CR0: RegNo = 0; break;  | 
1073  | 52  |     case PPC_CR1: RegNo = 1; break;  | 
1074  | 17  |     case PPC_CR2: RegNo = 2; break;  | 
1075  | 42  |     case PPC_CR3: RegNo = 3; break;  | 
1076  | 347  |     case PPC_CR4: RegNo = 4; break;  | 
1077  | 67  |     case PPC_CR5: RegNo = 5; break;  | 
1078  | 108  |     case PPC_CR6: RegNo = 6; break;  | 
1079  | 61  |     case PPC_CR7: RegNo = 7; break;  | 
1080  | 826  |   }  | 
1081  |  |  | 
1082  | 826  |   printUInt32(O, 0x80 >> RegNo);  | 
1083  | 826  | }  | 
1084  |  |  | 
1085  |  | static void printMemRegImm(MCInst *MI, unsigned OpNo, SStream *O)  | 
1086  | 26.2k  | { | 
1087  | 26.2k  |   set_mem_access(MI, true);  | 
1088  |  |  | 
1089  | 26.2k  |   printS16ImmOperand(MI, OpNo, O);  | 
1090  |  |  | 
1091  | 26.2k  |   SStream_concat0(O, "("); | 
1092  |  |  | 
1093  | 26.2k  |   if (MCOperand_getReg(MCInst_getOperand(MI, OpNo + 1)) == PPC_R0)  | 
1094  | 0  |     SStream_concat0(O, "0");  | 
1095  | 26.2k  |   else  | 
1096  | 26.2k  |     printOperand(MI, OpNo + 1, O);  | 
1097  |  |  | 
1098  | 26.2k  |   SStream_concat0(O, ")");  | 
1099  |  |  | 
1100  | 26.2k  |   set_mem_access(MI, false);  | 
1101  | 26.2k  | }  | 
1102  |  |  | 
1103  |  | static void printPSMemRegImm(MCInst *MI, unsigned OpNo, SStream *O)  | 
1104  | 0  | { | 
1105  | 0  |   set_mem_access(MI, true);  | 
1106  |  | 
  | 
1107  | 0  |   printS12ImmOperand(MI, OpNo, O);  | 
1108  |  | 
  | 
1109  | 0  |   SStream_concat0(O, "("); | 
1110  | 0  |   printOperand(MI, OpNo + 1, O);  | 
1111  | 0  |   SStream_concat0(O, ")");  | 
1112  |  | 
  | 
1113  | 0  |   set_mem_access(MI, false);  | 
1114  | 0  | }  | 
1115  |  |  | 
1116  |  | static void printMemRegReg(MCInst *MI, unsigned OpNo, SStream *O)  | 
1117  | 7.94k  | { | 
1118  |  |   // When used as the base register, r0 reads constant zero rather than  | 
1119  |  |   // the value contained in the register.  For this reason, the darwin  | 
1120  |  |   // assembler requires that we print r0 as 0 (no r) when used as the base.  | 
1121  | 7.94k  |   if (MCOperand_getReg(MCInst_getOperand(MI, OpNo)) == PPC_R0)  | 
1122  | 0  |     SStream_concat0(O, "0");  | 
1123  | 7.94k  |   else  | 
1124  | 7.94k  |     printOperand(MI, OpNo, O);  | 
1125  | 7.94k  |   SStream_concat0(O, ", ");  | 
1126  |  |  | 
1127  | 7.94k  |   printOperand(MI, OpNo + 1, O);  | 
1128  | 7.94k  | }  | 
1129  |  |  | 
1130  |  | static void printTLSCall(MCInst *MI, unsigned OpNo, SStream *O)  | 
1131  | 0  | { | 
1132  | 0  |   set_mem_access(MI, true);  | 
1133  |  |   //printBranchOperand(MI, OpNo, O);  | 
1134  |  |  | 
1135  |  |   // On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must  | 
1136  |  |   // come at the _end_ of the expression.  | 
1137  |  | 
  | 
1138  | 0  |   SStream_concat0(O, "("); | 
1139  | 0  |   printOperand(MI, OpNo + 1, O);  | 
1140  | 0  |   SStream_concat0(O, ")");  | 
1141  |  | 
  | 
1142  | 0  |   set_mem_access(MI, false);  | 
1143  | 0  | }  | 
1144  |  |  | 
1145  |  | /// stripRegisterPrefix - This method strips the character prefix from a  | 
1146  |  | /// register name so that only the number is left.  Used by for linux asm.  | 
1147  |  | static char *stripRegisterPrefix(const char *RegName)  | 
1148  | 0  | { | 
1149  | 0  |   switch (RegName[0]) { | 
1150  | 0  |     case 'r':  | 
1151  | 0  |     case 'f':  | 
1152  | 0  |     case 'q': // for QPX  | 
1153  | 0  |     case 'v':  | 
1154  | 0  |       if (RegName[1] == 's')  | 
1155  | 0  |         return cs_strdup(RegName + 2);  | 
1156  |  |  | 
1157  | 0  |       return cs_strdup(RegName + 1);  | 
1158  | 0  |     case 'c':  | 
1159  | 0  |       if (RegName[1] == 'r') { | 
1160  |  |         // skip the first 2 letters "cr"  | 
1161  | 0  |         char *name = cs_strdup(RegName + 2);  | 
1162  |  |  | 
1163  |  |         // also strip the last 2 letters  | 
1164  | 0  |         if(strlen(name) > 2)  | 
1165  | 0  |           name[strlen(name) - 2] = '\0';  | 
1166  |  | 
  | 
1167  | 0  |         return name;  | 
1168  | 0  |       }  | 
1169  | 0  |   }  | 
1170  |  |  | 
1171  | 0  |   return cs_strdup(RegName);  | 
1172  | 0  | }  | 
1173  |  |  | 
1174  |  | static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
1175  | 233k  | { | 
1176  | 233k  |   MCOperand *Op = MCInst_getOperand(MI, OpNo);  | 
1177  | 233k  |   if (MCOperand_isReg(Op)) { | 
1178  | 221k  |     unsigned reg = MCOperand_getReg(Op);  | 
1179  | 221k  | #ifndef CAPSTONE_DIET  | 
1180  | 221k  |     const char *RegName = getRegisterName(reg);  | 
1181  |  |  | 
1182  |  |     // printf("reg = %u (%s)\n", reg, RegName); | 
1183  |  |  | 
1184  |  |     // convert internal register ID to public register ID  | 
1185  | 221k  |     reg = PPC_name_reg(RegName);  | 
1186  |  |  | 
1187  |  |     // The linux and AIX assembler does not take register prefixes.  | 
1188  | 221k  |     if (MI->csh->syntax == CS_OPT_SYNTAX_NOREGNAME) { | 
1189  | 0  |       char *name = stripRegisterPrefix(RegName);  | 
1190  | 0  |       SStream_concat0(O, name);  | 
1191  | 0  |       cs_mem_free(name);  | 
1192  | 0  |     } else  | 
1193  | 221k  |       SStream_concat0(O, RegName);  | 
1194  | 221k  | #endif  | 
1195  |  |  | 
1196  | 221k  |     if (MI->csh->detail) { | 
1197  | 221k  |       if (MI->csh->doing_mem) { | 
1198  | 15.7k  |         MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.base = reg;  | 
1199  | 206k  |       } else { | 
1200  | 206k  |         MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_REG;  | 
1201  | 206k  |         MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].reg = reg;  | 
1202  | 206k  |         MI->flat_insn->detail->ppc.op_count++;  | 
1203  | 206k  |       }  | 
1204  | 221k  |     }  | 
1205  |  |  | 
1206  | 221k  |     return;  | 
1207  | 221k  |   }  | 
1208  |  |  | 
1209  | 11.7k  |   if (MCOperand_isImm(Op)) { | 
1210  | 11.7k  |     int32_t imm = (int32_t)MCOperand_getImm(Op);  | 
1211  | 11.7k  |     printInt32(O, imm);  | 
1212  |  |  | 
1213  | 11.7k  |     if (MI->csh->detail) { | 
1214  | 11.7k  |       if (MI->csh->doing_mem) { | 
1215  | 0  |         MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.disp = (int32_t)imm;  | 
1216  | 11.7k  |       } else { | 
1217  | 11.7k  |         MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
1218  | 11.7k  |         MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = imm;  | 
1219  | 11.7k  |         MI->flat_insn->detail->ppc.op_count++;  | 
1220  | 11.7k  |       }  | 
1221  | 11.7k  |     }  | 
1222  | 11.7k  |   }  | 
1223  | 11.7k  | }  | 
1224  |  |  | 
1225  |  | static void op_addImm(MCInst *MI, int v)  | 
1226  | 198  | { | 
1227  | 198  |   if (MI->csh->detail) { | 
1228  | 198  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;  | 
1229  | 198  |     MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = v;  | 
1230  | 198  |     MI->flat_insn->detail->ppc.op_count++;  | 
1231  | 198  |   }  | 
1232  | 198  | }  | 
1233  |  |  | 
1234  |  | #define PRINT_ALIAS_INSTR  | 
1235  |  | #include "PPCGenRegisterName.inc"  | 
1236  |  | #include "PPCGenAsmWriter.inc"  | 
1237  |  |  | 
1238  |  | #endif  |