/src/capstonenext/arch/X86/X86InstPrinterCommon.c
Line  | Count  | Source  | 
1  |  | //===--- X86InstPrinterCommon.cpp - X86 assembly instruction printing -----===//  | 
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 file includes common code for rendering MCInst instances as Intel-style  | 
11  |  | // and Intel-style assembly.  | 
12  |  | //  | 
13  |  | //===----------------------------------------------------------------------===//  | 
14  |  |  | 
15  |  | /* Capstone Disassembly Engine */  | 
16  |  | /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */  | 
17  |  |  | 
18  |  | #ifdef _MSC_VER  | 
19  |  | // disable MSVC's warning on strncpy()  | 
20  |  | #pragma warning(disable : 4996)  | 
21  |  | // disable MSVC's warning on strncpy()  | 
22  |  | #pragma warning(disable : 28719)  | 
23  |  | #endif  | 
24  |  |  | 
25  |  | #if !defined(CAPSTONE_HAS_OSXKERNEL)  | 
26  |  | #include <ctype.h>  | 
27  |  | #endif  | 
28  |  | #include <capstone/platform.h>  | 
29  |  |  | 
30  |  | #if defined(CAPSTONE_HAS_OSXKERNEL)  | 
31  |  | #include <Availability.h>  | 
32  |  | #include <libkern/libkern.h>  | 
33  |  | #else  | 
34  |  | #include <stdio.h>  | 
35  |  | #include <stdlib.h>  | 
36  |  | #endif  | 
37  |  |  | 
38  |  | #include <string.h>  | 
39  |  |  | 
40  |  | #include "../../utils.h"  | 
41  |  | #include "../../MCInst.h"  | 
42  |  | #include "../../SStream.h"  | 
43  |  |  | 
44  |  | #include "X86InstPrinterCommon.h"  | 
45  |  | #include "X86Mapping.h"  | 
46  |  |  | 
47  |  | #ifndef CAPSTONE_X86_REDUCE  | 
48  |  | void printSSEAVXCC(MCInst *MI, unsigned Op, SStream *O)  | 
49  | 24.9k  | { | 
50  | 24.9k  |   uint8_t Imm =  | 
51  | 24.9k  |     (uint8_t)(MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x1f);  | 
52  | 24.9k  |   switch (Imm) { | 
53  | 0  |   default:  | 
54  | 0  |     break; //printf("Invalid avxcc argument!\n"); break; | 
55  | 10.4k  |   case 0:  | 
56  | 10.4k  |     SStream_concat0(O, "eq");  | 
57  | 10.4k  |     op_addAvxCC(MI, X86_AVX_CC_EQ);  | 
58  | 10.4k  |     break;  | 
59  | 2.31k  |   case 1:  | 
60  | 2.31k  |     SStream_concat0(O, "lt");  | 
61  | 2.31k  |     op_addAvxCC(MI, X86_AVX_CC_LT);  | 
62  | 2.31k  |     break;  | 
63  | 1.11k  |   case 2:  | 
64  | 1.11k  |     SStream_concat0(O, "le");  | 
65  | 1.11k  |     op_addAvxCC(MI, X86_AVX_CC_LE);  | 
66  | 1.11k  |     break;  | 
67  | 770  |   case 3:  | 
68  | 770  |     SStream_concat0(O, "unord");  | 
69  | 770  |     op_addAvxCC(MI, X86_AVX_CC_UNORD);  | 
70  | 770  |     break;  | 
71  | 332  |   case 4:  | 
72  | 332  |     SStream_concat0(O, "neq");  | 
73  | 332  |     op_addAvxCC(MI, X86_AVX_CC_NEQ);  | 
74  | 332  |     break;  | 
75  | 390  |   case 5:  | 
76  | 390  |     SStream_concat0(O, "nlt");  | 
77  | 390  |     op_addAvxCC(MI, X86_AVX_CC_NLT);  | 
78  | 390  |     break;  | 
79  | 223  |   case 6:  | 
80  | 223  |     SStream_concat0(O, "nle");  | 
81  | 223  |     op_addAvxCC(MI, X86_AVX_CC_NLE);  | 
82  | 223  |     break;  | 
83  | 442  |   case 7:  | 
84  | 442  |     SStream_concat0(O, "ord");  | 
85  | 442  |     op_addAvxCC(MI, X86_AVX_CC_ORD);  | 
86  | 442  |     break;  | 
87  | 460  |   case 8:  | 
88  | 460  |     SStream_concat0(O, "eq_uq");  | 
89  | 460  |     op_addAvxCC(MI, X86_AVX_CC_EQ_UQ);  | 
90  | 460  |     break;  | 
91  | 404  |   case 9:  | 
92  | 404  |     SStream_concat0(O, "nge");  | 
93  | 404  |     op_addAvxCC(MI, X86_AVX_CC_NGE);  | 
94  | 404  |     break;  | 
95  | 105  |   case 0xa:  | 
96  | 105  |     SStream_concat0(O, "ngt");  | 
97  | 105  |     op_addAvxCC(MI, X86_AVX_CC_NGT);  | 
98  | 105  |     break;  | 
99  | 590  |   case 0xb:  | 
100  | 590  |     SStream_concat0(O, "false");  | 
101  | 590  |     op_addAvxCC(MI, X86_AVX_CC_FALSE);  | 
102  | 590  |     break;  | 
103  | 271  |   case 0xc:  | 
104  | 271  |     SStream_concat0(O, "neq_oq");  | 
105  | 271  |     op_addAvxCC(MI, X86_AVX_CC_NEQ_OQ);  | 
106  | 271  |     break;  | 
107  | 112  |   case 0xd:  | 
108  | 112  |     SStream_concat0(O, "ge");  | 
109  | 112  |     op_addAvxCC(MI, X86_AVX_CC_GE);  | 
110  | 112  |     break;  | 
111  | 112  |   case 0xe:  | 
112  | 112  |     SStream_concat0(O, "gt");  | 
113  | 112  |     op_addAvxCC(MI, X86_AVX_CC_GT);  | 
114  | 112  |     break;  | 
115  | 208  |   case 0xf:  | 
116  | 208  |     SStream_concat0(O, "true");  | 
117  | 208  |     op_addAvxCC(MI, X86_AVX_CC_TRUE);  | 
118  | 208  |     break;  | 
119  | 370  |   case 0x10:  | 
120  | 370  |     SStream_concat0(O, "eq_os");  | 
121  | 370  |     op_addAvxCC(MI, X86_AVX_CC_EQ_OS);  | 
122  | 370  |     break;  | 
123  | 239  |   case 0x11:  | 
124  | 239  |     SStream_concat0(O, "lt_oq");  | 
125  | 239  |     op_addAvxCC(MI, X86_AVX_CC_LT_OQ);  | 
126  | 239  |     break;  | 
127  | 354  |   case 0x12:  | 
128  | 354  |     SStream_concat0(O, "le_oq");  | 
129  | 354  |     op_addAvxCC(MI, X86_AVX_CC_LE_OQ);  | 
130  | 354  |     break;  | 
131  | 269  |   case 0x13:  | 
132  | 269  |     SStream_concat0(O, "unord_s");  | 
133  | 269  |     op_addAvxCC(MI, X86_AVX_CC_UNORD_S);  | 
134  | 269  |     break;  | 
135  | 447  |   case 0x14:  | 
136  | 447  |     SStream_concat0(O, "neq_us");  | 
137  | 447  |     op_addAvxCC(MI, X86_AVX_CC_NEQ_US);  | 
138  | 447  |     break;  | 
139  | 992  |   case 0x15:  | 
140  | 992  |     SStream_concat0(O, "nlt_uq");  | 
141  | 992  |     op_addAvxCC(MI, X86_AVX_CC_NLT_UQ);  | 
142  | 992  |     break;  | 
143  | 115  |   case 0x16:  | 
144  | 115  |     SStream_concat0(O, "nle_uq");  | 
145  | 115  |     op_addAvxCC(MI, X86_AVX_CC_NLE_UQ);  | 
146  | 115  |     break;  | 
147  | 389  |   case 0x17:  | 
148  | 389  |     SStream_concat0(O, "ord_s");  | 
149  | 389  |     op_addAvxCC(MI, X86_AVX_CC_ORD_S);  | 
150  | 389  |     break;  | 
151  | 291  |   case 0x18:  | 
152  | 291  |     SStream_concat0(O, "eq_us");  | 
153  | 291  |     op_addAvxCC(MI, X86_AVX_CC_EQ_US);  | 
154  | 291  |     break;  | 
155  | 202  |   case 0x19:  | 
156  | 202  |     SStream_concat0(O, "nge_uq");  | 
157  | 202  |     op_addAvxCC(MI, X86_AVX_CC_NGE_UQ);  | 
158  | 202  |     break;  | 
159  | 216  |   case 0x1a:  | 
160  | 216  |     SStream_concat0(O, "ngt_uq");  | 
161  | 216  |     op_addAvxCC(MI, X86_AVX_CC_NGT_UQ);  | 
162  | 216  |     break;  | 
163  | 840  |   case 0x1b:  | 
164  | 840  |     SStream_concat0(O, "false_os");  | 
165  | 840  |     op_addAvxCC(MI, X86_AVX_CC_FALSE_OS);  | 
166  | 840  |     break;  | 
167  | 1.12k  |   case 0x1c:  | 
168  | 1.12k  |     SStream_concat0(O, "neq_os");  | 
169  | 1.12k  |     op_addAvxCC(MI, X86_AVX_CC_NEQ_OS);  | 
170  | 1.12k  |     break;  | 
171  | 202  |   case 0x1d:  | 
172  | 202  |     SStream_concat0(O, "ge_oq");  | 
173  | 202  |     op_addAvxCC(MI, X86_AVX_CC_GE_OQ);  | 
174  | 202  |     break;  | 
175  | 121  |   case 0x1e:  | 
176  | 121  |     SStream_concat0(O, "gt_oq");  | 
177  | 121  |     op_addAvxCC(MI, X86_AVX_CC_GT_OQ);  | 
178  | 121  |     break;  | 
179  | 433  |   case 0x1f:  | 
180  | 433  |     SStream_concat0(O, "true_us");  | 
181  | 433  |     op_addAvxCC(MI, X86_AVX_CC_TRUE_US);  | 
182  | 433  |     break;  | 
183  | 24.9k  |   }  | 
184  |  |  | 
185  | 24.9k  |   MI->popcode_adjust = Imm + 1;  | 
186  | 24.9k  | }  | 
187  |  |  | 
188  |  | void printXOPCC(MCInst *MI, unsigned Op, SStream *O)  | 
189  | 3.63k  | { | 
190  | 3.63k  |   int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op));  | 
191  |  |  | 
192  | 3.63k  |   switch (Imm) { | 
193  | 0  |   default: // llvm_unreachable("Invalid xopcc argument!"); | 
194  | 1.16k  |   case 0:  | 
195  | 1.16k  |     SStream_concat0(O, "lt");  | 
196  | 1.16k  |     op_addXopCC(MI, X86_XOP_CC_LT);  | 
197  | 1.16k  |     break;  | 
198  | 458  |   case 1:  | 
199  | 458  |     SStream_concat0(O, "le");  | 
200  | 458  |     op_addXopCC(MI, X86_XOP_CC_LE);  | 
201  | 458  |     break;  | 
202  | 348  |   case 2:  | 
203  | 348  |     SStream_concat0(O, "gt");  | 
204  | 348  |     op_addXopCC(MI, X86_XOP_CC_GT);  | 
205  | 348  |     break;  | 
206  | 492  |   case 3:  | 
207  | 492  |     SStream_concat0(O, "ge");  | 
208  | 492  |     op_addXopCC(MI, X86_XOP_CC_GE);  | 
209  | 492  |     break;  | 
210  | 275  |   case 4:  | 
211  | 275  |     SStream_concat0(O, "eq");  | 
212  | 275  |     op_addXopCC(MI, X86_XOP_CC_EQ);  | 
213  | 275  |     break;  | 
214  | 277  |   case 5:  | 
215  | 277  |     SStream_concat0(O, "neq");  | 
216  | 277  |     op_addXopCC(MI, X86_XOP_CC_NEQ);  | 
217  | 277  |     break;  | 
218  | 267  |   case 6:  | 
219  | 267  |     SStream_concat0(O, "false");  | 
220  | 267  |     op_addXopCC(MI, X86_XOP_CC_FALSE);  | 
221  | 267  |     break;  | 
222  | 347  |   case 7:  | 
223  | 347  |     SStream_concat0(O, "true");  | 
224  | 347  |     op_addXopCC(MI, X86_XOP_CC_TRUE);  | 
225  | 347  |     break;  | 
226  | 3.63k  |   }  | 
227  | 3.63k  | }  | 
228  |  |  | 
229  |  | void printRoundingControl(MCInst *MI, unsigned Op, SStream *O)  | 
230  | 6.12k  | { | 
231  | 6.12k  |   int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3;  | 
232  | 6.12k  |   switch (Imm) { | 
233  | 2.70k  |   case 0:  | 
234  | 2.70k  |     SStream_concat0(O, "{rn-sae}"); | 
235  | 2.70k  |     op_addAvxSae(MI);  | 
236  | 2.70k  |     op_addAvxRoundingMode(MI, X86_AVX_RM_RN);  | 
237  | 2.70k  |     break;  | 
238  | 1.62k  |   case 1:  | 
239  | 1.62k  |     SStream_concat0(O, "{rd-sae}"); | 
240  | 1.62k  |     op_addAvxSae(MI);  | 
241  | 1.62k  |     op_addAvxRoundingMode(MI, X86_AVX_RM_RD);  | 
242  | 1.62k  |     break;  | 
243  | 987  |   case 2:  | 
244  | 987  |     SStream_concat0(O, "{ru-sae}"); | 
245  | 987  |     op_addAvxSae(MI);  | 
246  | 987  |     op_addAvxRoundingMode(MI, X86_AVX_RM_RU);  | 
247  | 987  |     break;  | 
248  | 806  |   case 3:  | 
249  | 806  |     SStream_concat0(O, "{rz-sae}"); | 
250  | 806  |     op_addAvxSae(MI);  | 
251  | 806  |     op_addAvxRoundingMode(MI, X86_AVX_RM_RZ);  | 
252  | 806  |     break;  | 
253  | 0  |   default:  | 
254  | 0  |     break; // never reach  | 
255  | 6.12k  |   }  | 
256  | 6.12k  | }  | 
257  |  | #endif  |