/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.18k | { |
45 | 1.18k | if (MI->csh->detail) { |
46 | 1.18k | MI->flat_insn->detail->sparc.hint = hint; |
47 | 1.18k | } |
48 | 1.18k | } |
49 | | |
50 | | static void Sparc_add_reg(MCInst *MI, unsigned int reg) |
51 | 5.29k | { |
52 | 5.29k | if (MI->csh->detail) { |
53 | 5.29k | MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_REG; |
54 | 5.29k | MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].reg = reg; |
55 | 5.29k | MI->flat_insn->detail->sparc.op_count++; |
56 | 5.29k | } |
57 | 5.29k | } |
58 | | |
59 | | static void set_mem_access(MCInst *MI, bool status) |
60 | 14.4k | { |
61 | 14.4k | if (MI->csh->detail != CS_OPT_ON) |
62 | 0 | return; |
63 | | |
64 | 14.4k | MI->csh->doing_mem = status; |
65 | | |
66 | 14.4k | if (status) { |
67 | 7.23k | MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_MEM; |
68 | 7.23k | MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base = SPARC_REG_INVALID; |
69 | 7.23k | MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.disp = 0; |
70 | 7.23k | } else { |
71 | | // done, create the next operand slot |
72 | 7.23k | MI->flat_insn->detail->sparc.op_count++; |
73 | 7.23k | } |
74 | 14.4k | } |
75 | | |
76 | | void Sparc_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci) |
77 | 87.8k | { |
78 | 87.8k | if (((cs_struct *)ud)->detail != CS_OPT_ON) |
79 | 0 | return; |
80 | | |
81 | | // fix up some instructions |
82 | 87.8k | 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 | 87.8k | } |
89 | | |
90 | | static void printRegName(SStream *OS, unsigned RegNo) |
91 | 100k | { |
92 | 100k | SStream_concat0(OS, "%"); |
93 | 100k | SStream_concat0(OS, getRegisterName(RegNo)); |
94 | 100k | } |
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 | 45.0k | { |
104 | 45.0k | switch (MCInst_getOpcode(MI)) { |
105 | 41.8k | default: return false; |
106 | 195 | case SP_LDDri: |
107 | 261 | case SP_LDDrr: |
108 | 261 | SStream_concat0(O, "ldd\t["); |
109 | 261 | printMemOperand(MI, 1, O, NULL); |
110 | 261 | SStream_concat0(O, "], "); |
111 | 261 | printOperand(MI, 0, O); |
112 | 261 | return true; |
113 | 67 | case SP_LDSTUBri: |
114 | 105 | case SP_LDSTUBrr: |
115 | 105 | SStream_concat0(O, "ldstub\t["); |
116 | 105 | printMemOperand(MI, 1, O, NULL); |
117 | 105 | SStream_concat0(O, "], "); |
118 | 105 | printOperand(MI, 0, O); |
119 | 105 | return true; |
120 | 195 | case SP_STDri: |
121 | 261 | case SP_STDrr: |
122 | 261 | SStream_concat0(O, "std\t"); |
123 | 261 | printOperand(MI, 2, O); |
124 | 261 | SStream_concat0(O, ", ["); |
125 | 261 | printMemOperand(MI, 0, O, NULL); |
126 | 261 | SStream_concat0(O, "]"); |
127 | 261 | return true; |
128 | 360 | case SP_JMPLrr: |
129 | 1.65k | case SP_JMPLri: |
130 | 1.65k | if (MCInst_getNumOperands(MI) != 3) |
131 | 0 | return false; |
132 | 1.65k | if (!MCOperand_isReg(MCInst_getOperand(MI, 0))) |
133 | 0 | return false; |
134 | | |
135 | 1.65k | switch (MCOperand_getReg(MCInst_getOperand(MI, 0))) { |
136 | 212 | default: return false; |
137 | 1.07k | case SP_G0: // jmp $addr | ret | retl |
138 | 1.07k | if (MCOperand_isImm(MCInst_getOperand(MI, 2)) && |
139 | 1.00k | MCOperand_getImm(MCInst_getOperand(MI, 2)) == 8) { |
140 | 668 | switch(MCOperand_getReg(MCInst_getOperand(MI, 1))) { |
141 | 204 | default: break; |
142 | 249 | case SP_I7: SStream_concat0(O, "ret"); MCInst_setOpcodePub(MI, SPARC_INS_RET); return true; |
143 | 215 | case SP_O7: SStream_concat0(O, "retl"); MCInst_setOpcodePub(MI, SPARC_INS_RETL); return true; |
144 | 668 | } |
145 | 668 | } |
146 | | |
147 | 606 | SStream_concat0(O, "jmp\t"); |
148 | 606 | MCInst_setOpcodePub(MI, SPARC_INS_JMP); |
149 | 606 | printMemOperand(MI, 1, O, NULL); |
150 | 606 | return true; |
151 | 373 | case SP_O7: // call $addr |
152 | 373 | SStream_concat0(O, "call "); |
153 | 373 | MCInst_setOpcodePub(MI, SPARC_INS_CALL); |
154 | 373 | printMemOperand(MI, 1, O, NULL); |
155 | 373 | return true; |
156 | 1.65k | } |
157 | 202 | case SP_V9FCMPS: |
158 | 270 | case SP_V9FCMPD: |
159 | 476 | case SP_V9FCMPQ: |
160 | 550 | case SP_V9FCMPES: |
161 | 760 | case SP_V9FCMPED: |
162 | 984 | case SP_V9FCMPEQ: |
163 | 984 | if (MI->csh->mode & CS_MODE_V9 || (MCInst_getNumOperands(MI) != 3) || |
164 | 430 | (!MCOperand_isReg(MCInst_getOperand(MI, 0))) || |
165 | 430 | (MCOperand_getReg(MCInst_getOperand(MI, 0)) != SP_FCC0)) |
166 | 984 | return false; |
167 | | // if V8, skip printing %fcc0. |
168 | 0 | switch(MCInst_getOpcode(MI)) { |
169 | 0 | default: |
170 | 0 | case SP_V9FCMPS: SStream_concat0(O, "fcmps\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPS); break; |
171 | 0 | case SP_V9FCMPD: SStream_concat0(O, "fcmpd\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPD); break; |
172 | 0 | case SP_V9FCMPQ: SStream_concat0(O, "fcmpq\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPQ); break; |
173 | 0 | case SP_V9FCMPES: SStream_concat0(O, "fcmpes\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPES); break; |
174 | 0 | case SP_V9FCMPED: SStream_concat0(O, "fcmped\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPED); break; |
175 | 0 | case SP_V9FCMPEQ: SStream_concat0(O, "fcmpeq\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPEQ); break; |
176 | 0 | } |
177 | 0 | printOperand(MI, 1, O); |
178 | 0 | SStream_concat0(O, ", "); |
179 | 0 | printOperand(MI, 2, O); |
180 | 0 | return true; |
181 | 45.0k | } |
182 | 45.0k | } |
183 | | |
184 | | static void printOperand(MCInst *MI, int opNum, SStream *O) |
185 | 149k | { |
186 | 149k | int64_t Imm; |
187 | 149k | unsigned reg; |
188 | 149k | MCOperand *MO = MCInst_getOperand(MI, opNum); |
189 | | |
190 | 149k | if (MCOperand_isReg(MO)) { |
191 | 83.8k | reg = MCOperand_getReg(MO); |
192 | 83.8k | printRegName(O, reg); |
193 | 83.8k | reg = Sparc_map_register(reg); |
194 | | |
195 | 83.8k | if (MI->csh->detail) { |
196 | 83.8k | if (MI->csh->doing_mem) { |
197 | 8.70k | if (MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base) |
198 | 1.46k | MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.index = (uint8_t)reg; |
199 | 7.23k | else |
200 | 7.23k | MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base = (uint8_t)reg; |
201 | 75.1k | } else { |
202 | 75.1k | MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_REG; |
203 | 75.1k | MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].reg = reg; |
204 | 75.1k | MI->flat_insn->detail->sparc.op_count++; |
205 | 75.1k | } |
206 | 83.8k | } |
207 | | |
208 | 83.8k | return; |
209 | 83.8k | } |
210 | | |
211 | 65.5k | if (MCOperand_isImm(MO)) { |
212 | 65.3k | Imm = (int)MCOperand_getImm(MO); |
213 | | |
214 | | // Conditional branches displacements needs to be signextended to be |
215 | | // able to jump backwards. |
216 | | // |
217 | | // Displacements are measured as the number of instructions forward or |
218 | | // backward, so they need to be multiplied by 4 |
219 | 65.3k | switch (MI->Opcode) { |
220 | 7.13k | case SP_CALL: |
221 | | // Imm = SignExtend32(Imm, 30); |
222 | 7.13k | Imm += MI->address; |
223 | 7.13k | break; |
224 | | |
225 | | // Branch on integer condition with prediction (BPcc) |
226 | | // Branch on floating point condition with prediction (FBPfcc) |
227 | 268 | case SP_BPICC: |
228 | 487 | case SP_BPICCA: |
229 | 4.21k | case SP_BPICCANT: |
230 | 7.82k | case SP_BPICCNT: |
231 | 8.34k | case SP_BPXCC: |
232 | 8.57k | case SP_BPXCCA: |
233 | 11.8k | case SP_BPXCCANT: |
234 | 16.1k | case SP_BPXCCNT: |
235 | 16.4k | case SP_BPFCC: |
236 | 16.6k | case SP_BPFCCA: |
237 | 20.2k | case SP_BPFCCANT: |
238 | 23.8k | case SP_BPFCCNT: |
239 | 23.8k | Imm = SignExtend32(Imm, 19); |
240 | 23.8k | Imm = MI->address + Imm * 4; |
241 | 23.8k | break; |
242 | | |
243 | | // Branch on integer condition (Bicc) |
244 | | // Branch on floating point condition (FBfcc) |
245 | 415 | case SP_BA: |
246 | 4.48k | case SP_BCOND: |
247 | 8.33k | case SP_BCONDA: |
248 | 8.87k | case SP_FBCOND: |
249 | 9.36k | case SP_FBCONDA: |
250 | 9.36k | Imm = SignExtend32(Imm, 22); |
251 | 9.36k | Imm = MI->address + Imm * 4; |
252 | 9.36k | break; |
253 | | |
254 | | // Branch on integer register with prediction (BPr) |
255 | 147 | case SP_BPGEZapn: |
256 | 346 | case SP_BPGEZapt: |
257 | 544 | case SP_BPGEZnapn: |
258 | 746 | case SP_BPGEZnapt: |
259 | 953 | case SP_BPGZapn: |
260 | 1.15k | case SP_BPGZapt: |
261 | 1.49k | case SP_BPGZnapn: |
262 | 1.69k | case SP_BPGZnapt: |
263 | 1.76k | case SP_BPLEZapn: |
264 | 1.96k | case SP_BPLEZapt: |
265 | 2.19k | case SP_BPLEZnapn: |
266 | 2.67k | case SP_BPLEZnapt: |
267 | 3.09k | case SP_BPLZapn: |
268 | 3.29k | case SP_BPLZapt: |
269 | 3.57k | case SP_BPLZnapn: |
270 | 3.77k | case SP_BPLZnapt: |
271 | 4.33k | case SP_BPNZapn: |
272 | 4.53k | case SP_BPNZapt: |
273 | 4.75k | case SP_BPNZnapn: |
274 | 4.83k | case SP_BPNZnapt: |
275 | 5.11k | case SP_BPZapn: |
276 | 5.31k | case SP_BPZapt: |
277 | 5.74k | case SP_BPZnapn: |
278 | 5.81k | case SP_BPZnapt: |
279 | 5.81k | Imm = SignExtend32(Imm, 16); |
280 | 5.81k | Imm = MI->address + Imm * 4; |
281 | 5.81k | break; |
282 | 65.3k | } |
283 | | |
284 | 65.3k | printInt64(O, Imm); |
285 | | |
286 | 65.3k | if (MI->csh->detail) { |
287 | 65.3k | if (MI->csh->doing_mem) { |
288 | 4.12k | MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.disp = Imm; |
289 | 61.2k | } else { |
290 | 61.2k | MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_IMM; |
291 | 61.2k | MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].imm = Imm; |
292 | 61.2k | MI->flat_insn->detail->sparc.op_count++; |
293 | 61.2k | } |
294 | 65.3k | } |
295 | 65.3k | } |
296 | | |
297 | 65.5k | return; |
298 | 65.5k | } |
299 | | |
300 | | static void printMemOperand(MCInst *MI, int opNum, SStream *O, const char *Modifier) |
301 | 7.23k | { |
302 | 7.23k | MCOperand *MO; |
303 | | |
304 | 7.23k | set_mem_access(MI, true); |
305 | 7.23k | printOperand(MI, opNum, O); |
306 | | |
307 | | // If this is an ADD operand, emit it like normal operands. |
308 | 7.23k | if (Modifier && !strcmp(Modifier, "arith")) { |
309 | 0 | SStream_concat0(O, ", "); |
310 | 0 | printOperand(MI, opNum + 1, O); |
311 | 0 | set_mem_access(MI, false); |
312 | 0 | return; |
313 | 0 | } |
314 | | |
315 | 7.23k | MO = MCInst_getOperand(MI, opNum + 1); |
316 | | |
317 | 7.23k | if (MCOperand_isReg(MO) && (MCOperand_getReg(MO) == SP_G0)) { |
318 | 1.33k | set_mem_access(MI, false); |
319 | 1.33k | return; // don't print "+%g0" |
320 | 1.33k | } |
321 | | |
322 | 5.90k | if (MCOperand_isImm(MO) && (MCOperand_getImm(MO) == 0)) { |
323 | 316 | set_mem_access(MI, false); |
324 | 316 | return; // don't print "+0" |
325 | 316 | } |
326 | | |
327 | 5.59k | SStream_concat0(O, "+"); // qq |
328 | | |
329 | 5.59k | printOperand(MI, opNum + 1, O); |
330 | 5.59k | set_mem_access(MI, false); |
331 | 5.59k | } |
332 | | |
333 | | static void printCCOperand(MCInst *MI, int opNum, SStream *O) |
334 | 8.00k | { |
335 | 8.00k | int CC = (int)MCOperand_getImm(MCInst_getOperand(MI, opNum)) + 256; |
336 | | |
337 | 8.00k | switch (MCInst_getOpcode(MI)) { |
338 | 4.11k | default: break; |
339 | 4.11k | case SP_FBCOND: |
340 | 1.02k | case SP_FBCONDA: |
341 | 1.32k | case SP_BPFCC: |
342 | 1.57k | case SP_BPFCCA: |
343 | 1.57k | case SP_BPFCCNT: |
344 | 1.57k | case SP_BPFCCANT: |
345 | 2.17k | case SP_MOVFCCrr: case SP_V9MOVFCCrr: |
346 | 2.68k | case SP_MOVFCCri: case SP_V9MOVFCCri: |
347 | 3.02k | case SP_FMOVS_FCC: case SP_V9FMOVS_FCC: |
348 | 3.63k | case SP_FMOVD_FCC: case SP_V9FMOVD_FCC: |
349 | 3.89k | case SP_FMOVQ_FCC: case SP_V9FMOVQ_FCC: |
350 | | // Make sure CC is a fp conditional flag. |
351 | 3.89k | CC = (CC < 16+256) ? (CC + 16) : CC; |
352 | 3.89k | break; |
353 | 8.00k | } |
354 | | |
355 | 8.00k | SStream_concat0(O, SPARCCondCodeToString((sparc_cc)CC)); |
356 | | |
357 | 8.00k | if (MI->csh->detail) |
358 | 8.00k | MI->flat_insn->detail->sparc.cc = (sparc_cc)CC; |
359 | 8.00k | } |
360 | | |
361 | | |
362 | | static bool printGetPCX(MCInst *MI, unsigned opNum, SStream *O) |
363 | 0 | { |
364 | 0 | return true; |
365 | 0 | } |
366 | | |
367 | | |
368 | | #define PRINT_ALIAS_INSTR |
369 | | #include "SparcGenAsmWriter.inc" |
370 | | |
371 | | void Sparc_printInst(MCInst *MI, SStream *O, void *Info) |
372 | 87.8k | { |
373 | 87.8k | char *mnem, *p; |
374 | 87.8k | char instr[64]; // Sparc has no instruction this long |
375 | | |
376 | 87.8k | mnem = printAliasInstr(MI, O, Info); |
377 | 87.8k | if (mnem) { |
378 | | // fixup instruction id due to the change in alias instruction |
379 | 42.7k | unsigned cpy_len = sizeof(instr) - 1 < strlen(mnem) ? sizeof(instr) - 1 : strlen(mnem); |
380 | 42.7k | memcpy(instr, mnem, cpy_len); |
381 | 42.7k | instr[cpy_len] = '\0'; |
382 | | // does this contains hint with a coma? |
383 | 42.7k | p = strchr(instr, ','); |
384 | 42.7k | if (p) |
385 | 25.9k | *p = '\0'; // now instr only has instruction mnemonic |
386 | 42.7k | MCInst_setOpcodePub(MI, Sparc_map_insn(instr)); |
387 | 42.7k | switch(MCInst_getOpcode(MI)) { |
388 | 4.06k | case SP_BCOND: |
389 | 7.92k | case SP_BCONDA: |
390 | 11.6k | case SP_BPICCANT: |
391 | 15.2k | case SP_BPICCNT: |
392 | 18.4k | case SP_BPXCCANT: |
393 | 22.8k | case SP_BPXCCNT: |
394 | 28.5k | case SP_TXCCri: |
395 | 32.9k | case SP_TXCCrr: |
396 | 32.9k | if (MI->csh->detail) { |
397 | | // skip 'b', 't' |
398 | 32.9k | MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 1); |
399 | 32.9k | MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); |
400 | 32.9k | } |
401 | 32.9k | break; |
402 | 3.56k | case SP_BPFCCANT: |
403 | 7.17k | case SP_BPFCCNT: |
404 | 7.17k | if (MI->csh->detail) { |
405 | | // skip 'fb' |
406 | 7.17k | MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 2); |
407 | 7.17k | MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); |
408 | 7.17k | } |
409 | 7.17k | break; |
410 | 0 | case SP_FMOVD_ICC: |
411 | 0 | case SP_FMOVD_XCC: |
412 | 0 | case SP_FMOVQ_ICC: |
413 | 0 | case SP_FMOVQ_XCC: |
414 | 0 | case SP_FMOVS_ICC: |
415 | 0 | case SP_FMOVS_XCC: |
416 | 0 | if (MI->csh->detail) { |
417 | | // skip 'fmovd', 'fmovq', 'fmovs' |
418 | 0 | MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 5); |
419 | 0 | MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); |
420 | 0 | } |
421 | 0 | break; |
422 | 0 | case SP_MOVICCri: |
423 | 0 | case SP_MOVICCrr: |
424 | 0 | case SP_MOVXCCri: |
425 | 0 | case SP_MOVXCCrr: |
426 | 0 | if (MI->csh->detail) { |
427 | | // skip 'mov' |
428 | 0 | MI->flat_insn->detail->sparc.cc = Sparc_map_ICC(instr + 3); |
429 | 0 | MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); |
430 | 0 | } |
431 | 0 | break; |
432 | 0 | case SP_V9FMOVD_FCC: |
433 | 0 | case SP_V9FMOVQ_FCC: |
434 | 0 | case SP_V9FMOVS_FCC: |
435 | 0 | if (MI->csh->detail) { |
436 | | // skip 'fmovd', 'fmovq', 'fmovs' |
437 | 0 | MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 5); |
438 | 0 | MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); |
439 | 0 | } |
440 | 0 | break; |
441 | 0 | case SP_V9MOVFCCri: |
442 | 0 | case SP_V9MOVFCCrr: |
443 | 0 | if (MI->csh->detail) { |
444 | | // skip 'mov' |
445 | 0 | MI->flat_insn->detail->sparc.cc = Sparc_map_FCC(instr + 3); |
446 | 0 | MI->flat_insn->detail->sparc.hint = Sparc_map_hint(mnem); |
447 | 0 | } |
448 | 0 | break; |
449 | 2.64k | default: |
450 | 2.64k | break; |
451 | 42.7k | } |
452 | 42.7k | cs_mem_free(mnem); |
453 | 45.0k | } else { |
454 | 45.0k | if (!printSparcAliasInstr(MI, O)) |
455 | 43.0k | printInstruction(MI, O, NULL); |
456 | 45.0k | } |
457 | 87.8k | } |
458 | | |
459 | | void Sparc_addReg(MCInst *MI, int reg) |
460 | 25.0k | { |
461 | 25.0k | if (MI->csh->detail) { |
462 | 25.0k | MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_REG; |
463 | 25.0k | MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].reg = reg; |
464 | 25.0k | MI->flat_insn->detail->sparc.op_count++; |
465 | 25.0k | } |
466 | 25.0k | } |
467 | | |
468 | | #endif |