/src/capstonev5/arch/Sparc/SparcInstPrinter.c
Line  | Count  | Source  | 
1  |  | //===-- SparcInstPrinter.cpp - Convert Sparc 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 Sparc 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_SPARC  | 
18  |  |  | 
19  |  | #ifdef _MSC_VER  | 
20  |  | #define _CRT_SECURE_NO_WARNINGS  | 
21  |  | #endif  | 
22  |  |  | 
23  |  | #include <stdio.h>  | 
24  |  | #include <stdlib.h>  | 
25  |  | #include <string.h>  | 
26  |  | #include <limits.h>  | 
27  |  |  | 
28  |  | #include "SparcInstPrinter.h"  | 
29  |  | #include "../../MCInst.h"  | 
30  |  | #include "../../utils.h"  | 
31  |  | #include "../../SStream.h"  | 
32  |  | #include "../../MCRegisterInfo.h"  | 
33  |  | #include "../../MathExtras.h"  | 
34  |  | #include "SparcMapping.h"  | 
35  |  |  | 
36  |  | #include "Sparc.h"  | 
37  |  |  | 
38  |  | static const char *getRegisterName(unsigned RegNo);  | 
39  |  | static void printInstruction(MCInst *MI, SStream *O, const MCRegisterInfo *MRI);  | 
40  |  | static void printMemOperand(MCInst *MI, int opNum, SStream *O, const char *Modifier);  | 
41  |  | static void printOperand(MCInst *MI, int opNum, SStream *O);  | 
42  |  |  | 
43  |  | static void Sparc_add_hint(MCInst *MI, unsigned int hint)  | 
44  | 1.73k  | { | 
45  | 1.73k  |   if (MI->csh->detail) { | 
46  | 1.73k  |     MI->flat_insn->detail->sparc.hint = hint;  | 
47  | 1.73k  |   }  | 
48  | 1.73k  | }  | 
49  |  |  | 
50  |  | static void Sparc_add_reg(MCInst *MI, unsigned int reg)  | 
51  | 6.09k  | { | 
52  | 6.09k  |   if (MI->csh->detail) { | 
53  | 6.09k  |     MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_REG;  | 
54  | 6.09k  |     MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].reg = reg;  | 
55  | 6.09k  |     MI->flat_insn->detail->sparc.op_count++;  | 
56  | 6.09k  |   }  | 
57  | 6.09k  | }  | 
58  |  |  | 
59  |  | static void set_mem_access(MCInst *MI, bool status)  | 
60  | 9.96k  | { | 
61  | 9.96k  |   if (MI->csh->detail != CS_OPT_ON)  | 
62  | 0  |     return;  | 
63  |  |  | 
64  | 9.96k  |   MI->csh->doing_mem = status;  | 
65  |  |  | 
66  | 9.96k  |   if (status) { | 
67  | 4.98k  |     MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_MEM;  | 
68  | 4.98k  |     MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base = SPARC_REG_INVALID;  | 
69  | 4.98k  |     MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.disp = 0;  | 
70  | 4.98k  |   } else { | 
71  |  |     // done, create the next operand slot  | 
72  | 4.98k  |     MI->flat_insn->detail->sparc.op_count++;  | 
73  | 4.98k  |   }  | 
74  | 9.96k  | }  | 
75  |  |  | 
76  |  | void Sparc_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)  | 
77  | 83.0k  | { | 
78  | 83.0k  |   if (((cs_struct *)ud)->detail != CS_OPT_ON)  | 
79  | 0  |     return;  | 
80  |  |  | 
81  |  |   // fix up some instructions  | 
82  | 83.0k  |   if (insn->id == SPARC_INS_CASX) { | 
83  |  |     // first op is actually a memop, not regop  | 
84  | 66  |     insn->detail->sparc.operands[0].type = SPARC_OP_MEM;  | 
85  | 66  |     insn->detail->sparc.operands[0].mem.base = (uint8_t)insn->detail->sparc.operands[0].reg;  | 
86  | 66  |     insn->detail->sparc.operands[0].mem.disp = 0;  | 
87  | 66  |   }  | 
88  | 83.0k  | }  | 
89  |  |  | 
90  |  | static void printRegName(SStream *OS, unsigned RegNo)  | 
91  | 78.7k  | { | 
92  | 78.7k  |   SStream_concat0(OS, "%");  | 
93  | 78.7k  |   SStream_concat0(OS, getRegisterName(RegNo));  | 
94  | 78.7k  | }  | 
95  |  |  | 
96  |  | #define GET_INSTRINFO_ENUM  | 
97  |  | #include "SparcGenInstrInfo.inc"  | 
98  |  |  | 
99  |  | #define GET_REGINFO_ENUM  | 
100  |  | #include "SparcGenRegisterInfo.inc"  | 
101  |  |  | 
102  |  | static bool printSparcAliasInstr(MCInst *MI, SStream *O)  | 
103  | 43.9k  | { | 
104  | 43.9k  |   switch (MCInst_getOpcode(MI)) { | 
105  | 40.3k  |     default: return false;  | 
106  | 69  |     case SP_JMPLrr:  | 
107  | 1.57k  |     case SP_JMPLri:  | 
108  | 1.57k  |          if (MCInst_getNumOperands(MI) != 3)  | 
109  | 0  |            return false;  | 
110  | 1.57k  |          if (!MCOperand_isReg(MCInst_getOperand(MI, 0)))  | 
111  | 0  |            return false;  | 
112  |  |  | 
113  | 1.57k  |          switch (MCOperand_getReg(MCInst_getOperand(MI, 0))) { | 
114  | 255  |            default: return false;  | 
115  | 1.25k  |            case SP_G0: // jmp $addr | ret | retl  | 
116  | 1.25k  |                 if (MCOperand_isImm(MCInst_getOperand(MI, 2)) &&  | 
117  | 1.18k  |                   MCOperand_getImm(MCInst_getOperand(MI, 2)) == 8) { | 
118  | 697  |                   switch(MCOperand_getReg(MCInst_getOperand(MI, 1))) { | 
119  | 67  |                     default: break;  | 
120  | 67  |                     case SP_I7: SStream_concat0(O, "ret"); MCInst_setOpcodePub(MI, SPARC_INS_RET); return true;  | 
121  | 564  |                     case SP_O7: SStream_concat0(O, "retl"); MCInst_setOpcodePub(MI, SPARC_INS_RETL); return true;  | 
122  | 697  |                   }  | 
123  | 697  |                 }  | 
124  |  |  | 
125  | 625  |                 SStream_concat0(O, "jmp\t");  | 
126  | 625  |                 MCInst_setOpcodePub(MI, SPARC_INS_JMP);  | 
127  | 625  |                 printMemOperand(MI, 1, O, NULL);  | 
128  | 625  |                 return true;  | 
129  | 67  |            case SP_O7: // call $addr  | 
130  | 67  |                 SStream_concat0(O, "call ");  | 
131  | 67  |                 MCInst_setOpcodePub(MI, SPARC_INS_CALL);  | 
132  | 67  |                 printMemOperand(MI, 1, O, NULL);  | 
133  | 67  |                 return true;  | 
134  | 1.57k  |          }  | 
135  | 298  |     case SP_V9FCMPS:  | 
136  | 369  |     case SP_V9FCMPD:  | 
137  | 1.42k  |     case SP_V9FCMPQ:  | 
138  | 1.55k  |     case SP_V9FCMPES:  | 
139  | 1.62k  |     case SP_V9FCMPED:  | 
140  | 2.02k  |     case SP_V9FCMPEQ:  | 
141  | 2.02k  |          if (MI->csh->mode & CS_MODE_V9 || (MCInst_getNumOperands(MI) != 3) ||  | 
142  | 573  |              (!MCOperand_isReg(MCInst_getOperand(MI, 0))) ||  | 
143  | 573  |              (MCOperand_getReg(MCInst_getOperand(MI, 0)) != SP_FCC0))  | 
144  | 2.02k  |              return false;  | 
145  |  |          // if V8, skip printing %fcc0.  | 
146  | 0  |          switch(MCInst_getOpcode(MI)) { | 
147  | 0  |            default:  | 
148  | 0  |            case SP_V9FCMPS:  SStream_concat0(O, "fcmps\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPS); break;  | 
149  | 0  |            case SP_V9FCMPD:  SStream_concat0(O, "fcmpd\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPD); break;  | 
150  | 0  |            case SP_V9FCMPQ:  SStream_concat0(O, "fcmpq\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPQ); break;  | 
151  | 0  |            case SP_V9FCMPES: SStream_concat0(O, "fcmpes\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPES); break;  | 
152  | 0  |            case SP_V9FCMPED: SStream_concat0(O, "fcmped\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPED); break;  | 
153  | 0  |            case SP_V9FCMPEQ: SStream_concat0(O, "fcmpeq\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPEQ); break;  | 
154  | 0  |          }  | 
155  | 0  |          printOperand(MI, 1, O);  | 
156  | 0  |          SStream_concat0(O, ", ");  | 
157  | 0  |          printOperand(MI, 2, O);  | 
158  | 0  |          return true;  | 
159  | 43.9k  |   }  | 
160  | 43.9k  | }  | 
161  |  |  | 
162  |  | static void printOperand(MCInst *MI, int opNum, SStream *O)  | 
163  | 136k  | { | 
164  | 136k  |   int64_t Imm;  | 
165  | 136k  |   unsigned reg;  | 
166  | 136k  |   MCOperand *MO = MCInst_getOperand(MI, opNum);  | 
167  |  |  | 
168  | 136k  |   if (MCOperand_isReg(MO)) { | 
169  | 70.9k  |     reg = MCOperand_getReg(MO);  | 
170  | 70.9k  |     printRegName(O, reg);  | 
171  | 70.9k  |     reg = Sparc_map_register(reg);  | 
172  |  |  | 
173  | 70.9k  |     if (MI->csh->detail) { | 
174  | 70.9k  |       if (MI->csh->doing_mem) { | 
175  | 6.05k  |         if (MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base)  | 
176  | 1.07k  |           MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.index = (uint8_t)reg;  | 
177  | 4.98k  |         else  | 
178  | 4.98k  |           MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base = (uint8_t)reg;  | 
179  | 64.9k  |       } else { | 
180  | 64.9k  |         MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_REG;  | 
181  | 64.9k  |         MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].reg = reg;  | 
182  | 64.9k  |         MI->flat_insn->detail->sparc.op_count++;  | 
183  | 64.9k  |       }  | 
184  | 70.9k  |     }  | 
185  |  |  | 
186  | 70.9k  |     return;  | 
187  | 70.9k  |   }  | 
188  |  |  | 
189  | 65.6k  |   if (MCOperand_isImm(MO)) { | 
190  | 65.6k  |     Imm = (int)MCOperand_getImm(MO);  | 
191  |  |  | 
192  |  |     // Conditional branches displacements needs to be signextended to be  | 
193  |  |     // able to jump backwards.  | 
194  |  |     //  | 
195  |  |     // Displacements are measured as the number of instructions forward or  | 
196  |  |     // backward, so they need to be multiplied by 4  | 
197  | 65.6k  |     switch (MI->Opcode) { | 
198  | 12.2k  |       case SP_CALL:  | 
199  |  |         // Imm = SignExtend32(Imm, 30);  | 
200  | 12.2k  |         Imm += MI->address;  | 
201  | 12.2k  |         break;  | 
202  |  |  | 
203  |  |       // Branch on integer condition with prediction (BPcc)  | 
204  |  |       // Branch on floating point condition with prediction (FBPfcc)  | 
205  | 229  |       case SP_BPICC:  | 
206  | 601  |       case SP_BPICCA:  | 
207  | 4.59k  |       case SP_BPICCANT:  | 
208  | 7.91k  |       case SP_BPICCNT:  | 
209  | 8.71k  |       case SP_BPXCC:  | 
210  | 8.92k  |       case SP_BPXCCA:  | 
211  | 11.5k  |       case SP_BPXCCANT:  | 
212  | 14.1k  |       case SP_BPXCCNT:  | 
213  | 14.4k  |       case SP_BPFCC:  | 
214  | 15.2k  |       case SP_BPFCCA:  | 
215  | 19.0k  |       case SP_BPFCCANT:  | 
216  | 23.1k  |       case SP_BPFCCNT:  | 
217  | 23.1k  |         Imm = SignExtend32(Imm, 19);  | 
218  | 23.1k  |         Imm = MI->address + Imm * 4;  | 
219  | 23.1k  |         break;  | 
220  |  |  | 
221  |  |       // Branch on integer condition (Bicc)  | 
222  |  |       // Branch on floating point condition (FBfcc)  | 
223  | 699  |       case SP_BA:  | 
224  | 4.24k  |       case SP_BCOND:  | 
225  | 7.70k  |       case SP_BCONDA:  | 
226  | 8.23k  |       case SP_FBCOND:  | 
227  | 8.54k  |       case SP_FBCONDA:  | 
228  | 8.54k  |         Imm = SignExtend32(Imm, 22);  | 
229  | 8.54k  |         Imm = MI->address + Imm * 4;  | 
230  | 8.54k  |         break;  | 
231  |  |  | 
232  |  |       // Branch on integer register with prediction (BPr)  | 
233  | 190  |       case SP_BPGEZapn:  | 
234  | 301  |       case SP_BPGEZapt:  | 
235  | 540  |       case SP_BPGEZnapn:  | 
236  | 737  |       case SP_BPGEZnapt:  | 
237  | 804  |       case SP_BPGZapn:  | 
238  | 886  |       case SP_BPGZapt:  | 
239  | 1.08k  |       case SP_BPGZnapn:  | 
240  | 1.28k  |       case SP_BPGZnapt:  | 
241  | 1.36k  |       case SP_BPLEZapn:  | 
242  | 1.42k  |       case SP_BPLEZapt:  | 
243  | 1.62k  |       case SP_BPLEZnapn:  | 
244  | 1.83k  |       case SP_BPLEZnapt:  | 
245  | 1.89k  |       case SP_BPLZapn:  | 
246  | 1.96k  |       case SP_BPLZapt:  | 
247  | 2.03k  |       case SP_BPLZnapn:  | 
248  | 2.23k  |       case SP_BPLZnapt:  | 
249  | 2.75k  |       case SP_BPNZapn:  | 
250  | 2.84k  |       case SP_BPNZapt:  | 
251  | 3.04k  |       case SP_BPNZnapn:  | 
252  | 3.11k  |       case SP_BPNZnapt:  | 
253  | 3.33k  |       case SP_BPZapn:  | 
254  | 3.54k  |       case SP_BPZapt:  | 
255  | 3.62k  |       case SP_BPZnapn:  | 
256  | 3.82k  |       case SP_BPZnapt:  | 
257  | 3.82k  |         Imm = SignExtend32(Imm, 16);  | 
258  | 3.82k  |         Imm = MI->address + Imm * 4;  | 
259  | 3.82k  |         break;  | 
260  | 65.6k  |     }  | 
261  |  |       | 
262  | 65.6k  |     printInt64(O, Imm);  | 
263  |  |  | 
264  | 65.6k  |     if (MI->csh->detail) { | 
265  | 65.6k  |       if (MI->csh->doing_mem) { | 
266  | 3.20k  |         MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.disp = Imm;  | 
267  | 62.4k  |       } else { | 
268  | 62.4k  |         MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_IMM;  | 
269  | 62.4k  |         MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].imm = Imm;  | 
270  | 62.4k  |         MI->flat_insn->detail->sparc.op_count++;  | 
271  | 62.4k  |       }  | 
272  | 65.6k  |     }  | 
273  | 65.6k  |   }  | 
274  |  |  | 
275  | 65.6k  |   return;  | 
276  | 65.6k  | }  | 
277  |  |  | 
278  |  | static void printMemOperand(MCInst *MI, int opNum, SStream *O, const char *Modifier)  | 
279  | 4.98k  | { | 
280  | 4.98k  |   MCOperand *MO;  | 
281  |  |  | 
282  | 4.98k  |   set_mem_access(MI, true);  | 
283  | 4.98k  |   printOperand(MI, opNum, O);  | 
284  |  |  | 
285  |  |   // If this is an ADD operand, emit it like normal operands.  | 
286  | 4.98k  |   if (Modifier && !strcmp(Modifier, "arith")) { | 
287  | 0  |     SStream_concat0(O, ", ");  | 
288  | 0  |     printOperand(MI, opNum + 1, O);  | 
289  | 0  |     set_mem_access(MI, false);  | 
290  | 0  |     return;  | 
291  | 0  |   }  | 
292  |  |  | 
293  | 4.98k  |   MO = MCInst_getOperand(MI, opNum + 1);  | 
294  |  |  | 
295  | 4.98k  |   if (MCOperand_isReg(MO) && (MCOperand_getReg(MO) == SP_G0)) { | 
296  | 467  |     set_mem_access(MI, false);  | 
297  | 467  |     return;   // don't print "+%g0"  | 
298  | 467  |   }  | 
299  |  |  | 
300  | 4.51k  |   if (MCOperand_isImm(MO) && (MCOperand_getImm(MO) == 0)) { | 
301  | 235  |     set_mem_access(MI, false);  | 
302  | 235  |     return;   // don't print "+0"  | 
303  | 235  |   }  | 
304  |  |  | 
305  | 4.28k  |   SStream_concat0(O, "+");  // qq  | 
306  |  |  | 
307  | 4.28k  |   printOperand(MI, opNum + 1, O);  | 
308  | 4.28k  |   set_mem_access(MI, false);  | 
309  | 4.28k  | }  | 
310  |  |  | 
311  |  | static void printCCOperand(MCInst *MI, int opNum, SStream *O)  | 
312  | 8.63k  | { | 
313  | 8.63k  |   int CC = (int)MCOperand_getImm(MCInst_getOperand(MI, opNum)) + 256;  | 
314  |  |  | 
315  | 8.63k  |   switch (MCInst_getOpcode(MI)) { | 
316  | 4.82k  |     default: break;  | 
317  | 4.82k  |     case SP_FBCOND:  | 
318  | 839  |     case SP_FBCONDA:  | 
319  | 1.10k  |     case SP_BPFCC:  | 
320  | 1.94k  |     case SP_BPFCCA:  | 
321  | 1.94k  |     case SP_BPFCCNT:  | 
322  | 1.94k  |     case SP_BPFCCANT:  | 
323  | 2.80k  |     case SP_MOVFCCrr:  case SP_V9MOVFCCrr:  | 
324  | 3.21k  |     case SP_MOVFCCri:  case SP_V9MOVFCCri:  | 
325  | 3.53k  |     case SP_FMOVS_FCC: case SP_V9FMOVS_FCC:  | 
326  | 3.66k  |     case SP_FMOVD_FCC: case SP_V9FMOVD_FCC:  | 
327  | 3.81k  |     case SP_FMOVQ_FCC: case SP_V9FMOVQ_FCC:  | 
328  |  |          // Make sure CC is a fp conditional flag.  | 
329  | 3.81k  |          CC = (CC < 16+256) ? (CC + 16) : CC;  | 
330  | 3.81k  |          break;  | 
331  | 8.63k  |   }  | 
332  |  |  | 
333  | 8.63k  |   SStream_concat0(O, SPARCCondCodeToString((sparc_cc)CC));  | 
334  |  |  | 
335  | 8.63k  |   if (MI->csh->detail)  | 
336  | 8.63k  |     MI->flat_insn->detail->sparc.cc = (sparc_cc)CC;  | 
337  | 8.63k  | }  | 
338  |  |  | 
339  |  |  | 
340  |  | static bool printGetPCX(MCInst *MI, unsigned opNum, SStream *O)  | 
341  | 0  | { | 
342  | 0  |   return true;  | 
343  | 0  | }  | 
344  |  |  | 
345  |  |  | 
346  |  | #define PRINT_ALIAS_INSTR  | 
347  |  | #include "SparcGenAsmWriter.inc"  | 
348  |  |  | 
349  |  | void Sparc_printInst(MCInst *MI, SStream *O, void *Info)  | 
350  | 83.0k  | { | 
351  | 83.0k  |   char *mnem, *p;  | 
352  | 83.0k  |   char instr[64]; // Sparc has no instruction this long  | 
353  |  |  | 
354  | 83.0k  |   mnem = printAliasInstr(MI, O, Info);  | 
355  | 83.0k  |   if (mnem) { | 
356  |  |     // fixup instruction id due to the change in alias instruction  | 
357  | 39.1k  |     unsigned cpy_len = sizeof(instr) - 1 < strlen(mnem) ? sizeof(instr) - 1 : strlen(mnem);  | 
358  | 39.1k  |     memcpy(instr, mnem, cpy_len);  | 
359  | 39.1k  |     instr[cpy_len] = '\0';  | 
360  |  |     // does this contains hint with a coma?  | 
361  | 39.1k  |     p = strchr(instr, ',');  | 
362  | 39.1k  |     if (p)  | 
363  | 23.8k  |       *p = '\0'; // now instr only has instruction mnemonic  | 
364  | 39.1k  |     MCInst_setOpcodePub(MI, Sparc_map_insn(instr));  | 
365  | 39.1k  |     switch(MCInst_getOpcode(MI)) { | 
366  | 3.54k  |       case SP_BCOND:  | 
367  | 7.01k  |       case SP_BCONDA:  | 
368  | 11.0k  |       case SP_BPICCANT:  | 
369  | 14.3k  |       case SP_BPICCNT:  | 
370  | 16.9k  |       case SP_BPXCCANT:  | 
371  | 19.5k  |       case SP_BPXCCNT:  | 
372  | 25.8k  |       case SP_TXCCri:  | 
373  | 29.1k  |       case SP_TXCCrr:  | 
374  | 29.1k  |         if (MI->csh->detail) { | 
375  |  |           // skip 'b', 't'  | 
376  | 29.1k  |           MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 1);  | 
377  | 29.1k  |           MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem);  | 
378  | 29.1k  |         }  | 
379  | 29.1k  |         break;  | 
380  | 3.80k  |       case SP_BPFCCANT:  | 
381  | 7.82k  |       case SP_BPFCCNT:  | 
382  | 7.82k  |         if (MI->csh->detail) { | 
383  |  |           // skip 'fb'  | 
384  | 7.82k  |           MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 2);  | 
385  | 7.82k  |           MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem);  | 
386  | 7.82k  |         }  | 
387  | 7.82k  |         break;  | 
388  | 0  |       case SP_FMOVD_ICC:  | 
389  | 0  |       case SP_FMOVD_XCC:  | 
390  | 0  |       case SP_FMOVQ_ICC:  | 
391  | 0  |       case SP_FMOVQ_XCC:  | 
392  | 0  |       case SP_FMOVS_ICC:  | 
393  | 0  |       case SP_FMOVS_XCC:  | 
394  | 0  |         if (MI->csh->detail) { | 
395  |  |           // skip 'fmovd', 'fmovq', 'fmovs'  | 
396  | 0  |           MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 5);  | 
397  | 0  |           MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem);  | 
398  | 0  |         }  | 
399  | 0  |         break;  | 
400  | 0  |       case SP_MOVICCri:  | 
401  | 0  |       case SP_MOVICCrr:  | 
402  | 0  |       case SP_MOVXCCri:  | 
403  | 0  |       case SP_MOVXCCrr:  | 
404  | 0  |         if (MI->csh->detail) { | 
405  |  |           // skip 'mov'  | 
406  | 0  |           MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 3);  | 
407  | 0  |           MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem);  | 
408  | 0  |         }  | 
409  | 0  |         break;  | 
410  | 0  |       case SP_V9FMOVD_FCC:  | 
411  | 0  |       case SP_V9FMOVQ_FCC:  | 
412  | 0  |       case SP_V9FMOVS_FCC:  | 
413  | 0  |         if (MI->csh->detail) { | 
414  |  |           // skip 'fmovd', 'fmovq', 'fmovs'  | 
415  | 0  |           MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 5);  | 
416  | 0  |           MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem);  | 
417  | 0  |         }  | 
418  | 0  |         break;  | 
419  | 0  |       case SP_V9MOVFCCri:  | 
420  | 0  |       case SP_V9MOVFCCrr:  | 
421  | 0  |         if (MI->csh->detail) { | 
422  |  |           // skip 'mov'  | 
423  | 0  |           MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 3);  | 
424  | 0  |           MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem);  | 
425  | 0  |         }  | 
426  | 0  |         break;  | 
427  | 2.16k  |       default:  | 
428  | 2.16k  |         break;  | 
429  | 39.1k  |     }  | 
430  | 39.1k  |     cs_mem_free(mnem);  | 
431  | 43.9k  |   } else { | 
432  | 43.9k  |     if (!printSparcAliasInstr(MI, O))  | 
433  | 42.5k  |       printInstruction(MI, O, NULL);  | 
434  | 43.9k  |   }  | 
435  | 83.0k  | }  | 
436  |  |  | 
437  |  | void Sparc_addReg(MCInst *MI, int reg)  | 
438  | 22.1k  | { | 
439  | 22.1k  |   if (MI->csh->detail) { | 
440  | 22.1k  |     MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_REG;  | 
441  | 22.1k  |     MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].reg = reg;  | 
442  | 22.1k  |     MI->flat_insn->detail->sparc.op_count++;  | 
443  | 22.1k  |   }  | 
444  | 22.1k  | }  | 
445  |  |  | 
446  |  | #endif  |