/src/capstonenext/arch/Mips/MipsInstPrinter.c
Line  | Count  | Source  | 
1  |  | /* Capstone Disassembly Engine, http://www.capstone-engine.org */  | 
2  |  | /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */  | 
3  |  | /*    Rot127 <unisono@quyllur.org> 2022-2023 */  | 
4  |  | /* Automatically translated source file from LLVM. */  | 
5  |  |  | 
6  |  | /* LLVM-commit: <commit> */  | 
7  |  | /* LLVM-tag: <tag> */  | 
8  |  |  | 
9  |  | /* Only small edits allowed. */  | 
10  |  | /* For multiple similar edits, please create a Patch for the translator. */  | 
11  |  |  | 
12  |  | /* Capstone's C++ file translator: */  | 
13  |  | /* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */  | 
14  |  |  | 
15  |  | //===-- MipsInstPrinter.cpp - Convert Mips MCInst to assembly syntax ------===//  | 
16  |  | //  | 
17  |  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.  | 
18  |  | // See https://llvm.org/LICENSE.txt for license information.  | 
19  |  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception  | 
20  |  | //  | 
21  |  | //===----------------------------------------------------------------------===//  | 
22  |  | //  | 
23  |  | // This class prints an Mips MCInst to a .s file.  | 
24  |  | //  | 
25  |  | //===----------------------------------------------------------------------===//  | 
26  |  |  | 
27  |  | #include <stdio.h>  | 
28  |  | #include <string.h>  | 
29  |  | #include <stdlib.h>  | 
30  |  | #include <capstone/platform.h>  | 
31  |  |  | 
32  |  | #include "MipsMapping.h"  | 
33  |  | #include "MipsInstPrinter.h"  | 
34  |  |  | 
35  |  | #define GET_SUBTARGETINFO_ENUM  | 
36  |  | #include "MipsGenSubtargetInfo.inc"  | 
37  |  |  | 
38  |  | #define GET_INSTRINFO_ENUM  | 
39  |  | #include "MipsGenInstrInfo.inc"  | 
40  |  |  | 
41  |  | #define GET_REGINFO_ENUM  | 
42  |  | #include "MipsGenRegisterInfo.inc"  | 
43  |  |  | 
44  | 18.6k  | #define CONCAT(a, b) CONCAT_(a, b)  | 
45  | 18.6k  | #define CONCAT_(a, b) a##_##b  | 
46  |  |  | 
47  |  | #define DEBUG_TYPE "asm-printer"  | 
48  |  |  | 
49  |  | #define PRINT_ALIAS_INSTR  | 
50  |  | #include "MipsGenAsmWriter.inc"  | 
51  |  |  | 
52  |  | static bool isReg(const MCInst *MI, unsigned OpNo, unsigned R)  | 
53  | 5.84k  | { | 
54  | 5.84k  |   return MCOperand_getReg(MCInst_getOperand((MCInst *)MI, (OpNo))) == R;  | 
55  | 5.84k  | }  | 
56  |  |  | 
57  |  | static const char *MipsFCCToString(Mips_CondCode CC)  | 
58  | 0  | { | 
59  | 0  |   switch (CC) { | 
60  | 0  |   case Mips_FCOND_F:  | 
61  | 0  |   case Mips_FCOND_T:  | 
62  | 0  |     return "f";  | 
63  | 0  |   case Mips_FCOND_UN:  | 
64  | 0  |   case Mips_FCOND_OR:  | 
65  | 0  |     return "un";  | 
66  | 0  |   case Mips_FCOND_OEQ:  | 
67  | 0  |   case Mips_FCOND_UNE:  | 
68  | 0  |     return "eq";  | 
69  | 0  |   case Mips_FCOND_UEQ:  | 
70  | 0  |   case Mips_FCOND_ONE:  | 
71  | 0  |     return "ueq";  | 
72  | 0  |   case Mips_FCOND_OLT:  | 
73  | 0  |   case Mips_FCOND_UGE:  | 
74  | 0  |     return "olt";  | 
75  | 0  |   case Mips_FCOND_ULT:  | 
76  | 0  |   case Mips_FCOND_OGE:  | 
77  | 0  |     return "ult";  | 
78  | 0  |   case Mips_FCOND_OLE:  | 
79  | 0  |   case Mips_FCOND_UGT:  | 
80  | 0  |     return "ole";  | 
81  | 0  |   case Mips_FCOND_ULE:  | 
82  | 0  |   case Mips_FCOND_OGT:  | 
83  | 0  |     return "ule";  | 
84  | 0  |   case Mips_FCOND_SF:  | 
85  | 0  |   case Mips_FCOND_ST:  | 
86  | 0  |     return "sf";  | 
87  | 0  |   case Mips_FCOND_NGLE:  | 
88  | 0  |   case Mips_FCOND_GLE:  | 
89  | 0  |     return "ngle";  | 
90  | 0  |   case Mips_FCOND_SEQ:  | 
91  | 0  |   case Mips_FCOND_SNE:  | 
92  | 0  |     return "seq";  | 
93  | 0  |   case Mips_FCOND_NGL:  | 
94  | 0  |   case Mips_FCOND_GL:  | 
95  | 0  |     return "ngl";  | 
96  | 0  |   case Mips_FCOND_LT:  | 
97  | 0  |   case Mips_FCOND_NLT:  | 
98  | 0  |     return "lt";  | 
99  | 0  |   case Mips_FCOND_NGE:  | 
100  | 0  |   case Mips_FCOND_GE:  | 
101  | 0  |     return "nge";  | 
102  | 0  |   case Mips_FCOND_LE:  | 
103  | 0  |   case Mips_FCOND_NLE:  | 
104  | 0  |     return "le";  | 
105  | 0  |   case Mips_FCOND_NGT:  | 
106  | 0  |   case Mips_FCOND_GT:  | 
107  | 0  |     return "ngt";  | 
108  | 0  |   }  | 
109  | 0  |   CS_ASSERT_RET_VAL(0 && "Impossible condition code!", NULL);  | 
110  | 0  |   return "";  | 
111  | 0  | }  | 
112  |  |  | 
113  |  | const char *Mips_LLVM_getRegisterName(unsigned RegNo, bool noRegName);  | 
114  |  |  | 
115  |  | static void printRegName(MCInst *MI, SStream *OS, MCRegister Reg)  | 
116  | 190k  | { | 
117  | 190k  |   int syntax_opt = MI->csh->syntax;  | 
118  | 190k  |   if (!(syntax_opt & CS_OPT_SYNTAX_NO_DOLLAR)) { | 
119  | 190k  |     SStream_concat1(OS, '$');  | 
120  | 190k  |   }  | 
121  | 190k  |   SStream_concat0(OS, Mips_LLVM_getRegisterName(  | 
122  | 190k  |             Reg, syntax_opt & CS_OPT_SYNTAX_NOREGNAME));  | 
123  | 190k  | }  | 
124  |  |  | 
125  |  | static void patch_cs_printer(MCInst *MI, SStream *O)  | 
126  | 103k  | { | 
127  |  |   // replace '# 16 bit inst' to empty.  | 
128  | 103k  |   SStream_replc(O, '#', 0);  | 
129  | 103k  |   SStream_trimls(O);  | 
130  |  |  | 
131  | 103k  |   if (MI->csh->syntax & CS_OPT_SYNTAX_NO_DOLLAR) { | 
132  | 0  |     char *dollar = strchr(O->buffer, '$');  | 
133  | 0  |     if (!dollar) { | 
134  | 0  |       return;  | 
135  | 0  |     }  | 
136  | 0  |     size_t dollar_len = strlen(dollar + 1);  | 
137  |  |     // to include `\0`  | 
138  | 0  |     memmove(dollar, dollar + 1, dollar_len + 1);  | 
139  | 0  |   }  | 
140  | 103k  | }  | 
141  |  |  | 
142  |  | static void patch_cs_detail_operand_reg(cs_mips_op *op, unsigned reg,  | 
143  |  |           unsigned access)  | 
144  | 915  | { | 
145  | 915  |   op->type = MIPS_OP_REG;  | 
146  | 915  |   op->reg = reg;  | 
147  | 915  |   op->is_reglist = false;  | 
148  | 915  |   op->access = access;  | 
149  | 915  | }  | 
150  |  |  | 
151  |  | static void patch_cs_details(MCInst *MI)  | 
152  | 103k  | { | 
153  | 103k  |   if (!detail_is_set(MI))  | 
154  | 0  |     return;  | 
155  |  |  | 
156  | 103k  |   cs_mips_op *op0 = NULL, *op1 = NULL, *op2 = NULL;  | 
157  | 103k  |   unsigned opcode = MCInst_getOpcode(MI);  | 
158  | 103k  |   unsigned n_ops = MCInst_getNumOperands(MI);  | 
159  |  |  | 
160  | 103k  |   switch (opcode) { | 
161  |  |   /* mips r2 to r5 only 64bit */  | 
162  | 66  |   case Mips_DSDIV: /// ddiv $$zero, $rs, $rt  | 
163  |  |     /* fall-thru */  | 
164  | 133  |   case Mips_DUDIV: /// ddivu $$zero, $rs, $rt  | 
165  | 133  |     if (n_ops != 2) { | 
166  | 0  |       return;  | 
167  | 0  |     }  | 
168  | 133  |     Mips_inc_op_count(MI);  | 
169  | 133  |     op0 = Mips_get_detail_op(MI, -3);  | 
170  | 133  |     op1 = Mips_get_detail_op(MI, -2);  | 
171  | 133  |     op2 = Mips_get_detail_op(MI, -1);  | 
172  |  |     // move all details by one and add $zero reg  | 
173  | 133  |     *op2 = *op1;  | 
174  | 133  |     *op1 = *op0;  | 
175  | 133  |     patch_cs_detail_operand_reg(op0, MIPS_REG_ZERO_64, CS_AC_WRITE);  | 
176  | 133  |     return;  | 
177  |  |  | 
178  |  |   /* mips r2 to r5 only */  | 
179  | 196  |   case Mips_SDIV: /// div $$zero, $rs, $rt  | 
180  |  |     /* fall-thru */  | 
181  | 393  |   case Mips_UDIV: /// divu $$zero, $rs, $rt  | 
182  |  |     /* fall-thru */  | 
183  |  |   /* microMIPS only */  | 
184  | 588  |   case Mips_SDIV_MM: /// div $$zero, $rs, $rt  | 
185  |  |     /* fall-thru */  | 
186  | 782  |   case Mips_UDIV_MM: /// divu $$zero, $rs, $rt  | 
187  |  |     /* fall-thru */  | 
188  |  |  | 
189  |  |   /* MIPS16 only */  | 
190  | 782  |   case Mips_DivRxRy16: /// div $$zero, $rx, $ry  | 
191  |  |     /* fall-thru */  | 
192  | 782  |   case Mips_DivuRxRy16: /// divu $$zero, $rx, $ry  | 
193  | 782  |     if (n_ops != 2) { | 
194  | 0  |       return;  | 
195  | 0  |     }  | 
196  | 782  |     Mips_inc_op_count(MI);  | 
197  | 782  |     op0 = Mips_get_detail_op(MI, -3);  | 
198  | 782  |     op1 = Mips_get_detail_op(MI, -2);  | 
199  | 782  |     op2 = Mips_get_detail_op(MI, -1);  | 
200  |  |     // move all details by one and add $zero reg  | 
201  | 782  |     *op2 = *op1;  | 
202  | 782  |     *op1 = *op0;  | 
203  | 782  |     patch_cs_detail_operand_reg(op0, MIPS_REG_ZERO, CS_AC_WRITE);  | 
204  | 782  |     return;  | 
205  | 0  |   case Mips_AddiuSpImm16: /// addiu $$sp, imm8  | 
206  |  |     /* fall-thru */  | 
207  | 0  |   case Mips_AddiuSpImmX16: /// addiu $$sp, imm8  | 
208  | 0  |     if (n_ops != 1) { | 
209  | 0  |       return;  | 
210  | 0  |     }  | 
211  | 0  |     Mips_inc_op_count(MI);  | 
212  | 0  |     op0 = Mips_get_detail_op(MI, -2);  | 
213  | 0  |     op1 = Mips_get_detail_op(MI, -1);  | 
214  |  |     // move all details by one and add $sp reg  | 
215  | 0  |     *op1 = *op0;  | 
216  | 0  |     patch_cs_detail_operand_reg(op0, MIPS_REG_SP, CS_AC_READ_WRITE);  | 
217  | 0  |     return;  | 
218  | 0  |   case Mips_JrcRa16: /// jrc $ra  | 
219  |  |     /* fall-thru */  | 
220  | 0  |   case Mips_JrRa16: /// jr $ra  | 
221  | 0  |     if (n_ops > 0) { | 
222  | 0  |       return;  | 
223  | 0  |     }  | 
224  | 0  |     Mips_inc_op_count(MI);  | 
225  | 0  |     op0 = Mips_get_detail_op(MI, -1);  | 
226  | 0  |     patch_cs_detail_operand_reg(op0, MIPS_REG_RA, CS_AC_READ);  | 
227  | 0  |     return;  | 
228  | 102k  |   default:  | 
229  | 102k  |     return;  | 
230  | 103k  |   }  | 
231  | 103k  | }  | 
232  |  |  | 
233  |  | void Mips_LLVM_printInst(MCInst *MI, uint64_t Address, SStream *O)  | 
234  | 103k  | { | 
235  | 103k  |   bool useAliasDetails = map_use_alias_details(MI);  | 
236  | 103k  |   if (!useAliasDetails) { | 
237  | 0  |     SStream_Close(O);  | 
238  | 0  |     printInstruction(MI, Address, O);  | 
239  | 0  |     SStream_Open(O);  | 
240  | 0  |     map_set_fill_detail_ops(MI, false);  | 
241  | 0  |   }  | 
242  |  |  | 
243  | 103k  |   if (printAliasInstr(MI, Address, O) || printAlias4(MI, Address, O)) { | 
244  | 5.83k  |     MCInst_setIsAlias(MI, true);  | 
245  | 97.1k  |   } else { | 
246  | 97.1k  |     printInstruction(MI, Address, O);  | 
247  | 97.1k  |   }  | 
248  |  |  | 
249  | 103k  |   patch_cs_printer(MI, O);  | 
250  | 103k  |   patch_cs_details(MI);  | 
251  |  |  | 
252  | 103k  |   if (!useAliasDetails) { | 
253  | 0  |     map_set_fill_detail_ops(MI, true);  | 
254  | 0  |   }  | 
255  | 103k  | }  | 
256  |  |  | 
257  |  | void printOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
258  | 220k  | { | 
259  | 220k  |   switch (MCInst_getOpcode(MI)) { | 
260  | 220k  |   default:  | 
261  | 220k  |     break;  | 
262  | 220k  |   case Mips_AND16_NM:  | 
263  | 0  |   case Mips_XOR16_NM:  | 
264  | 0  |   case Mips_OR16_NM:  | 
265  | 0  |     if (MCInst_getNumOperands(MI) == 2 && OpNo == 2)  | 
266  | 0  |       OpNo = 0; // rt, rs -> rt, rs, rt  | 
267  | 0  |     break;  | 
268  | 0  |   case Mips_ADDu4x4_NM:  | 
269  | 0  |   case Mips_MUL4x4_NM:  | 
270  | 0  |     if (MCInst_getNumOperands(MI) == 2 && OpNo > 0)  | 
271  | 0  |       OpNo = OpNo - 1; // rt, rs -> rt, rt, rs  | 
272  | 0  |     break;  | 
273  | 220k  |   }  | 
274  |  |  | 
275  | 220k  |   MCOperand *Op = MCInst_getOperand(MI, (OpNo));  | 
276  | 220k  |   if (MCOperand_isReg(Op)) { | 
277  | 183k  |     add_cs_detail(MI, Mips_OP_GROUP_Operand, OpNo);  | 
278  | 183k  |     printRegName(MI, O, MCOperand_getReg(Op));  | 
279  | 183k  |     return;  | 
280  | 183k  |   }  | 
281  |  |  | 
282  | 37.1k  |   if (MCOperand_isImm(Op)) { | 
283  | 37.1k  |     switch (MCInst_getOpcode(MI)) { | 
284  | 0  |     case Mips_LI48_NM:  | 
285  | 0  |     case Mips_ANDI16_NM:  | 
286  | 0  |     case Mips_ANDI_NM:  | 
287  | 0  |     case Mips_ORI_NM:  | 
288  | 0  |     case Mips_XORI_NM:  | 
289  | 0  |     case Mips_TEQ_NM:  | 
290  | 0  |     case Mips_TNE_NM:  | 
291  | 0  |     case Mips_SIGRIE_NM:  | 
292  | 0  |     case Mips_SDBBP_NM:  | 
293  | 0  |     case Mips_SDBBP16_NM:  | 
294  | 0  |     case Mips_BREAK_NM:  | 
295  | 0  |     case Mips_BREAK16_NM:  | 
296  | 0  |     case Mips_SYSCALL_NM:  | 
297  | 0  |     case Mips_SYSCALL16_NM:  | 
298  | 0  |     case Mips_WAIT_NM:  | 
299  | 0  |       CONCAT(printUImm, CONCAT(32, 0))  | 
300  | 0  |       (MI, OpNo, O);  | 
301  | 0  |       break;  | 
302  | 37.1k  |     default:  | 
303  | 37.1k  |       add_cs_detail(MI, Mips_OP_GROUP_Operand, OpNo);  | 
304  | 37.1k  |       printInt64(O, MCOperand_getImm(Op));  | 
305  | 37.1k  |       break;  | 
306  | 37.1k  |     }  | 
307  | 37.1k  |     return;  | 
308  | 37.1k  |   }  | 
309  | 37.1k  | }  | 
310  |  |  | 
311  |  | static void printJumpOperand(MCInst *MI, unsigned OpNo, SStream *O)  | 
312  | 1.73k  | { | 
313  | 1.73k  |   add_cs_detail(MI, Mips_OP_GROUP_JumpOperand, OpNo);  | 
314  | 1.73k  |   MCOperand *Op = MCInst_getOperand(MI, (OpNo));  | 
315  | 1.73k  |   if (MCOperand_isReg(Op))  | 
316  | 0  |     return printRegName(MI, O, MCOperand_getReg(Op));  | 
317  |  |  | 
318  |  |   // only the upper bits are needed.  | 
319  | 1.73k  |   uint64_t Base = MI->address & ~0x0fffffffull;  | 
320  | 1.73k  |   uint64_t Target = MCOperand_getImm(Op);  | 
321  | 1.73k  |   printInt64(O, Base | Target);  | 
322  | 1.73k  | }  | 
323  |  |  | 
324  |  | static void printBranchOperand(MCInst *MI, uint64_t Address, unsigned OpNo,  | 
325  |  |              SStream *O)  | 
326  | 19.4k  | { | 
327  | 19.4k  |   add_cs_detail(MI, Mips_OP_GROUP_BranchOperand, OpNo);  | 
328  | 19.4k  |   MCOperand *Op = MCInst_getOperand(MI, (OpNo));  | 
329  | 19.4k  |   if (MCOperand_isReg(Op))  | 
330  | 739  |     return printRegName(MI, O, MCOperand_getReg(Op));  | 
331  |  |  | 
332  | 18.6k  |   uint64_t Target = Address + MCOperand_getImm(Op);  | 
333  | 18.6k  |   printInt64(O, Target);  | 
334  | 18.6k  | }  | 
335  |  |  | 
336  |  | #define DEFINE_printUImm(Bits) \  | 
337  |  |   static void CONCAT(printUImm, CONCAT(Bits, 0))(MCInst * MI, int opNum, \  | 
338  |  |                    SStream *O) \  | 
339  | 18.0k  |   { \ | 
340  | 18.0k  |     add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), \  | 
341  | 18.0k  |             opNum); \  | 
342  | 18.0k  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  | 
343  | 18.0k  |     if (MCOperand_isImm(MO)) { \ | 
344  | 18.0k  |       uint64_t Imm = MCOperand_getImm(MO); \  | 
345  | 18.0k  |       Imm &= (((uint64_t)1) << Bits) - 1; \  | 
346  | 18.0k  |       printUInt64(O, Imm); \  | 
347  | 18.0k  |       return; \  | 
348  | 18.0k  |     } \  | 
349  | 18.0k  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  | 
350  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  | 
351  | 0  |   } MipsInstPrinter.c:printUImm_10_0 Line  | Count  | Source  |  339  | 1.28k  |   { \ |  340  | 1.28k  |     add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), \  |  341  | 1.28k  |             opNum); \  |  342  | 1.28k  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  |  343  | 1.28k  |     if (MCOperand_isImm(MO)) { \ |  344  | 1.28k  |       uint64_t Imm = MCOperand_getImm(MO); \  |  345  | 1.28k  |       Imm &= (((uint64_t)1) << Bits) - 1; \  |  346  | 1.28k  |       printUInt64(O, Imm); \  |  347  | 1.28k  |       return; \  |  348  | 1.28k  |     } \  |  349  | 1.28k  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  |  350  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  |  351  | 0  |   }  |  
 MipsInstPrinter.c:printUImm_4_0 Line  | Count  | Source  |  339  | 2.15k  |   { \ |  340  | 2.15k  |     add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), \  |  341  | 2.15k  |             opNum); \  |  342  | 2.15k  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  |  343  | 2.15k  |     if (MCOperand_isImm(MO)) { \ |  344  | 2.15k  |       uint64_t Imm = MCOperand_getImm(MO); \  |  345  | 2.15k  |       Imm &= (((uint64_t)1) << Bits) - 1; \  |  346  | 2.15k  |       printUInt64(O, Imm); \  |  347  | 2.15k  |       return; \  |  348  | 2.15k  |     } \  |  349  | 2.15k  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  |  350  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  |  351  | 0  |   }  |  
 MipsInstPrinter.c:printUImm_5_0 Line  | Count  | Source  |  339  | 3.82k  |   { \ |  340  | 3.82k  |     add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), \  |  341  | 3.82k  |             opNum); \  |  342  | 3.82k  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  |  343  | 3.82k  |     if (MCOperand_isImm(MO)) { \ |  344  | 3.82k  |       uint64_t Imm = MCOperand_getImm(MO); \  |  345  | 3.82k  |       Imm &= (((uint64_t)1) << Bits) - 1; \  |  346  | 3.82k  |       printUInt64(O, Imm); \  |  347  | 3.82k  |       return; \  |  348  | 3.82k  |     } \  |  349  | 3.82k  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  |  350  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  |  351  | 0  |   }  |  
 Unexecuted instantiation: MipsInstPrinter.c:printUImm_26_0 MipsInstPrinter.c:printUImm_8_0 Line  | Count  | Source  |  339  | 1.14k  |   { \ |  340  | 1.14k  |     add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), \  |  341  | 1.14k  |             opNum); \  |  342  | 1.14k  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  |  343  | 1.14k  |     if (MCOperand_isImm(MO)) { \ |  344  | 1.14k  |       uint64_t Imm = MCOperand_getImm(MO); \  |  345  | 1.14k  |       Imm &= (((uint64_t)1) << Bits) - 1; \  |  346  | 1.14k  |       printUInt64(O, Imm); \  |  347  | 1.14k  |       return; \  |  348  | 1.14k  |     } \  |  349  | 1.14k  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  |  350  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  |  351  | 0  |   }  |  
 Unexecuted instantiation: MipsInstPrinter.c:printUImm_12_0 MipsInstPrinter.c:printUImm_20_0 Line  | Count  | Source  |  339  | 225  |   { \ |  340  | 225  |     add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), \  |  341  | 225  |             opNum); \  |  342  | 225  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  |  343  | 225  |     if (MCOperand_isImm(MO)) { \ |  344  | 225  |       uint64_t Imm = MCOperand_getImm(MO); \  |  345  | 225  |       Imm &= (((uint64_t)1) << Bits) - 1; \  |  346  | 225  |       printUInt64(O, Imm); \  |  347  | 225  |       return; \  |  348  | 225  |     } \  |  349  | 225  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  |  350  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  |  351  | 0  |   }  |  
 MipsInstPrinter.c:printUImm_16_0 Line  | Count  | Source  |  339  | 3.19k  |   { \ |  340  | 3.19k  |     add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), \  |  341  | 3.19k  |             opNum); \  |  342  | 3.19k  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  |  343  | 3.19k  |     if (MCOperand_isImm(MO)) { \ |  344  | 3.19k  |       uint64_t Imm = MCOperand_getImm(MO); \  |  345  | 3.19k  |       Imm &= (((uint64_t)1) << Bits) - 1; \  |  346  | 3.19k  |       printUInt64(O, Imm); \  |  347  | 3.19k  |       return; \  |  348  | 3.19k  |     } \  |  349  | 3.19k  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  |  350  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  |  351  | 0  |   }  |  
 Unexecuted instantiation: MipsInstPrinter.c:printUImm_32_0 MipsInstPrinter.c:printUImm_7_0 Line  | Count  | Source  |  339  | 71  |   { \ |  340  | 71  |     add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), \  |  341  | 71  |             opNum); \  |  342  | 71  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  |  343  | 71  |     if (MCOperand_isImm(MO)) { \ |  344  | 71  |       uint64_t Imm = MCOperand_getImm(MO); \  |  345  | 71  |       Imm &= (((uint64_t)1) << Bits) - 1; \  |  346  | 71  |       printUInt64(O, Imm); \  |  347  | 71  |       return; \  |  348  | 71  |     } \  |  349  | 71  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  |  350  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  |  351  | 0  |   }  |  
 MipsInstPrinter.c:printUImm_2_0 Line  | Count  | Source  |  339  | 1.60k  |   { \ |  340  | 1.60k  |     add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), \  |  341  | 1.60k  |             opNum); \  |  342  | 1.60k  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  |  343  | 1.60k  |     if (MCOperand_isImm(MO)) { \ |  344  | 1.60k  |       uint64_t Imm = MCOperand_getImm(MO); \  |  345  | 1.60k  |       Imm &= (((uint64_t)1) << Bits) - 1; \  |  346  | 1.60k  |       printUInt64(O, Imm); \  |  347  | 1.60k  |       return; \  |  348  | 1.60k  |     } \  |  349  | 1.60k  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  |  350  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  |  351  | 0  |   }  |  
 MipsInstPrinter.c:printUImm_1_0 Line  | Count  | Source  |  339  | 1.23k  |   { \ |  340  | 1.23k  |     add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), \  |  341  | 1.23k  |             opNum); \  |  342  | 1.23k  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  |  343  | 1.23k  |     if (MCOperand_isImm(MO)) { \ |  344  | 1.23k  |       uint64_t Imm = MCOperand_getImm(MO); \  |  345  | 1.23k  |       Imm &= (((uint64_t)1) << Bits) - 1; \  |  346  | 1.23k  |       printUInt64(O, Imm); \  |  347  | 1.23k  |       return; \  |  348  | 1.23k  |     } \  |  349  | 1.23k  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  |  350  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  |  351  | 0  |   }  |  
 MipsInstPrinter.c:printUImm_3_0 Line  | Count  | Source  |  339  | 2.23k  |   { \ |  340  | 2.23k  |     add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), \  |  341  | 2.23k  |             opNum); \  |  342  | 2.23k  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  |  343  | 2.23k  |     if (MCOperand_isImm(MO)) { \ |  344  | 2.23k  |       uint64_t Imm = MCOperand_getImm(MO); \  |  345  | 2.23k  |       Imm &= (((uint64_t)1) << Bits) - 1; \  |  346  | 2.23k  |       printUInt64(O, Imm); \  |  347  | 2.23k  |       return; \  |  348  | 2.23k  |     } \  |  349  | 2.23k  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  |  350  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  |  351  | 0  |   }  |  
 MipsInstPrinter.c:printUImm_0_0 Line  | Count  | Source  |  339  | 399  |   { \ |  340  | 399  |     add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), \  |  341  | 399  |             opNum); \  |  342  | 399  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  |  343  | 399  |     if (MCOperand_isImm(MO)) { \ |  344  | 399  |       uint64_t Imm = MCOperand_getImm(MO); \  |  345  | 399  |       Imm &= (((uint64_t)1) << Bits) - 1; \  |  346  | 399  |       printUInt64(O, Imm); \  |  347  | 399  |       return; \  |  348  | 399  |     } \  |  349  | 399  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  |  350  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  |  351  | 0  |   }  |  
 MipsInstPrinter.c:printUImm_6_0 Line  | Count  | Source  |  339  | 624  |   { \ |  340  | 624  |     add_cs_detail(MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, 0)), \  |  341  | 624  |             opNum); \  |  342  | 624  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  |  343  | 624  |     if (MCOperand_isImm(MO)) { \ |  344  | 624  |       uint64_t Imm = MCOperand_getImm(MO); \  |  345  | 624  |       Imm &= (((uint64_t)1) << Bits) - 1; \  |  346  | 624  |       printUInt64(O, Imm); \  |  347  | 624  |       return; \  |  348  | 624  |     } \  |  349  | 624  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  |  350  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  |  351  | 0  |   }  |  
  | 
