/src/capstonenext/arch/LoongArch/LoongArchDisassembler.c
Line | Count | Source (jump to first uncovered line) |
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 | | //===-- LoongArchDisassembler.cpp - Disassembler for LoongArch ------------===// |
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 file implements the LoongArchDisassembler class. |
24 | | // |
25 | | //===----------------------------------------------------------------------===// |
26 | | #include <stdio.h> |
27 | | #include <string.h> |
28 | | #include <stdlib.h> |
29 | | #include <capstone/platform.h> |
30 | | |
31 | | #include "../../MCInst.h" |
32 | | #include "../../MathExtras.h" |
33 | | #include "../../MCInstPrinter.h" |
34 | | #include "../../MCDisassembler.h" |
35 | | #include "../../MCFixedLenDisassembler.h" |
36 | | #include "../../cs_priv.h" |
37 | | #include "../../utils.h" |
38 | | #include "LoongArchDisassemblerExtension.h" |
39 | | #define GET_SUBTARGETINFO_ENUM |
40 | | #include "LoongArchGenSubtargetInfo.inc" |
41 | | |
42 | | #define GET_INSTRINFO_ENUM |
43 | | #include "LoongArchGenInstrInfo.inc" |
44 | | |
45 | | #define GET_REGINFO_ENUM |
46 | | #include "LoongArchGenRegisterInfo.inc" |
47 | | |
48 | | #define CONCAT(a, b) CONCAT_(a, b) |
49 | | #define CONCAT_(a, b) a##_##b |
50 | | |
51 | | #define DEBUG_TYPE "loongarch-disassembler" |
52 | | |
53 | | static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, uint64_t RegNo, |
54 | | uint64_t Address, |
55 | | const void *Decoder) |
56 | 0 | { |
57 | 0 | if (RegNo >= 32) |
58 | 0 | return MCDisassembler_Fail; |
59 | 0 | MCOperand_CreateReg0(Inst, (LoongArch_R0 + RegNo)); |
60 | 0 | return MCDisassembler_Success; |
61 | 0 | } |
62 | | |
63 | | static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, uint64_t RegNo, |
64 | | uint64_t Address, |
65 | | const void *Decoder) |
66 | 0 | { |
67 | 0 | if (RegNo >= 32) |
68 | 0 | return MCDisassembler_Fail; |
69 | 0 | MCOperand_CreateReg0(Inst, (LoongArch_F0 + RegNo)); |
70 | 0 | return MCDisassembler_Success; |
71 | 0 | } |
72 | | |
73 | | static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, uint64_t RegNo, |
74 | | uint64_t Address, |
75 | | const void *Decoder) |
76 | 0 | { |
77 | 0 | if (RegNo >= 32) |
78 | 0 | return MCDisassembler_Fail; |
79 | 0 | MCOperand_CreateReg0(Inst, (LoongArch_F0_64 + RegNo)); |
80 | 0 | return MCDisassembler_Success; |
81 | 0 | } |
82 | | |
83 | | static DecodeStatus DecodeCFRRegisterClass(MCInst *Inst, uint64_t RegNo, |
84 | | uint64_t Address, |
85 | | const void *Decoder) |
86 | 0 | { |
87 | 0 | if (RegNo >= 8) |
88 | 0 | return MCDisassembler_Fail; |
89 | 0 | MCOperand_CreateReg0(Inst, (LoongArch_FCC0 + RegNo)); |
90 | 0 | return MCDisassembler_Success; |
91 | 0 | } |
92 | | |
93 | | static DecodeStatus DecodeFCSRRegisterClass(MCInst *Inst, uint64_t RegNo, |
94 | | uint64_t Address, |
95 | | const void *Decoder) |
96 | 0 | { |
97 | 0 | if (RegNo >= 4) |
98 | 0 | return MCDisassembler_Fail; |
99 | 0 | MCOperand_CreateReg0(Inst, (LoongArch_FCSR0 + RegNo)); |
100 | 0 | return MCDisassembler_Success; |
101 | 0 | } |
102 | | |
103 | | static DecodeStatus DecodeLSX128RegisterClass(MCInst *Inst, uint64_t RegNo, |
104 | | uint64_t Address, |
105 | | const void *Decoder) |
106 | 0 | { |
107 | 0 | if (RegNo >= 32) |
108 | 0 | return MCDisassembler_Fail; |
109 | 0 | MCOperand_CreateReg0(Inst, (LoongArch_VR0 + RegNo)); |
110 | 0 | return MCDisassembler_Success; |
111 | 0 | } |
112 | | |
113 | | static DecodeStatus DecodeLASX256RegisterClass(MCInst *Inst, uint64_t RegNo, |
114 | | uint64_t Address, |
115 | | const void *Decoder) |
116 | 0 | { |
117 | 0 | if (RegNo >= 32) |
118 | 0 | return MCDisassembler_Fail; |
119 | 0 | MCOperand_CreateReg0(Inst, (LoongArch_XR0 + RegNo)); |
120 | 0 | return MCDisassembler_Success; |
121 | 0 | } |
122 | | |
123 | | static DecodeStatus DecodeSCRRegisterClass(MCInst *Inst, uint64_t RegNo, |
124 | | uint64_t Address, |
125 | | const void *Decoder) |
126 | 0 | { |
127 | 0 | if (RegNo >= 4) |
128 | 0 | return MCDisassembler_Fail; |
129 | 0 | MCOperand_CreateReg0(Inst, (LoongArch_SCR0 + RegNo)); |
130 | 0 | return MCDisassembler_Success; |
131 | 0 | } |
132 | | |
133 | | #define DEFINE_decodeUImmOperand(N, P) \ |
134 | | static DecodeStatus CONCAT(decodeUImmOperand, CONCAT(N, P))( \ |
135 | | MCInst * Inst, uint64_t Imm, int64_t Address, \ |
136 | | const void *Decoder) \ |
137 | 0 | { \ |
138 | 0 | MCOperand_CreateImm0(Inst, (Imm + P)); \ |
139 | 0 | return MCDisassembler_Success; \ |
140 | 0 | } Unexecuted instantiation: LoongArchDisassembler.c:decodeUImmOperand_2_1 Unexecuted instantiation: LoongArchDisassembler.c:decodeUImmOperand_12_0 |
141 | | DEFINE_decodeUImmOperand(2, 1); |
142 | | DEFINE_decodeUImmOperand(12, 0); |
143 | | |
144 | | #define DEFINE_decodeSImmOperand(N, S) \ |
145 | | static DecodeStatus CONCAT(decodeSImmOperand, CONCAT(N, S))( \ |
146 | | MCInst * Inst, uint64_t Imm, int64_t Address, \ |
147 | | const void *Decoder) \ |
148 | 0 | { \ |
149 | 0 | MCOperand_CreateImm0(Inst, (SignExtend64((Imm << S), N + S))); \ |
150 | 0 | return MCDisassembler_Success; \ |
151 | 0 | } Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_5_0 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_12_0 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_16_0 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_20_0 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_14_2 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_9_3 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_10_2 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_11_1 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_8_3 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_8_2 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_8_1 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_8_0 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_21_2 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_16_2 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_26_2 Unexecuted instantiation: LoongArchDisassembler.c:decodeSImmOperand_13_0 |
152 | | DEFINE_decodeSImmOperand(5, 0); |
153 | | DEFINE_decodeSImmOperand(12, 0); |
154 | | DEFINE_decodeSImmOperand(16, 0); |
155 | | DEFINE_decodeSImmOperand(20, 0); |
156 | | DEFINE_decodeSImmOperand(14, 2); |
157 | | DEFINE_decodeSImmOperand(9, 3); |
158 | | DEFINE_decodeSImmOperand(10, 2); |
159 | | DEFINE_decodeSImmOperand(11, 1); |
160 | | DEFINE_decodeSImmOperand(8, 3); |
161 | | DEFINE_decodeSImmOperand(8, 2); |
162 | | DEFINE_decodeSImmOperand(8, 1); |
163 | | DEFINE_decodeSImmOperand(8, 0); |
164 | | DEFINE_decodeSImmOperand(21, 2); |
165 | | DEFINE_decodeSImmOperand(16, 2); |
166 | | DEFINE_decodeSImmOperand(26, 2); |
167 | | DEFINE_decodeSImmOperand(13, 0); |
168 | | |
169 | | #include "LoongArchGenDisassemblerTables.inc" |
170 | | |
171 | | static DecodeStatus getInstruction(MCInst *MI, uint64_t *Size, |
172 | | const uint8_t *Bytes, size_t BytesLen, |
173 | | uint64_t Address, SStream *CS) |
174 | 0 | { |
175 | 0 | uint32_t Insn; |
176 | 0 | DecodeStatus Result; |
177 | | |
178 | | // We want to read exactly 4 bytes of data because all LoongArch instructions |
179 | | // are fixed 32 bits. |
180 | 0 | if (BytesLen < 4) { |
181 | 0 | *Size = 0; |
182 | 0 | return MCDisassembler_Fail; |
183 | 0 | } |
184 | | |
185 | 0 | Insn = readBytes32(MI, Bytes); |
186 | | // Calling the auto-generated decoder function. |
187 | 0 | Result = decodeInstruction_4(DecoderTable32, MI, Insn, Address, NULL); |
188 | 0 | *Size = 4; |
189 | |
|
190 | 0 | return Result; |
191 | 0 | } |
192 | | |
193 | | DecodeStatus LoongArch_LLVM_getInstruction(MCInst *MI, uint64_t *Size, |
194 | | const uint8_t *Bytes, |
195 | | size_t BytesLen, uint64_t Address, |
196 | | SStream *CS) |
197 | 0 | { |
198 | 0 | return getInstruction(MI, Size, Bytes, BytesLen, Address, CS); |
199 | 0 | } |