1 | //===- HexagonDisassembler.cpp - Disassembler for Hexagon ISA -------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "MCTargetDesc/HexagonBaseInfo.h" |
10 | #include "MCTargetDesc/HexagonMCChecker.h" |
11 | #include "MCTargetDesc/HexagonMCInstrInfo.h" |
12 | #include "MCTargetDesc/HexagonMCTargetDesc.h" |
13 | #include "TargetInfo/HexagonTargetInfo.h" |
14 | #include "llvm/ADT/ArrayRef.h" |
15 | #include "llvm/ADT/STLExtras.h" |
16 | #include "llvm/MC/MCContext.h" |
17 | #include "llvm/MC/MCDecoderOps.h" |
18 | #include "llvm/MC/MCDisassembler/MCDisassembler.h" |
19 | #include "llvm/MC/MCExpr.h" |
20 | #include "llvm/MC/MCInst.h" |
21 | #include "llvm/MC/MCInstrInfo.h" |
22 | #include "llvm/MC/MCRegisterInfo.h" |
23 | #include "llvm/MC/MCSubtargetInfo.h" |
24 | #include "llvm/MC/TargetRegistry.h" |
25 | #include "llvm/Support/Endian.h" |
26 | #include "llvm/Support/MathExtras.h" |
27 | #include "llvm/Support/raw_ostream.h" |
28 | #include <cassert> |
29 | #include <cstddef> |
30 | #include <cstdint> |
31 | #include <memory> |
32 | |
33 | #define DEBUG_TYPE "hexagon-disassembler" |
34 | |
35 | using namespace llvm; |
36 | using namespace Hexagon; |
37 | |
38 | using DecodeStatus = MCDisassembler::DecodeStatus; |
39 | |
40 | namespace { |
41 | |
42 | /// Hexagon disassembler for all Hexagon platforms. |
43 | class HexagonDisassembler : public MCDisassembler { |
44 | public: |
45 | std::unique_ptr<MCInstrInfo const> const MCII; |
46 | std::unique_ptr<MCInst *> CurrentBundle; |
47 | mutable MCInst const *CurrentExtender; |
48 | |
49 | HexagonDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, |
50 | MCInstrInfo const *MCII) |
51 | : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(new MCInst *), |
52 | CurrentExtender(nullptr) {} |
53 | |
54 | DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB, |
55 | ArrayRef<uint8_t> Bytes, uint64_t Address, |
56 | raw_ostream &CStream, bool &Complete) const; |
57 | DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, |
58 | ArrayRef<uint8_t> Bytes, uint64_t Address, |
59 | raw_ostream &CStream) const override; |
60 | void remapInstruction(MCInst &Instr) const; |
61 | }; |
62 | |
63 | static uint64_t fullValue(HexagonDisassembler const &Disassembler, MCInst &MI, |
64 | int64_t Value) { |
65 | MCInstrInfo MCII = *Disassembler.MCII; |
66 | if (!Disassembler.CurrentExtender || |
67 | MI.size() != HexagonMCInstrInfo::getExtendableOp(MCII, MCI: MI)) |
68 | return Value; |
69 | unsigned Alignment = HexagonMCInstrInfo::getExtentAlignment(MCII, MCI: MI); |
70 | uint32_t Lower6 = static_cast<uint32_t>(Value >> Alignment) & 0x3f; |
71 | int64_t Bits; |
72 | bool Success = |
73 | Disassembler.CurrentExtender->getOperand(i: 0).getExpr()->evaluateAsAbsolute( |
74 | Res&: Bits); |
75 | assert(Success); |
76 | (void)Success; |
77 | uint64_t Upper26 = static_cast<uint64_t>(Bits); |
78 | uint64_t Operand = Upper26 | Lower6; |
79 | return Operand; |
80 | } |
81 | static HexagonDisassembler const &disassembler(const MCDisassembler *Decoder) { |
82 | return *static_cast<HexagonDisassembler const *>(Decoder); |
83 | } |
84 | template <size_t T> |
85 | static void signedDecoder(MCInst &MI, unsigned tmp, |
86 | const MCDisassembler *Decoder) { |
87 | HexagonDisassembler const &Disassembler = disassembler(Decoder); |
88 | int64_t FullValue = fullValue(Disassembler, MI, SignExtend64<T>(tmp)); |
89 | int64_t Extended = SignExtend64<32>(x: FullValue); |
90 | HexagonMCInstrInfo::addConstant(MI, Value: Extended, Context&: Disassembler.getContext()); |
91 | } |
92 | } |
93 | |
94 | // Forward declare these because the auto-generated code will reference them. |
95 | // Definitions are further down. |
96 | |
97 | static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
98 | uint64_t Address, |
99 | const MCDisassembler *Decoder); |
100 | static DecodeStatus |
101 | DecodeGeneralSubRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
102 | uint64_t Address, |
103 | const MCDisassembler *Decoder); |
104 | static DecodeStatus |
105 | DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, |
106 | const MCDisassembler *Decoder); |
107 | static DecodeStatus DecodeHvxVRRegisterClass(MCInst &Inst, unsigned RegNo, |
108 | uint64_t Address, |
109 | const MCDisassembler *Decoder); |
110 | static DecodeStatus |
111 | DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, |
112 | const MCDisassembler *Decoder); |
113 | static DecodeStatus |
114 | DecodeGeneralDoubleLow8RegsRegisterClass(MCInst &Inst, unsigned RegNo, |
115 | uint64_t Address, |
116 | const MCDisassembler *Decoder); |
117 | static DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo, |
118 | uint64_t Address, |
119 | const MCDisassembler *Decoder); |
120 | static DecodeStatus DecodeHvxVQRRegisterClass(MCInst &Inst, unsigned RegNo, |
121 | uint64_t Address, |
122 | const MCDisassembler *Decoder); |
123 | static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
124 | uint64_t Address, |
125 | const MCDisassembler *Decoder); |
126 | static DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo, |
127 | uint64_t Address, |
128 | const MCDisassembler *Decoder); |
129 | static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
130 | uint64_t Address, |
131 | const MCDisassembler *Decoder); |
132 | static DecodeStatus DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
133 | uint64_t Address, |
134 | const MCDisassembler *Decoder); |
135 | static DecodeStatus DecodeSysRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
136 | uint64_t Address, |
137 | const MCDisassembler *Decoder); |
138 | static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
139 | uint64_t Address, |
140 | const MCDisassembler *Decoder); |
141 | static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo, |
142 | uint64_t Address, |
143 | const MCDisassembler *Decoder); |
144 | static DecodeStatus |
145 | DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, |
146 | const MCDisassembler *Decoder); |
147 | static DecodeStatus DecodeSysRegs64RegisterClass(MCInst &Inst, unsigned RegNo, |
148 | uint64_t Address, |
149 | const MCDisassembler *Decoder); |
150 | |
151 | static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp, |
152 | uint64_t Address, |
153 | const MCDisassembler *Decoder); |
154 | static DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp, |
155 | uint64_t /*Address*/, |
156 | const MCDisassembler *Decoder); |
157 | static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address, |
158 | const MCDisassembler *Decoder); |
159 | #include "HexagonDepDecoders.inc" |
160 | #include "HexagonGenDisassemblerTables.inc" |
161 | |
162 | static MCDisassembler *createHexagonDisassembler(const Target &T, |
163 | const MCSubtargetInfo &STI, |
164 | MCContext &Ctx) { |
165 | return new HexagonDisassembler(STI, Ctx, T.createMCInstrInfo()); |
166 | } |
167 | |
168 | extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonDisassembler() { |
169 | TargetRegistry::RegisterMCDisassembler(T&: getTheHexagonTarget(), |
170 | Fn: createHexagonDisassembler); |
171 | } |
172 | |
173 | DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size, |
174 | ArrayRef<uint8_t> Bytes, |
175 | uint64_t Address, |
176 | raw_ostream &cs) const { |
177 | DecodeStatus Result = DecodeStatus::Success; |
178 | bool Complete = false; |
179 | Size = 0; |
180 | |
181 | *CurrentBundle = &MI; |
182 | MI.setOpcode(Hexagon::BUNDLE); |
183 | MI.addOperand(Op: MCOperand::createImm(Val: 0)); |
184 | while (Result == Success && !Complete) { |
185 | if (Bytes.size() < HEXAGON_INSTR_SIZE) |
186 | return MCDisassembler::Fail; |
187 | MCInst *Inst = getContext().createMCInst(); |
188 | Result = getSingleInstruction(Instr&: *Inst, MCB&: MI, Bytes, Address, CStream&: cs, Complete); |
189 | MI.addOperand(Op: MCOperand::createInst(Val: Inst)); |
190 | Size += HEXAGON_INSTR_SIZE; |
191 | Bytes = Bytes.slice(HEXAGON_INSTR_SIZE); |
192 | } |
193 | if (Result == MCDisassembler::Fail) |
194 | return Result; |
195 | if (Size > HEXAGON_MAX_PACKET_SIZE) |
196 | return MCDisassembler::Fail; |
197 | |
198 | const auto ArchSTI = Hexagon_MC::getArchSubtarget(STI: &STI); |
199 | const auto STI_ = (ArchSTI != nullptr) ? *ArchSTI : STI; |
200 | HexagonMCChecker Checker(getContext(), *MCII, STI_, MI, |
201 | *getContext().getRegisterInfo(), false); |
202 | if (!Checker.check()) |
203 | return MCDisassembler::Fail; |
204 | remapInstruction(Instr&: MI); |
205 | return MCDisassembler::Success; |
206 | } |
207 | |
208 | void HexagonDisassembler::remapInstruction(MCInst &Instr) const { |
209 | for (auto I: HexagonMCInstrInfo::bundleInstructions(MCI: Instr)) { |
210 | auto &MI = const_cast<MCInst &>(*I.getInst()); |
211 | switch (MI.getOpcode()) { |
212 | case Hexagon::S2_allocframe: |
213 | if (MI.getOperand(i: 0).getReg() == Hexagon::R29) { |
214 | MI.setOpcode(Hexagon::S6_allocframe_to_raw); |
215 | MI.erase(I: MI.begin () + 1); |
216 | MI.erase(I: MI.begin ()); |
217 | } |
218 | break; |
219 | case Hexagon::L2_deallocframe: |
220 | if (MI.getOperand(i: 0).getReg() == Hexagon::D15 && |
221 | MI.getOperand(i: 1).getReg() == Hexagon::R30) { |
222 | MI.setOpcode(L6_deallocframe_map_to_raw); |
223 | MI.erase(I: MI.begin () + 1); |
224 | MI.erase(I: MI.begin ()); |
225 | } |
226 | break; |
227 | case Hexagon::L4_return: |
228 | if (MI.getOperand(i: 0).getReg() == Hexagon::D15 && |
229 | MI.getOperand(i: 1).getReg() == Hexagon::R30) { |
230 | MI.setOpcode(L6_return_map_to_raw); |
231 | MI.erase(I: MI.begin () + 1); |
232 | MI.erase(I: MI.begin ()); |
233 | } |
234 | break; |
235 | case Hexagon::L4_return_t: |
236 | if (MI.getOperand(i: 0).getReg() == Hexagon::D15 && |
237 | MI.getOperand(i: 2).getReg() == Hexagon::R30) { |
238 | MI.setOpcode(L4_return_map_to_raw_t); |
239 | MI.erase(I: MI.begin () + 2); |
240 | MI.erase(I: MI.begin ()); |
241 | } |
242 | break; |
243 | case Hexagon::L4_return_f: |
244 | if (MI.getOperand(i: 0).getReg() == Hexagon::D15 && |
245 | MI.getOperand(i: 2).getReg() == Hexagon::R30) { |
246 | MI.setOpcode(L4_return_map_to_raw_f); |
247 | MI.erase(I: MI.begin () + 2); |
248 | MI.erase(I: MI.begin ()); |
249 | } |
250 | break; |
251 | case Hexagon::L4_return_tnew_pt: |
252 | if (MI.getOperand(i: 0).getReg() == Hexagon::D15 && |
253 | MI.getOperand(i: 2).getReg() == Hexagon::R30) { |
254 | MI.setOpcode(L4_return_map_to_raw_tnew_pt); |
255 | MI.erase(I: MI.begin () + 2); |
256 | MI.erase(I: MI.begin ()); |
257 | } |
258 | break; |
259 | case Hexagon::L4_return_fnew_pt: |
260 | if (MI.getOperand(i: 0).getReg() == Hexagon::D15 && |
261 | MI.getOperand(i: 2).getReg() == Hexagon::R30) { |
262 | MI.setOpcode(L4_return_map_to_raw_fnew_pt); |
263 | MI.erase(I: MI.begin () + 2); |
264 | MI.erase(I: MI.begin ()); |
265 | } |
266 | break; |
267 | case Hexagon::L4_return_tnew_pnt: |
268 | if (MI.getOperand(i: 0).getReg() == Hexagon::D15 && |
269 | MI.getOperand(i: 2).getReg() == Hexagon::R30) { |
270 | MI.setOpcode(L4_return_map_to_raw_tnew_pnt); |
271 | MI.erase(I: MI.begin () + 2); |
272 | MI.erase(I: MI.begin ()); |
273 | } |
274 | break; |
275 | case Hexagon::L4_return_fnew_pnt: |
276 | if (MI.getOperand(i: 0).getReg() == Hexagon::D15 && |
277 | MI.getOperand(i: 2).getReg() == Hexagon::R30) { |
278 | MI.setOpcode(L4_return_map_to_raw_fnew_pnt); |
279 | MI.erase(I: MI.begin () + 2); |
280 | MI.erase(I: MI.begin ()); |
281 | } |
282 | break; |
283 | } |
284 | } |
285 | } |
286 | |
287 | static void adjustDuplex(MCInst &MI, MCContext &Context) { |
288 | switch (MI.getOpcode()) { |
289 | case Hexagon::SA1_setin1: |
290 | MI.insert(I: MI.begin() + 1, |
291 | Op: MCOperand::createExpr(Val: MCConstantExpr::create(Value: -1, Ctx&: Context))); |
292 | break; |
293 | case Hexagon::SA1_dec: |
294 | MI.insert(I: MI.begin() + 2, |
295 | Op: MCOperand::createExpr(Val: MCConstantExpr::create(Value: -1, Ctx&: Context))); |
296 | break; |
297 | default: |
298 | break; |
299 | } |
300 | } |
301 | |
302 | DecodeStatus HexagonDisassembler::getSingleInstruction(MCInst &MI, MCInst &MCB, |
303 | ArrayRef<uint8_t> Bytes, |
304 | uint64_t Address, |
305 | raw_ostream &cs, |
306 | bool &Complete) const { |
307 | assert(Bytes.size() >= HEXAGON_INSTR_SIZE); |
308 | |
309 | uint32_t Instruction = support::endian::read32le(P: Bytes.data()); |
310 | |
311 | auto BundleSize = HexagonMCInstrInfo::bundleSize(MCI: MCB); |
312 | if ((Instruction & HexagonII::INST_PARSE_MASK) == |
313 | HexagonII::INST_PARSE_LOOP_END) { |
314 | if (BundleSize == 0) |
315 | HexagonMCInstrInfo::setInnerLoop(MCB); |
316 | else if (BundleSize == 1) |
317 | HexagonMCInstrInfo::setOuterLoop(MCB); |
318 | else |
319 | return DecodeStatus::Fail; |
320 | } |
321 | |
322 | CurrentExtender = HexagonMCInstrInfo::extenderForIndex( |
323 | MCB, Index: HexagonMCInstrInfo::bundleSize(MCI: MCB)); |
324 | |
325 | DecodeStatus Result = DecodeStatus::Fail; |
326 | if ((Instruction & HexagonII::INST_PARSE_MASK) == |
327 | HexagonII::INST_PARSE_DUPLEX) { |
328 | unsigned duplexIClass; |
329 | uint8_t const *DecodeLow, *DecodeHigh; |
330 | duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1); |
331 | switch (duplexIClass) { |
332 | default: |
333 | return MCDisassembler::Fail; |
334 | case 0: |
335 | DecodeLow = DecoderTableSUBINSN_L132; |
336 | DecodeHigh = DecoderTableSUBINSN_L132; |
337 | break; |
338 | case 1: |
339 | DecodeLow = DecoderTableSUBINSN_L232; |
340 | DecodeHigh = DecoderTableSUBINSN_L132; |
341 | break; |
342 | case 2: |
343 | DecodeLow = DecoderTableSUBINSN_L232; |
344 | DecodeHigh = DecoderTableSUBINSN_L232; |
345 | break; |
346 | case 3: |
347 | DecodeLow = DecoderTableSUBINSN_A32; |
348 | DecodeHigh = DecoderTableSUBINSN_A32; |
349 | break; |
350 | case 4: |
351 | DecodeLow = DecoderTableSUBINSN_L132; |
352 | DecodeHigh = DecoderTableSUBINSN_A32; |
353 | break; |
354 | case 5: |
355 | DecodeLow = DecoderTableSUBINSN_L232; |
356 | DecodeHigh = DecoderTableSUBINSN_A32; |
357 | break; |
358 | case 6: |
359 | DecodeLow = DecoderTableSUBINSN_S132; |
360 | DecodeHigh = DecoderTableSUBINSN_A32; |
361 | break; |
362 | case 7: |
363 | DecodeLow = DecoderTableSUBINSN_S232; |
364 | DecodeHigh = DecoderTableSUBINSN_A32; |
365 | break; |
366 | case 8: |
367 | DecodeLow = DecoderTableSUBINSN_S132; |
368 | DecodeHigh = DecoderTableSUBINSN_L132; |
369 | break; |
370 | case 9: |
371 | DecodeLow = DecoderTableSUBINSN_S132; |
372 | DecodeHigh = DecoderTableSUBINSN_L232; |
373 | break; |
374 | case 10: |
375 | DecodeLow = DecoderTableSUBINSN_S132; |
376 | DecodeHigh = DecoderTableSUBINSN_S132; |
377 | break; |
378 | case 11: |
379 | DecodeLow = DecoderTableSUBINSN_S232; |
380 | DecodeHigh = DecoderTableSUBINSN_S132; |
381 | break; |
382 | case 12: |
383 | DecodeLow = DecoderTableSUBINSN_S232; |
384 | DecodeHigh = DecoderTableSUBINSN_L132; |
385 | break; |
386 | case 13: |
387 | DecodeLow = DecoderTableSUBINSN_S232; |
388 | DecodeHigh = DecoderTableSUBINSN_L232; |
389 | break; |
390 | case 14: |
391 | DecodeLow = DecoderTableSUBINSN_S232; |
392 | DecodeHigh = DecoderTableSUBINSN_S232; |
393 | break; |
394 | } |
395 | MI.setOpcode(Hexagon::DuplexIClass0 + duplexIClass); |
396 | MCInst *MILow = getContext().createMCInst(); |
397 | MCInst *MIHigh = getContext().createMCInst(); |
398 | auto TmpExtender = CurrentExtender; |
399 | CurrentExtender = |
400 | nullptr; // constant extenders in duplex must always be in slot 1 |
401 | Result = decodeInstruction(DecodeTable: DecodeLow, MI&: *MILow, insn: Instruction & 0x1fff, Address, |
402 | DisAsm: this, STI); |
403 | CurrentExtender = TmpExtender; |
404 | if (Result != DecodeStatus::Success) |
405 | return DecodeStatus::Fail; |
406 | adjustDuplex(MI&: *MILow, Context&: getContext()); |
407 | Result = decodeInstruction( |
408 | DecodeTable: DecodeHigh, MI&: *MIHigh, insn: (Instruction >> 16) & 0x1fff, Address, DisAsm: this, STI); |
409 | if (Result != DecodeStatus::Success) |
410 | return DecodeStatus::Fail; |
411 | adjustDuplex(MI&: *MIHigh, Context&: getContext()); |
412 | MCOperand OPLow = MCOperand::createInst(Val: MILow); |
413 | MCOperand OPHigh = MCOperand::createInst(Val: MIHigh); |
414 | MI.addOperand(Op: OPLow); |
415 | MI.addOperand(Op: OPHigh); |
416 | Complete = true; |
417 | } else { |
418 | if ((Instruction & HexagonII::INST_PARSE_MASK) == |
419 | HexagonII::INST_PARSE_PACKET_END) |
420 | Complete = true; |
421 | |
422 | if (CurrentExtender != nullptr) |
423 | Result = decodeInstruction(DecodeTable: DecoderTableMustExtend32, MI, insn: Instruction, |
424 | Address, DisAsm: this, STI); |
425 | |
426 | if (Result != MCDisassembler::Success) |
427 | Result = decodeInstruction(DecodeTable: DecoderTable32, MI, insn: Instruction, Address, DisAsm: this, |
428 | STI); |
429 | |
430 | if (Result != MCDisassembler::Success && |
431 | STI.hasFeature(Feature: Hexagon::ExtensionHVX)) |
432 | Result = decodeInstruction(DecodeTable: DecoderTableEXT_mmvec32, MI, insn: Instruction, |
433 | Address, DisAsm: this, STI); |
434 | |
435 | } |
436 | |
437 | switch (MI.getOpcode()) { |
438 | case Hexagon::J4_cmpeqn1_f_jumpnv_nt: |
439 | case Hexagon::J4_cmpeqn1_f_jumpnv_t: |
440 | case Hexagon::J4_cmpeqn1_fp0_jump_nt: |
441 | case Hexagon::J4_cmpeqn1_fp0_jump_t: |
442 | case Hexagon::J4_cmpeqn1_fp1_jump_nt: |
443 | case Hexagon::J4_cmpeqn1_fp1_jump_t: |
444 | case Hexagon::J4_cmpeqn1_t_jumpnv_nt: |
445 | case Hexagon::J4_cmpeqn1_t_jumpnv_t: |
446 | case Hexagon::J4_cmpeqn1_tp0_jump_nt: |
447 | case Hexagon::J4_cmpeqn1_tp0_jump_t: |
448 | case Hexagon::J4_cmpeqn1_tp1_jump_nt: |
449 | case Hexagon::J4_cmpeqn1_tp1_jump_t: |
450 | case Hexagon::J4_cmpgtn1_f_jumpnv_nt: |
451 | case Hexagon::J4_cmpgtn1_f_jumpnv_t: |
452 | case Hexagon::J4_cmpgtn1_fp0_jump_nt: |
453 | case Hexagon::J4_cmpgtn1_fp0_jump_t: |
454 | case Hexagon::J4_cmpgtn1_fp1_jump_nt: |
455 | case Hexagon::J4_cmpgtn1_fp1_jump_t: |
456 | case Hexagon::J4_cmpgtn1_t_jumpnv_nt: |
457 | case Hexagon::J4_cmpgtn1_t_jumpnv_t: |
458 | case Hexagon::J4_cmpgtn1_tp0_jump_nt: |
459 | case Hexagon::J4_cmpgtn1_tp0_jump_t: |
460 | case Hexagon::J4_cmpgtn1_tp1_jump_nt: |
461 | case Hexagon::J4_cmpgtn1_tp1_jump_t: |
462 | MI.insert(I: MI.begin() + 1, |
463 | Op: MCOperand::createExpr(Val: MCConstantExpr::create(Value: -1, Ctx&: getContext()))); |
464 | break; |
465 | default: |
466 | break; |
467 | } |
468 | |
469 | if (HexagonMCInstrInfo::isNewValue(MCII: *MCII, MCI: MI)) { |
470 | unsigned OpIndex = HexagonMCInstrInfo::getNewValueOp(MCII: *MCII, MCI: MI); |
471 | MCOperand &MCO = MI.getOperand(i: OpIndex); |
472 | assert(MCO.isReg() && "New value consumers must be registers" ); |
473 | unsigned Register = |
474 | getContext().getRegisterInfo()->getEncodingValue(RegNo: MCO.getReg()); |
475 | if ((Register & 0x6) == 0) |
476 | // HexagonPRM 10.11 Bit 1-2 == 0 is reserved |
477 | return MCDisassembler::Fail; |
478 | unsigned Lookback = (Register & 0x6) >> 1; |
479 | unsigned Offset = 1; |
480 | bool Vector = HexagonMCInstrInfo::isVector(MCII: *MCII, MCI: MI); |
481 | bool PrevVector = false; |
482 | auto Instructions = HexagonMCInstrInfo::bundleInstructions(MCI: **CurrentBundle); |
483 | auto i = Instructions.end() - 1; |
484 | for (auto n = Instructions.begin() - 1;; --i, ++Offset) { |
485 | if (i == n) |
486 | // Couldn't find producer |
487 | return MCDisassembler::Fail; |
488 | bool CurrentVector = HexagonMCInstrInfo::isVector(MCII: *MCII, MCI: *i->getInst()); |
489 | if (Vector && !CurrentVector) |
490 | // Skip scalars when calculating distances for vectors |
491 | ++Lookback; |
492 | if (HexagonMCInstrInfo::isImmext(MCI: *i->getInst()) && (Vector == PrevVector)) |
493 | ++Lookback; |
494 | PrevVector = CurrentVector; |
495 | if (Offset == Lookback) |
496 | break; |
497 | } |
498 | auto const &Inst = *i->getInst(); |
499 | bool SubregBit = (Register & 0x1) != 0; |
500 | if (HexagonMCInstrInfo::hasNewValue2(MCII: *MCII, MCI: Inst)) { |
501 | // If subreg bit is set we're selecting the second produced newvalue |
502 | unsigned Producer = SubregBit ? |
503 | HexagonMCInstrInfo::getNewValueOperand(MCII: *MCII, MCI: Inst).getReg() : |
504 | HexagonMCInstrInfo::getNewValueOperand2(MCII: *MCII, MCI: Inst).getReg(); |
505 | assert(Producer != Hexagon::NoRegister); |
506 | MCO.setReg(Producer); |
507 | } else if (HexagonMCInstrInfo::hasNewValue(MCII: *MCII, MCI: Inst)) { |
508 | unsigned Producer = |
509 | HexagonMCInstrInfo::getNewValueOperand(MCII: *MCII, MCI: Inst).getReg(); |
510 | |
511 | if (HexagonMCInstrInfo::IsVecRegPair(VecReg: Producer)) { |
512 | const bool Rev = HexagonMCInstrInfo::IsReverseVecRegPair(VecReg: Producer); |
513 | const unsigned ProdPairIndex = |
514 | Rev ? Producer - Hexagon::WR0 : Producer - Hexagon::W0; |
515 | if (Rev) |
516 | SubregBit = !SubregBit; |
517 | Producer = (ProdPairIndex << 1) + SubregBit + Hexagon::V0; |
518 | } else if (SubregBit) |
519 | // Hexagon PRM 10.11 New-value operands |
520 | // Nt[0] is reserved and should always be encoded as zero. |
521 | return MCDisassembler::Fail; |
522 | assert(Producer != Hexagon::NoRegister); |
523 | MCO.setReg(Producer); |
524 | } else |
525 | return MCDisassembler::Fail; |
526 | } |
527 | |
528 | if (CurrentExtender != nullptr) { |
529 | MCInst const &Inst = HexagonMCInstrInfo::isDuplex(MCII: *MCII, MCI: MI) |
530 | ? *MI.getOperand(i: 1).getInst() |
531 | : MI; |
532 | if (!HexagonMCInstrInfo::isExtendable(MCII: *MCII, MCI: Inst) && |
533 | !HexagonMCInstrInfo::isExtended(MCII: *MCII, MCI: Inst)) |
534 | return MCDisassembler::Fail; |
535 | } |
536 | return Result; |
537 | } |
538 | |
539 | static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo, |
540 | ArrayRef<MCPhysReg> Table) { |
541 | if (RegNo < Table.size()) { |
542 | Inst.addOperand(Op: MCOperand::createReg(Reg: Table[RegNo])); |
543 | return MCDisassembler::Success; |
544 | } |
545 | |
546 | return MCDisassembler::Fail; |
547 | } |
548 | |
549 | static DecodeStatus |
550 | DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, |
551 | const MCDisassembler *Decoder) { |
552 | return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder); |
553 | } |
554 | |
555 | static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
556 | uint64_t Address, |
557 | const MCDisassembler *Decoder) { |
558 | static const MCPhysReg IntRegDecoderTable[] = { |
559 | Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4, |
560 | Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9, |
561 | Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14, |
562 | Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, |
563 | Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24, |
564 | Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29, |
565 | Hexagon::R30, Hexagon::R31}; |
566 | |
567 | return DecodeRegisterClass(Inst, RegNo, Table: IntRegDecoderTable); |
568 | } |
569 | |
570 | static DecodeStatus |
571 | DecodeGeneralSubRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
572 | uint64_t Address, |
573 | const MCDisassembler *Decoder) { |
574 | static const MCPhysReg GeneralSubRegDecoderTable[] = { |
575 | Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, |
576 | Hexagon::R4, Hexagon::R5, Hexagon::R6, Hexagon::R7, |
577 | Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, |
578 | Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, |
579 | }; |
580 | |
581 | return DecodeRegisterClass(Inst, RegNo, Table: GeneralSubRegDecoderTable); |
582 | } |
583 | |
584 | static DecodeStatus DecodeHvxVRRegisterClass(MCInst &Inst, unsigned RegNo, |
585 | uint64_t /*Address*/, |
586 | const MCDisassembler *Decoder) { |
587 | static const MCPhysReg HvxVRDecoderTable[] = { |
588 | Hexagon::V0, Hexagon::V1, Hexagon::V2, Hexagon::V3, Hexagon::V4, |
589 | Hexagon::V5, Hexagon::V6, Hexagon::V7, Hexagon::V8, Hexagon::V9, |
590 | Hexagon::V10, Hexagon::V11, Hexagon::V12, Hexagon::V13, Hexagon::V14, |
591 | Hexagon::V15, Hexagon::V16, Hexagon::V17, Hexagon::V18, Hexagon::V19, |
592 | Hexagon::V20, Hexagon::V21, Hexagon::V22, Hexagon::V23, Hexagon::V24, |
593 | Hexagon::V25, Hexagon::V26, Hexagon::V27, Hexagon::V28, Hexagon::V29, |
594 | Hexagon::V30, Hexagon::V31}; |
595 | |
596 | return DecodeRegisterClass(Inst, RegNo, Table: HvxVRDecoderTable); |
597 | } |
598 | |
599 | static DecodeStatus |
600 | DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
601 | uint64_t /*Address*/, |
602 | const MCDisassembler *Decoder) { |
603 | static const MCPhysReg DoubleRegDecoderTable[] = { |
604 | Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3, |
605 | Hexagon::D4, Hexagon::D5, Hexagon::D6, Hexagon::D7, |
606 | Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11, |
607 | Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15}; |
608 | |
609 | return DecodeRegisterClass(Inst, RegNo: RegNo >> 1, Table: DoubleRegDecoderTable); |
610 | } |
611 | |
612 | static DecodeStatus |
613 | DecodeGeneralDoubleLow8RegsRegisterClass(MCInst &Inst, unsigned RegNo, |
614 | uint64_t /*Address*/, |
615 | const MCDisassembler *Decoder) { |
616 | static const MCPhysReg GeneralDoubleLow8RegDecoderTable[] = { |
617 | Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3, |
618 | Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11}; |
619 | |
620 | return DecodeRegisterClass(Inst, RegNo, Table: GeneralDoubleLow8RegDecoderTable); |
621 | } |
622 | |
623 | static DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo, |
624 | uint64_t /*Address*/, |
625 | const MCDisassembler *Decoder) { |
626 | static const MCPhysReg HvxWRDecoderTable[] = { |
627 | Hexagon::W0, Hexagon::WR0, Hexagon::W1, Hexagon::WR1, Hexagon::W2, |
628 | Hexagon::WR2, Hexagon::W3, Hexagon::WR3, Hexagon::W4, Hexagon::WR4, |
629 | Hexagon::W5, Hexagon::WR5, Hexagon::W6, Hexagon::WR6, Hexagon::W7, |
630 | Hexagon::WR7, Hexagon::W8, Hexagon::WR8, Hexagon::W9, Hexagon::WR9, |
631 | Hexagon::W10, Hexagon::WR10, Hexagon::W11, Hexagon::WR11, Hexagon::W12, |
632 | Hexagon::WR12, Hexagon::W13, Hexagon::WR13, Hexagon::W14, Hexagon::WR14, |
633 | Hexagon::W15, Hexagon::WR15, |
634 | }; |
635 | |
636 | return DecodeRegisterClass(Inst, RegNo, Table: HvxWRDecoderTable); |
637 | } |
638 | |
639 | LLVM_ATTRIBUTE_UNUSED // Suppress warning temporarily. |
640 | static DecodeStatus |
641 | DecodeHvxVQRRegisterClass(MCInst &Inst, unsigned RegNo, |
642 | uint64_t /*Address*/, |
643 | const MCDisassembler *Decoder) { |
644 | static const MCPhysReg HvxVQRDecoderTable[] = { |
645 | Hexagon::VQ0, Hexagon::VQ1, Hexagon::VQ2, Hexagon::VQ3, |
646 | Hexagon::VQ4, Hexagon::VQ5, Hexagon::VQ6, Hexagon::VQ7}; |
647 | |
648 | return DecodeRegisterClass(Inst, RegNo: RegNo >> 2, Table: HvxVQRDecoderTable); |
649 | } |
650 | |
651 | static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
652 | uint64_t /*Address*/, |
653 | const MCDisassembler *Decoder) { |
654 | static const MCPhysReg PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1, |
655 | Hexagon::P2, Hexagon::P3}; |
656 | |
657 | return DecodeRegisterClass(Inst, RegNo, Table: PredRegDecoderTable); |
658 | } |
659 | |
660 | static DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo, |
661 | uint64_t /*Address*/, |
662 | const MCDisassembler *Decoder) { |
663 | static const MCPhysReg HvxQRDecoderTable[] = {Hexagon::Q0, Hexagon::Q1, |
664 | Hexagon::Q2, Hexagon::Q3}; |
665 | |
666 | return DecodeRegisterClass(Inst, RegNo, Table: HvxQRDecoderTable); |
667 | } |
668 | |
669 | static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
670 | uint64_t /*Address*/, |
671 | const MCDisassembler *Decoder) { |
672 | using namespace Hexagon; |
673 | |
674 | static const MCPhysReg CtrlRegDecoderTable[] = { |
675 | /* 0 */ SA0, LC0, SA1, LC1, |
676 | /* 4 */ P3_0, C5, M0, M1, |
677 | /* 8 */ USR, PC, UGP, GP, |
678 | /* 12 */ CS0, CS1, UPCYCLELO, UPCYCLEHI, |
679 | /* 16 */ FRAMELIMIT, FRAMEKEY, PKTCOUNTLO, PKTCOUNTHI, |
680 | /* 20 */ 0, 0, 0, 0, |
681 | /* 24 */ 0, 0, 0, 0, |
682 | /* 28 */ 0, 0, UTIMERLO, UTIMERHI |
683 | }; |
684 | |
685 | if (RegNo >= std::size(CtrlRegDecoderTable)) |
686 | return MCDisassembler::Fail; |
687 | |
688 | static_assert(NoRegister == 0, "Expecting NoRegister to be 0" ); |
689 | if (CtrlRegDecoderTable[RegNo] == NoRegister) |
690 | return MCDisassembler::Fail; |
691 | |
692 | unsigned Register = CtrlRegDecoderTable[RegNo]; |
693 | Inst.addOperand(Op: MCOperand::createReg(Reg: Register)); |
694 | return MCDisassembler::Success; |
695 | } |
696 | |
697 | static DecodeStatus |
698 | DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/, |
699 | const MCDisassembler *Decoder) { |
700 | using namespace Hexagon; |
701 | |
702 | static const MCPhysReg CtrlReg64DecoderTable[] = { |
703 | /* 0 */ C1_0, 0, C3_2, 0, |
704 | /* 4 */ C5_4, 0, C7_6, 0, |
705 | /* 8 */ C9_8, 0, C11_10, 0, |
706 | /* 12 */ CS, 0, UPCYCLE, 0, |
707 | /* 16 */ C17_16, 0, PKTCOUNT, 0, |
708 | /* 20 */ 0, 0, 0, 0, |
709 | /* 24 */ 0, 0, 0, 0, |
710 | /* 28 */ 0, 0, UTIMER, 0 |
711 | }; |
712 | |
713 | if (RegNo >= std::size(CtrlReg64DecoderTable)) |
714 | return MCDisassembler::Fail; |
715 | |
716 | static_assert(NoRegister == 0, "Expecting NoRegister to be 0" ); |
717 | if (CtrlReg64DecoderTable[RegNo] == NoRegister) |
718 | return MCDisassembler::Fail; |
719 | |
720 | unsigned Register = CtrlReg64DecoderTable[RegNo]; |
721 | Inst.addOperand(Op: MCOperand::createReg(Reg: Register)); |
722 | return MCDisassembler::Success; |
723 | } |
724 | |
725 | static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
726 | uint64_t /*Address*/, |
727 | const MCDisassembler *Decoder) { |
728 | unsigned Register = 0; |
729 | switch (RegNo) { |
730 | case 0: |
731 | Register = Hexagon::M0; |
732 | break; |
733 | case 1: |
734 | Register = Hexagon::M1; |
735 | break; |
736 | default: |
737 | return MCDisassembler::Fail; |
738 | } |
739 | Inst.addOperand(Op: MCOperand::createReg(Reg: Register)); |
740 | return MCDisassembler::Success; |
741 | } |
742 | |
743 | static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp, |
744 | uint64_t /*Address*/, |
745 | const MCDisassembler *Decoder) { |
746 | HexagonDisassembler const &Disassembler = disassembler(Decoder); |
747 | int64_t FullValue = fullValue(Disassembler, MI, Value: tmp); |
748 | assert(FullValue >= 0 && "Negative in unsigned decoder" ); |
749 | HexagonMCInstrInfo::addConstant(MI, Value: FullValue, Context&: Disassembler.getContext()); |
750 | return MCDisassembler::Success; |
751 | } |
752 | |
753 | static DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp, |
754 | uint64_t /*Address*/, |
755 | const MCDisassembler *Decoder) { |
756 | HexagonDisassembler const &Disassembler = disassembler(Decoder); |
757 | unsigned Bits = HexagonMCInstrInfo::getExtentBits(MCII: *Disassembler.MCII, MCI: MI); |
758 | tmp = SignExtend64(X: tmp, B: Bits); |
759 | signedDecoder<32>(MI, tmp, Decoder); |
760 | return MCDisassembler::Success; |
761 | } |
762 | |
763 | // custom decoder for various jump/call immediates |
764 | static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address, |
765 | const MCDisassembler *Decoder) { |
766 | HexagonDisassembler const &Disassembler = disassembler(Decoder); |
767 | unsigned Bits = HexagonMCInstrInfo::getExtentBits(MCII: *Disassembler.MCII, MCI: MI); |
768 | // r13_2 is not extendable, so if there are no extent bits, it's r13_2 |
769 | if (Bits == 0) |
770 | Bits = 15; |
771 | uint64_t FullValue = fullValue(Disassembler, MI, Value: SignExtend64(X: tmp, B: Bits)); |
772 | uint32_t Extended = FullValue + Address; |
773 | if (!Disassembler.tryAddingSymbolicOperand(Inst&: MI, Value: Extended, Address, IsBranch: true, Offset: 0, OpSize: 0, |
774 | InstSize: 4)) |
775 | HexagonMCInstrInfo::addConstant(MI, Value: Extended, Context&: Disassembler.getContext()); |
776 | return MCDisassembler::Success; |
777 | } |
778 | |
779 | static const uint16_t SysRegDecoderTable[] = { |
780 | Hexagon::SGP0, Hexagon::SGP1, Hexagon::STID, |
781 | Hexagon::ELR, Hexagon::BADVA0, Hexagon::BADVA1, |
782 | Hexagon::SSR, Hexagon::CCR, Hexagon::HTID, |
783 | Hexagon::BADVA, Hexagon::IMASK, Hexagon::S11, |
784 | Hexagon::S12, Hexagon::S13, Hexagon::S14, |
785 | Hexagon::S15, Hexagon::EVB, Hexagon::MODECTL, |
786 | Hexagon::SYSCFG, Hexagon::S19, Hexagon::S20, |
787 | Hexagon::VID, Hexagon::S22, Hexagon::S23, |
788 | Hexagon::S24, Hexagon::S25, Hexagon::S26, |
789 | Hexagon::CFGBASE, Hexagon::DIAG, Hexagon::REV, |
790 | Hexagon::PCYCLELO, Hexagon::PCYCLEHI, Hexagon::ISDBST, |
791 | Hexagon::ISDBCFG0, Hexagon::ISDBCFG1, Hexagon::S35, |
792 | Hexagon::BRKPTPC0, Hexagon::BRKPTCFG0, Hexagon::BRKPTPC1, |
793 | Hexagon::BRKPTCFG1, Hexagon::ISDBMBXIN, Hexagon::ISDBMBXOUT, |
794 | Hexagon::ISDBEN, Hexagon::ISDBGPR, Hexagon::S44, |
795 | Hexagon::S45, Hexagon::S46, Hexagon::S47, |
796 | Hexagon::PMUCNT0, Hexagon::PMUCNT1, Hexagon::PMUCNT2, |
797 | Hexagon::PMUCNT3, Hexagon::PMUEVTCFG, Hexagon::PMUCFG, |
798 | Hexagon::S54, Hexagon::S55, Hexagon::S56, |
799 | Hexagon::S57, Hexagon::S58, Hexagon::S59, |
800 | Hexagon::S60, Hexagon::S61, Hexagon::S62, |
801 | Hexagon::S63, Hexagon::S64, Hexagon::S65, |
802 | Hexagon::S66, Hexagon::S67, Hexagon::S68, |
803 | Hexagon::S69, Hexagon::S70, Hexagon::S71, |
804 | Hexagon::S72, Hexagon::S73, Hexagon::S74, |
805 | Hexagon::S75, Hexagon::S76, Hexagon::S77, |
806 | Hexagon::S78, Hexagon::S79, Hexagon::S80, |
807 | }; |
808 | |
809 | static DecodeStatus DecodeSysRegsRegisterClass(MCInst &Inst, unsigned RegNo, |
810 | uint64_t /*Address*/, |
811 | const MCDisassembler *Decoder) { |
812 | if (RegNo >= std::size(SysRegDecoderTable)) |
813 | return MCDisassembler::Fail; |
814 | |
815 | if (SysRegDecoderTable[RegNo] == Hexagon::NoRegister) |
816 | return MCDisassembler::Fail; |
817 | |
818 | unsigned Register = SysRegDecoderTable[RegNo]; |
819 | Inst.addOperand(Op: MCOperand::createReg(Reg: Register)); |
820 | return MCDisassembler::Success; |
821 | } |
822 | |
823 | static const uint16_t SysReg64DecoderTable[] = { |
824 | Hexagon::SGP1_0, Hexagon::S3_2, Hexagon::S5_4, Hexagon::S7_6, |
825 | Hexagon::S9_8, Hexagon::S11_10, Hexagon::S13_12, Hexagon::S15_14, |
826 | Hexagon::S17_16, Hexagon::S19_18, Hexagon::S21_20, Hexagon::S23_22, |
827 | Hexagon::S25_24, Hexagon::S27_26, Hexagon::S29_28, Hexagon::S31_30, |
828 | Hexagon::S33_32, Hexagon::S35_34, Hexagon::S37_36, Hexagon::S39_38, |
829 | Hexagon::S41_40, Hexagon::S43_42, Hexagon::S45_44, Hexagon::S47_46, |
830 | Hexagon::S49_48, Hexagon::S51_50, Hexagon::S53_52, Hexagon::S55_54, |
831 | Hexagon::S57_56, Hexagon::S59_58, Hexagon::S61_60, Hexagon::S63_62, |
832 | Hexagon::S65_64, Hexagon::S67_66, Hexagon::S69_68, Hexagon::S71_70, |
833 | Hexagon::S73_72, Hexagon::S75_74, Hexagon::S77_76, Hexagon::S79_78, |
834 | }; |
835 | |
836 | static DecodeStatus |
837 | DecodeSysRegs64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/, |
838 | const MCDisassembler *Decoder) { |
839 | RegNo = RegNo >> 1; |
840 | if (RegNo >= std::size(SysReg64DecoderTable)) |
841 | return MCDisassembler::Fail; |
842 | |
843 | if (SysReg64DecoderTable[RegNo] == Hexagon::NoRegister) |
844 | return MCDisassembler::Fail; |
845 | |
846 | unsigned Register = SysReg64DecoderTable[RegNo]; |
847 | Inst.addOperand(Op: MCOperand::createReg(Reg: Register)); |
848 | return MCDisassembler::Success; |
849 | } |
850 | |
851 | static DecodeStatus |
852 | DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/, |
853 | const MCDisassembler *Decoder) { |
854 | using namespace Hexagon; |
855 | |
856 | static const MCPhysReg GuestRegDecoderTable[] = { |
857 | /* 0 */ GELR, GSR, GOSP, G3, |
858 | /* 4 */ G4, G5, G6, G7, |
859 | /* 8 */ G8, G9, G10, G11, |
860 | /* 12 */ G12, G13, G14, G15, |
861 | /* 16 */ GPMUCNT4, GPMUCNT5, GPMUCNT6, GPMUCNT7, |
862 | /* 20 */ G20, G21, G22, G23, |
863 | /* 24 */ GPCYCLELO, GPCYCLEHI, GPMUCNT0, GPMUCNT1, |
864 | /* 28 */ GPMUCNT2, GPMUCNT3, G30, G31 |
865 | }; |
866 | |
867 | if (RegNo >= std::size(GuestRegDecoderTable)) |
868 | return MCDisassembler::Fail; |
869 | if (GuestRegDecoderTable[RegNo] == Hexagon::NoRegister) |
870 | return MCDisassembler::Fail; |
871 | |
872 | unsigned Register = GuestRegDecoderTable[RegNo]; |
873 | Inst.addOperand(Op: MCOperand::createReg(Reg: Register)); |
874 | return MCDisassembler::Success; |
875 | } |
876 | |
877 | static DecodeStatus |
878 | DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo, |
879 | uint64_t /*Address*/, |
880 | const MCDisassembler *Decoder) { |
881 | using namespace Hexagon; |
882 | |
883 | static const MCPhysReg GuestReg64DecoderTable[] = { |
884 | /* 0 */ G1_0, 0, G3_2, 0, |
885 | /* 4 */ G5_4, 0, G7_6, 0, |
886 | /* 8 */ G9_8, 0, G11_10, 0, |
887 | /* 12 */ G13_12, 0, G15_14, 0, |
888 | /* 16 */ G17_16, 0, G19_18, 0, |
889 | /* 20 */ G21_20, 0, G23_22, 0, |
890 | /* 24 */ G25_24, 0, G27_26, 0, |
891 | /* 28 */ G29_28, 0, G31_30, 0 |
892 | }; |
893 | |
894 | if (RegNo >= std::size(GuestReg64DecoderTable)) |
895 | return MCDisassembler::Fail; |
896 | if (GuestReg64DecoderTable[RegNo] == Hexagon::NoRegister) |
897 | return MCDisassembler::Fail; |
898 | |
899 | unsigned Register = GuestReg64DecoderTable[RegNo]; |
900 | Inst.addOperand(Op: MCOperand::createReg(Reg: Register)); |
901 | return MCDisassembler::Success; |
902 | } |
903 | |