352  |  |  | 
353  |  | #define DEFINE_printUImm_2(Bits, Offset) \  | 
354  |  |   static void CONCAT(printUImm, CONCAT(Bits, Offset))( \  | 
355  |  |     MCInst * MI, int opNum, SStream *O) \  | 
356  | 681  |   { \ | 
357  | 681  |     add_cs_detail( \  | 
358  | 681  |       MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, Offset)), \  | 
359  | 681  |       opNum); \  | 
360  | 681  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  | 
361  | 681  |     if (MCOperand_isImm(MO)) { \ | 
362  | 681  |       uint64_t Imm = MCOperand_getImm(MO); \  | 
363  | 681  |       Imm -= Offset; \  | 
364  | 681  |       Imm &= (1 << Bits) - 1; \  | 
365  | 681  |       Imm += Offset; \  | 
366  | 681  |       printUInt64(O, Imm); \  | 
367  | 681  |       return; \  | 
368  | 681  |     } \  | 
369  | 681  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  | 
370  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  | 
371  | 0  |   } MipsInstPrinter.c:printUImm_2_1 Line  | Count  | Source  |  356  | 394  |   { \ |  357  | 394  |     add_cs_detail( \  |  358  | 394  |       MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, Offset)), \  |  359  | 394  |       opNum); \  |  360  | 394  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  |  361  | 394  |     if (MCOperand_isImm(MO)) { \ |  362  | 394  |       uint64_t Imm = MCOperand_getImm(MO); \  |  363  | 394  |       Imm -= Offset; \  |  364  | 394  |       Imm &= (1 << Bits) - 1; \  |  365  | 394  |       Imm += Offset; \  |  366  | 394  |       printUInt64(O, Imm); \  |  367  | 394  |       return; \  |  368  | 394  |     } \  |  369  | 394  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  |  370  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  |  371  | 0  |   }  |  
 Unexecuted instantiation: MipsInstPrinter.c:printUImm_5_32 MipsInstPrinter.c:printUImm_5_1 Line  | Count  | Source  |  356  | 287  |   { \ |  357  | 287  |     add_cs_detail( \  |  358  | 287  |       MI, CONCAT(Mips_OP_GROUP_UImm, CONCAT(Bits, Offset)), \  |  359  | 287  |       opNum); \  |  360  | 287  |     MCOperand *MO = MCInst_getOperand(MI, (opNum)); \  |  361  | 287  |     if (MCOperand_isImm(MO)) { \ |  362  | 287  |       uint64_t Imm = MCOperand_getImm(MO); \  |  363  | 287  |       Imm -= Offset; \  |  364  | 287  |       Imm &= (1 << Bits) - 1; \  |  365  | 287  |       Imm += Offset; \  |  366  | 287  |       printUInt64(O, Imm); \  |  367  | 287  |       return; \  |  368  | 287  |     } \  |  369  | 287  |     MCOperand *Op = MCInst_getOperand(MI, (opNum)); \  |  370  | 0  |     printRegName(MI, O, MCOperand_getReg(Op)); \  |  371  | 0  |   }  |  
 Unexecuted instantiation: MipsInstPrinter.c:printUImm_6_1 Unexecuted instantiation: MipsInstPrinter.c:printUImm_5_33 Unexecuted instantiation: MipsInstPrinter.c:printUImm_6_2  | 
