/src/capstonenext/arch/ARC/ARCInstPrinter.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  |  | //===- ARCInstPrinter.cpp - ARC MCInst to assembly syntax -------*- C++ -*-===//  | 
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 ARC MCInst to a .s file.  | 
24  |  | //  | 
25  |  | //===----------------------------------------------------------------------===//  | 
26  |  |  | 
27  |  | #ifdef CAPSTONE_HAS_ARC  | 
28  |  |  | 
29  |  | #include <stdio.h>  | 
30  |  | #include <string.h>  | 
31  |  | #include <stdlib.h>  | 
32  |  | #include <capstone/platform.h>  | 
33  |  |  | 
34  |  | #include "../../SStream.h"  | 
35  |  | #include "../../MCInst.h"  | 
36  |  | #include "../../MCInstPrinter.h"  | 
37  |  |  | 
38  |  | #include "ARCInfo.h"  | 
39  |  | #include "ARCInstPrinter.h"  | 
40  |  | #include "ARCLinkage.h"  | 
41  |  | #include "ARCMapping.h"  | 
42  |  |  | 
43  |  | #define CONCAT(a, b) CONCAT_(a, b)  | 
44  |  | #define CONCAT_(a, b) a##_##b  | 
45  |  |  | 
46  |  | #define DEBUG_TYPE "asm-printer"  | 
47  |  |  | 
48  |  | #include "ARCGenAsmWriter.inc"  | 
49  |  |  | 
50  |  | static const char *ARCBRCondCodeToString(ARCCC_BRCondCode BRCC)  | 
51  | 0  | { | 
52  | 0  |   switch (BRCC) { | 
53  | 0  |   case ARCCC_BREQ:  | 
54  | 0  |     return "eq";  | 
55  | 0  |   case ARCCC_BRNE:  | 
56  | 0  |     return "ne";  | 
57  | 0  |   case ARCCC_BRLT:  | 
58  | 0  |     return "lt";  | 
59  | 0  |   case ARCCC_BRGE:  | 
60  | 0  |     return "ge";  | 
61  | 0  |   case ARCCC_BRLO:  | 
62  | 0  |     return "lo";  | 
63  | 0  |   case ARCCC_BRHS:  | 
64  | 0  |     return "hs";  | 
65  | 0  |   }  | 
66  |  |   // CS_ASSERT(0 && "Unknown condition code passed");  | 
67  | 0  |   return "";  | 
68  | 0  | }  | 
69  |  |  | 
70  |  | static const char *ARCCondCodeToString(ARCCC_CondCode CC)  | 
71  | 0  | { | 
72  | 0  |   switch (CC) { | 
73  | 0  |   case ARCCC_EQ:  | 
74  | 0  |     return "eq";  | 
75  | 0  |   case ARCCC_NE:  | 
76  | 0  |     return "ne";  | 
77  | 0  |   case ARCCC_P:  | 
78  | 0  |     return "p";  | 
79  | 0  |   case ARCCC_N:  | 
80  | 0  |     return "n";  | 
81  | 0  |   case ARCCC_HS:  | 
82  | 0  |     return "hs";  | 
83  | 0  |   case ARCCC_LO:  | 
84  | 0  |     return "lo";  | 
85  | 0  |   case ARCCC_GT:  | 
86  | 0  |     return "gt";  | 
87  | 0  |   case ARCCC_GE:  | 
88  | 0  |     return "ge";  | 
89  | 0  |   case ARCCC_VS:  | 
90  | 0  |     return "vs";  | 
91  | 0  |   case ARCCC_VC:  | 
92  | 0  |     return "vc";  | 
93  | 0  |   case ARCCC_LT:  | 
94  | 0  |     return "lt";  | 
95  | 0  |   case ARCCC_LE:  | 
96  | 0  |     return "le";  | 
97  | 0  |   case ARCCC_HI:  | 
98  | 0  |     return "hi";  | 
99  | 0  |   case ARCCC_LS:  | 
100  | 0  |     return "ls";  | 
101  | 0  |   case ARCCC_PNZ:  | 
102  | 0  |     return "pnz";  | 
103  | 0  |   case ARCCC_AL:  | 
104  | 0  |     return "al";  | 
105  | 0  |   case ARCCC_NZ:  | 
106  | 0  |     return "nz";  | 
107  | 0  |   case ARCCC_Z:  | 
108  | 0  |     return "z";  | 
109  | 0  |   }  | 
110  |  |   // CS_ASSERT(0 && "Unknown condition code passed");  | 
111  | 0  |   return "";  | 
112  | 0  | }  | 
113  |  |  | 
114  |  | static void printRegName(SStream *OS, MCRegister Reg)  | 
115  | 0  | { | 
116  | 0  |   SStream_concat0(OS, getRegisterName(Reg));  | 
117  | 0  | }  | 
118  |  |  | 
119  |  | static void printInst(MCInst *MI, uint64_t Address, const char *Annot,  | 
120  |  |           SStream *O)  | 
121  | 0  | { | 
122  | 0  |   printInstruction(MI, Address, O);  | 
123  | 0  | }  | 
124  |  |  | 
125  |  | static void printOperand(MCInst *MI, unsigned OpNum, SStream *O)  | 
126  | 0  | { | 
127  | 0  |   add_cs_detail(MI, ARC_OP_GROUP_Operand, OpNum);  | 
128  | 0  |   MCOperand *Op = MCInst_getOperand(MI, (OpNum));  | 
129  | 0  |   if (MCOperand_isReg(Op)) { | 
130  | 0  |     printRegName(O, MCOperand_getReg(Op));  | 
131  | 0  |   } else if (MCOperand_isImm(Op)) { | 
132  | 0  |     SStream_concat(O, "%" PRId64, MCOperand_getImm(Op));  | 
133  | 0  |   } else if (MCOperand_isExpr(Op)) { | 
134  | 0  |     printExpr(O, MCOperand_getExpr(Op));  | 
135  | 0  |   }  | 
136  | 0  | }  | 
137  |  |  | 
138  |  | static void printOperandAddr(MCInst *MI, uint64_t Address, unsigned OpNum,  | 
139  |  |            SStream *O)  | 
140  | 0  | { | 
141  | 0  |   printOperand(MI, OpNum, O);  | 
142  | 0  | }  | 
143  |  |  | 
144  |  | static void printMemOperandRI(MCInst *MI, unsigned OpNum, SStream *O)  | 
145  | 0  | { | 
146  | 0  |   add_cs_detail(MI, ARC_OP_GROUP_MemOperandRI, OpNum);  | 
147  | 0  |   MCOperand *base = MCInst_getOperand(MI, (OpNum));  | 
148  | 0  |   MCOperand *offset = MCInst_getOperand(MI, (OpNum + 1));  | 
149  | 0  |   CS_ASSERT((MCOperand_isReg(base) && "Base should be register."));  | 
150  | 0  |   CS_ASSERT((MCOperand_isImm(offset) && "Offset should be immediate."));  | 
151  | 0  |   printRegName(O, MCOperand_getReg(base));  | 
152  | 0  |   SStream_concat(O, "%s", ",");  | 
153  | 0  |   printInt64(O, MCOperand_getImm(offset));  | 
154  | 0  | }  | 
155  |  |  | 
156  |  | static void printPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O)  | 
157  | 0  | { | 
158  | 0  |   add_cs_detail(MI, ARC_OP_GROUP_PredicateOperand, OpNum);  | 
159  |  | 
  | 
160  | 0  |   MCOperand *Op = MCInst_getOperand(MI, (OpNum));  | 
161  | 0  |   CS_ASSERT((MCOperand_isImm(Op) && "Predicate operand is immediate."));  | 
162  | 0  |   SStream_concat0(  | 
163  | 0  |     O, ARCCondCodeToString((ARCCC_CondCode)MCOperand_getImm(Op)));  | 
164  | 0  | }  | 
165  |  |  | 
166  |  | static void printBRCCPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O)  | 
167  | 0  | { | 
168  | 0  |   add_cs_detail(MI, ARC_OP_GROUP_BRCCPredicateOperand, OpNum);  | 
169  | 0  |   MCOperand *Op = MCInst_getOperand(MI, (OpNum));  | 
170  | 0  |   CS_ASSERT((MCOperand_isImm(Op) && "Predicate operand is immediate."));  | 
171  | 0  |   SStream_concat0(O, ARCBRCondCodeToString(  | 
172  | 0  |            (ARCCC_BRCondCode)MCOperand_getImm(Op)));  | 
173  | 0  | }  | 
174  |  |  | 
175  |  | static void printCCOperand(MCInst *MI, int OpNum, SStream *O)  | 
176  | 0  | { | 
177  | 0  |   add_cs_detail(MI, ARC_OP_GROUP_CCOperand, OpNum);  | 
178  | 0  |   SStream_concat0(O, ARCCondCodeToString((ARCCC_CondCode)MCOperand_getImm(  | 
179  | 0  |            MCInst_getOperand(MI, (OpNum)))));  | 
180  | 0  | }  | 
181  |  |  | 
182  |  | static void printU6ShiftedBy(unsigned ShiftBy, MCInst *MI, int OpNum,  | 
183  |  |            SStream *O)  | 
184  | 0  | { | 
185  | 0  |   MCOperand *MO = MCInst_getOperand(MI, (OpNum));  | 
186  | 0  |   if (MCOperand_isImm(MO)) { | 
187  | 0  |     unsigned Value = MCOperand_getImm(MO);  | 
188  | 0  |     unsigned Value2 = Value >> ShiftBy;  | 
189  | 0  |     if (Value2 > 0x3F || (Value2 << ShiftBy != Value)) { | 
190  | 0  |       CS_ASSERT((false && "instruction has wrong format"));  | 
191  | 0  |     }  | 
192  | 0  |   }  | 
193  | 0  |   printOperand(MI, OpNum, O);  | 
194  | 0  | }  | 
195  |  |  | 
196  |  | static void printU6(MCInst *MI, int OpNum, SStream *O)  | 
197  | 0  | { | 
198  | 0  |   add_cs_detail(MI, ARC_OP_GROUP_U6, OpNum);  | 
199  | 0  |   printU6ShiftedBy(0, MI, OpNum, O);  | 
200  | 0  | }  | 
201  |  |  | 
202  |  | void ARC_LLVM_printInst(MCInst *MI, uint64_t Address, const char *Annot,  | 
203  |  |       SStream *O)  | 
204  | 0  | { | 
205  | 0  |   printInst(MI, Address, Annot, O);  | 
206  | 0  | }  | 
207  |  |  | 
208  |  | const char *ARC_LLVM_getRegisterName(unsigned RegNo)  | 
209  | 0  | { | 
210  | 0  |   return getRegisterName(RegNo);  | 
211  | 0  | }  | 
212  |  |  | 
213  |  | #endif  |