xref: /openbsd-src/gnu/llvm/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
109467b48Spatrick //===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- C++ -*-===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file is part of the Sparc Disassembler.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick 
1309467b48Spatrick #include "MCTargetDesc/SparcMCTargetDesc.h"
1409467b48Spatrick #include "TargetInfo/SparcTargetInfo.h"
1509467b48Spatrick #include "llvm/MC/MCAsmInfo.h"
1609467b48Spatrick #include "llvm/MC/MCContext.h"
17*d415bd75Srobert #include "llvm/MC/MCDecoderOps.h"
1809467b48Spatrick #include "llvm/MC/MCDisassembler/MCDisassembler.h"
1909467b48Spatrick #include "llvm/MC/MCInst.h"
20*d415bd75Srobert #include "llvm/MC/TargetRegistry.h"
2109467b48Spatrick 
2209467b48Spatrick using namespace llvm;
2309467b48Spatrick 
2409467b48Spatrick #define DEBUG_TYPE "sparc-disassembler"
2509467b48Spatrick 
2609467b48Spatrick typedef MCDisassembler::DecodeStatus DecodeStatus;
2709467b48Spatrick 
2809467b48Spatrick namespace {
2909467b48Spatrick 
3009467b48Spatrick /// A disassembler class for Sparc.
3109467b48Spatrick class SparcDisassembler : public MCDisassembler {
3209467b48Spatrick public:
SparcDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx)3309467b48Spatrick   SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
3409467b48Spatrick       : MCDisassembler(STI, Ctx) {}
35*d415bd75Srobert   virtual ~SparcDisassembler() = default;
3609467b48Spatrick 
3709467b48Spatrick   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
3809467b48Spatrick                               ArrayRef<uint8_t> Bytes, uint64_t Address,
3909467b48Spatrick                               raw_ostream &CStream) const override;
4009467b48Spatrick };
4109467b48Spatrick }
4209467b48Spatrick 
createSparcDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)4309467b48Spatrick static MCDisassembler *createSparcDisassembler(const Target &T,
4409467b48Spatrick                                                const MCSubtargetInfo &STI,
4509467b48Spatrick                                                MCContext &Ctx) {
4609467b48Spatrick   return new SparcDisassembler(STI, Ctx);
4709467b48Spatrick }
4809467b48Spatrick 
4909467b48Spatrick 
LLVMInitializeSparcDisassembler()5009467b48Spatrick extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcDisassembler() {
5109467b48Spatrick   // Register the disassembler.
5209467b48Spatrick   TargetRegistry::RegisterMCDisassembler(getTheSparcTarget(),
5309467b48Spatrick                                          createSparcDisassembler);
5409467b48Spatrick   TargetRegistry::RegisterMCDisassembler(getTheSparcV9Target(),
5509467b48Spatrick                                          createSparcDisassembler);
5609467b48Spatrick   TargetRegistry::RegisterMCDisassembler(getTheSparcelTarget(),
5709467b48Spatrick                                          createSparcDisassembler);
5809467b48Spatrick }
5909467b48Spatrick 
6009467b48Spatrick static const unsigned IntRegDecoderTable[] = {
6109467b48Spatrick   SP::G0,  SP::G1,  SP::G2,  SP::G3,
6209467b48Spatrick   SP::G4,  SP::G5,  SP::G6,  SP::G7,
6309467b48Spatrick   SP::O0,  SP::O1,  SP::O2,  SP::O3,
6409467b48Spatrick   SP::O4,  SP::O5,  SP::O6,  SP::O7,
6509467b48Spatrick   SP::L0,  SP::L1,  SP::L2,  SP::L3,
6609467b48Spatrick   SP::L4,  SP::L5,  SP::L6,  SP::L7,
6709467b48Spatrick   SP::I0,  SP::I1,  SP::I2,  SP::I3,
6809467b48Spatrick   SP::I4,  SP::I5,  SP::I6,  SP::I7 };
6909467b48Spatrick 
7009467b48Spatrick static const unsigned FPRegDecoderTable[] = {
7109467b48Spatrick   SP::F0,   SP::F1,   SP::F2,   SP::F3,
7209467b48Spatrick   SP::F4,   SP::F5,   SP::F6,   SP::F7,
7309467b48Spatrick   SP::F8,   SP::F9,   SP::F10,  SP::F11,
7409467b48Spatrick   SP::F12,  SP::F13,  SP::F14,  SP::F15,
7509467b48Spatrick   SP::F16,  SP::F17,  SP::F18,  SP::F19,
7609467b48Spatrick   SP::F20,  SP::F21,  SP::F22,  SP::F23,
7709467b48Spatrick   SP::F24,  SP::F25,  SP::F26,  SP::F27,
7809467b48Spatrick   SP::F28,  SP::F29,  SP::F30,  SP::F31 };
7909467b48Spatrick 
8009467b48Spatrick static const unsigned DFPRegDecoderTable[] = {
8109467b48Spatrick   SP::D0,   SP::D16,  SP::D1,   SP::D17,
8209467b48Spatrick   SP::D2,   SP::D18,  SP::D3,   SP::D19,
8309467b48Spatrick   SP::D4,   SP::D20,  SP::D5,   SP::D21,
8409467b48Spatrick   SP::D6,   SP::D22,  SP::D7,   SP::D23,
8509467b48Spatrick   SP::D8,   SP::D24,  SP::D9,   SP::D25,
8609467b48Spatrick   SP::D10,  SP::D26,  SP::D11,  SP::D27,
8709467b48Spatrick   SP::D12,  SP::D28,  SP::D13,  SP::D29,
8809467b48Spatrick   SP::D14,  SP::D30,  SP::D15,  SP::D31 };
8909467b48Spatrick 
9009467b48Spatrick static const unsigned QFPRegDecoderTable[] = {
9109467b48Spatrick   SP::Q0,  SP::Q8,   ~0U,  ~0U,
9209467b48Spatrick   SP::Q1,  SP::Q9,   ~0U,  ~0U,
9309467b48Spatrick   SP::Q2,  SP::Q10,  ~0U,  ~0U,
9409467b48Spatrick   SP::Q3,  SP::Q11,  ~0U,  ~0U,
9509467b48Spatrick   SP::Q4,  SP::Q12,  ~0U,  ~0U,
9609467b48Spatrick   SP::Q5,  SP::Q13,  ~0U,  ~0U,
9709467b48Spatrick   SP::Q6,  SP::Q14,  ~0U,  ~0U,
9809467b48Spatrick   SP::Q7,  SP::Q15,  ~0U,  ~0U } ;
9909467b48Spatrick 
10009467b48Spatrick static const unsigned FCCRegDecoderTable[] = {
10109467b48Spatrick   SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 };
10209467b48Spatrick 
10309467b48Spatrick static const unsigned ASRRegDecoderTable[] = {
10409467b48Spatrick   SP::Y,     SP::ASR1,  SP::ASR2,  SP::ASR3,
10509467b48Spatrick   SP::ASR4,  SP::ASR5,  SP::ASR6,  SP::ASR7,
10609467b48Spatrick   SP::ASR8,  SP::ASR9,  SP::ASR10, SP::ASR11,
10709467b48Spatrick   SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
10809467b48Spatrick   SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
10909467b48Spatrick   SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
11009467b48Spatrick   SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
11109467b48Spatrick   SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
11209467b48Spatrick 
11309467b48Spatrick static const unsigned PRRegDecoderTable[] = {
11409467b48Spatrick   SP::TPC, SP::TNPC, SP::TSTATE, SP::TT, SP::TICK, SP::TBA, SP::PSTATE,
11509467b48Spatrick   SP::TL, SP::PIL, SP::CWP, SP::CANSAVE, SP::CANRESTORE, SP::CLEANWIN,
11673471bf0Spatrick   SP::OTHERWIN, SP::WSTATE, SP::PC
11709467b48Spatrick };
11809467b48Spatrick 
11909467b48Spatrick static const uint16_t IntPairDecoderTable[] = {
12009467b48Spatrick   SP::G0_G1, SP::G2_G3, SP::G4_G5, SP::G6_G7,
12109467b48Spatrick   SP::O0_O1, SP::O2_O3, SP::O4_O5, SP::O6_O7,
12209467b48Spatrick   SP::L0_L1, SP::L2_L3, SP::L4_L5, SP::L6_L7,
12309467b48Spatrick   SP::I0_I1, SP::I2_I3, SP::I4_I5, SP::I6_I7,
12409467b48Spatrick };
12509467b48Spatrick 
12609467b48Spatrick static const unsigned CPRegDecoderTable[] = {
12709467b48Spatrick   SP::C0,  SP::C1,  SP::C2,  SP::C3,
12809467b48Spatrick   SP::C4,  SP::C5,  SP::C6,  SP::C7,
12909467b48Spatrick   SP::C8,  SP::C9,  SP::C10, SP::C11,
13009467b48Spatrick   SP::C12, SP::C13, SP::C14, SP::C15,
13109467b48Spatrick   SP::C16, SP::C17, SP::C18, SP::C19,
13209467b48Spatrick   SP::C20, SP::C21, SP::C22, SP::C23,
13309467b48Spatrick   SP::C24, SP::C25, SP::C26, SP::C27,
13409467b48Spatrick   SP::C28, SP::C29, SP::C30, SP::C31
13509467b48Spatrick };
13609467b48Spatrick 
13709467b48Spatrick 
13809467b48Spatrick static const uint16_t CPPairDecoderTable[] = {
13909467b48Spatrick   SP::C0_C1,   SP::C2_C3,   SP::C4_C5,   SP::C6_C7,
14009467b48Spatrick   SP::C8_C9,   SP::C10_C11, SP::C12_C13, SP::C14_C15,
14109467b48Spatrick   SP::C16_C17, SP::C18_C19, SP::C20_C21, SP::C22_C23,
14209467b48Spatrick   SP::C24_C25, SP::C26_C27, SP::C28_C29, SP::C30_C31
14309467b48Spatrick };
14409467b48Spatrick 
DecodeIntRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)145*d415bd75Srobert static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
14609467b48Spatrick                                                uint64_t Address,
147*d415bd75Srobert                                                const MCDisassembler *Decoder) {
14809467b48Spatrick   if (RegNo > 31)
14909467b48Spatrick     return MCDisassembler::Fail;
15009467b48Spatrick   unsigned Reg = IntRegDecoderTable[RegNo];
15109467b48Spatrick   Inst.addOperand(MCOperand::createReg(Reg));
15209467b48Spatrick   return MCDisassembler::Success;
15309467b48Spatrick }
15409467b48Spatrick 
DecodeI64RegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)155*d415bd75Srobert static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, unsigned RegNo,
15609467b48Spatrick                                                uint64_t Address,
157*d415bd75Srobert                                                const MCDisassembler *Decoder) {
158*d415bd75Srobert   return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);
15909467b48Spatrick }
16009467b48Spatrick 
161*d415bd75Srobert // This is used for the type "ptr_rc", which is either IntRegs or I64Regs
162*d415bd75Srobert // depending on SparcRegisterInfo::getPointerRegClass.
DecodePointerLikeRegClass0(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)163*d415bd75Srobert static DecodeStatus DecodePointerLikeRegClass0(MCInst &Inst, unsigned RegNo,
16409467b48Spatrick                                                uint64_t Address,
165*d415bd75Srobert                                                const MCDisassembler *Decoder) {
166*d415bd75Srobert   return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);
167*d415bd75Srobert }
168*d415bd75Srobert 
DecodeFPRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)169*d415bd75Srobert static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, unsigned RegNo,
170*d415bd75Srobert                                               uint64_t Address,
171*d415bd75Srobert                                               const MCDisassembler *Decoder) {
17209467b48Spatrick   if (RegNo > 31)
17309467b48Spatrick     return MCDisassembler::Fail;
17409467b48Spatrick   unsigned Reg = FPRegDecoderTable[RegNo];
17509467b48Spatrick   Inst.addOperand(MCOperand::createReg(Reg));
17609467b48Spatrick   return MCDisassembler::Success;
17709467b48Spatrick }
17809467b48Spatrick 
DecodeDFPRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)179*d415bd75Srobert static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, unsigned RegNo,
18009467b48Spatrick                                                uint64_t Address,
181*d415bd75Srobert                                                const MCDisassembler *Decoder) {
18209467b48Spatrick   if (RegNo > 31)
18309467b48Spatrick     return MCDisassembler::Fail;
18409467b48Spatrick   unsigned Reg = DFPRegDecoderTable[RegNo];
18509467b48Spatrick   Inst.addOperand(MCOperand::createReg(Reg));
18609467b48Spatrick   return MCDisassembler::Success;
18709467b48Spatrick }
18809467b48Spatrick 
DecodeQFPRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)189*d415bd75Srobert static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, unsigned RegNo,
19009467b48Spatrick                                                uint64_t Address,
191*d415bd75Srobert                                                const MCDisassembler *Decoder) {
19209467b48Spatrick   if (RegNo > 31)
19309467b48Spatrick     return MCDisassembler::Fail;
19409467b48Spatrick 
19509467b48Spatrick   unsigned Reg = QFPRegDecoderTable[RegNo];
19609467b48Spatrick   if (Reg == ~0U)
19709467b48Spatrick     return MCDisassembler::Fail;
19809467b48Spatrick   Inst.addOperand(MCOperand::createReg(Reg));
19909467b48Spatrick   return MCDisassembler::Success;
20009467b48Spatrick }
20109467b48Spatrick 
202*d415bd75Srobert static DecodeStatus
DecodeCoprocRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)203*d415bd75Srobert DecodeCoprocRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
204*d415bd75Srobert                               const MCDisassembler *Decoder) {
20509467b48Spatrick   if (RegNo > 31)
20609467b48Spatrick     return MCDisassembler::Fail;
20709467b48Spatrick   unsigned Reg = CPRegDecoderTable[RegNo];
20809467b48Spatrick   Inst.addOperand(MCOperand::createReg(Reg));
20909467b48Spatrick   return MCDisassembler::Success;
21009467b48Spatrick }
21109467b48Spatrick 
DecodeFCCRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)21209467b48Spatrick static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo,
21309467b48Spatrick                                                uint64_t Address,
214*d415bd75Srobert                                                const MCDisassembler *Decoder) {
21509467b48Spatrick   if (RegNo > 3)
21609467b48Spatrick     return MCDisassembler::Fail;
21709467b48Spatrick   Inst.addOperand(MCOperand::createReg(FCCRegDecoderTable[RegNo]));
21809467b48Spatrick   return MCDisassembler::Success;
21909467b48Spatrick }
22009467b48Spatrick 
DecodeASRRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)22109467b48Spatrick static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo,
22209467b48Spatrick                                                uint64_t Address,
223*d415bd75Srobert                                                const MCDisassembler *Decoder) {
22409467b48Spatrick   if (RegNo > 31)
22509467b48Spatrick     return MCDisassembler::Fail;
22609467b48Spatrick   Inst.addOperand(MCOperand::createReg(ASRRegDecoderTable[RegNo]));
22709467b48Spatrick   return MCDisassembler::Success;
22809467b48Spatrick }
22909467b48Spatrick 
DecodePRRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)23009467b48Spatrick static DecodeStatus DecodePRRegsRegisterClass(MCInst &Inst, unsigned RegNo,
23109467b48Spatrick                                               uint64_t Address,
232*d415bd75Srobert                                               const MCDisassembler *Decoder) {
233*d415bd75Srobert   if (RegNo >= std::size(PRRegDecoderTable))
23409467b48Spatrick     return MCDisassembler::Fail;
23509467b48Spatrick   Inst.addOperand(MCOperand::createReg(PRRegDecoderTable[RegNo]));
23609467b48Spatrick   return MCDisassembler::Success;
23709467b48Spatrick }
23809467b48Spatrick 
DecodeIntPairRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)23909467b48Spatrick static DecodeStatus DecodeIntPairRegisterClass(MCInst &Inst, unsigned RegNo,
240*d415bd75Srobert                                                uint64_t Address,
241*d415bd75Srobert                                                const MCDisassembler *Decoder) {
24209467b48Spatrick   DecodeStatus S = MCDisassembler::Success;
24309467b48Spatrick 
24409467b48Spatrick   if (RegNo > 31)
24509467b48Spatrick     return MCDisassembler::Fail;
24609467b48Spatrick 
24709467b48Spatrick   if ((RegNo & 1))
24809467b48Spatrick     S = MCDisassembler::SoftFail;
24909467b48Spatrick 
25009467b48Spatrick   unsigned RegisterPair = IntPairDecoderTable[RegNo/2];
25109467b48Spatrick   Inst.addOperand(MCOperand::createReg(RegisterPair));
25209467b48Spatrick   return S;
25309467b48Spatrick }
25409467b48Spatrick 
255*d415bd75Srobert static DecodeStatus
DecodeCoprocPairRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)256*d415bd75Srobert DecodeCoprocPairRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
257*d415bd75Srobert                               const MCDisassembler *Decoder) {
25809467b48Spatrick   if (RegNo > 31)
25909467b48Spatrick     return MCDisassembler::Fail;
26009467b48Spatrick 
26109467b48Spatrick   unsigned RegisterPair = CPPairDecoderTable[RegNo/2];
26209467b48Spatrick   Inst.addOperand(MCOperand::createReg(RegisterPair));
26309467b48Spatrick   return MCDisassembler::Success;
26409467b48Spatrick }
26509467b48Spatrick 
266*d415bd75Srobert static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, uint64_t Address,
267*d415bd75Srobert                                const MCDisassembler *Decoder);
268*d415bd75Srobert static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, uint64_t Address,
269*d415bd75Srobert                                  const MCDisassembler *Decoder);
27009467b48Spatrick 
27109467b48Spatrick #include "SparcGenDisassemblerTables.inc"
27209467b48Spatrick 
27309467b48Spatrick /// Read four bytes from the ArrayRef and return 32 bit word.
readInstruction32(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & Size,uint32_t & Insn,bool IsLittleEndian)27409467b48Spatrick static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
27509467b48Spatrick                                       uint64_t &Size, uint32_t &Insn,
27609467b48Spatrick                                       bool IsLittleEndian) {
27709467b48Spatrick   // We want to read exactly 4 Bytes of data.
27809467b48Spatrick   if (Bytes.size() < 4) {
27909467b48Spatrick     Size = 0;
28009467b48Spatrick     return MCDisassembler::Fail;
28109467b48Spatrick   }
28209467b48Spatrick 
28309467b48Spatrick   Insn = IsLittleEndian
28409467b48Spatrick              ? (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
28509467b48Spatrick                    (Bytes[3] << 24)
28609467b48Spatrick              : (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) |
28709467b48Spatrick                    (Bytes[0] << 24);
28809467b48Spatrick 
28909467b48Spatrick   return MCDisassembler::Success;
29009467b48Spatrick }
29109467b48Spatrick 
getInstruction(MCInst & Instr,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CStream) const29209467b48Spatrick DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
29309467b48Spatrick                                                ArrayRef<uint8_t> Bytes,
29409467b48Spatrick                                                uint64_t Address,
29509467b48Spatrick                                                raw_ostream &CStream) const {
29609467b48Spatrick   uint32_t Insn;
29709467b48Spatrick   bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian();
29809467b48Spatrick   DecodeStatus Result =
29909467b48Spatrick       readInstruction32(Bytes, Address, Size, Insn, isLittleEndian);
30009467b48Spatrick   if (Result == MCDisassembler::Fail)
30109467b48Spatrick     return MCDisassembler::Fail;
30209467b48Spatrick 
30309467b48Spatrick   // Calling the auto-generated decoder function.
30409467b48Spatrick 
30509467b48Spatrick   if (STI.getFeatureBits()[Sparc::FeatureV9])
30609467b48Spatrick   {
30709467b48Spatrick     Result = decodeInstruction(DecoderTableSparcV932, Instr, Insn, Address, this, STI);
30809467b48Spatrick   }
30909467b48Spatrick   else
31009467b48Spatrick   {
31109467b48Spatrick     Result = decodeInstruction(DecoderTableSparcV832, Instr, Insn, Address, this, STI);
31209467b48Spatrick   }
31309467b48Spatrick   if (Result != MCDisassembler::Fail)
31409467b48Spatrick     return Result;
31509467b48Spatrick 
31609467b48Spatrick   Result =
31709467b48Spatrick       decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI);
31809467b48Spatrick 
31909467b48Spatrick   if (Result != MCDisassembler::Fail) {
32009467b48Spatrick     Size = 4;
32109467b48Spatrick     return Result;
32209467b48Spatrick   }
32309467b48Spatrick 
32409467b48Spatrick   return MCDisassembler::Fail;
32509467b48Spatrick }
32609467b48Spatrick 
tryAddingSymbolicOperand(int64_t Value,bool isBranch,uint64_t Address,uint64_t Offset,uint64_t Width,MCInst & MI,const MCDisassembler * Decoder)32709467b48Spatrick static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
32809467b48Spatrick                                      uint64_t Address, uint64_t Offset,
32909467b48Spatrick                                      uint64_t Width, MCInst &MI,
330*d415bd75Srobert                                      const MCDisassembler *Decoder) {
331*d415bd75Srobert   return Decoder->tryAddingSymbolicOperand(MI, Value, Address, isBranch, Offset,
332*d415bd75Srobert                                            Width, /*InstSize=*/4);
33309467b48Spatrick }
33409467b48Spatrick 
DecodeCall(MCInst & MI,unsigned insn,uint64_t Address,const MCDisassembler * Decoder)335*d415bd75Srobert static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, uint64_t Address,
336*d415bd75Srobert                                const MCDisassembler *Decoder) {
33709467b48Spatrick   unsigned tgt = fieldFromInstruction(insn, 0, 30);
33809467b48Spatrick   tgt <<= 2;
33909467b48Spatrick   if (!tryAddingSymbolicOperand(tgt+Address, false, Address,
34009467b48Spatrick                                 0, 30, MI, Decoder))
34109467b48Spatrick     MI.addOperand(MCOperand::createImm(tgt));
34209467b48Spatrick   return MCDisassembler::Success;
34309467b48Spatrick }
34409467b48Spatrick 
DecodeSIMM13(MCInst & MI,unsigned insn,uint64_t Address,const MCDisassembler * Decoder)345*d415bd75Srobert static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, uint64_t Address,
346*d415bd75Srobert                                  const MCDisassembler *Decoder) {
34709467b48Spatrick   unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
34809467b48Spatrick   MI.addOperand(MCOperand::createImm(tgt));
34909467b48Spatrick   return MCDisassembler::Success;
35009467b48Spatrick }
351