372  |  |  | 
373  |  | DEFINE_printUImm(0);  | 
374  |  | DEFINE_printUImm(1);  | 
375  |  | DEFINE_printUImm(10);  | 
376  |  | DEFINE_printUImm(12);  | 
377  |  | DEFINE_printUImm(16);  | 
378  |  | DEFINE_printUImm(2);  | 
379  |  | DEFINE_printUImm(20);  | 
380  |  | DEFINE_printUImm(26);  | 
381  |  | DEFINE_printUImm(3);  | 
382  |  | DEFINE_printUImm(32);  | 
383  |  | DEFINE_printUImm(4);  | 
384  |  | DEFINE_printUImm(5);  | 
385  |  | DEFINE_printUImm(6);  | 
386  |  | DEFINE_printUImm(7);  | 
387  |  | DEFINE_printUImm(8);  | 
388  |  | DEFINE_printUImm_2(2, 1);  | 
389  |  | DEFINE_printUImm_2(5, 1);  | 
390  |  | DEFINE_printUImm_2(5, 32);  | 
391  |  | DEFINE_printUImm_2(5, 33);  | 
392  |  | DEFINE_printUImm_2(6, 1);  | 
393  |  | DEFINE_printUImm_2(6, 2);  | 
394  |  |  | 
395  |  | static void printMemOperand(MCInst *MI, int opNum, SStream *O)  | 
396  | 24.0k  | { | 
397  |  |   // Load/Store memory operands -- imm($reg)  | 
398  |  |   // If PIC target the target is loaded as the  | 
399  |  |   // pattern lw $25,%call16($28)  | 
400  |  |  | 
401  |  |   // opNum can be invalid if instruction had reglist as operand.  | 
402  |  |   // MemOperand is always last operand of instruction (base + offset).  | 
403  | 24.0k  |   switch (MCInst_getOpcode(MI)) { | 
404  | 22.6k  |   default:  | 
405  | 22.6k  |     break;  | 
406  | 22.6k  |   case Mips_SWM32_MM:  | 
407  | 482  |   case Mips_LWM32_MM:  | 
408  | 698  |   case Mips_SWM16_MM:  | 
409  | 913  |   case Mips_SWM16_MMR6:  | 
410  | 1.11k  |   case Mips_LWM16_MM:  | 
411  | 1.44k  |   case Mips_LWM16_MMR6:  | 
412  | 1.44k  |     opNum = MCInst_getNumOperands(MI) - 2;  | 
413  | 1.44k  |     break;  | 
414  | 24.0k  |   }  | 
415  |  |  | 
416  | 24.0k  |   set_mem_access(MI, true);  | 
417  |  |   // Index register is encoded as immediate value  | 
418  |  |   // in case of nanoMIPS indexed instructions  | 
419  | 24.0k  |   switch (MCInst_getOpcode(MI)) { | 
420  |  |   // No offset needed for paired LL/SC  | 
421  | 0  |   case Mips_LLWP_NM:  | 
422  | 0  |   case Mips_SCWP_NM:  | 
423  | 0  |     break;  | 
424  | 0  |   case Mips_LWX_NM:  | 
425  | 0  |   case Mips_LWXS_NM:  | 
426  | 0  |   case Mips_LWXS16_NM:  | 
427  | 0  |   case Mips_LBX_NM:  | 
428  | 0  |   case Mips_LBUX_NM:  | 
429  | 0  |   case Mips_LHX_NM:  | 
430  | 0  |   case Mips_LHUX_NM:  | 
431  | 0  |   case Mips_LHXS_NM:  | 
432  | 0  |   case Mips_LHUXS_NM:  | 
433  | 0  |   case Mips_SWX_NM:  | 
434  | 0  |   case Mips_SWXS_NM:  | 
435  | 0  |   case Mips_SBX_NM:  | 
436  | 0  |   case Mips_SHX_NM:  | 
437  | 0  |   case Mips_SHXS_NM:  | 
438  | 0  |     if (!MCOperand_isReg(MCInst_getOperand(MI, (opNum + 1)))) { | 
439  | 0  |       add_cs_detail(MI, Mips_OP_GROUP_MemOperand,  | 
440  | 0  |               (opNum + 1));  | 
441  | 0  |       printRegName(MI, O,  | 
442  | 0  |              MCOperand_getImm(MCInst_getOperand(  | 
443  | 0  |                MI, (opNum + 1))));  | 
444  | 0  |       break;  | 
445  | 0  |     }  | 
446  |  |     // Fall through  | 
447  | 24.0k  |   default:  | 
448  | 24.0k  |     printOperand((MCInst *)MI, opNum + 1, O);  | 
449  | 24.0k  |     break;  | 
450  | 24.0k  |   }  | 
451  | 24.0k  |   SStream_concat0(O, "("); | 
452  | 24.0k  |   printOperand((MCInst *)MI, opNum, O);  | 
453  | 24.0k  |   SStream_concat0(O, ")");  | 
454  | 24.0k  |   set_mem_access(MI, false);  | 
455  | 24.0k  | }  | 
456  |  |  | 
457  |  | static void printMemOperandEA(MCInst *MI, int opNum, SStream *O)  | 
458  | 0  | { | 
459  |  |   // when using stack locations for not load/store instructions  | 
460  |  |   // print the same way as all normal 3 operand instructions.  | 
461  | 0  |   printOperand((MCInst *)MI, opNum, O);  | 
462  | 0  |   SStream_concat0(O, ", ");  | 
463  | 0  |   printOperand((MCInst *)MI, opNum + 1, O);  | 
464  | 0  | }  | 
465  |  |  | 
466  |  | static void printFCCOperand(MCInst *MI, int opNum, SStream *O)  | 
467  | 0  | { | 
468  | 0  |   MCOperand *MO = MCInst_getOperand(MI, (opNum));  | 
469  | 0  |   SStream_concat0(O,  | 
470  | 0  |       MipsFCCToString((Mips_CondCode)MCOperand_getImm(MO)));  | 
471  | 0  | }  | 
472  |  |  | 
473  |  | static bool printAlias(const char *Str, const MCInst *MI, uint64_t Address,  | 
474  |  |            unsigned OpNo, SStream *OS, bool IsBranch)  | 
475  | 1.34k  | { | 
476  | 1.34k  |   SStream_concat(OS, "%s%s", "\t", Str);  | 
477  | 1.34k  |   SStream_concat0(OS, "\t");  | 
478  | 1.34k  |   if (IsBranch)  | 
479  | 1.04k  |     printBranchOperand((MCInst *)MI, Address, OpNo, OS);  | 
480  | 304  |   else  | 
481  | 304  |     printOperand((MCInst *)MI, OpNo, OS);  | 
482  | 1.34k  |   return true;  | 
483  | 1.34k  | }  | 
484  |  |  | 
485  |  | static bool printAlias2(const char *Str, const MCInst *MI, uint64_t Address,  | 
486  |  |       unsigned OpNo0, unsigned OpNo1, SStream *OS,  | 
487  |  |       bool IsBranch)  | 
488  | 901  | { | 
489  | 901  |   printAlias(Str, MI, Address, OpNo0, OS, IsBranch);  | 
490  | 901  |   SStream_concat0(OS, ", ");  | 
491  | 901  |   if (IsBranch)  | 
492  | 739  |     printBranchOperand((MCInst *)MI, Address, OpNo1, OS);  | 
493  | 162  |   else  | 
494  | 162  |     printOperand((MCInst *)MI, OpNo1, OS);  | 
495  | 901  |   return true;  | 
496  | 901  | }  | 
497  |  |  | 
498  |  | static bool printAlias3(const char *Str, const MCInst *MI, uint64_t Address,  | 
499  |  |       unsigned OpNo0, unsigned OpNo1, unsigned OpNo2,  | 
500  |  |       SStream *OS)  | 
501  | 0  | { | 
502  | 0  |   printAlias(Str, MI, Address, OpNo0, OS, false);  | 
503  | 0  |   SStream_concat0(OS, ", ");  | 
504  | 0  |   printOperand((MCInst *)MI, OpNo1, OS);  | 
505  | 0  |   SStream_concat0(OS, ", ");  | 
506  | 0  |   printOperand((MCInst *)MI, OpNo2, OS);  | 
507  | 0  |   return true;  | 
508  | 0  | }  | 
509  |  |  | 
510  |  | static bool printAlias4(const MCInst *MI, uint64_t Address, SStream *OS)  | 
511  | 98.5k  | { | 
512  | 98.5k  |   switch (MCInst_getOpcode(MI)) { | 
513  | 1.46k  |   case Mips_BEQ:  | 
514  | 1.69k  |   case Mips_BEQ_MM:  | 
515  |  |     // beq $zero, $zero, $L2 => b $L2  | 
516  |  |     // beq $r0, $zero, $L2 => beqz $r0, $L2  | 
517  | 1.69k  |     return (isReg(MI, 0, Mips_ZERO) && isReg(MI, 1, Mips_ZERO) &&  | 
518  | 301  |       printAlias("b", MI, Address, 2, OS, true)) || | 
519  | 1.39k  |            (isReg(MI, 1, Mips_ZERO) &&  | 
520  | 451  |       printAlias2("beqz", MI, Address, 0, 2, OS, true)); | 
521  | 0  |   case Mips_BEQ64:  | 
522  |  |     // beq $r0, $zero, $L2 => beqz $r0, $L2  | 
523  | 0  |     return isReg(MI, 1, Mips_ZERO_64) &&  | 
524  | 0  |            printAlias2("beqz", MI, Address, 0, 2, OS, true); | 
525  | 649  |   case Mips_BNE:  | 
526  | 916  |   case Mips_BNE_MM:  | 
527  |  |     // bne $r0, $zero, $L2 => bnez $r0, $L2  | 
528  | 916  |     return isReg(MI, 1, Mips_ZERO) &&  | 
529  | 288  |            printAlias2("bnez", MI, Address, 0, 2, OS, true); | 
530  | 0  |   case Mips_BNE64:  | 
531  |  |     // bne $r0, $zero, $L2 => bnez $r0, $L2  | 
532  | 0  |     return isReg(MI, 1, Mips_ZERO_64) &&  | 
533  | 0  |            printAlias2("bnez", MI, Address, 0, 2, OS, true); | 
534  | 207  |   case Mips_BGEZAL:  | 
535  |  |     // bgezal $zero, $L1 => bal $L1  | 
536  | 207  |     return isReg(MI, 0, Mips_ZERO) &&  | 
537  | 0  |            printAlias("bal", MI, Address, 1, OS, true); | 
538  | 205  |   case Mips_BC1T:  | 
539  |  |     // bc1t $fcc0, $L1 => bc1t $L1  | 
540  | 205  |     return isReg(MI, 0, Mips_FCC0) &&  | 
541  | 0  |            printAlias("bc1t", MI, Address, 1, OS, true); | 
542  | 195  |   case Mips_BC1F:  | 
543  |  |     // bc1f $fcc0, $L1 => bc1f $L1  | 
544  | 195  |     return isReg(MI, 0, Mips_FCC0) &&  | 
545  | 0  |            printAlias("bc1f", MI, Address, 1, OS, true); | 
546  | 226  |   case Mips_JALR:  | 
547  |  |     // jalr $zero, $r1 => jr $r1  | 
548  |  |     // jalr $ra, $r1 => jalr $r1  | 
549  | 226  |     return (isReg(MI, 0, Mips_ZERO) &&  | 
550  | 76  |       printAlias("jr", MI, Address, 1, OS, false)) || | 
551  | 150  |            (isReg(MI, 0, Mips_RA) &&  | 
552  | 66  |       printAlias("jalr", MI, Address, 1, OS, false)); | 
553  | 0  |   case Mips_JALR64:  | 
554  |  |     // jalr $zero, $r1 => jr $r1  | 
555  |  |     // jalr $ra, $r1 => jalr $r1  | 
556  | 0  |     return (isReg(MI, 0, Mips_ZERO_64) &&  | 
557  | 0  |       printAlias("jr", MI, Address, 1, OS, false)) || | 
558  | 0  |            (isReg(MI, 0, Mips_RA_64) &&  | 
559  | 0  |       printAlias("jalr", MI, Address, 1, OS, false)); | 
560  | 69  |   case Mips_NOR:  | 
561  | 140  |   case Mips_NOR_MM:  | 
562  | 206  |   case Mips_NOR_MMR6:  | 
563  |  |     // nor $r0, $r1, $zero => not $r0, $r1  | 
564  | 206  |     return isReg(MI, 2, Mips_ZERO) &&  | 
565  | 78  |            printAlias2("not", MI, Address, 0, 1, OS, false); | 
566  | 0  |   case Mips_NOR64:  | 
567  |  |     // nor $r0, $r1, $zero => not $r0, $r1  | 
568  | 0  |     return isReg(MI, 2, Mips_ZERO_64) &&  | 
569  | 0  |            printAlias2("not", MI, Address, 0, 1, OS, false); | 
570  | 66  |   case Mips_OR:  | 
571  | 155  |   case Mips_ADDu:  | 
572  |  |     // or $r0, $r1, $zero => move $r0, $r1  | 
573  |  |     // addu $r0, $r1, $zero => move $r0, $r1  | 
574  | 155  |     return isReg(MI, 2, Mips_ZERO) &&  | 
575  | 84  |            printAlias2("move", MI, Address, 0, 1, OS, false); | 
576  | 0  |   case Mips_LI48_NM:  | 
577  | 0  |   case Mips_LI16_NM:  | 
578  |  |     // li[16/48] $r0, imm => li $r0, imm  | 
579  | 0  |     return printAlias2("li", MI, Address, 0, 1, OS, false); | 
580  | 0  |   case Mips_ADDIU_NM:  | 
581  | 0  |   case Mips_ADDIUNEG_NM:  | 
582  | 0  |     if (isReg(MI, 1, Mips_ZERO_NM))  | 
583  | 0  |       return printAlias2("li", MI, Address, 0, 2, OS, false); | 
584  | 0  |     else  | 
585  | 0  |       return printAlias3("addiu", MI, Address, 0, 1, 2, OS); | 
586  | 0  |   case Mips_ADDIU48_NM:  | 
587  | 0  |   case Mips_ADDIURS5_NM:  | 
588  | 0  |   case Mips_ADDIUR1SP_NM:  | 
589  | 0  |   case Mips_ADDIUR2_NM:  | 
590  | 0  |   case Mips_ADDIUGPB_NM:  | 
591  | 0  |   case Mips_ADDIUGPW_NM:  | 
592  | 0  |     return printAlias3("addiu", MI, Address, 0, 1, 2, OS); | 
593  | 0  |   case Mips_ANDI16_NM:  | 
594  | 0  |   case Mips_ANDI_NM:  | 
595  |  |     // andi[16/32] $r0, $r1, imm => andi $r0, $r1, imm  | 
596  | 0  |     return printAlias3("andi", MI, Address, 0, 1, 2, OS); | 
597  | 94.7k  |   default:  | 
598  | 94.7k  |     return false;  | 
599  | 98.5k  |   }  | 
600  | 98.5k  | }  | 
601  |  |  | 
602  |  | static void printRegisterList(MCInst *MI, int opNum, SStream *O)  | 
603  | 1.44k  | { | 
604  |  |   // - 2 because register List is always first operand of instruction and it is  | 
605  |  |   // always followed by memory operand (base + offset).  | 
606  | 1.44k  |   add_cs_detail(MI, Mips_OP_GROUP_RegisterList, opNum);  | 
607  | 7.48k  |   for (int i = opNum, e = MCInst_getNumOperands(MI) - 2; i != e; ++i) { | 
608  | 6.04k  |     if (i != opNum)  | 
609  | 4.60k  |       SStream_concat0(O, ", ");  | 
610  | 6.04k  |     printRegName(MI, O,  | 
611  | 6.04k  |            MCOperand_getReg(MCInst_getOperand(MI, (i))));  | 
612  | 6.04k  |   }  | 
613  | 1.44k  | }  | 
614  |  |  | 
615  |  | static void printNanoMipsRegisterList(MCInst *MI, int OpNum, SStream *O)  | 
616  | 0  | { | 
617  | 0  |   add_cs_detail(MI, Mips_OP_GROUP_NanoMipsRegisterList, OpNum);  | 
618  | 0  |   for (unsigned I = OpNum; I < MCInst_getNumOperands(MI); I++) { | 
619  | 0  |     SStream_concat0(O, ", ");  | 
620  | 0  |     printRegName(MI, O,  | 
621  | 0  |            MCOperand_getReg(MCInst_getOperand(MI, (I))));  | 
622  | 0  |   }  | 
623  | 0  | }  | 
624  |  |  | 
625  |  | static void printHi20(MCInst *MI, int OpNum, SStream *O)  | 
626  | 0  | { | 
627  | 0  |   MCOperand *MO = MCInst_getOperand(MI, (OpNum));  | 
628  | 0  |   if (MCOperand_isImm(MO)) { | 
629  | 0  |     add_cs_detail(MI, Mips_OP_GROUP_Hi20, OpNum);  | 
630  | 0  |     SStream_concat0(O, "%hi("); | 
631  | 0  |     printUInt64(O, MCOperand_getImm(MO));  | 
632  | 0  |     SStream_concat0(O, ")");  | 
633  | 0  |   } else  | 
634  | 0  |     printOperand(MI, OpNum, O);  | 
635  | 0  | }  | 
636  |  |  | 
637  |  | static void printHi20PCRel(MCInst *MI, uint64_t Address, int OpNum, SStream *O)  | 
638  | 0  | { | 
639  | 0  |   MCOperand *MO = MCInst_getOperand(MI, (OpNum));  | 
640  | 0  |   if (MCOperand_isImm(MO)) { | 
641  | 0  |     add_cs_detail(MI, Mips_OP_GROUP_Hi20PCRel, OpNum);  | 
642  | 0  |     SStream_concat0(O, "%pcrel_hi("); | 
643  | 0  |     printUInt64(O, MCOperand_getImm(MO) + Address);  | 
644  | 0  |     SStream_concat0(O, ")");  | 
645  | 0  |   } else  | 
646  | 0  |     printOperand(MI, OpNum, O);  | 
647  | 0  | }  | 
648  |  |  | 
649  |  | static void printPCRel(MCInst *MI, uint64_t Address, int OpNum, SStream *O)  | 
650  | 0  | { | 
651  | 0  |   MCOperand *MO = MCInst_getOperand(MI, (OpNum));  | 
652  | 0  |   if (MCOperand_isImm(MO)) { | 
653  | 0  |     add_cs_detail(MI, Mips_OP_GROUP_PCRel, OpNum);  | 
654  | 0  |     printUInt64(O, MCOperand_getImm(MO) + Address);  | 
655  | 0  |   } else  | 
656  | 0  |     printOperand(MI, OpNum, O);  | 
657  | 0  | }  | 
658  |  |  | 
659  |  | const char *Mips_LLVM_getRegisterName(unsigned RegNo, bool noRegName)  | 
660  | 215k  | { | 
661  | 215k  |   if (!RegNo || RegNo >= MIPS_REG_ENDING) { | 
662  | 0  |     return NULL;  | 
663  | 0  |   }  | 
664  | 215k  |   if (noRegName) { | 
665  | 0  |     return getRegisterName(RegNo);  | 
666  | 0  |   }  | 
667  | 215k  |   switch (RegNo) { | 
668  | 22.3k  |   case MIPS_REG_AT:  | 
669  | 23.2k  |   case MIPS_REG_AT_64:  | 
670  | 23.2k  |     return "at";  | 
671  | 4.90k  |   case MIPS_REG_A0:  | 
672  | 5.17k  |   case MIPS_REG_A0_64:  | 
673  | 5.17k  |     return "a0";  | 
674  | 5.23k  |   case MIPS_REG_A1:  | 
675  | 5.90k  |   case MIPS_REG_A1_64:  | 
676  | 5.90k  |     return "a1";  | 
677  | 5.68k  |   case MIPS_REG_A2:  | 
678  | 6.02k  |   case MIPS_REG_A2_64:  | 
679  | 6.02k  |     return "a2";  | 
680  | 4.95k  |   case MIPS_REG_A3:  | 
681  | 5.36k  |   case MIPS_REG_A3_64:  | 
682  | 5.36k  |     return "a3";  | 
683  | 1.75k  |   case MIPS_REG_K0:  | 
684  | 1.84k  |   case MIPS_REG_K0_64:  | 
685  | 1.84k  |     return "k0";  | 
686  | 2.82k  |   case MIPS_REG_K1:  | 
687  | 3.62k  |   case MIPS_REG_K1_64:  | 
688  | 3.62k  |     return "k1";  | 
689  | 11.7k  |   case MIPS_REG_S0:  | 
690  | 12.0k  |   case MIPS_REG_S0_64:  | 
691  | 12.0k  |     return "s0";  | 
692  | 4.48k  |   case MIPS_REG_S1:  | 
693  | 4.77k  |   case MIPS_REG_S1_64:  | 
694  | 4.77k  |     return "s1";  | 
695  | 2.06k  |   case MIPS_REG_S2:  | 
696  | 2.28k  |   case MIPS_REG_S2_64:  | 
697  | 2.28k  |     return "s2";  | 
698  | 4.25k  |   case MIPS_REG_S3:  | 
699  | 4.87k  |   case MIPS_REG_S3_64:  | 
700  | 4.87k  |     return "s3";  | 
701  | 2.78k  |   case MIPS_REG_S4:  | 
702  | 3.20k  |   case MIPS_REG_S4_64:  | 
703  | 3.20k  |     return "s4";  | 
704  | 1.97k  |   case MIPS_REG_S5:  | 
705  | 2.17k  |   case MIPS_REG_S5_64:  | 
706  | 2.17k  |     return "s5";  | 
707  | 2.42k  |   case MIPS_REG_S6:  | 
708  | 2.73k  |   case MIPS_REG_S6_64:  | 
709  | 2.73k  |     return "s6";  | 
710  | 2.04k  |   case MIPS_REG_S7:  | 
711  | 2.29k  |   case MIPS_REG_S7_64:  | 
712  | 2.29k  |     return "s7";  | 
713  | 2.90k  |   case MIPS_REG_T0:  | 
714  | 3.28k  |   case MIPS_REG_T0_64:  | 
715  | 3.28k  |     return "t0";  | 
716  | 1.86k  |   case MIPS_REG_T1:  | 
717  | 2.09k  |   case MIPS_REG_T1_64:  | 
718  | 2.09k  |     return "t1";  | 
719  | 2.04k  |   case MIPS_REG_T2:  | 
720  | 2.44k  |   case MIPS_REG_T2_64:  | 
721  | 2.44k  |     return "t2";  | 
722  | 1.59k  |   case MIPS_REG_T3:  | 
723  | 1.97k  |   case MIPS_REG_T3_64:  | 
724  | 1.97k  |     return "t3";  | 
725  | 2.07k  |   case MIPS_REG_T4:  | 
726  | 2.31k  |   case MIPS_REG_T4_64:  | 
727  | 2.31k  |     return "t4";  | 
728  | 1.58k  |   case MIPS_REG_T5:  | 
729  | 1.79k  |   case MIPS_REG_T5_64:  | 
730  | 1.79k  |     return "t5";  | 
731  | 2.29k  |   case MIPS_REG_T6:  | 
732  | 2.53k  |   case MIPS_REG_T6_64:  | 
733  | 2.53k  |     return "t6";  | 
734  | 2.58k  |   case MIPS_REG_T7:  | 
735  | 3.02k  |   case MIPS_REG_T7_64:  | 
736  | 3.02k  |     return "t7";  | 
737  | 3.18k  |   case MIPS_REG_T8:  | 
738  | 3.89k  |   case MIPS_REG_T8_64:  | 
739  | 3.89k  |     return "t8";  | 
740  | 2.51k  |   case MIPS_REG_T9:  | 
741  | 2.82k  |   case MIPS_REG_T9_64:  | 
742  | 2.82k  |     return "t9";  | 
743  | 8.16k  |   case MIPS_REG_V0:  | 
744  | 8.81k  |   case MIPS_REG_V0_64:  | 
745  | 8.81k  |     return "v0";  | 
746  | 5.30k  |   case MIPS_REG_V1:  | 
747  | 5.77k  |   case MIPS_REG_V1_64:  | 
748  | 5.77k  |     return "v1";  | 
749  | 89.0k  |   default:  | 
750  | 89.0k  |     return getRegisterName(RegNo);  | 
751  | 215k  |   }  | 
752  | 215k  | }  |