/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- C++ -*-===// |
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 is part of the Sparc Disassembler. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "Sparc.h" |
15 | | #include "SparcRegisterInfo.h" |
16 | | #include "SparcSubtarget.h" |
17 | | #include "llvm/MC/MCAsmInfo.h" |
18 | | #include "llvm/MC/MCContext.h" |
19 | | #include "llvm/MC/MCDisassembler/MCDisassembler.h" |
20 | | #include "llvm/MC/MCFixedLenDisassembler.h" |
21 | | #include "llvm/MC/MCInst.h" |
22 | | #include "llvm/Support/TargetRegistry.h" |
23 | | |
24 | | using namespace llvm; |
25 | | |
26 | | #define DEBUG_TYPE "sparc-disassembler" |
27 | | |
28 | | typedef MCDisassembler::DecodeStatus DecodeStatus; |
29 | | |
30 | | namespace { |
31 | | |
32 | | /// A disassembler class for Sparc. |
33 | | class SparcDisassembler : public MCDisassembler { |
34 | | public: |
35 | | SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) |
36 | 8 | : MCDisassembler(STI, Ctx) {} |
37 | 8 | virtual ~SparcDisassembler() {} |
38 | | |
39 | | DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, |
40 | | ArrayRef<uint8_t> Bytes, uint64_t Address, |
41 | | raw_ostream &VStream, |
42 | | raw_ostream &CStream) const override; |
43 | | }; |
44 | | } |
45 | | |
46 | | namespace llvm { |
47 | | Target &getTheSparcTarget(); |
48 | | Target &getTheSparcV9Target(); |
49 | | Target &getTheSparcelTarget(); |
50 | | } |
51 | | |
52 | | static MCDisassembler *createSparcDisassembler(const Target &T, |
53 | | const MCSubtargetInfo &STI, |
54 | 8 | MCContext &Ctx) { |
55 | 8 | return new SparcDisassembler(STI, Ctx); |
56 | 8 | } |
57 | | |
58 | | |
59 | 7.19k | extern "C" void LLVMInitializeSparcDisassembler() { |
60 | 7.19k | // Register the disassembler. |
61 | 7.19k | TargetRegistry::RegisterMCDisassembler(getTheSparcTarget(), |
62 | 7.19k | createSparcDisassembler); |
63 | 7.19k | TargetRegistry::RegisterMCDisassembler(getTheSparcV9Target(), |
64 | 7.19k | createSparcDisassembler); |
65 | 7.19k | TargetRegistry::RegisterMCDisassembler(getTheSparcelTarget(), |
66 | 7.19k | createSparcDisassembler); |
67 | 7.19k | } |
68 | | |
69 | | static const unsigned IntRegDecoderTable[] = { |
70 | | SP::G0, SP::G1, SP::G2, SP::G3, |
71 | | SP::G4, SP::G5, SP::G6, SP::G7, |
72 | | SP::O0, SP::O1, SP::O2, SP::O3, |
73 | | SP::O4, SP::O5, SP::O6, SP::O7, |
74 | | SP::L0, SP::L1, SP::L2, SP::L3, |
75 | | SP::L4, SP::L5, SP::L6, SP::L7, |
76 | | SP::I0, SP::I1, SP::I2, SP::I3, |
77 | | SP::I4, SP::I5, SP::I6, SP::I7 }; |
78 | | |
79 | | static const unsigned FPRegDecoderTable[] = { |
80 | | SP::F0, SP::F1, SP::F2, SP::F3, |
81 | | SP::F4, SP::F5, SP::F6, SP::F7, |
82 | | SP::F8, SP::F9, SP::F10, SP::F11, |
83 | | SP::F12, SP::F13, SP::F14, SP::F15, |
84 | | SP::F16, SP::F17, SP::F18, SP::F19, |
85 | | SP::F20, SP::F21, SP::F22, SP::F23, |
86 | | SP::F24, SP::F25, SP::F26, SP::F27, |
87 | | SP::F28, SP::F29, SP::F30, SP::F31 }; |
88 | | |
89 | | static const unsigned DFPRegDecoderTable[] = { |
90 | | SP::D0, SP::D16, SP::D1, SP::D17, |
91 | | SP::D2, SP::D18, SP::D3, SP::D19, |
92 | | SP::D4, SP::D20, SP::D5, SP::D21, |
93 | | SP::D6, SP::D22, SP::D7, SP::D23, |
94 | | SP::D8, SP::D24, SP::D9, SP::D25, |
95 | | SP::D10, SP::D26, SP::D11, SP::D27, |
96 | | SP::D12, SP::D28, SP::D13, SP::D29, |
97 | | SP::D14, SP::D30, SP::D15, SP::D31 }; |
98 | | |
99 | | static const unsigned QFPRegDecoderTable[] = { |
100 | | SP::Q0, SP::Q8, ~0U, ~0U, |
101 | | SP::Q1, SP::Q9, ~0U, ~0U, |
102 | | SP::Q2, SP::Q10, ~0U, ~0U, |
103 | | SP::Q3, SP::Q11, ~0U, ~0U, |
104 | | SP::Q4, SP::Q12, ~0U, ~0U, |
105 | | SP::Q5, SP::Q13, ~0U, ~0U, |
106 | | SP::Q6, SP::Q14, ~0U, ~0U, |
107 | | SP::Q7, SP::Q15, ~0U, ~0U } ; |
108 | | |
109 | | static const unsigned FCCRegDecoderTable[] = { |
110 | | SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 }; |
111 | | |
112 | | static const unsigned ASRRegDecoderTable[] = { |
113 | | SP::Y, SP::ASR1, SP::ASR2, SP::ASR3, |
114 | | SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7, |
115 | | SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11, |
116 | | SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15, |
117 | | SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19, |
118 | | SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23, |
119 | | SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27, |
120 | | SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31}; |
121 | | |
122 | | static const unsigned PRRegDecoderTable[] = { |
123 | | SP::TPC, SP::TNPC, SP::TSTATE, SP::TT, SP::TICK, SP::TBA, SP::PSTATE, |
124 | | SP::TL, SP::PIL, SP::CWP, SP::CANSAVE, SP::CANRESTORE, SP::CLEANWIN, |
125 | | SP::OTHERWIN, SP::WSTATE |
126 | | }; |
127 | | |
128 | | static const uint16_t IntPairDecoderTable[] = { |
129 | | SP::G0_G1, SP::G2_G3, SP::G4_G5, SP::G6_G7, |
130 | | SP::O0_O1, SP::O2_O3, SP::O4_O5, SP::O6_O7, |
131 | | SP::L0_L1, SP::L2_L3, SP::L4_L5, SP::L6_L7, |
132 | | SP::I0_I1, SP::I2_I3, SP::I4_I5, SP::I6_I7, |
133 | | }; |
134 | | |
135 | | static const unsigned CPRegDecoderTable[] = { |
136 | | SP::C0, SP::C1, SP::C2, SP::C3, |
137 | | SP::C4, SP::C5, SP::C6, SP::C7, |
138 | | SP::C8, SP::C9, SP::C10, SP::C11, |
139 | | SP::C12, SP::C13, SP::C14, SP::C15, |
140 | | SP::C16, SP::C17, SP::C18, SP::C19, |
141 | | SP::C20, SP::C21, SP::C22, SP::C23, |
142 | | SP::C24, SP::C25, SP::C26, SP::C27, |
143 | | SP::C28, SP::C29, SP::C30, SP::C31 |
144 | | }; |
145 | | |
146 | | |
147 | | static const uint16_t CPPairDecoderTable[] = { |
148 | | SP::C0_C1, SP::C2_C3, SP::C4_C5, SP::C6_C7, |
149 | | SP::C8_C9, SP::C10_C11, SP::C12_C13, SP::C14_C15, |
150 | | SP::C16_C17, SP::C18_C19, SP::C20_C21, SP::C22_C23, |
151 | | SP::C24_C25, SP::C26_C27, SP::C28_C29, SP::C30_C31 |
152 | | }; |
153 | | |
154 | | static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, |
155 | | unsigned RegNo, |
156 | | uint64_t Address, |
157 | 390 | const void *Decoder) { |
158 | 390 | if (RegNo > 31) |
159 | 0 | return MCDisassembler::Fail; |
160 | 390 | unsigned Reg = IntRegDecoderTable[RegNo]; |
161 | 390 | Inst.addOperand(MCOperand::createReg(Reg)); |
162 | 390 | return MCDisassembler::Success; |
163 | 390 | } |
164 | | |
165 | | static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, |
166 | | unsigned RegNo, |
167 | | uint64_t Address, |
168 | 0 | const void *Decoder) { |
169 | 0 | if (RegNo > 31) |
170 | 0 | return MCDisassembler::Fail; |
171 | 0 | unsigned Reg = IntRegDecoderTable[RegNo]; |
172 | 0 | Inst.addOperand(MCOperand::createReg(Reg)); |
173 | 0 | return MCDisassembler::Success; |
174 | 0 | } |
175 | | |
176 | | |
177 | | static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, |
178 | | unsigned RegNo, |
179 | | uint64_t Address, |
180 | 48 | const void *Decoder) { |
181 | 48 | if (RegNo > 31) |
182 | 0 | return MCDisassembler::Fail; |
183 | 48 | unsigned Reg = FPRegDecoderTable[RegNo]; |
184 | 48 | Inst.addOperand(MCOperand::createReg(Reg)); |
185 | 48 | return MCDisassembler::Success; |
186 | 48 | } |
187 | | |
188 | | |
189 | | static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, |
190 | | unsigned RegNo, |
191 | | uint64_t Address, |
192 | 50 | const void *Decoder) { |
193 | 50 | if (RegNo > 31) |
194 | 0 | return MCDisassembler::Fail; |
195 | 50 | unsigned Reg = DFPRegDecoderTable[RegNo]; |
196 | 50 | Inst.addOperand(MCOperand::createReg(Reg)); |
197 | 50 | return MCDisassembler::Success; |
198 | 50 | } |
199 | | |
200 | | |
201 | | static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, |
202 | | unsigned RegNo, |
203 | | uint64_t Address, |
204 | 42 | const void *Decoder) { |
205 | 42 | if (RegNo > 31) |
206 | 0 | return MCDisassembler::Fail; |
207 | 42 | |
208 | 42 | unsigned Reg = QFPRegDecoderTable[RegNo]; |
209 | 42 | if (Reg == ~0U) |
210 | 0 | return MCDisassembler::Fail; |
211 | 42 | Inst.addOperand(MCOperand::createReg(Reg)); |
212 | 42 | return MCDisassembler::Success; |
213 | 42 | } |
214 | | |
215 | | static DecodeStatus DecodeCPRegsRegisterClass(MCInst &Inst, |
216 | | unsigned RegNo, |
217 | | uint64_t Address, |
218 | 2 | const void *Decoder) { |
219 | 2 | if (RegNo > 31) |
220 | 0 | return MCDisassembler::Fail; |
221 | 2 | unsigned Reg = CPRegDecoderTable[RegNo]; |
222 | 2 | Inst.addOperand(MCOperand::createReg(Reg)); |
223 | 2 | return MCDisassembler::Success; |
224 | 2 | } |
225 | | |
226 | | static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
227 | | uint64_t Address, |
228 | 3 | const void *Decoder) { |
229 | 3 | if (RegNo > 3) |
230 | 0 | return MCDisassembler::Fail; |
231 | 3 | Inst.addOperand(MCOperand::createReg(FCCRegDecoderTable[RegNo])); |
232 | 3 | return MCDisassembler::Success; |
233 | 3 | } |
234 | | |
235 | | static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
236 | | uint64_t Address, |
237 | 5 | const void *Decoder) { |
238 | 5 | if (RegNo > 31) |
239 | 0 | return MCDisassembler::Fail; |
240 | 5 | Inst.addOperand(MCOperand::createReg(ASRRegDecoderTable[RegNo])); |
241 | 5 | return MCDisassembler::Success; |
242 | 5 | } |
243 | | |
244 | | static DecodeStatus DecodePRRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
245 | | uint64_t Address, |
246 | 0 | const void *Decoder) { |
247 | 0 | if (RegNo >= array_lengthof(PRRegDecoderTable)) |
248 | 0 | return MCDisassembler::Fail; |
249 | 0 | Inst.addOperand(MCOperand::createReg(PRRegDecoderTable[RegNo])); |
250 | 0 | return MCDisassembler::Success; |
251 | 0 | } |
252 | | |
253 | | static DecodeStatus DecodeIntPairRegisterClass(MCInst &Inst, unsigned RegNo, |
254 | 8 | uint64_t Address, const void *Decoder) { |
255 | 8 | DecodeStatus S = MCDisassembler::Success; |
256 | 8 | |
257 | 8 | if (RegNo > 31) |
258 | 0 | return MCDisassembler::Fail; |
259 | 8 | |
260 | 8 | if ((RegNo & 1)) |
261 | 0 | S = MCDisassembler::SoftFail; |
262 | 8 | |
263 | 8 | unsigned RegisterPair = IntPairDecoderTable[RegNo/2]; |
264 | 8 | Inst.addOperand(MCOperand::createReg(RegisterPair)); |
265 | 8 | return S; |
266 | 8 | } |
267 | | |
268 | | static DecodeStatus DecodeCPPairRegisterClass(MCInst &Inst, unsigned RegNo, |
269 | 0 | uint64_t Address, const void *Decoder) { |
270 | 0 | if (RegNo > 31) |
271 | 0 | return MCDisassembler::Fail; |
272 | 0 | |
273 | 0 | unsigned RegisterPair = CPPairDecoderTable[RegNo/2]; |
274 | 0 | Inst.addOperand(MCOperand::createReg(RegisterPair)); |
275 | 0 | return MCDisassembler::Success; |
276 | 0 | } |
277 | | |
278 | | static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, |
279 | | const void *Decoder); |
280 | | static DecodeStatus DecodeLoadIntPair(MCInst &Inst, unsigned insn, uint64_t Address, |
281 | | const void *Decoder); |
282 | | static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, |
283 | | const void *Decoder); |
284 | | static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, |
285 | | const void *Decoder); |
286 | | static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, |
287 | | const void *Decoder); |
288 | | static DecodeStatus DecodeLoadCP(MCInst &Inst, unsigned insn, uint64_t Address, |
289 | | const void *Decoder); |
290 | | static DecodeStatus DecodeLoadCPPair(MCInst &Inst, unsigned insn, uint64_t Address, |
291 | | const void *Decoder); |
292 | | static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, |
293 | | uint64_t Address, const void *Decoder); |
294 | | static DecodeStatus DecodeStoreIntPair(MCInst &Inst, unsigned insn, |
295 | | uint64_t Address, const void *Decoder); |
296 | | static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, |
297 | | uint64_t Address, const void *Decoder); |
298 | | static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, |
299 | | uint64_t Address, const void *Decoder); |
300 | | static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, |
301 | | uint64_t Address, const void *Decoder); |
302 | | static DecodeStatus DecodeStoreCP(MCInst &Inst, unsigned insn, |
303 | | uint64_t Address, const void *Decoder); |
304 | | static DecodeStatus DecodeStoreCPPair(MCInst &Inst, unsigned insn, |
305 | | uint64_t Address, const void *Decoder); |
306 | | static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, |
307 | | uint64_t Address, const void *Decoder); |
308 | | static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, |
309 | | uint64_t Address, const void *Decoder); |
310 | | static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address, |
311 | | const void *Decoder); |
312 | | static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, |
313 | | const void *Decoder); |
314 | | static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address, |
315 | | const void *Decoder); |
316 | | static DecodeStatus DecodeTRAP(MCInst &Inst, unsigned insn, uint64_t Address, |
317 | | const void *Decoder); |
318 | | |
319 | | #include "SparcGenDisassemblerTables.inc" |
320 | | |
321 | | /// Read four bytes from the ArrayRef and return 32 bit word. |
322 | | static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, |
323 | | uint64_t &Size, uint32_t &Insn, |
324 | 300 | bool IsLittleEndian) { |
325 | 300 | // We want to read exactly 4 Bytes of data. |
326 | 300 | if (Bytes.size() < 4) { |
327 | 0 | Size = 0; |
328 | 0 | return MCDisassembler::Fail; |
329 | 0 | } |
330 | 300 | |
331 | 300 | Insn = IsLittleEndian |
332 | 300 | ? (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | |
333 | 2 | (Bytes[3] << 24) |
334 | 300 | : (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | |
335 | 298 | (Bytes[0] << 24); |
336 | 300 | |
337 | 300 | return MCDisassembler::Success; |
338 | 300 | } |
339 | | |
340 | | DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, |
341 | | ArrayRef<uint8_t> Bytes, |
342 | | uint64_t Address, |
343 | | raw_ostream &VStream, |
344 | 300 | raw_ostream &CStream) const { |
345 | 300 | uint32_t Insn; |
346 | 300 | bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian(); |
347 | 300 | DecodeStatus Result = |
348 | 300 | readInstruction32(Bytes, Address, Size, Insn, isLittleEndian); |
349 | 300 | if (Result == MCDisassembler::Fail) |
350 | 0 | return MCDisassembler::Fail; |
351 | 300 | |
352 | 300 | // Calling the auto-generated decoder function. |
353 | 300 | |
354 | 300 | if (STI.getFeatureBits()[Sparc::FeatureV9]) |
355 | 176 | { |
356 | 176 | Result = decodeInstruction(DecoderTableSparcV932, Instr, Insn, Address, this, STI); |
357 | 176 | } |
358 | 124 | else |
359 | 124 | { |
360 | 124 | Result = decodeInstruction(DecoderTableSparcV832, Instr, Insn, Address, this, STI); |
361 | 124 | } |
362 | 300 | if (Result != MCDisassembler::Fail) |
363 | 38 | return Result; |
364 | 262 | |
365 | 262 | Result = |
366 | 262 | decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI); |
367 | 262 | |
368 | 262 | if (Result != MCDisassembler::Fail) { |
369 | 262 | Size = 4; |
370 | 262 | return Result; |
371 | 262 | } |
372 | 0 | |
373 | 0 | return MCDisassembler::Fail; |
374 | 0 | } |
375 | | |
376 | | |
377 | | typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, |
378 | | const void *Decoder); |
379 | | |
380 | | static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address, |
381 | | const void *Decoder, |
382 | 80 | bool isLoad, DecodeFunc DecodeRD) { |
383 | 80 | unsigned rd = fieldFromInstruction(insn, 25, 5); |
384 | 80 | unsigned rs1 = fieldFromInstruction(insn, 14, 5); |
385 | 80 | bool isImm = fieldFromInstruction(insn, 13, 1); |
386 | 80 | bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field) |
387 | 80 | unsigned asi = fieldFromInstruction(insn, 5, 8); |
388 | 80 | unsigned rs2 = 0; |
389 | 80 | unsigned simm13 = 0; |
390 | 80 | if (isImm) |
391 | 39 | simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); |
392 | 41 | else |
393 | 41 | rs2 = fieldFromInstruction(insn, 0, 5); |
394 | 80 | |
395 | 80 | DecodeStatus status; |
396 | 80 | if (isLoad) { |
397 | 44 | status = DecodeRD(MI, rd, Address, Decoder); |
398 | 44 | if (status != MCDisassembler::Success) |
399 | 0 | return status; |
400 | 80 | } |
401 | 80 | |
402 | 80 | // Decode rs1. |
403 | 80 | status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); |
404 | 80 | if (status != MCDisassembler::Success) |
405 | 0 | return status; |
406 | 80 | |
407 | 80 | // Decode imm|rs2. |
408 | 80 | if (isImm) |
409 | 39 | MI.addOperand(MCOperand::createImm(simm13)); |
410 | 41 | else { |
411 | 41 | status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); |
412 | 41 | if (status != MCDisassembler::Success) |
413 | 0 | return status; |
414 | 80 | } |
415 | 80 | |
416 | 80 | if (hasAsi) |
417 | 2 | MI.addOperand(MCOperand::createImm(asi)); |
418 | 80 | |
419 | 80 | if (!isLoad) { |
420 | 36 | status = DecodeRD(MI, rd, Address, Decoder); |
421 | 36 | if (status != MCDisassembler::Success) |
422 | 0 | return status; |
423 | 80 | } |
424 | 80 | return MCDisassembler::Success; |
425 | 80 | } |
426 | | |
427 | | static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, |
428 | 28 | const void *Decoder) { |
429 | 28 | return DecodeMem(Inst, insn, Address, Decoder, true, |
430 | 28 | DecodeIntRegsRegisterClass); |
431 | 28 | } |
432 | | |
433 | | static DecodeStatus DecodeLoadIntPair(MCInst &Inst, unsigned insn, uint64_t Address, |
434 | 4 | const void *Decoder) { |
435 | 4 | return DecodeMem(Inst, insn, Address, Decoder, true, |
436 | 4 | DecodeIntPairRegisterClass); |
437 | 4 | } |
438 | | |
439 | | static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, |
440 | 4 | const void *Decoder) { |
441 | 4 | return DecodeMem(Inst, insn, Address, Decoder, true, |
442 | 4 | DecodeFPRegsRegisterClass); |
443 | 4 | } |
444 | | |
445 | | static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, |
446 | 4 | const void *Decoder) { |
447 | 4 | return DecodeMem(Inst, insn, Address, Decoder, true, |
448 | 4 | DecodeDFPRegsRegisterClass); |
449 | 4 | } |
450 | | |
451 | | static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, |
452 | 4 | const void *Decoder) { |
453 | 4 | return DecodeMem(Inst, insn, Address, Decoder, true, |
454 | 4 | DecodeQFPRegsRegisterClass); |
455 | 4 | } |
456 | | |
457 | | static DecodeStatus DecodeLoadCP(MCInst &Inst, unsigned insn, uint64_t Address, |
458 | 0 | const void *Decoder) { |
459 | 0 | return DecodeMem(Inst, insn, Address, Decoder, true, |
460 | 0 | DecodeCPRegsRegisterClass); |
461 | 0 | } |
462 | | |
463 | | static DecodeStatus DecodeLoadCPPair(MCInst &Inst, unsigned insn, uint64_t Address, |
464 | 0 | const void *Decoder) { |
465 | 0 | return DecodeMem(Inst, insn, Address, Decoder, true, |
466 | 0 | DecodeCPPairRegisterClass); |
467 | 0 | } |
468 | | |
469 | | static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, |
470 | 16 | uint64_t Address, const void *Decoder) { |
471 | 16 | return DecodeMem(Inst, insn, Address, Decoder, false, |
472 | 16 | DecodeIntRegsRegisterClass); |
473 | 16 | } |
474 | | |
475 | | static DecodeStatus DecodeStoreIntPair(MCInst &Inst, unsigned insn, |
476 | 4 | uint64_t Address, const void *Decoder) { |
477 | 4 | return DecodeMem(Inst, insn, Address, Decoder, false, |
478 | 4 | DecodeIntPairRegisterClass); |
479 | 4 | } |
480 | | |
481 | | static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address, |
482 | 6 | const void *Decoder) { |
483 | 6 | return DecodeMem(Inst, insn, Address, Decoder, false, |
484 | 6 | DecodeFPRegsRegisterClass); |
485 | 6 | } |
486 | | |
487 | | static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, |
488 | 4 | uint64_t Address, const void *Decoder) { |
489 | 4 | return DecodeMem(Inst, insn, Address, Decoder, false, |
490 | 4 | DecodeDFPRegsRegisterClass); |
491 | 4 | } |
492 | | |
493 | | static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, |
494 | 4 | uint64_t Address, const void *Decoder) { |
495 | 4 | return DecodeMem(Inst, insn, Address, Decoder, false, |
496 | 4 | DecodeQFPRegsRegisterClass); |
497 | 4 | } |
498 | | |
499 | | static DecodeStatus DecodeStoreCP(MCInst &Inst, unsigned insn, |
500 | 2 | uint64_t Address, const void *Decoder) { |
501 | 2 | return DecodeMem(Inst, insn, Address, Decoder, false, |
502 | 2 | DecodeCPRegsRegisterClass); |
503 | 2 | } |
504 | | |
505 | | static DecodeStatus DecodeStoreCPPair(MCInst &Inst, unsigned insn, |
506 | 0 | uint64_t Address, const void *Decoder) { |
507 | 0 | return DecodeMem(Inst, insn, Address, Decoder, false, |
508 | 0 | DecodeCPPairRegisterClass); |
509 | 0 | } |
510 | | |
511 | | static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, |
512 | | uint64_t Address, uint64_t Offset, |
513 | | uint64_t Width, MCInst &MI, |
514 | 1 | const void *Decoder) { |
515 | 1 | const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); |
516 | 1 | return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, |
517 | 1 | Offset, Width); |
518 | 1 | } |
519 | | |
520 | | static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, |
521 | 1 | uint64_t Address, const void *Decoder) { |
522 | 1 | unsigned tgt = fieldFromInstruction(insn, 0, 30); |
523 | 1 | tgt <<= 2; |
524 | 1 | if (!tryAddingSymbolicOperand(tgt+Address, false, Address, |
525 | 1 | 0, 30, MI, Decoder)) |
526 | 1 | MI.addOperand(MCOperand::createImm(tgt)); |
527 | 1 | return MCDisassembler::Success; |
528 | 1 | } |
529 | | |
530 | | static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, |
531 | 18 | uint64_t Address, const void *Decoder) { |
532 | 18 | unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); |
533 | 18 | MI.addOperand(MCOperand::createImm(tgt)); |
534 | 18 | return MCDisassembler::Success; |
535 | 18 | } |
536 | | |
537 | | static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address, |
538 | 4 | const void *Decoder) { |
539 | 4 | |
540 | 4 | unsigned rd = fieldFromInstruction(insn, 25, 5); |
541 | 4 | unsigned rs1 = fieldFromInstruction(insn, 14, 5); |
542 | 4 | unsigned isImm = fieldFromInstruction(insn, 13, 1); |
543 | 4 | unsigned rs2 = 0; |
544 | 4 | unsigned simm13 = 0; |
545 | 4 | if (isImm) |
546 | 3 | simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); |
547 | 1 | else |
548 | 1 | rs2 = fieldFromInstruction(insn, 0, 5); |
549 | 4 | |
550 | 4 | // Decode RD. |
551 | 4 | DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); |
552 | 4 | if (status != MCDisassembler::Success) |
553 | 0 | return status; |
554 | 4 | |
555 | 4 | // Decode RS1. |
556 | 4 | status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); |
557 | 4 | if (status != MCDisassembler::Success) |
558 | 0 | return status; |
559 | 4 | |
560 | 4 | // Decode RS1 | SIMM13. |
561 | 4 | if (isImm) |
562 | 3 | MI.addOperand(MCOperand::createImm(simm13)); |
563 | 1 | else { |
564 | 1 | status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); |
565 | 1 | if (status != MCDisassembler::Success) |
566 | 0 | return status; |
567 | 4 | } |
568 | 4 | return MCDisassembler::Success; |
569 | 4 | } |
570 | | |
571 | | static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, |
572 | 1 | const void *Decoder) { |
573 | 1 | |
574 | 1 | unsigned rs1 = fieldFromInstruction(insn, 14, 5); |
575 | 1 | unsigned isImm = fieldFromInstruction(insn, 13, 1); |
576 | 1 | unsigned rs2 = 0; |
577 | 1 | unsigned simm13 = 0; |
578 | 1 | if (isImm) |
579 | 1 | simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); |
580 | 0 | else |
581 | 0 | rs2 = fieldFromInstruction(insn, 0, 5); |
582 | 1 | |
583 | 1 | // Decode RS1. |
584 | 1 | DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); |
585 | 1 | if (status != MCDisassembler::Success) |
586 | 0 | return status; |
587 | 1 | |
588 | 1 | // Decode RS2 | SIMM13. |
589 | 1 | if (isImm) |
590 | 1 | MI.addOperand(MCOperand::createImm(simm13)); |
591 | 0 | else { |
592 | 0 | status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); |
593 | 0 | if (status != MCDisassembler::Success) |
594 | 0 | return status; |
595 | 1 | } |
596 | 1 | return MCDisassembler::Success; |
597 | 1 | } |
598 | | |
599 | | static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address, |
600 | 6 | const void *Decoder) { |
601 | 6 | |
602 | 6 | unsigned rd = fieldFromInstruction(insn, 25, 5); |
603 | 6 | unsigned rs1 = fieldFromInstruction(insn, 14, 5); |
604 | 6 | unsigned isImm = fieldFromInstruction(insn, 13, 1); |
605 | 6 | bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field) |
606 | 6 | unsigned asi = fieldFromInstruction(insn, 5, 8); |
607 | 6 | unsigned rs2 = 0; |
608 | 6 | unsigned simm13 = 0; |
609 | 6 | if (isImm) |
610 | 2 | simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13)); |
611 | 4 | else |
612 | 4 | rs2 = fieldFromInstruction(insn, 0, 5); |
613 | 6 | |
614 | 6 | // Decode RD. |
615 | 6 | DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder); |
616 | 6 | if (status != MCDisassembler::Success) |
617 | 0 | return status; |
618 | 6 | |
619 | 6 | // Decode RS1. |
620 | 6 | status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); |
621 | 6 | if (status != MCDisassembler::Success) |
622 | 0 | return status; |
623 | 6 | |
624 | 6 | // Decode RS1 | SIMM13. |
625 | 6 | if (isImm) |
626 | 2 | MI.addOperand(MCOperand::createImm(simm13)); |
627 | 4 | else { |
628 | 4 | status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); |
629 | 4 | if (status != MCDisassembler::Success) |
630 | 0 | return status; |
631 | 6 | } |
632 | 6 | |
633 | 6 | if (hasAsi) |
634 | 2 | MI.addOperand(MCOperand::createImm(asi)); |
635 | 6 | |
636 | 6 | return MCDisassembler::Success; |
637 | 6 | } |
638 | | |
639 | | static DecodeStatus DecodeTRAP(MCInst &MI, unsigned insn, uint64_t Address, |
640 | 38 | const void *Decoder) { |
641 | 38 | |
642 | 38 | unsigned rs1 = fieldFromInstruction(insn, 14, 5); |
643 | 38 | unsigned isImm = fieldFromInstruction(insn, 13, 1); |
644 | 38 | unsigned cc =fieldFromInstruction(insn, 25, 4); |
645 | 38 | unsigned rs2 = 0; |
646 | 38 | unsigned imm7 = 0; |
647 | 38 | if (isImm) |
648 | 18 | imm7 = fieldFromInstruction(insn, 0, 7); |
649 | 20 | else |
650 | 20 | rs2 = fieldFromInstruction(insn, 0, 5); |
651 | 38 | |
652 | 38 | // Decode RS1. |
653 | 38 | DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); |
654 | 38 | if (status != MCDisassembler::Success) |
655 | 0 | return status; |
656 | 38 | |
657 | 38 | // Decode RS1 | IMM7. |
658 | 38 | if (isImm) |
659 | 18 | MI.addOperand(MCOperand::createImm(imm7)); |
660 | 20 | else { |
661 | 20 | status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); |
662 | 20 | if (status != MCDisassembler::Success) |
663 | 0 | return status; |
664 | 38 | } |
665 | 38 | |
666 | 38 | // Decode CC |
667 | 38 | MI.addOperand(MCOperand::createImm(cc)); |
668 | 38 | |
669 | 38 | return MCDisassembler::Success; |
670 | 38 | } |