1*9880d681SAndroid Build Coastguard Worker //===-- HexagonDisassembler.cpp - Disassembler for Hexagon ISA ------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "hexagon-disassembler"
11*9880d681SAndroid Build Coastguard Worker
12*9880d681SAndroid Build Coastguard Worker #include "Hexagon.h"
13*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/HexagonBaseInfo.h"
14*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/HexagonMCChecker.h"
15*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/HexagonMCTargetDesc.h"
16*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/HexagonMCInstrInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/HexagonInstPrinter.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringExtras.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCDisassembler/MCDisassembler.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCFixedLenDisassembler.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrDesc.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/LEB128.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryObject.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker using namespace llvm;
35*9880d681SAndroid Build Coastguard Worker using namespace Hexagon;
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker typedef MCDisassembler::DecodeStatus DecodeStatus;
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker namespace {
40*9880d681SAndroid Build Coastguard Worker /// \brief Hexagon disassembler for all Hexagon platforms.
41*9880d681SAndroid Build Coastguard Worker class HexagonDisassembler : public MCDisassembler {
42*9880d681SAndroid Build Coastguard Worker public:
43*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCInstrInfo const> const MCII;
44*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCInst *> CurrentBundle;
HexagonDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,MCInstrInfo const * MCII)45*9880d681SAndroid Build Coastguard Worker HexagonDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
46*9880d681SAndroid Build Coastguard Worker MCInstrInfo const *MCII)
47*9880d681SAndroid Build Coastguard Worker : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(new MCInst *) {}
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB,
50*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> Bytes, uint64_t Address,
51*9880d681SAndroid Build Coastguard Worker raw_ostream &VStream, raw_ostream &CStream,
52*9880d681SAndroid Build Coastguard Worker bool &Complete) const;
53*9880d681SAndroid Build Coastguard Worker DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
54*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> Bytes, uint64_t Address,
55*9880d681SAndroid Build Coastguard Worker raw_ostream &VStream,
56*9880d681SAndroid Build Coastguard Worker raw_ostream &CStream) const override;
57*9880d681SAndroid Build Coastguard Worker
58*9880d681SAndroid Build Coastguard Worker void adjustExtendedInstructions(MCInst &MCI, MCInst const &MCB) const;
59*9880d681SAndroid Build Coastguard Worker void addSubinstOperands(MCInst *MI, unsigned opcode, unsigned inst) const;
60*9880d681SAndroid Build Coastguard Worker };
61*9880d681SAndroid Build Coastguard Worker }
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker // Forward declare these because the auto-generated code will reference them.
64*9880d681SAndroid Build Coastguard Worker // Definitions are further down.
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
67*9880d681SAndroid Build Coastguard Worker uint64_t Address,
68*9880d681SAndroid Build Coastguard Worker const void *Decoder);
69*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo,
70*9880d681SAndroid Build Coastguard Worker uint64_t Address,
71*9880d681SAndroid Build Coastguard Worker const void *Decoder);
72*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVectorRegsRegisterClass(MCInst &Inst, unsigned RegNo,
73*9880d681SAndroid Build Coastguard Worker uint64_t Address,
74*9880d681SAndroid Build Coastguard Worker const void *Decoder);
75*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
76*9880d681SAndroid Build Coastguard Worker uint64_t Address,
77*9880d681SAndroid Build Coastguard Worker const void *Decoder);
78*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecDblRegsRegisterClass(MCInst &Inst, unsigned RegNo,
79*9880d681SAndroid Build Coastguard Worker uint64_t Address,
80*9880d681SAndroid Build Coastguard Worker const void *Decoder);
81*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
82*9880d681SAndroid Build Coastguard Worker uint64_t Address,
83*9880d681SAndroid Build Coastguard Worker const void *Decoder);
84*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecPredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
85*9880d681SAndroid Build Coastguard Worker uint64_t Address,
86*9880d681SAndroid Build Coastguard Worker const void *Decoder);
87*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
88*9880d681SAndroid Build Coastguard Worker uint64_t Address,
89*9880d681SAndroid Build Coastguard Worker const void *Decoder);
90*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
91*9880d681SAndroid Build Coastguard Worker uint64_t Address,
92*9880d681SAndroid Build Coastguard Worker const void *Decoder);
93*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
94*9880d681SAndroid Build Coastguard Worker uint64_t Address,
95*9880d681SAndroid Build Coastguard Worker const void *Decoder);
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn);
98*9880d681SAndroid Build Coastguard Worker static DecodeStatus decodeImmext(MCInst &MI, uint32_t insn,
99*9880d681SAndroid Build Coastguard Worker void const *Decoder);
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op,
102*9880d681SAndroid Build Coastguard Worker raw_ostream &os);
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker static unsigned getRegFromSubinstEncoding(unsigned encoded_reg);
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
107*9880d681SAndroid Build Coastguard Worker uint64_t Address, const void *Decoder);
108*9880d681SAndroid Build Coastguard Worker static DecodeStatus s16ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
109*9880d681SAndroid Build Coastguard Worker const void *Decoder);
110*9880d681SAndroid Build Coastguard Worker static DecodeStatus s12ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
111*9880d681SAndroid Build Coastguard Worker const void *Decoder);
112*9880d681SAndroid Build Coastguard Worker static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
113*9880d681SAndroid Build Coastguard Worker const void *Decoder);
114*9880d681SAndroid Build Coastguard Worker static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
115*9880d681SAndroid Build Coastguard Worker const void *Decoder);
116*9880d681SAndroid Build Coastguard Worker static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
117*9880d681SAndroid Build Coastguard Worker const void *Decoder);
118*9880d681SAndroid Build Coastguard Worker static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
119*9880d681SAndroid Build Coastguard Worker const void *Decoder);
120*9880d681SAndroid Build Coastguard Worker static DecodeStatus s10ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
121*9880d681SAndroid Build Coastguard Worker const void *Decoder);
122*9880d681SAndroid Build Coastguard Worker static DecodeStatus s8ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
123*9880d681SAndroid Build Coastguard Worker const void *Decoder);
124*9880d681SAndroid Build Coastguard Worker static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
125*9880d681SAndroid Build Coastguard Worker const void *Decoder);
126*9880d681SAndroid Build Coastguard Worker static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
127*9880d681SAndroid Build Coastguard Worker const void *Decoder);
128*9880d681SAndroid Build Coastguard Worker static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
129*9880d681SAndroid Build Coastguard Worker const void *Decoder);
130*9880d681SAndroid Build Coastguard Worker static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
131*9880d681SAndroid Build Coastguard Worker const void *Decoder);
132*9880d681SAndroid Build Coastguard Worker static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
133*9880d681SAndroid Build Coastguard Worker const void *Decoder);
134*9880d681SAndroid Build Coastguard Worker static DecodeStatus s4_6ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
135*9880d681SAndroid Build Coastguard Worker const void *Decoder);
136*9880d681SAndroid Build Coastguard Worker static DecodeStatus s3_6ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
137*9880d681SAndroid Build Coastguard Worker const void *Decoder);
138*9880d681SAndroid Build Coastguard Worker static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
139*9880d681SAndroid Build Coastguard Worker const void *Decoder);
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker #include "HexagonGenDisassemblerTables.inc"
142*9880d681SAndroid Build Coastguard Worker
createHexagonDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)143*9880d681SAndroid Build Coastguard Worker static MCDisassembler *createHexagonDisassembler(const Target &T,
144*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
145*9880d681SAndroid Build Coastguard Worker MCContext &Ctx) {
146*9880d681SAndroid Build Coastguard Worker return new HexagonDisassembler(STI, Ctx, T.createMCInstrInfo());
147*9880d681SAndroid Build Coastguard Worker }
148*9880d681SAndroid Build Coastguard Worker
LLVMInitializeHexagonDisassembler()149*9880d681SAndroid Build Coastguard Worker extern "C" void LLVMInitializeHexagonDisassembler() {
150*9880d681SAndroid Build Coastguard Worker TargetRegistry::RegisterMCDisassembler(TheHexagonTarget,
151*9880d681SAndroid Build Coastguard Worker createHexagonDisassembler);
152*9880d681SAndroid Build Coastguard Worker }
153*9880d681SAndroid Build Coastguard Worker
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & os,raw_ostream & cs) const154*9880d681SAndroid Build Coastguard Worker DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
155*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> Bytes,
156*9880d681SAndroid Build Coastguard Worker uint64_t Address,
157*9880d681SAndroid Build Coastguard Worker raw_ostream &os,
158*9880d681SAndroid Build Coastguard Worker raw_ostream &cs) const {
159*9880d681SAndroid Build Coastguard Worker DecodeStatus Result = DecodeStatus::Success;
160*9880d681SAndroid Build Coastguard Worker bool Complete = false;
161*9880d681SAndroid Build Coastguard Worker Size = 0;
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker *CurrentBundle = &MI;
164*9880d681SAndroid Build Coastguard Worker MI = HexagonMCInstrInfo::createBundle();
165*9880d681SAndroid Build Coastguard Worker while (Result == Success && Complete == false) {
166*9880d681SAndroid Build Coastguard Worker if (Bytes.size() < HEXAGON_INSTR_SIZE)
167*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
168*9880d681SAndroid Build Coastguard Worker MCInst *Inst = new (getContext()) MCInst;
169*9880d681SAndroid Build Coastguard Worker Result = getSingleInstruction(*Inst, MI, Bytes, Address, os, cs, Complete);
170*9880d681SAndroid Build Coastguard Worker MI.addOperand(MCOperand::createInst(Inst));
171*9880d681SAndroid Build Coastguard Worker Size += HEXAGON_INSTR_SIZE;
172*9880d681SAndroid Build Coastguard Worker Bytes = Bytes.slice(HEXAGON_INSTR_SIZE);
173*9880d681SAndroid Build Coastguard Worker }
174*9880d681SAndroid Build Coastguard Worker if(Result == MCDisassembler::Fail)
175*9880d681SAndroid Build Coastguard Worker return Result;
176*9880d681SAndroid Build Coastguard Worker HexagonMCChecker Checker (*MCII, STI, MI, MI, *getContext().getRegisterInfo());
177*9880d681SAndroid Build Coastguard Worker if(!Checker.check())
178*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
179*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
180*9880d681SAndroid Build Coastguard Worker }
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Worker namespace {
disassembler(void const * Decoder)183*9880d681SAndroid Build Coastguard Worker HexagonDisassembler const &disassembler(void const *Decoder) {
184*9880d681SAndroid Build Coastguard Worker return *static_cast<HexagonDisassembler const *>(Decoder);
185*9880d681SAndroid Build Coastguard Worker }
contextFromDecoder(void const * Decoder)186*9880d681SAndroid Build Coastguard Worker MCContext &contextFromDecoder(void const *Decoder) {
187*9880d681SAndroid Build Coastguard Worker return disassembler(Decoder).getContext();
188*9880d681SAndroid Build Coastguard Worker }
189*9880d681SAndroid Build Coastguard Worker }
190*9880d681SAndroid Build Coastguard Worker
getSingleInstruction(MCInst & MI,MCInst & MCB,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & os,raw_ostream & cs,bool & Complete) const191*9880d681SAndroid Build Coastguard Worker DecodeStatus HexagonDisassembler::getSingleInstruction(
192*9880d681SAndroid Build Coastguard Worker MCInst &MI, MCInst &MCB, ArrayRef<uint8_t> Bytes, uint64_t Address,
193*9880d681SAndroid Build Coastguard Worker raw_ostream &os, raw_ostream &cs, bool &Complete) const {
194*9880d681SAndroid Build Coastguard Worker assert(Bytes.size() >= HEXAGON_INSTR_SIZE);
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker uint32_t Instruction =
197*9880d681SAndroid Build Coastguard Worker (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Worker auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB);
200*9880d681SAndroid Build Coastguard Worker if ((Instruction & HexagonII::INST_PARSE_MASK) ==
201*9880d681SAndroid Build Coastguard Worker HexagonII::INST_PARSE_LOOP_END) {
202*9880d681SAndroid Build Coastguard Worker if (BundleSize == 0)
203*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::setInnerLoop(MCB);
204*9880d681SAndroid Build Coastguard Worker else if (BundleSize == 1)
205*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::setOuterLoop(MCB);
206*9880d681SAndroid Build Coastguard Worker else
207*9880d681SAndroid Build Coastguard Worker return DecodeStatus::Fail;
208*9880d681SAndroid Build Coastguard Worker }
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker DecodeStatus Result = DecodeStatus::Success;
211*9880d681SAndroid Build Coastguard Worker if ((Instruction & HexagonII::INST_PARSE_MASK) ==
212*9880d681SAndroid Build Coastguard Worker HexagonII::INST_PARSE_DUPLEX) {
213*9880d681SAndroid Build Coastguard Worker // Determine the instruction class of each instruction in the duplex.
214*9880d681SAndroid Build Coastguard Worker unsigned duplexIClass, IClassLow, IClassHigh;
215*9880d681SAndroid Build Coastguard Worker
216*9880d681SAndroid Build Coastguard Worker duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1);
217*9880d681SAndroid Build Coastguard Worker switch (duplexIClass) {
218*9880d681SAndroid Build Coastguard Worker default:
219*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
220*9880d681SAndroid Build Coastguard Worker case 0:
221*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_L1;
222*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_L1;
223*9880d681SAndroid Build Coastguard Worker break;
224*9880d681SAndroid Build Coastguard Worker case 1:
225*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_L2;
226*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_L1;
227*9880d681SAndroid Build Coastguard Worker break;
228*9880d681SAndroid Build Coastguard Worker case 2:
229*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_L2;
230*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_L2;
231*9880d681SAndroid Build Coastguard Worker break;
232*9880d681SAndroid Build Coastguard Worker case 3:
233*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_A;
234*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_A;
235*9880d681SAndroid Build Coastguard Worker break;
236*9880d681SAndroid Build Coastguard Worker case 4:
237*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_L1;
238*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_A;
239*9880d681SAndroid Build Coastguard Worker break;
240*9880d681SAndroid Build Coastguard Worker case 5:
241*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_L2;
242*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_A;
243*9880d681SAndroid Build Coastguard Worker break;
244*9880d681SAndroid Build Coastguard Worker case 6:
245*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_S1;
246*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_A;
247*9880d681SAndroid Build Coastguard Worker break;
248*9880d681SAndroid Build Coastguard Worker case 7:
249*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_S2;
250*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_A;
251*9880d681SAndroid Build Coastguard Worker break;
252*9880d681SAndroid Build Coastguard Worker case 8:
253*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_S1;
254*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_L1;
255*9880d681SAndroid Build Coastguard Worker break;
256*9880d681SAndroid Build Coastguard Worker case 9:
257*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_S1;
258*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_L2;
259*9880d681SAndroid Build Coastguard Worker break;
260*9880d681SAndroid Build Coastguard Worker case 10:
261*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_S1;
262*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_S1;
263*9880d681SAndroid Build Coastguard Worker break;
264*9880d681SAndroid Build Coastguard Worker case 11:
265*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_S2;
266*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_S1;
267*9880d681SAndroid Build Coastguard Worker break;
268*9880d681SAndroid Build Coastguard Worker case 12:
269*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_S2;
270*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_L1;
271*9880d681SAndroid Build Coastguard Worker break;
272*9880d681SAndroid Build Coastguard Worker case 13:
273*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_S2;
274*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_L2;
275*9880d681SAndroid Build Coastguard Worker break;
276*9880d681SAndroid Build Coastguard Worker case 14:
277*9880d681SAndroid Build Coastguard Worker IClassLow = HexagonII::HSIG_S2;
278*9880d681SAndroid Build Coastguard Worker IClassHigh = HexagonII::HSIG_S2;
279*9880d681SAndroid Build Coastguard Worker break;
280*9880d681SAndroid Build Coastguard Worker }
281*9880d681SAndroid Build Coastguard Worker
282*9880d681SAndroid Build Coastguard Worker // Set the MCInst to be a duplex instruction. Which one doesn't matter.
283*9880d681SAndroid Build Coastguard Worker MI.setOpcode(Hexagon::DuplexIClass0);
284*9880d681SAndroid Build Coastguard Worker
285*9880d681SAndroid Build Coastguard Worker // Decode each instruction in the duplex.
286*9880d681SAndroid Build Coastguard Worker // Create an MCInst for each instruction.
287*9880d681SAndroid Build Coastguard Worker unsigned instLow = Instruction & 0x1fff;
288*9880d681SAndroid Build Coastguard Worker unsigned instHigh = (Instruction >> 16) & 0x1fff;
289*9880d681SAndroid Build Coastguard Worker unsigned opLow;
290*9880d681SAndroid Build Coastguard Worker if (GetSubinstOpcode(IClassLow, instLow, opLow, os) !=
291*9880d681SAndroid Build Coastguard Worker MCDisassembler::Success)
292*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
293*9880d681SAndroid Build Coastguard Worker unsigned opHigh;
294*9880d681SAndroid Build Coastguard Worker if (GetSubinstOpcode(IClassHigh, instHigh, opHigh, os) !=
295*9880d681SAndroid Build Coastguard Worker MCDisassembler::Success)
296*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
297*9880d681SAndroid Build Coastguard Worker MCInst *MILow = new (getContext()) MCInst;
298*9880d681SAndroid Build Coastguard Worker MILow->setOpcode(opLow);
299*9880d681SAndroid Build Coastguard Worker MCInst *MIHigh = new (getContext()) MCInst;
300*9880d681SAndroid Build Coastguard Worker MIHigh->setOpcode(opHigh);
301*9880d681SAndroid Build Coastguard Worker addSubinstOperands(MILow, opLow, instLow);
302*9880d681SAndroid Build Coastguard Worker addSubinstOperands(MIHigh, opHigh, instHigh);
303*9880d681SAndroid Build Coastguard Worker // see ConvertToSubInst() in
304*9880d681SAndroid Build Coastguard Worker // lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp
305*9880d681SAndroid Build Coastguard Worker
306*9880d681SAndroid Build Coastguard Worker // Add the duplex instruction MCInsts as operands to the passed in MCInst.
307*9880d681SAndroid Build Coastguard Worker MCOperand OPLow = MCOperand::createInst(MILow);
308*9880d681SAndroid Build Coastguard Worker MCOperand OPHigh = MCOperand::createInst(MIHigh);
309*9880d681SAndroid Build Coastguard Worker MI.addOperand(OPLow);
310*9880d681SAndroid Build Coastguard Worker MI.addOperand(OPHigh);
311*9880d681SAndroid Build Coastguard Worker Complete = true;
312*9880d681SAndroid Build Coastguard Worker } else {
313*9880d681SAndroid Build Coastguard Worker if ((Instruction & HexagonII::INST_PARSE_MASK) ==
314*9880d681SAndroid Build Coastguard Worker HexagonII::INST_PARSE_PACKET_END)
315*9880d681SAndroid Build Coastguard Worker Complete = true;
316*9880d681SAndroid Build Coastguard Worker // Calling the auto-generated decoder function.
317*9880d681SAndroid Build Coastguard Worker Result =
318*9880d681SAndroid Build Coastguard Worker decodeInstruction(DecoderTable32, MI, Instruction, Address, this, STI);
319*9880d681SAndroid Build Coastguard Worker
320*9880d681SAndroid Build Coastguard Worker // If a, "standard" insn isn't found check special cases.
321*9880d681SAndroid Build Coastguard Worker if (MCDisassembler::Success != Result ||
322*9880d681SAndroid Build Coastguard Worker MI.getOpcode() == Hexagon::A4_ext) {
323*9880d681SAndroid Build Coastguard Worker Result = decodeImmext(MI, Instruction, this);
324*9880d681SAndroid Build Coastguard Worker if (MCDisassembler::Success != Result) {
325*9880d681SAndroid Build Coastguard Worker Result = decodeSpecial(MI, Instruction);
326*9880d681SAndroid Build Coastguard Worker }
327*9880d681SAndroid Build Coastguard Worker } else {
328*9880d681SAndroid Build Coastguard Worker // If the instruction is a compound instruction, register values will
329*9880d681SAndroid Build Coastguard Worker // follow the duplex model, so the register values in the MCInst are
330*9880d681SAndroid Build Coastguard Worker // incorrect. If the instruction is a compound, loop through the
331*9880d681SAndroid Build Coastguard Worker // operands and change registers appropriately.
332*9880d681SAndroid Build Coastguard Worker if (llvm::HexagonMCInstrInfo::getType(*MCII, MI) ==
333*9880d681SAndroid Build Coastguard Worker HexagonII::TypeCOMPOUND) {
334*9880d681SAndroid Build Coastguard Worker for (MCInst::iterator i = MI.begin(), last = MI.end(); i < last; ++i) {
335*9880d681SAndroid Build Coastguard Worker if (i->isReg()) {
336*9880d681SAndroid Build Coastguard Worker unsigned reg = i->getReg() - Hexagon::R0;
337*9880d681SAndroid Build Coastguard Worker i->setReg(getRegFromSubinstEncoding(reg));
338*9880d681SAndroid Build Coastguard Worker }
339*9880d681SAndroid Build Coastguard Worker }
340*9880d681SAndroid Build Coastguard Worker }
341*9880d681SAndroid Build Coastguard Worker }
342*9880d681SAndroid Build Coastguard Worker }
343*9880d681SAndroid Build Coastguard Worker
344*9880d681SAndroid Build Coastguard Worker if (HexagonMCInstrInfo::isNewValue(*MCII, MI)) {
345*9880d681SAndroid Build Coastguard Worker unsigned OpIndex = HexagonMCInstrInfo::getNewValueOp(*MCII, MI);
346*9880d681SAndroid Build Coastguard Worker MCOperand &MCO = MI.getOperand(OpIndex);
347*9880d681SAndroid Build Coastguard Worker assert(MCO.isReg() && "New value consumers must be registers");
348*9880d681SAndroid Build Coastguard Worker unsigned Register =
349*9880d681SAndroid Build Coastguard Worker getContext().getRegisterInfo()->getEncodingValue(MCO.getReg());
350*9880d681SAndroid Build Coastguard Worker if ((Register & 0x6) == 0)
351*9880d681SAndroid Build Coastguard Worker // HexagonPRM 10.11 Bit 1-2 == 0 is reserved
352*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
353*9880d681SAndroid Build Coastguard Worker unsigned Lookback = (Register & 0x6) >> 1;
354*9880d681SAndroid Build Coastguard Worker unsigned Offset = 1;
355*9880d681SAndroid Build Coastguard Worker bool Vector = HexagonMCInstrInfo::isVector(*MCII, MI);
356*9880d681SAndroid Build Coastguard Worker auto Instructions = HexagonMCInstrInfo::bundleInstructions(**CurrentBundle);
357*9880d681SAndroid Build Coastguard Worker auto i = Instructions.end() - 1;
358*9880d681SAndroid Build Coastguard Worker for (auto n = Instructions.begin() - 1;; --i, ++Offset) {
359*9880d681SAndroid Build Coastguard Worker if (i == n)
360*9880d681SAndroid Build Coastguard Worker // Couldn't find producer
361*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
362*9880d681SAndroid Build Coastguard Worker if (Vector && !HexagonMCInstrInfo::isVector(*MCII, *i->getInst()))
363*9880d681SAndroid Build Coastguard Worker // Skip scalars when calculating distances for vectors
364*9880d681SAndroid Build Coastguard Worker ++Lookback;
365*9880d681SAndroid Build Coastguard Worker if (HexagonMCInstrInfo::isImmext(*i->getInst()))
366*9880d681SAndroid Build Coastguard Worker ++Lookback;
367*9880d681SAndroid Build Coastguard Worker if (Offset == Lookback)
368*9880d681SAndroid Build Coastguard Worker break;
369*9880d681SAndroid Build Coastguard Worker }
370*9880d681SAndroid Build Coastguard Worker auto const &Inst = *i->getInst();
371*9880d681SAndroid Build Coastguard Worker bool SubregBit = (Register & 0x1) != 0;
372*9880d681SAndroid Build Coastguard Worker if (SubregBit && HexagonMCInstrInfo::hasNewValue2(*MCII, Inst)) {
373*9880d681SAndroid Build Coastguard Worker // If subreg bit is set we're selecting the second produced newvalue
374*9880d681SAndroid Build Coastguard Worker unsigned Producer =
375*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::getNewValueOperand2(*MCII, Inst).getReg();
376*9880d681SAndroid Build Coastguard Worker assert(Producer != Hexagon::NoRegister);
377*9880d681SAndroid Build Coastguard Worker MCO.setReg(Producer);
378*9880d681SAndroid Build Coastguard Worker } else if (HexagonMCInstrInfo::hasNewValue(*MCII, Inst)) {
379*9880d681SAndroid Build Coastguard Worker unsigned Producer =
380*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg();
381*9880d681SAndroid Build Coastguard Worker if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15)
382*9880d681SAndroid Build Coastguard Worker Producer = ((Producer - Hexagon::W0) << 1) + SubregBit + Hexagon::V0;
383*9880d681SAndroid Build Coastguard Worker else if (SubregBit)
384*9880d681SAndroid Build Coastguard Worker // Hexagon PRM 10.11 New-value operands
385*9880d681SAndroid Build Coastguard Worker // Nt[0] is reserved and should always be encoded as zero.
386*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
387*9880d681SAndroid Build Coastguard Worker assert(Producer != Hexagon::NoRegister);
388*9880d681SAndroid Build Coastguard Worker MCO.setReg(Producer);
389*9880d681SAndroid Build Coastguard Worker } else
390*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
391*9880d681SAndroid Build Coastguard Worker }
392*9880d681SAndroid Build Coastguard Worker
393*9880d681SAndroid Build Coastguard Worker adjustExtendedInstructions(MI, MCB);
394*9880d681SAndroid Build Coastguard Worker MCInst const *Extender =
395*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::extenderForIndex(MCB,
396*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::bundleSize(MCB));
397*9880d681SAndroid Build Coastguard Worker if(Extender != nullptr) {
398*9880d681SAndroid Build Coastguard Worker MCInst const & Inst = HexagonMCInstrInfo::isDuplex(*MCII, MI) ?
399*9880d681SAndroid Build Coastguard Worker *MI.getOperand(1).getInst() : MI;
400*9880d681SAndroid Build Coastguard Worker if (!HexagonMCInstrInfo::isExtendable(*MCII, Inst) &&
401*9880d681SAndroid Build Coastguard Worker !HexagonMCInstrInfo::isExtended(*MCII, Inst))
402*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
403*9880d681SAndroid Build Coastguard Worker }
404*9880d681SAndroid Build Coastguard Worker return Result;
405*9880d681SAndroid Build Coastguard Worker }
406*9880d681SAndroid Build Coastguard Worker
adjustExtendedInstructions(MCInst & MCI,MCInst const & MCB) const407*9880d681SAndroid Build Coastguard Worker void HexagonDisassembler::adjustExtendedInstructions(MCInst &MCI,
408*9880d681SAndroid Build Coastguard Worker MCInst const &MCB) const {
409*9880d681SAndroid Build Coastguard Worker if (!HexagonMCInstrInfo::hasExtenderForIndex(
410*9880d681SAndroid Build Coastguard Worker MCB, HexagonMCInstrInfo::bundleSize(MCB))) {
411*9880d681SAndroid Build Coastguard Worker unsigned opcode;
412*9880d681SAndroid Build Coastguard Worker // This code is used by the disassembler to disambiguate between GP
413*9880d681SAndroid Build Coastguard Worker // relative and absolute addressing instructions since they both have
414*9880d681SAndroid Build Coastguard Worker // same encoding bits. However, an absolute addressing instruction must
415*9880d681SAndroid Build Coastguard Worker // follow an immediate extender. Disassembler alwaus select absolute
416*9880d681SAndroid Build Coastguard Worker // addressing instructions first and uses this code to change them into
417*9880d681SAndroid Build Coastguard Worker // GP relative instruction in the absence of the corresponding immediate
418*9880d681SAndroid Build Coastguard Worker // extender.
419*9880d681SAndroid Build Coastguard Worker switch (MCI.getOpcode()) {
420*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storerbabs:
421*9880d681SAndroid Build Coastguard Worker opcode = Hexagon::S2_storerbgp;
422*9880d681SAndroid Build Coastguard Worker break;
423*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storerhabs:
424*9880d681SAndroid Build Coastguard Worker opcode = Hexagon::S2_storerhgp;
425*9880d681SAndroid Build Coastguard Worker break;
426*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storerfabs:
427*9880d681SAndroid Build Coastguard Worker opcode = Hexagon::S2_storerfgp;
428*9880d681SAndroid Build Coastguard Worker break;
429*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storeriabs:
430*9880d681SAndroid Build Coastguard Worker opcode = Hexagon::S2_storerigp;
431*9880d681SAndroid Build Coastguard Worker break;
432*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storerbnewabs:
433*9880d681SAndroid Build Coastguard Worker opcode = Hexagon::S2_storerbnewgp;
434*9880d681SAndroid Build Coastguard Worker break;
435*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storerhnewabs:
436*9880d681SAndroid Build Coastguard Worker opcode = Hexagon::S2_storerhnewgp;
437*9880d681SAndroid Build Coastguard Worker break;
438*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storerinewabs:
439*9880d681SAndroid Build Coastguard Worker opcode = Hexagon::S2_storerinewgp;
440*9880d681SAndroid Build Coastguard Worker break;
441*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storerdabs:
442*9880d681SAndroid Build Coastguard Worker opcode = Hexagon::S2_storerdgp;
443*9880d681SAndroid Build Coastguard Worker break;
444*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_loadrb_abs:
445*9880d681SAndroid Build Coastguard Worker opcode = Hexagon::L2_loadrbgp;
446*9880d681SAndroid Build Coastguard Worker break;
447*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_loadrub_abs:
448*9880d681SAndroid Build Coastguard Worker opcode = Hexagon::L2_loadrubgp;
449*9880d681SAndroid Build Coastguard Worker break;
450*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_loadrh_abs:
451*9880d681SAndroid Build Coastguard Worker opcode = Hexagon::L2_loadrhgp;
452*9880d681SAndroid Build Coastguard Worker break;
453*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_loadruh_abs:
454*9880d681SAndroid Build Coastguard Worker opcode = Hexagon::L2_loadruhgp;
455*9880d681SAndroid Build Coastguard Worker break;
456*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_loadri_abs:
457*9880d681SAndroid Build Coastguard Worker opcode = Hexagon::L2_loadrigp;
458*9880d681SAndroid Build Coastguard Worker break;
459*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_loadrd_abs:
460*9880d681SAndroid Build Coastguard Worker opcode = Hexagon::L2_loadrdgp;
461*9880d681SAndroid Build Coastguard Worker break;
462*9880d681SAndroid Build Coastguard Worker default:
463*9880d681SAndroid Build Coastguard Worker opcode = MCI.getOpcode();
464*9880d681SAndroid Build Coastguard Worker }
465*9880d681SAndroid Build Coastguard Worker MCI.setOpcode(opcode);
466*9880d681SAndroid Build Coastguard Worker }
467*9880d681SAndroid Build Coastguard Worker }
468*9880d681SAndroid Build Coastguard Worker
469*9880d681SAndroid Build Coastguard Worker namespace llvm {
470*9880d681SAndroid Build Coastguard Worker extern const MCInstrDesc HexagonInsts[];
471*9880d681SAndroid Build Coastguard Worker }
472*9880d681SAndroid Build Coastguard Worker
DecodeRegisterClass(MCInst & Inst,unsigned RegNo,ArrayRef<MCPhysReg> Table)473*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo,
474*9880d681SAndroid Build Coastguard Worker ArrayRef<MCPhysReg> Table) {
475*9880d681SAndroid Build Coastguard Worker if (RegNo < Table.size()) {
476*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Table[RegNo]));
477*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
478*9880d681SAndroid Build Coastguard Worker }
479*9880d681SAndroid Build Coastguard Worker
480*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
481*9880d681SAndroid Build Coastguard Worker }
482*9880d681SAndroid Build Coastguard Worker
DecodeIntRegsLow8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)483*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo,
484*9880d681SAndroid Build Coastguard Worker uint64_t Address,
485*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
486*9880d681SAndroid Build Coastguard Worker return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);
487*9880d681SAndroid Build Coastguard Worker }
488*9880d681SAndroid Build Coastguard Worker
DecodeIntRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const void * Decoder)489*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
490*9880d681SAndroid Build Coastguard Worker uint64_t Address,
491*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
492*9880d681SAndroid Build Coastguard Worker static const MCPhysReg IntRegDecoderTable[] = {
493*9880d681SAndroid Build Coastguard Worker Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
494*9880d681SAndroid Build Coastguard Worker Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9,
495*9880d681SAndroid Build Coastguard Worker Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
496*9880d681SAndroid Build Coastguard Worker Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
497*9880d681SAndroid Build Coastguard Worker Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24,
498*9880d681SAndroid Build Coastguard Worker Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29,
499*9880d681SAndroid Build Coastguard Worker Hexagon::R30, Hexagon::R31};
500*9880d681SAndroid Build Coastguard Worker
501*9880d681SAndroid Build Coastguard Worker return DecodeRegisterClass(Inst, RegNo, IntRegDecoderTable);
502*9880d681SAndroid Build Coastguard Worker }
503*9880d681SAndroid Build Coastguard Worker
DecodeVectorRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const void * Decoder)504*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVectorRegsRegisterClass(MCInst &Inst, unsigned RegNo,
505*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/,
506*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
507*9880d681SAndroid Build Coastguard Worker static const MCPhysReg VecRegDecoderTable[] = {
508*9880d681SAndroid Build Coastguard Worker Hexagon::V0, Hexagon::V1, Hexagon::V2, Hexagon::V3, Hexagon::V4,
509*9880d681SAndroid Build Coastguard Worker Hexagon::V5, Hexagon::V6, Hexagon::V7, Hexagon::V8, Hexagon::V9,
510*9880d681SAndroid Build Coastguard Worker Hexagon::V10, Hexagon::V11, Hexagon::V12, Hexagon::V13, Hexagon::V14,
511*9880d681SAndroid Build Coastguard Worker Hexagon::V15, Hexagon::V16, Hexagon::V17, Hexagon::V18, Hexagon::V19,
512*9880d681SAndroid Build Coastguard Worker Hexagon::V20, Hexagon::V21, Hexagon::V22, Hexagon::V23, Hexagon::V24,
513*9880d681SAndroid Build Coastguard Worker Hexagon::V25, Hexagon::V26, Hexagon::V27, Hexagon::V28, Hexagon::V29,
514*9880d681SAndroid Build Coastguard Worker Hexagon::V30, Hexagon::V31};
515*9880d681SAndroid Build Coastguard Worker
516*9880d681SAndroid Build Coastguard Worker return DecodeRegisterClass(Inst, RegNo, VecRegDecoderTable);
517*9880d681SAndroid Build Coastguard Worker }
518*9880d681SAndroid Build Coastguard Worker
DecodeDoubleRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const void * Decoder)519*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
520*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/,
521*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
522*9880d681SAndroid Build Coastguard Worker static const MCPhysReg DoubleRegDecoderTable[] = {
523*9880d681SAndroid Build Coastguard Worker Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3,
524*9880d681SAndroid Build Coastguard Worker Hexagon::D4, Hexagon::D5, Hexagon::D6, Hexagon::D7,
525*9880d681SAndroid Build Coastguard Worker Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11,
526*9880d681SAndroid Build Coastguard Worker Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15};
527*9880d681SAndroid Build Coastguard Worker
528*9880d681SAndroid Build Coastguard Worker return DecodeRegisterClass(Inst, RegNo >> 1, DoubleRegDecoderTable);
529*9880d681SAndroid Build Coastguard Worker }
530*9880d681SAndroid Build Coastguard Worker
DecodeVecDblRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const void * Decoder)531*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecDblRegsRegisterClass(MCInst &Inst, unsigned RegNo,
532*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/,
533*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
534*9880d681SAndroid Build Coastguard Worker static const MCPhysReg VecDblRegDecoderTable[] = {
535*9880d681SAndroid Build Coastguard Worker Hexagon::W0, Hexagon::W1, Hexagon::W2, Hexagon::W3,
536*9880d681SAndroid Build Coastguard Worker Hexagon::W4, Hexagon::W5, Hexagon::W6, Hexagon::W7,
537*9880d681SAndroid Build Coastguard Worker Hexagon::W8, Hexagon::W9, Hexagon::W10, Hexagon::W11,
538*9880d681SAndroid Build Coastguard Worker Hexagon::W12, Hexagon::W13, Hexagon::W14, Hexagon::W15};
539*9880d681SAndroid Build Coastguard Worker
540*9880d681SAndroid Build Coastguard Worker return (DecodeRegisterClass(Inst, RegNo >> 1, VecDblRegDecoderTable));
541*9880d681SAndroid Build Coastguard Worker }
542*9880d681SAndroid Build Coastguard Worker
DecodePredRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const void * Decoder)543*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
544*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/,
545*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
546*9880d681SAndroid Build Coastguard Worker static const MCPhysReg PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1,
547*9880d681SAndroid Build Coastguard Worker Hexagon::P2, Hexagon::P3};
548*9880d681SAndroid Build Coastguard Worker
549*9880d681SAndroid Build Coastguard Worker return DecodeRegisterClass(Inst, RegNo, PredRegDecoderTable);
550*9880d681SAndroid Build Coastguard Worker }
551*9880d681SAndroid Build Coastguard Worker
DecodeVecPredRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const void * Decoder)552*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVecPredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
553*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/,
554*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
555*9880d681SAndroid Build Coastguard Worker static const MCPhysReg VecPredRegDecoderTable[] = {Hexagon::Q0, Hexagon::Q1,
556*9880d681SAndroid Build Coastguard Worker Hexagon::Q2, Hexagon::Q3};
557*9880d681SAndroid Build Coastguard Worker
558*9880d681SAndroid Build Coastguard Worker return DecodeRegisterClass(Inst, RegNo, VecPredRegDecoderTable);
559*9880d681SAndroid Build Coastguard Worker }
560*9880d681SAndroid Build Coastguard Worker
DecodeCtrRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const void * Decoder)561*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
562*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/,
563*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
564*9880d681SAndroid Build Coastguard Worker static const MCPhysReg CtrlRegDecoderTable[] = {
565*9880d681SAndroid Build Coastguard Worker Hexagon::SA0, Hexagon::LC0, Hexagon::SA1, Hexagon::LC1,
566*9880d681SAndroid Build Coastguard Worker Hexagon::P3_0, Hexagon::C5, Hexagon::C6, Hexagon::C7,
567*9880d681SAndroid Build Coastguard Worker Hexagon::USR, Hexagon::PC, Hexagon::UGP, Hexagon::GP,
568*9880d681SAndroid Build Coastguard Worker Hexagon::CS0, Hexagon::CS1, Hexagon::UPCL, Hexagon::UPC
569*9880d681SAndroid Build Coastguard Worker };
570*9880d681SAndroid Build Coastguard Worker
571*9880d681SAndroid Build Coastguard Worker if (RegNo >= array_lengthof(CtrlRegDecoderTable))
572*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
573*9880d681SAndroid Build Coastguard Worker
574*9880d681SAndroid Build Coastguard Worker if (CtrlRegDecoderTable[RegNo] == Hexagon::NoRegister)
575*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
576*9880d681SAndroid Build Coastguard Worker
577*9880d681SAndroid Build Coastguard Worker unsigned Register = CtrlRegDecoderTable[RegNo];
578*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
579*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
580*9880d681SAndroid Build Coastguard Worker }
581*9880d681SAndroid Build Coastguard Worker
DecodeCtrRegs64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const void * Decoder)582*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
583*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/,
584*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
585*9880d681SAndroid Build Coastguard Worker static const MCPhysReg CtrlReg64DecoderTable[] = {
586*9880d681SAndroid Build Coastguard Worker Hexagon::C1_0, Hexagon::NoRegister,
587*9880d681SAndroid Build Coastguard Worker Hexagon::C3_2, Hexagon::NoRegister,
588*9880d681SAndroid Build Coastguard Worker Hexagon::C7_6, Hexagon::NoRegister,
589*9880d681SAndroid Build Coastguard Worker Hexagon::C9_8, Hexagon::NoRegister,
590*9880d681SAndroid Build Coastguard Worker Hexagon::C11_10, Hexagon::NoRegister,
591*9880d681SAndroid Build Coastguard Worker Hexagon::CS, Hexagon::NoRegister,
592*9880d681SAndroid Build Coastguard Worker Hexagon::UPC, Hexagon::NoRegister
593*9880d681SAndroid Build Coastguard Worker };
594*9880d681SAndroid Build Coastguard Worker
595*9880d681SAndroid Build Coastguard Worker if (RegNo >= array_lengthof(CtrlReg64DecoderTable))
596*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
597*9880d681SAndroid Build Coastguard Worker
598*9880d681SAndroid Build Coastguard Worker if (CtrlReg64DecoderTable[RegNo] == Hexagon::NoRegister)
599*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
600*9880d681SAndroid Build Coastguard Worker
601*9880d681SAndroid Build Coastguard Worker unsigned Register = CtrlReg64DecoderTable[RegNo];
602*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
603*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
604*9880d681SAndroid Build Coastguard Worker }
605*9880d681SAndroid Build Coastguard Worker
DecodeModRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const void * Decoder)606*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
607*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/,
608*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
609*9880d681SAndroid Build Coastguard Worker unsigned Register = 0;
610*9880d681SAndroid Build Coastguard Worker switch (RegNo) {
611*9880d681SAndroid Build Coastguard Worker case 0:
612*9880d681SAndroid Build Coastguard Worker Register = Hexagon::M0;
613*9880d681SAndroid Build Coastguard Worker break;
614*9880d681SAndroid Build Coastguard Worker case 1:
615*9880d681SAndroid Build Coastguard Worker Register = Hexagon::M1;
616*9880d681SAndroid Build Coastguard Worker break;
617*9880d681SAndroid Build Coastguard Worker default:
618*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
619*9880d681SAndroid Build Coastguard Worker }
620*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Register));
621*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
622*9880d681SAndroid Build Coastguard Worker }
623*9880d681SAndroid Build Coastguard Worker
624*9880d681SAndroid Build Coastguard Worker namespace {
fullValue(MCInstrInfo const & MCII,MCInst & MCB,MCInst & MI,int64_t Value)625*9880d681SAndroid Build Coastguard Worker uint32_t fullValue(MCInstrInfo const &MCII,
626*9880d681SAndroid Build Coastguard Worker MCInst &MCB,
627*9880d681SAndroid Build Coastguard Worker MCInst &MI,
628*9880d681SAndroid Build Coastguard Worker int64_t Value) {
629*9880d681SAndroid Build Coastguard Worker MCInst const *Extender = HexagonMCInstrInfo::extenderForIndex(
630*9880d681SAndroid Build Coastguard Worker MCB, HexagonMCInstrInfo::bundleSize(MCB));
631*9880d681SAndroid Build Coastguard Worker if(!Extender || MI.size() != HexagonMCInstrInfo::getExtendableOp(MCII, MI))
632*9880d681SAndroid Build Coastguard Worker return Value;
633*9880d681SAndroid Build Coastguard Worker unsigned Alignment = HexagonMCInstrInfo::getExtentAlignment(MCII, MI);
634*9880d681SAndroid Build Coastguard Worker uint32_t Lower6 = static_cast<uint32_t>(Value >> Alignment) & 0x3f;
635*9880d681SAndroid Build Coastguard Worker int64_t Bits;
636*9880d681SAndroid Build Coastguard Worker bool Success = Extender->getOperand(0).getExpr()->evaluateAsAbsolute(Bits);
637*9880d681SAndroid Build Coastguard Worker assert(Success);(void)Success;
638*9880d681SAndroid Build Coastguard Worker uint32_t Upper26 = static_cast<uint32_t>(Bits);
639*9880d681SAndroid Build Coastguard Worker uint32_t Operand = Upper26 | Lower6;
640*9880d681SAndroid Build Coastguard Worker return Operand;
641*9880d681SAndroid Build Coastguard Worker }
642*9880d681SAndroid Build Coastguard Worker template <size_t T>
signedDecoder(MCInst & MI,unsigned tmp,const void * Decoder)643*9880d681SAndroid Build Coastguard Worker void signedDecoder(MCInst &MI, unsigned tmp, const void *Decoder) {
644*9880d681SAndroid Build Coastguard Worker HexagonDisassembler const &Disassembler = disassembler(Decoder);
645*9880d681SAndroid Build Coastguard Worker int64_t FullValue = fullValue(*Disassembler.MCII,
646*9880d681SAndroid Build Coastguard Worker **Disassembler.CurrentBundle,
647*9880d681SAndroid Build Coastguard Worker MI, SignExtend64<T>(tmp));
648*9880d681SAndroid Build Coastguard Worker int64_t Extended = SignExtend64<32>(FullValue);
649*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(MI, Extended,
650*9880d681SAndroid Build Coastguard Worker Disassembler.getContext());
651*9880d681SAndroid Build Coastguard Worker }
652*9880d681SAndroid Build Coastguard Worker }
653*9880d681SAndroid Build Coastguard Worker
unsignedImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)654*9880d681SAndroid Build Coastguard Worker static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
655*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/,
656*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
657*9880d681SAndroid Build Coastguard Worker HexagonDisassembler const &Disassembler = disassembler(Decoder);
658*9880d681SAndroid Build Coastguard Worker int64_t FullValue = fullValue(*Disassembler.MCII,
659*9880d681SAndroid Build Coastguard Worker **Disassembler.CurrentBundle,
660*9880d681SAndroid Build Coastguard Worker MI, tmp);
661*9880d681SAndroid Build Coastguard Worker assert(FullValue >= 0 && "Negative in unsigned decoder");
662*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(MI, FullValue, Disassembler.getContext());
663*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
664*9880d681SAndroid Build Coastguard Worker }
665*9880d681SAndroid Build Coastguard Worker
s16ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)666*9880d681SAndroid Build Coastguard Worker static DecodeStatus s16ImmDecoder(MCInst &MI, unsigned tmp,
667*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/, const void *Decoder) {
668*9880d681SAndroid Build Coastguard Worker signedDecoder<16>(MI, tmp, Decoder);
669*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
670*9880d681SAndroid Build Coastguard Worker }
671*9880d681SAndroid Build Coastguard Worker
s12ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)672*9880d681SAndroid Build Coastguard Worker static DecodeStatus s12ImmDecoder(MCInst &MI, unsigned tmp,
673*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/, const void *Decoder) {
674*9880d681SAndroid Build Coastguard Worker signedDecoder<12>(MI, tmp, Decoder);
675*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
676*9880d681SAndroid Build Coastguard Worker }
677*9880d681SAndroid Build Coastguard Worker
s11_0ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)678*9880d681SAndroid Build Coastguard Worker static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp,
679*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/, const void *Decoder) {
680*9880d681SAndroid Build Coastguard Worker signedDecoder<11>(MI, tmp, Decoder);
681*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
682*9880d681SAndroid Build Coastguard Worker }
683*9880d681SAndroid Build Coastguard Worker
s11_1ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)684*9880d681SAndroid Build Coastguard Worker static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp,
685*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/, const void *Decoder) {
686*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(MI, SignExtend64<12>(tmp), contextFromDecoder(Decoder));
687*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
688*9880d681SAndroid Build Coastguard Worker }
689*9880d681SAndroid Build Coastguard Worker
s11_2ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)690*9880d681SAndroid Build Coastguard Worker static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp,
691*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/, const void *Decoder) {
692*9880d681SAndroid Build Coastguard Worker signedDecoder<13>(MI, tmp, Decoder);
693*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
694*9880d681SAndroid Build Coastguard Worker }
695*9880d681SAndroid Build Coastguard Worker
s11_3ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)696*9880d681SAndroid Build Coastguard Worker static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp,
697*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/, const void *Decoder) {
698*9880d681SAndroid Build Coastguard Worker signedDecoder<14>(MI, tmp, Decoder);
699*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
700*9880d681SAndroid Build Coastguard Worker }
701*9880d681SAndroid Build Coastguard Worker
s10ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)702*9880d681SAndroid Build Coastguard Worker static DecodeStatus s10ImmDecoder(MCInst &MI, unsigned tmp,
703*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/, const void *Decoder) {
704*9880d681SAndroid Build Coastguard Worker signedDecoder<10>(MI, tmp, Decoder);
705*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
706*9880d681SAndroid Build Coastguard Worker }
707*9880d681SAndroid Build Coastguard Worker
s8ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)708*9880d681SAndroid Build Coastguard Worker static DecodeStatus s8ImmDecoder(MCInst &MI, unsigned tmp, uint64_t /*Address*/,
709*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
710*9880d681SAndroid Build Coastguard Worker signedDecoder<8>(MI, tmp, Decoder);
711*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
712*9880d681SAndroid Build Coastguard Worker }
713*9880d681SAndroid Build Coastguard Worker
s6_0ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)714*9880d681SAndroid Build Coastguard Worker static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp,
715*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/, const void *Decoder) {
716*9880d681SAndroid Build Coastguard Worker signedDecoder<6>(MI, tmp, Decoder);
717*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
718*9880d681SAndroid Build Coastguard Worker }
719*9880d681SAndroid Build Coastguard Worker
s4_0ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)720*9880d681SAndroid Build Coastguard Worker static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp,
721*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/, const void *Decoder) {
722*9880d681SAndroid Build Coastguard Worker signedDecoder<4>(MI, tmp, Decoder);
723*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
724*9880d681SAndroid Build Coastguard Worker }
725*9880d681SAndroid Build Coastguard Worker
s4_1ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)726*9880d681SAndroid Build Coastguard Worker static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp,
727*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/, const void *Decoder) {
728*9880d681SAndroid Build Coastguard Worker signedDecoder<5>(MI, tmp, Decoder);
729*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
730*9880d681SAndroid Build Coastguard Worker }
731*9880d681SAndroid Build Coastguard Worker
s4_2ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)732*9880d681SAndroid Build Coastguard Worker static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp,
733*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/, const void *Decoder) {
734*9880d681SAndroid Build Coastguard Worker signedDecoder<6>(MI, tmp, Decoder);
735*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
736*9880d681SAndroid Build Coastguard Worker }
737*9880d681SAndroid Build Coastguard Worker
s4_3ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)738*9880d681SAndroid Build Coastguard Worker static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp,
739*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/, const void *Decoder) {
740*9880d681SAndroid Build Coastguard Worker signedDecoder<7>(MI, tmp, Decoder);
741*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
742*9880d681SAndroid Build Coastguard Worker }
743*9880d681SAndroid Build Coastguard Worker
s4_6ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)744*9880d681SAndroid Build Coastguard Worker static DecodeStatus s4_6ImmDecoder(MCInst &MI, unsigned tmp,
745*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/, const void *Decoder) {
746*9880d681SAndroid Build Coastguard Worker signedDecoder<10>(MI, tmp, Decoder);
747*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
748*9880d681SAndroid Build Coastguard Worker }
749*9880d681SAndroid Build Coastguard Worker
s3_6ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const void * Decoder)750*9880d681SAndroid Build Coastguard Worker static DecodeStatus s3_6ImmDecoder(MCInst &MI, unsigned tmp,
751*9880d681SAndroid Build Coastguard Worker uint64_t /*Address*/, const void *Decoder) {
752*9880d681SAndroid Build Coastguard Worker signedDecoder<19>(MI, tmp, Decoder);
753*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
754*9880d681SAndroid Build Coastguard Worker }
755*9880d681SAndroid Build Coastguard Worker
756*9880d681SAndroid Build Coastguard Worker // custom decoder for various jump/call immediates
brtargetDecoder(MCInst & MI,unsigned tmp,uint64_t Address,const void * Decoder)757*9880d681SAndroid Build Coastguard Worker static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
758*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
759*9880d681SAndroid Build Coastguard Worker HexagonDisassembler const &Disassembler = disassembler(Decoder);
760*9880d681SAndroid Build Coastguard Worker unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII, MI);
761*9880d681SAndroid Build Coastguard Worker // r13_2 is not extendable, so if there are no extent bits, it's r13_2
762*9880d681SAndroid Build Coastguard Worker if (Bits == 0)
763*9880d681SAndroid Build Coastguard Worker Bits = 15;
764*9880d681SAndroid Build Coastguard Worker uint32_t FullValue = fullValue(*Disassembler.MCII,
765*9880d681SAndroid Build Coastguard Worker **Disassembler.CurrentBundle,
766*9880d681SAndroid Build Coastguard Worker MI, SignExtend64(tmp, Bits));
767*9880d681SAndroid Build Coastguard Worker int64_t Extended = SignExtend64<32>(FullValue) + Address;
768*9880d681SAndroid Build Coastguard Worker if (!Disassembler.tryAddingSymbolicOperand(MI, Extended, Address, true,
769*9880d681SAndroid Build Coastguard Worker 0, 4))
770*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext());
771*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
772*9880d681SAndroid Build Coastguard Worker }
773*9880d681SAndroid Build Coastguard Worker
774*9880d681SAndroid Build Coastguard Worker // Addressing mode dependent load store opcode map.
775*9880d681SAndroid Build Coastguard Worker // - If an insn is preceded by an extender the address is absolute.
776*9880d681SAndroid Build Coastguard Worker // - memw(##symbol) = r0
777*9880d681SAndroid Build Coastguard Worker // - If an insn is not preceded by an extender the address is GP relative.
778*9880d681SAndroid Build Coastguard Worker // - memw(gp + #symbol) = r0
779*9880d681SAndroid Build Coastguard Worker // Please note that the instructions must be ordered in the descending order
780*9880d681SAndroid Build Coastguard Worker // of their opcode.
781*9880d681SAndroid Build Coastguard Worker // HexagonII::INST_ICLASS_ST
782*9880d681SAndroid Build Coastguard Worker static const unsigned int StoreConditionalOpcodeData[][2] = {
783*9880d681SAndroid Build Coastguard Worker {S4_pstorerdfnew_abs, 0xafc02084},
784*9880d681SAndroid Build Coastguard Worker {S4_pstorerdtnew_abs, 0xafc02080},
785*9880d681SAndroid Build Coastguard Worker {S4_pstorerdf_abs, 0xafc00084},
786*9880d681SAndroid Build Coastguard Worker {S4_pstorerdt_abs, 0xafc00080},
787*9880d681SAndroid Build Coastguard Worker {S4_pstorerinewfnew_abs, 0xafa03084},
788*9880d681SAndroid Build Coastguard Worker {S4_pstorerinewtnew_abs, 0xafa03080},
789*9880d681SAndroid Build Coastguard Worker {S4_pstorerhnewfnew_abs, 0xafa02884},
790*9880d681SAndroid Build Coastguard Worker {S4_pstorerhnewtnew_abs, 0xafa02880},
791*9880d681SAndroid Build Coastguard Worker {S4_pstorerbnewfnew_abs, 0xafa02084},
792*9880d681SAndroid Build Coastguard Worker {S4_pstorerbnewtnew_abs, 0xafa02080},
793*9880d681SAndroid Build Coastguard Worker {S4_pstorerinewf_abs, 0xafa01084},
794*9880d681SAndroid Build Coastguard Worker {S4_pstorerinewt_abs, 0xafa01080},
795*9880d681SAndroid Build Coastguard Worker {S4_pstorerhnewf_abs, 0xafa00884},
796*9880d681SAndroid Build Coastguard Worker {S4_pstorerhnewt_abs, 0xafa00880},
797*9880d681SAndroid Build Coastguard Worker {S4_pstorerbnewf_abs, 0xafa00084},
798*9880d681SAndroid Build Coastguard Worker {S4_pstorerbnewt_abs, 0xafa00080},
799*9880d681SAndroid Build Coastguard Worker {S4_pstorerifnew_abs, 0xaf802084},
800*9880d681SAndroid Build Coastguard Worker {S4_pstoreritnew_abs, 0xaf802080},
801*9880d681SAndroid Build Coastguard Worker {S4_pstorerif_abs, 0xaf800084},
802*9880d681SAndroid Build Coastguard Worker {S4_pstorerit_abs, 0xaf800080},
803*9880d681SAndroid Build Coastguard Worker {S4_pstorerhfnew_abs, 0xaf402084},
804*9880d681SAndroid Build Coastguard Worker {S4_pstorerhtnew_abs, 0xaf402080},
805*9880d681SAndroid Build Coastguard Worker {S4_pstorerhf_abs, 0xaf400084},
806*9880d681SAndroid Build Coastguard Worker {S4_pstorerht_abs, 0xaf400080},
807*9880d681SAndroid Build Coastguard Worker {S4_pstorerbfnew_abs, 0xaf002084},
808*9880d681SAndroid Build Coastguard Worker {S4_pstorerbtnew_abs, 0xaf002080},
809*9880d681SAndroid Build Coastguard Worker {S4_pstorerbf_abs, 0xaf000084},
810*9880d681SAndroid Build Coastguard Worker {S4_pstorerbt_abs, 0xaf000080}};
811*9880d681SAndroid Build Coastguard Worker // HexagonII::INST_ICLASS_LD
812*9880d681SAndroid Build Coastguard Worker
813*9880d681SAndroid Build Coastguard Worker // HexagonII::INST_ICLASS_LD_ST_2
814*9880d681SAndroid Build Coastguard Worker static unsigned int LoadStoreOpcodeData[][2] = {{L4_loadrd_abs, 0x49c00000},
815*9880d681SAndroid Build Coastguard Worker {L4_loadri_abs, 0x49800000},
816*9880d681SAndroid Build Coastguard Worker {L4_loadruh_abs, 0x49600000},
817*9880d681SAndroid Build Coastguard Worker {L4_loadrh_abs, 0x49400000},
818*9880d681SAndroid Build Coastguard Worker {L4_loadrub_abs, 0x49200000},
819*9880d681SAndroid Build Coastguard Worker {L4_loadrb_abs, 0x49000000},
820*9880d681SAndroid Build Coastguard Worker {S2_storerdabs, 0x48c00000},
821*9880d681SAndroid Build Coastguard Worker {S2_storerinewabs, 0x48a01000},
822*9880d681SAndroid Build Coastguard Worker {S2_storerhnewabs, 0x48a00800},
823*9880d681SAndroid Build Coastguard Worker {S2_storerbnewabs, 0x48a00000},
824*9880d681SAndroid Build Coastguard Worker {S2_storeriabs, 0x48800000},
825*9880d681SAndroid Build Coastguard Worker {S2_storerfabs, 0x48600000},
826*9880d681SAndroid Build Coastguard Worker {S2_storerhabs, 0x48400000},
827*9880d681SAndroid Build Coastguard Worker {S2_storerbabs, 0x48000000}};
828*9880d681SAndroid Build Coastguard Worker static const size_t NumCondS = array_lengthof(StoreConditionalOpcodeData);
829*9880d681SAndroid Build Coastguard Worker static const size_t NumLS = array_lengthof(LoadStoreOpcodeData);
830*9880d681SAndroid Build Coastguard Worker
decodeSpecial(MCInst & MI,uint32_t insn)831*9880d681SAndroid Build Coastguard Worker static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
832*9880d681SAndroid Build Coastguard Worker
833*9880d681SAndroid Build Coastguard Worker unsigned MachineOpcode = 0;
834*9880d681SAndroid Build Coastguard Worker unsigned LLVMOpcode = 0;
835*9880d681SAndroid Build Coastguard Worker
836*9880d681SAndroid Build Coastguard Worker if ((insn & HexagonII::INST_ICLASS_MASK) == HexagonII::INST_ICLASS_ST) {
837*9880d681SAndroid Build Coastguard Worker for (size_t i = 0; i < NumCondS; ++i) {
838*9880d681SAndroid Build Coastguard Worker if ((insn & StoreConditionalOpcodeData[i][1]) ==
839*9880d681SAndroid Build Coastguard Worker StoreConditionalOpcodeData[i][1]) {
840*9880d681SAndroid Build Coastguard Worker MachineOpcode = StoreConditionalOpcodeData[i][1];
841*9880d681SAndroid Build Coastguard Worker LLVMOpcode = StoreConditionalOpcodeData[i][0];
842*9880d681SAndroid Build Coastguard Worker break;
843*9880d681SAndroid Build Coastguard Worker }
844*9880d681SAndroid Build Coastguard Worker }
845*9880d681SAndroid Build Coastguard Worker }
846*9880d681SAndroid Build Coastguard Worker if ((insn & HexagonII::INST_ICLASS_MASK) == HexagonII::INST_ICLASS_LD_ST_2) {
847*9880d681SAndroid Build Coastguard Worker for (size_t i = 0; i < NumLS; ++i) {
848*9880d681SAndroid Build Coastguard Worker if ((insn & LoadStoreOpcodeData[i][1]) == LoadStoreOpcodeData[i][1]) {
849*9880d681SAndroid Build Coastguard Worker MachineOpcode = LoadStoreOpcodeData[i][1];
850*9880d681SAndroid Build Coastguard Worker LLVMOpcode = LoadStoreOpcodeData[i][0];
851*9880d681SAndroid Build Coastguard Worker break;
852*9880d681SAndroid Build Coastguard Worker }
853*9880d681SAndroid Build Coastguard Worker }
854*9880d681SAndroid Build Coastguard Worker }
855*9880d681SAndroid Build Coastguard Worker
856*9880d681SAndroid Build Coastguard Worker if (MachineOpcode) {
857*9880d681SAndroid Build Coastguard Worker unsigned Value = 0;
858*9880d681SAndroid Build Coastguard Worker unsigned shift = 0;
859*9880d681SAndroid Build Coastguard Worker MI.setOpcode(LLVMOpcode);
860*9880d681SAndroid Build Coastguard Worker // Remove the parse bits from the insn.
861*9880d681SAndroid Build Coastguard Worker insn &= ~HexagonII::INST_PARSE_MASK;
862*9880d681SAndroid Build Coastguard Worker
863*9880d681SAndroid Build Coastguard Worker switch (LLVMOpcode) {
864*9880d681SAndroid Build Coastguard Worker default:
865*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
866*9880d681SAndroid Build Coastguard Worker break;
867*9880d681SAndroid Build Coastguard Worker
868*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerdf_abs:
869*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerdt_abs:
870*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerdfnew_abs:
871*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerdtnew_abs: {
872*9880d681SAndroid Build Coastguard Worker // op: Pv
873*9880d681SAndroid Build Coastguard Worker Value = insn & UINT64_C(3);
874*9880d681SAndroid Build Coastguard Worker DecodePredRegsRegisterClass(MI, Value, 0, 0);
875*9880d681SAndroid Build Coastguard Worker // op: u6
876*9880d681SAndroid Build Coastguard Worker Value = (insn >> 12) & UINT64_C(48);
877*9880d681SAndroid Build Coastguard Worker Value |= (insn >> 3) & UINT64_C(15);
878*9880d681SAndroid Build Coastguard Worker MI.addOperand(MCOperand::createImm(Value));
879*9880d681SAndroid Build Coastguard Worker // op: Rtt
880*9880d681SAndroid Build Coastguard Worker Value = (insn >> 8) & UINT64_C(31);
881*9880d681SAndroid Build Coastguard Worker DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
882*9880d681SAndroid Build Coastguard Worker break;
883*9880d681SAndroid Build Coastguard Worker }
884*9880d681SAndroid Build Coastguard Worker
885*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerbnewf_abs:
886*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerbnewt_abs:
887*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerbnewfnew_abs:
888*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerbnewtnew_abs:
889*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerhnewf_abs:
890*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerhnewt_abs:
891*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerhnewfnew_abs:
892*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerhnewtnew_abs:
893*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerinewf_abs:
894*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerinewt_abs:
895*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerinewfnew_abs:
896*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerinewtnew_abs: {
897*9880d681SAndroid Build Coastguard Worker // op: Pv
898*9880d681SAndroid Build Coastguard Worker Value = insn & UINT64_C(3);
899*9880d681SAndroid Build Coastguard Worker DecodePredRegsRegisterClass(MI, Value, 0, 0);
900*9880d681SAndroid Build Coastguard Worker // op: u6
901*9880d681SAndroid Build Coastguard Worker Value = (insn >> 12) & UINT64_C(48);
902*9880d681SAndroid Build Coastguard Worker Value |= (insn >> 3) & UINT64_C(15);
903*9880d681SAndroid Build Coastguard Worker MI.addOperand(MCOperand::createImm(Value));
904*9880d681SAndroid Build Coastguard Worker // op: Nt
905*9880d681SAndroid Build Coastguard Worker Value = (insn >> 8) & UINT64_C(7);
906*9880d681SAndroid Build Coastguard Worker DecodeIntRegsRegisterClass(MI, Value, 0, 0);
907*9880d681SAndroid Build Coastguard Worker break;
908*9880d681SAndroid Build Coastguard Worker }
909*9880d681SAndroid Build Coastguard Worker
910*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerbf_abs:
911*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerbt_abs:
912*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerbfnew_abs:
913*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerbtnew_abs:
914*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerhf_abs:
915*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerht_abs:
916*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerhfnew_abs:
917*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerhtnew_abs:
918*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerif_abs:
919*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerit_abs:
920*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstorerifnew_abs:
921*9880d681SAndroid Build Coastguard Worker case Hexagon::S4_pstoreritnew_abs: {
922*9880d681SAndroid Build Coastguard Worker // op: Pv
923*9880d681SAndroid Build Coastguard Worker Value = insn & UINT64_C(3);
924*9880d681SAndroid Build Coastguard Worker DecodePredRegsRegisterClass(MI, Value, 0, 0);
925*9880d681SAndroid Build Coastguard Worker // op: u6
926*9880d681SAndroid Build Coastguard Worker Value = (insn >> 12) & UINT64_C(48);
927*9880d681SAndroid Build Coastguard Worker Value |= (insn >> 3) & UINT64_C(15);
928*9880d681SAndroid Build Coastguard Worker MI.addOperand(MCOperand::createImm(Value));
929*9880d681SAndroid Build Coastguard Worker // op: Rt
930*9880d681SAndroid Build Coastguard Worker Value = (insn >> 8) & UINT64_C(31);
931*9880d681SAndroid Build Coastguard Worker DecodeIntRegsRegisterClass(MI, Value, 0, 0);
932*9880d681SAndroid Build Coastguard Worker break;
933*9880d681SAndroid Build Coastguard Worker }
934*9880d681SAndroid Build Coastguard Worker
935*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrdf_abs:
936*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrdt_abs:
937*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrdfnew_abs:
938*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrdtnew_abs: {
939*9880d681SAndroid Build Coastguard Worker // op: Rdd
940*9880d681SAndroid Build Coastguard Worker Value = insn & UINT64_C(31);
941*9880d681SAndroid Build Coastguard Worker DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
942*9880d681SAndroid Build Coastguard Worker // op: Pt
943*9880d681SAndroid Build Coastguard Worker Value = ((insn >> 9) & UINT64_C(3));
944*9880d681SAndroid Build Coastguard Worker DecodePredRegsRegisterClass(MI, Value, 0, 0);
945*9880d681SAndroid Build Coastguard Worker // op: u6
946*9880d681SAndroid Build Coastguard Worker Value = ((insn >> 15) & UINT64_C(62));
947*9880d681SAndroid Build Coastguard Worker Value |= ((insn >> 8) & UINT64_C(1));
948*9880d681SAndroid Build Coastguard Worker MI.addOperand(MCOperand::createImm(Value));
949*9880d681SAndroid Build Coastguard Worker break;
950*9880d681SAndroid Build Coastguard Worker }
951*9880d681SAndroid Build Coastguard Worker
952*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrbf_abs:
953*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrbt_abs:
954*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrbfnew_abs:
955*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrbtnew_abs:
956*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrhf_abs:
957*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrht_abs:
958*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrhfnew_abs:
959*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrhtnew_abs:
960*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrubf_abs:
961*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrubt_abs:
962*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrubfnew_abs:
963*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrubtnew_abs:
964*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadruhf_abs:
965*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadruht_abs:
966*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadruhfnew_abs:
967*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadruhtnew_abs:
968*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrif_abs:
969*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrit_abs:
970*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadrifnew_abs:
971*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_ploadritnew_abs:
972*9880d681SAndroid Build Coastguard Worker // op: Rd
973*9880d681SAndroid Build Coastguard Worker Value = insn & UINT64_C(31);
974*9880d681SAndroid Build Coastguard Worker DecodeIntRegsRegisterClass(MI, Value, 0, 0);
975*9880d681SAndroid Build Coastguard Worker // op: Pt
976*9880d681SAndroid Build Coastguard Worker Value = (insn >> 9) & UINT64_C(3);
977*9880d681SAndroid Build Coastguard Worker DecodePredRegsRegisterClass(MI, Value, 0, 0);
978*9880d681SAndroid Build Coastguard Worker // op: u6
979*9880d681SAndroid Build Coastguard Worker Value = (insn >> 15) & UINT64_C(62);
980*9880d681SAndroid Build Coastguard Worker Value |= (insn >> 8) & UINT64_C(1);
981*9880d681SAndroid Build Coastguard Worker MI.addOperand(MCOperand::createImm(Value));
982*9880d681SAndroid Build Coastguard Worker break;
983*9880d681SAndroid Build Coastguard Worker
984*9880d681SAndroid Build Coastguard Worker // op: g16_2
985*9880d681SAndroid Build Coastguard Worker case (Hexagon::L4_loadri_abs):
986*9880d681SAndroid Build Coastguard Worker ++shift;
987*9880d681SAndroid Build Coastguard Worker // op: g16_1
988*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_loadrh_abs:
989*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_loadruh_abs:
990*9880d681SAndroid Build Coastguard Worker ++shift;
991*9880d681SAndroid Build Coastguard Worker // op: g16_0
992*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_loadrb_abs:
993*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_loadrub_abs: {
994*9880d681SAndroid Build Coastguard Worker // op: Rd
995*9880d681SAndroid Build Coastguard Worker Value |= insn & UINT64_C(31);
996*9880d681SAndroid Build Coastguard Worker DecodeIntRegsRegisterClass(MI, Value, 0, 0);
997*9880d681SAndroid Build Coastguard Worker Value = (insn >> 11) & UINT64_C(49152);
998*9880d681SAndroid Build Coastguard Worker Value |= (insn >> 7) & UINT64_C(15872);
999*9880d681SAndroid Build Coastguard Worker Value |= (insn >> 5) & UINT64_C(511);
1000*9880d681SAndroid Build Coastguard Worker MI.addOperand(MCOperand::createImm(Value << shift));
1001*9880d681SAndroid Build Coastguard Worker break;
1002*9880d681SAndroid Build Coastguard Worker }
1003*9880d681SAndroid Build Coastguard Worker
1004*9880d681SAndroid Build Coastguard Worker case Hexagon::L4_loadrd_abs: {
1005*9880d681SAndroid Build Coastguard Worker Value = insn & UINT64_C(31);
1006*9880d681SAndroid Build Coastguard Worker DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
1007*9880d681SAndroid Build Coastguard Worker Value = (insn >> 11) & UINT64_C(49152);
1008*9880d681SAndroid Build Coastguard Worker Value |= (insn >> 7) & UINT64_C(15872);
1009*9880d681SAndroid Build Coastguard Worker Value |= (insn >> 5) & UINT64_C(511);
1010*9880d681SAndroid Build Coastguard Worker MI.addOperand(MCOperand::createImm(Value << 3));
1011*9880d681SAndroid Build Coastguard Worker break;
1012*9880d681SAndroid Build Coastguard Worker }
1013*9880d681SAndroid Build Coastguard Worker
1014*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storerdabs: {
1015*9880d681SAndroid Build Coastguard Worker // op: g16_3
1016*9880d681SAndroid Build Coastguard Worker Value = (insn >> 11) & UINT64_C(49152);
1017*9880d681SAndroid Build Coastguard Worker Value |= (insn >> 7) & UINT64_C(15872);
1018*9880d681SAndroid Build Coastguard Worker Value |= (insn >> 5) & UINT64_C(256);
1019*9880d681SAndroid Build Coastguard Worker Value |= insn & UINT64_C(255);
1020*9880d681SAndroid Build Coastguard Worker MI.addOperand(MCOperand::createImm(Value << 3));
1021*9880d681SAndroid Build Coastguard Worker // op: Rtt
1022*9880d681SAndroid Build Coastguard Worker Value = (insn >> 8) & UINT64_C(31);
1023*9880d681SAndroid Build Coastguard Worker DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
1024*9880d681SAndroid Build Coastguard Worker break;
1025*9880d681SAndroid Build Coastguard Worker }
1026*9880d681SAndroid Build Coastguard Worker
1027*9880d681SAndroid Build Coastguard Worker // op: g16_2
1028*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storerinewabs:
1029*9880d681SAndroid Build Coastguard Worker ++shift;
1030*9880d681SAndroid Build Coastguard Worker // op: g16_1
1031*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storerhnewabs:
1032*9880d681SAndroid Build Coastguard Worker ++shift;
1033*9880d681SAndroid Build Coastguard Worker // op: g16_0
1034*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storerbnewabs: {
1035*9880d681SAndroid Build Coastguard Worker Value = (insn >> 11) & UINT64_C(49152);
1036*9880d681SAndroid Build Coastguard Worker Value |= (insn >> 7) & UINT64_C(15872);
1037*9880d681SAndroid Build Coastguard Worker Value |= (insn >> 5) & UINT64_C(256);
1038*9880d681SAndroid Build Coastguard Worker Value |= insn & UINT64_C(255);
1039*9880d681SAndroid Build Coastguard Worker MI.addOperand(MCOperand::createImm(Value << shift));
1040*9880d681SAndroid Build Coastguard Worker // op: Nt
1041*9880d681SAndroid Build Coastguard Worker Value = (insn >> 8) & UINT64_C(7);
1042*9880d681SAndroid Build Coastguard Worker DecodeIntRegsRegisterClass(MI, Value, 0, 0);
1043*9880d681SAndroid Build Coastguard Worker break;
1044*9880d681SAndroid Build Coastguard Worker }
1045*9880d681SAndroid Build Coastguard Worker
1046*9880d681SAndroid Build Coastguard Worker // op: g16_2
1047*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storeriabs:
1048*9880d681SAndroid Build Coastguard Worker ++shift;
1049*9880d681SAndroid Build Coastguard Worker // op: g16_1
1050*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storerhabs:
1051*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storerfabs:
1052*9880d681SAndroid Build Coastguard Worker ++shift;
1053*9880d681SAndroid Build Coastguard Worker // op: g16_0
1054*9880d681SAndroid Build Coastguard Worker case Hexagon::S2_storerbabs: {
1055*9880d681SAndroid Build Coastguard Worker Value = (insn >> 11) & UINT64_C(49152);
1056*9880d681SAndroid Build Coastguard Worker Value |= (insn >> 7) & UINT64_C(15872);
1057*9880d681SAndroid Build Coastguard Worker Value |= (insn >> 5) & UINT64_C(256);
1058*9880d681SAndroid Build Coastguard Worker Value |= insn & UINT64_C(255);
1059*9880d681SAndroid Build Coastguard Worker MI.addOperand(MCOperand::createImm(Value << shift));
1060*9880d681SAndroid Build Coastguard Worker // op: Rt
1061*9880d681SAndroid Build Coastguard Worker Value = (insn >> 8) & UINT64_C(31);
1062*9880d681SAndroid Build Coastguard Worker DecodeIntRegsRegisterClass(MI, Value, 0, 0);
1063*9880d681SAndroid Build Coastguard Worker break;
1064*9880d681SAndroid Build Coastguard Worker }
1065*9880d681SAndroid Build Coastguard Worker }
1066*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
1067*9880d681SAndroid Build Coastguard Worker }
1068*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
1069*9880d681SAndroid Build Coastguard Worker }
1070*9880d681SAndroid Build Coastguard Worker
decodeImmext(MCInst & MI,uint32_t insn,void const * Decoder)1071*9880d681SAndroid Build Coastguard Worker static DecodeStatus decodeImmext(MCInst &MI, uint32_t insn,
1072*9880d681SAndroid Build Coastguard Worker void const *Decoder) {
1073*9880d681SAndroid Build Coastguard Worker
1074*9880d681SAndroid Build Coastguard Worker // Instruction Class for a constant a extender: bits 31:28 = 0x0000
1075*9880d681SAndroid Build Coastguard Worker if ((~insn & 0xf0000000) == 0xf0000000) {
1076*9880d681SAndroid Build Coastguard Worker unsigned Value;
1077*9880d681SAndroid Build Coastguard Worker // 27:16 High 12 bits of 26-bit extender.
1078*9880d681SAndroid Build Coastguard Worker Value = (insn & 0x0fff0000) << 4;
1079*9880d681SAndroid Build Coastguard Worker // 13:0 Low 14 bits of 26-bit extender.
1080*9880d681SAndroid Build Coastguard Worker Value |= ((insn & 0x3fff) << 6);
1081*9880d681SAndroid Build Coastguard Worker MI.setOpcode(Hexagon::A4_ext);
1082*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(MI, Value, contextFromDecoder(Decoder));
1083*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
1084*9880d681SAndroid Build Coastguard Worker }
1085*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
1086*9880d681SAndroid Build Coastguard Worker }
1087*9880d681SAndroid Build Coastguard Worker
1088*9880d681SAndroid Build Coastguard Worker // These values are from HexagonGenMCCodeEmitter.inc and HexagonIsetDx.td
1089*9880d681SAndroid Build Coastguard Worker enum subInstBinaryValues {
1090*9880d681SAndroid Build Coastguard Worker V4_SA1_addi_BITS = 0x0000,
1091*9880d681SAndroid Build Coastguard Worker V4_SA1_addi_MASK = 0x1800,
1092*9880d681SAndroid Build Coastguard Worker V4_SA1_addrx_BITS = 0x1800,
1093*9880d681SAndroid Build Coastguard Worker V4_SA1_addrx_MASK = 0x1f00,
1094*9880d681SAndroid Build Coastguard Worker V4_SA1_addsp_BITS = 0x0c00,
1095*9880d681SAndroid Build Coastguard Worker V4_SA1_addsp_MASK = 0x1c00,
1096*9880d681SAndroid Build Coastguard Worker V4_SA1_and1_BITS = 0x1200,
1097*9880d681SAndroid Build Coastguard Worker V4_SA1_and1_MASK = 0x1f00,
1098*9880d681SAndroid Build Coastguard Worker V4_SA1_clrf_BITS = 0x1a70,
1099*9880d681SAndroid Build Coastguard Worker V4_SA1_clrf_MASK = 0x1e70,
1100*9880d681SAndroid Build Coastguard Worker V4_SA1_clrfnew_BITS = 0x1a50,
1101*9880d681SAndroid Build Coastguard Worker V4_SA1_clrfnew_MASK = 0x1e70,
1102*9880d681SAndroid Build Coastguard Worker V4_SA1_clrt_BITS = 0x1a60,
1103*9880d681SAndroid Build Coastguard Worker V4_SA1_clrt_MASK = 0x1e70,
1104*9880d681SAndroid Build Coastguard Worker V4_SA1_clrtnew_BITS = 0x1a40,
1105*9880d681SAndroid Build Coastguard Worker V4_SA1_clrtnew_MASK = 0x1e70,
1106*9880d681SAndroid Build Coastguard Worker V4_SA1_cmpeqi_BITS = 0x1900,
1107*9880d681SAndroid Build Coastguard Worker V4_SA1_cmpeqi_MASK = 0x1f00,
1108*9880d681SAndroid Build Coastguard Worker V4_SA1_combine0i_BITS = 0x1c00,
1109*9880d681SAndroid Build Coastguard Worker V4_SA1_combine0i_MASK = 0x1d18,
1110*9880d681SAndroid Build Coastguard Worker V4_SA1_combine1i_BITS = 0x1c08,
1111*9880d681SAndroid Build Coastguard Worker V4_SA1_combine1i_MASK = 0x1d18,
1112*9880d681SAndroid Build Coastguard Worker V4_SA1_combine2i_BITS = 0x1c10,
1113*9880d681SAndroid Build Coastguard Worker V4_SA1_combine2i_MASK = 0x1d18,
1114*9880d681SAndroid Build Coastguard Worker V4_SA1_combine3i_BITS = 0x1c18,
1115*9880d681SAndroid Build Coastguard Worker V4_SA1_combine3i_MASK = 0x1d18,
1116*9880d681SAndroid Build Coastguard Worker V4_SA1_combinerz_BITS = 0x1d08,
1117*9880d681SAndroid Build Coastguard Worker V4_SA1_combinerz_MASK = 0x1d08,
1118*9880d681SAndroid Build Coastguard Worker V4_SA1_combinezr_BITS = 0x1d00,
1119*9880d681SAndroid Build Coastguard Worker V4_SA1_combinezr_MASK = 0x1d08,
1120*9880d681SAndroid Build Coastguard Worker V4_SA1_dec_BITS = 0x1300,
1121*9880d681SAndroid Build Coastguard Worker V4_SA1_dec_MASK = 0x1f00,
1122*9880d681SAndroid Build Coastguard Worker V4_SA1_inc_BITS = 0x1100,
1123*9880d681SAndroid Build Coastguard Worker V4_SA1_inc_MASK = 0x1f00,
1124*9880d681SAndroid Build Coastguard Worker V4_SA1_seti_BITS = 0x0800,
1125*9880d681SAndroid Build Coastguard Worker V4_SA1_seti_MASK = 0x1c00,
1126*9880d681SAndroid Build Coastguard Worker V4_SA1_setin1_BITS = 0x1a00,
1127*9880d681SAndroid Build Coastguard Worker V4_SA1_setin1_MASK = 0x1e40,
1128*9880d681SAndroid Build Coastguard Worker V4_SA1_sxtb_BITS = 0x1500,
1129*9880d681SAndroid Build Coastguard Worker V4_SA1_sxtb_MASK = 0x1f00,
1130*9880d681SAndroid Build Coastguard Worker V4_SA1_sxth_BITS = 0x1400,
1131*9880d681SAndroid Build Coastguard Worker V4_SA1_sxth_MASK = 0x1f00,
1132*9880d681SAndroid Build Coastguard Worker V4_SA1_tfr_BITS = 0x1000,
1133*9880d681SAndroid Build Coastguard Worker V4_SA1_tfr_MASK = 0x1f00,
1134*9880d681SAndroid Build Coastguard Worker V4_SA1_zxtb_BITS = 0x1700,
1135*9880d681SAndroid Build Coastguard Worker V4_SA1_zxtb_MASK = 0x1f00,
1136*9880d681SAndroid Build Coastguard Worker V4_SA1_zxth_BITS = 0x1600,
1137*9880d681SAndroid Build Coastguard Worker V4_SA1_zxth_MASK = 0x1f00,
1138*9880d681SAndroid Build Coastguard Worker V4_SL1_loadri_io_BITS = 0x0000,
1139*9880d681SAndroid Build Coastguard Worker V4_SL1_loadri_io_MASK = 0x1000,
1140*9880d681SAndroid Build Coastguard Worker V4_SL1_loadrub_io_BITS = 0x1000,
1141*9880d681SAndroid Build Coastguard Worker V4_SL1_loadrub_io_MASK = 0x1000,
1142*9880d681SAndroid Build Coastguard Worker V4_SL2_deallocframe_BITS = 0x1f00,
1143*9880d681SAndroid Build Coastguard Worker V4_SL2_deallocframe_MASK = 0x1fc0,
1144*9880d681SAndroid Build Coastguard Worker V4_SL2_jumpr31_BITS = 0x1fc0,
1145*9880d681SAndroid Build Coastguard Worker V4_SL2_jumpr31_MASK = 0x1fc4,
1146*9880d681SAndroid Build Coastguard Worker V4_SL2_jumpr31_f_BITS = 0x1fc5,
1147*9880d681SAndroid Build Coastguard Worker V4_SL2_jumpr31_f_MASK = 0x1fc7,
1148*9880d681SAndroid Build Coastguard Worker V4_SL2_jumpr31_fnew_BITS = 0x1fc7,
1149*9880d681SAndroid Build Coastguard Worker V4_SL2_jumpr31_fnew_MASK = 0x1fc7,
1150*9880d681SAndroid Build Coastguard Worker V4_SL2_jumpr31_t_BITS = 0x1fc4,
1151*9880d681SAndroid Build Coastguard Worker V4_SL2_jumpr31_t_MASK = 0x1fc7,
1152*9880d681SAndroid Build Coastguard Worker V4_SL2_jumpr31_tnew_BITS = 0x1fc6,
1153*9880d681SAndroid Build Coastguard Worker V4_SL2_jumpr31_tnew_MASK = 0x1fc7,
1154*9880d681SAndroid Build Coastguard Worker V4_SL2_loadrb_io_BITS = 0x1000,
1155*9880d681SAndroid Build Coastguard Worker V4_SL2_loadrb_io_MASK = 0x1800,
1156*9880d681SAndroid Build Coastguard Worker V4_SL2_loadrd_sp_BITS = 0x1e00,
1157*9880d681SAndroid Build Coastguard Worker V4_SL2_loadrd_sp_MASK = 0x1f00,
1158*9880d681SAndroid Build Coastguard Worker V4_SL2_loadrh_io_BITS = 0x0000,
1159*9880d681SAndroid Build Coastguard Worker V4_SL2_loadrh_io_MASK = 0x1800,
1160*9880d681SAndroid Build Coastguard Worker V4_SL2_loadri_sp_BITS = 0x1c00,
1161*9880d681SAndroid Build Coastguard Worker V4_SL2_loadri_sp_MASK = 0x1e00,
1162*9880d681SAndroid Build Coastguard Worker V4_SL2_loadruh_io_BITS = 0x0800,
1163*9880d681SAndroid Build Coastguard Worker V4_SL2_loadruh_io_MASK = 0x1800,
1164*9880d681SAndroid Build Coastguard Worker V4_SL2_return_BITS = 0x1f40,
1165*9880d681SAndroid Build Coastguard Worker V4_SL2_return_MASK = 0x1fc4,
1166*9880d681SAndroid Build Coastguard Worker V4_SL2_return_f_BITS = 0x1f45,
1167*9880d681SAndroid Build Coastguard Worker V4_SL2_return_f_MASK = 0x1fc7,
1168*9880d681SAndroid Build Coastguard Worker V4_SL2_return_fnew_BITS = 0x1f47,
1169*9880d681SAndroid Build Coastguard Worker V4_SL2_return_fnew_MASK = 0x1fc7,
1170*9880d681SAndroid Build Coastguard Worker V4_SL2_return_t_BITS = 0x1f44,
1171*9880d681SAndroid Build Coastguard Worker V4_SL2_return_t_MASK = 0x1fc7,
1172*9880d681SAndroid Build Coastguard Worker V4_SL2_return_tnew_BITS = 0x1f46,
1173*9880d681SAndroid Build Coastguard Worker V4_SL2_return_tnew_MASK = 0x1fc7,
1174*9880d681SAndroid Build Coastguard Worker V4_SS1_storeb_io_BITS = 0x1000,
1175*9880d681SAndroid Build Coastguard Worker V4_SS1_storeb_io_MASK = 0x1000,
1176*9880d681SAndroid Build Coastguard Worker V4_SS1_storew_io_BITS = 0x0000,
1177*9880d681SAndroid Build Coastguard Worker V4_SS1_storew_io_MASK = 0x1000,
1178*9880d681SAndroid Build Coastguard Worker V4_SS2_allocframe_BITS = 0x1c00,
1179*9880d681SAndroid Build Coastguard Worker V4_SS2_allocframe_MASK = 0x1e00,
1180*9880d681SAndroid Build Coastguard Worker V4_SS2_storebi0_BITS = 0x1200,
1181*9880d681SAndroid Build Coastguard Worker V4_SS2_storebi0_MASK = 0x1f00,
1182*9880d681SAndroid Build Coastguard Worker V4_SS2_storebi1_BITS = 0x1300,
1183*9880d681SAndroid Build Coastguard Worker V4_SS2_storebi1_MASK = 0x1f00,
1184*9880d681SAndroid Build Coastguard Worker V4_SS2_stored_sp_BITS = 0x0a00,
1185*9880d681SAndroid Build Coastguard Worker V4_SS2_stored_sp_MASK = 0x1e00,
1186*9880d681SAndroid Build Coastguard Worker V4_SS2_storeh_io_BITS = 0x0000,
1187*9880d681SAndroid Build Coastguard Worker V4_SS2_storeh_io_MASK = 0x1800,
1188*9880d681SAndroid Build Coastguard Worker V4_SS2_storew_sp_BITS = 0x0800,
1189*9880d681SAndroid Build Coastguard Worker V4_SS2_storew_sp_MASK = 0x1e00,
1190*9880d681SAndroid Build Coastguard Worker V4_SS2_storewi0_BITS = 0x1000,
1191*9880d681SAndroid Build Coastguard Worker V4_SS2_storewi0_MASK = 0x1f00,
1192*9880d681SAndroid Build Coastguard Worker V4_SS2_storewi1_BITS = 0x1100,
1193*9880d681SAndroid Build Coastguard Worker V4_SS2_storewi1_MASK = 0x1f00
1194*9880d681SAndroid Build Coastguard Worker };
1195*9880d681SAndroid Build Coastguard Worker
GetSubinstOpcode(unsigned IClass,unsigned inst,unsigned & op,raw_ostream & os)1196*9880d681SAndroid Build Coastguard Worker static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op,
1197*9880d681SAndroid Build Coastguard Worker raw_ostream &os) {
1198*9880d681SAndroid Build Coastguard Worker switch (IClass) {
1199*9880d681SAndroid Build Coastguard Worker case HexagonII::HSIG_L1:
1200*9880d681SAndroid Build Coastguard Worker if ((inst & V4_SL1_loadri_io_MASK) == V4_SL1_loadri_io_BITS)
1201*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL1_loadri_io;
1202*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL1_loadrub_io_MASK) == V4_SL1_loadrub_io_BITS)
1203*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL1_loadrub_io;
1204*9880d681SAndroid Build Coastguard Worker else {
1205*9880d681SAndroid Build Coastguard Worker os << "<unknown subinstruction>";
1206*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
1207*9880d681SAndroid Build Coastguard Worker }
1208*9880d681SAndroid Build Coastguard Worker break;
1209*9880d681SAndroid Build Coastguard Worker case HexagonII::HSIG_L2:
1210*9880d681SAndroid Build Coastguard Worker if ((inst & V4_SL2_deallocframe_MASK) == V4_SL2_deallocframe_BITS)
1211*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_deallocframe;
1212*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_jumpr31_MASK) == V4_SL2_jumpr31_BITS)
1213*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_jumpr31;
1214*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_jumpr31_f_MASK) == V4_SL2_jumpr31_f_BITS)
1215*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_jumpr31_f;
1216*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_jumpr31_fnew_MASK) == V4_SL2_jumpr31_fnew_BITS)
1217*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_jumpr31_fnew;
1218*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_jumpr31_t_MASK) == V4_SL2_jumpr31_t_BITS)
1219*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_jumpr31_t;
1220*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_jumpr31_tnew_MASK) == V4_SL2_jumpr31_tnew_BITS)
1221*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_jumpr31_tnew;
1222*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_loadrb_io_MASK) == V4_SL2_loadrb_io_BITS)
1223*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_loadrb_io;
1224*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_loadrd_sp_MASK) == V4_SL2_loadrd_sp_BITS)
1225*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_loadrd_sp;
1226*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_loadrh_io_MASK) == V4_SL2_loadrh_io_BITS)
1227*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_loadrh_io;
1228*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_loadri_sp_MASK) == V4_SL2_loadri_sp_BITS)
1229*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_loadri_sp;
1230*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_loadruh_io_MASK) == V4_SL2_loadruh_io_BITS)
1231*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_loadruh_io;
1232*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_return_MASK) == V4_SL2_return_BITS)
1233*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_return;
1234*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_return_f_MASK) == V4_SL2_return_f_BITS)
1235*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_return_f;
1236*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_return_fnew_MASK) == V4_SL2_return_fnew_BITS)
1237*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_return_fnew;
1238*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_return_t_MASK) == V4_SL2_return_t_BITS)
1239*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_return_t;
1240*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SL2_return_tnew_MASK) == V4_SL2_return_tnew_BITS)
1241*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SL2_return_tnew;
1242*9880d681SAndroid Build Coastguard Worker else {
1243*9880d681SAndroid Build Coastguard Worker os << "<unknown subinstruction>";
1244*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
1245*9880d681SAndroid Build Coastguard Worker }
1246*9880d681SAndroid Build Coastguard Worker break;
1247*9880d681SAndroid Build Coastguard Worker case HexagonII::HSIG_A:
1248*9880d681SAndroid Build Coastguard Worker if ((inst & V4_SA1_addi_MASK) == V4_SA1_addi_BITS)
1249*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_addi;
1250*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_addrx_MASK) == V4_SA1_addrx_BITS)
1251*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_addrx;
1252*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_addsp_MASK) == V4_SA1_addsp_BITS)
1253*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_addsp;
1254*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_and1_MASK) == V4_SA1_and1_BITS)
1255*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_and1;
1256*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_clrf_MASK) == V4_SA1_clrf_BITS)
1257*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_clrf;
1258*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_clrfnew_MASK) == V4_SA1_clrfnew_BITS)
1259*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_clrfnew;
1260*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_clrt_MASK) == V4_SA1_clrt_BITS)
1261*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_clrt;
1262*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_clrtnew_MASK) == V4_SA1_clrtnew_BITS)
1263*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_clrtnew;
1264*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_cmpeqi_MASK) == V4_SA1_cmpeqi_BITS)
1265*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_cmpeqi;
1266*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_combine0i_MASK) == V4_SA1_combine0i_BITS)
1267*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_combine0i;
1268*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_combine1i_MASK) == V4_SA1_combine1i_BITS)
1269*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_combine1i;
1270*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_combine2i_MASK) == V4_SA1_combine2i_BITS)
1271*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_combine2i;
1272*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_combine3i_MASK) == V4_SA1_combine3i_BITS)
1273*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_combine3i;
1274*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_combinerz_MASK) == V4_SA1_combinerz_BITS)
1275*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_combinerz;
1276*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_combinezr_MASK) == V4_SA1_combinezr_BITS)
1277*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_combinezr;
1278*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_dec_MASK) == V4_SA1_dec_BITS)
1279*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_dec;
1280*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_inc_MASK) == V4_SA1_inc_BITS)
1281*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_inc;
1282*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_seti_MASK) == V4_SA1_seti_BITS)
1283*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_seti;
1284*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_setin1_MASK) == V4_SA1_setin1_BITS)
1285*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_setin1;
1286*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_sxtb_MASK) == V4_SA1_sxtb_BITS)
1287*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_sxtb;
1288*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_sxth_MASK) == V4_SA1_sxth_BITS)
1289*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_sxth;
1290*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_tfr_MASK) == V4_SA1_tfr_BITS)
1291*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_tfr;
1292*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_zxtb_MASK) == V4_SA1_zxtb_BITS)
1293*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_zxtb;
1294*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SA1_zxth_MASK) == V4_SA1_zxth_BITS)
1295*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SA1_zxth;
1296*9880d681SAndroid Build Coastguard Worker else {
1297*9880d681SAndroid Build Coastguard Worker os << "<unknown subinstruction>";
1298*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
1299*9880d681SAndroid Build Coastguard Worker }
1300*9880d681SAndroid Build Coastguard Worker break;
1301*9880d681SAndroid Build Coastguard Worker case HexagonII::HSIG_S1:
1302*9880d681SAndroid Build Coastguard Worker if ((inst & V4_SS1_storeb_io_MASK) == V4_SS1_storeb_io_BITS)
1303*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SS1_storeb_io;
1304*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SS1_storew_io_MASK) == V4_SS1_storew_io_BITS)
1305*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SS1_storew_io;
1306*9880d681SAndroid Build Coastguard Worker else {
1307*9880d681SAndroid Build Coastguard Worker os << "<unknown subinstruction>";
1308*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
1309*9880d681SAndroid Build Coastguard Worker }
1310*9880d681SAndroid Build Coastguard Worker break;
1311*9880d681SAndroid Build Coastguard Worker case HexagonII::HSIG_S2:
1312*9880d681SAndroid Build Coastguard Worker if ((inst & V4_SS2_allocframe_MASK) == V4_SS2_allocframe_BITS)
1313*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SS2_allocframe;
1314*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SS2_storebi0_MASK) == V4_SS2_storebi0_BITS)
1315*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SS2_storebi0;
1316*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SS2_storebi1_MASK) == V4_SS2_storebi1_BITS)
1317*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SS2_storebi1;
1318*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SS2_stored_sp_MASK) == V4_SS2_stored_sp_BITS)
1319*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SS2_stored_sp;
1320*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SS2_storeh_io_MASK) == V4_SS2_storeh_io_BITS)
1321*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SS2_storeh_io;
1322*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SS2_storew_sp_MASK) == V4_SS2_storew_sp_BITS)
1323*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SS2_storew_sp;
1324*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SS2_storewi0_MASK) == V4_SS2_storewi0_BITS)
1325*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SS2_storewi0;
1326*9880d681SAndroid Build Coastguard Worker else if ((inst & V4_SS2_storewi1_MASK) == V4_SS2_storewi1_BITS)
1327*9880d681SAndroid Build Coastguard Worker op = Hexagon::V4_SS2_storewi1;
1328*9880d681SAndroid Build Coastguard Worker else {
1329*9880d681SAndroid Build Coastguard Worker os << "<unknown subinstruction>";
1330*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
1331*9880d681SAndroid Build Coastguard Worker }
1332*9880d681SAndroid Build Coastguard Worker break;
1333*9880d681SAndroid Build Coastguard Worker default:
1334*9880d681SAndroid Build Coastguard Worker os << "<unknown>";
1335*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
1336*9880d681SAndroid Build Coastguard Worker }
1337*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
1338*9880d681SAndroid Build Coastguard Worker }
1339*9880d681SAndroid Build Coastguard Worker
getRegFromSubinstEncoding(unsigned encoded_reg)1340*9880d681SAndroid Build Coastguard Worker static unsigned getRegFromSubinstEncoding(unsigned encoded_reg) {
1341*9880d681SAndroid Build Coastguard Worker if (encoded_reg < 8)
1342*9880d681SAndroid Build Coastguard Worker return Hexagon::R0 + encoded_reg;
1343*9880d681SAndroid Build Coastguard Worker else if (encoded_reg < 16)
1344*9880d681SAndroid Build Coastguard Worker return Hexagon::R0 + encoded_reg + 8;
1345*9880d681SAndroid Build Coastguard Worker
1346*9880d681SAndroid Build Coastguard Worker // patently false value
1347*9880d681SAndroid Build Coastguard Worker return Hexagon::NoRegister;
1348*9880d681SAndroid Build Coastguard Worker }
1349*9880d681SAndroid Build Coastguard Worker
getDRegFromSubinstEncoding(unsigned encoded_dreg)1350*9880d681SAndroid Build Coastguard Worker static unsigned getDRegFromSubinstEncoding(unsigned encoded_dreg) {
1351*9880d681SAndroid Build Coastguard Worker if (encoded_dreg < 4)
1352*9880d681SAndroid Build Coastguard Worker return Hexagon::D0 + encoded_dreg;
1353*9880d681SAndroid Build Coastguard Worker else if (encoded_dreg < 8)
1354*9880d681SAndroid Build Coastguard Worker return Hexagon::D0 + encoded_dreg + 4;
1355*9880d681SAndroid Build Coastguard Worker
1356*9880d681SAndroid Build Coastguard Worker // patently false value
1357*9880d681SAndroid Build Coastguard Worker return Hexagon::NoRegister;
1358*9880d681SAndroid Build Coastguard Worker }
1359*9880d681SAndroid Build Coastguard Worker
addSubinstOperands(MCInst * MI,unsigned opcode,unsigned inst) const1360*9880d681SAndroid Build Coastguard Worker void HexagonDisassembler::addSubinstOperands(MCInst *MI, unsigned opcode,
1361*9880d681SAndroid Build Coastguard Worker unsigned inst) const {
1362*9880d681SAndroid Build Coastguard Worker int64_t operand;
1363*9880d681SAndroid Build Coastguard Worker MCOperand Op;
1364*9880d681SAndroid Build Coastguard Worker switch (opcode) {
1365*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_deallocframe:
1366*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_jumpr31:
1367*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_jumpr31_f:
1368*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_jumpr31_fnew:
1369*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_jumpr31_t:
1370*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_jumpr31_tnew:
1371*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_return:
1372*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_return_f:
1373*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_return_fnew:
1374*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_return_t:
1375*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_return_tnew:
1376*9880d681SAndroid Build Coastguard Worker // no operands for these instructions
1377*9880d681SAndroid Build Coastguard Worker break;
1378*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SS2_allocframe:
1379*9880d681SAndroid Build Coastguard Worker // u 8-4{5_3}
1380*9880d681SAndroid Build Coastguard Worker operand = ((inst & 0x1f0) >> 4) << 3;
1381*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1382*9880d681SAndroid Build Coastguard Worker break;
1383*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL1_loadri_io:
1384*9880d681SAndroid Build Coastguard Worker // Rd 3-0, Rs 7-4, u 11-8{4_2}
1385*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1386*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1387*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1388*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1389*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1390*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1391*9880d681SAndroid Build Coastguard Worker operand = (inst & 0xf00) >> 6;
1392*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1393*9880d681SAndroid Build Coastguard Worker break;
1394*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL1_loadrub_io:
1395*9880d681SAndroid Build Coastguard Worker // Rd 3-0, Rs 7-4, u 11-8
1396*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1397*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1398*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1399*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1400*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1401*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1402*9880d681SAndroid Build Coastguard Worker operand = (inst & 0xf00) >> 8;
1403*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1404*9880d681SAndroid Build Coastguard Worker break;
1405*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_loadrb_io:
1406*9880d681SAndroid Build Coastguard Worker // Rd 3-0, Rs 7-4, u 10-8
1407*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1408*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1409*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1410*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1411*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1412*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1413*9880d681SAndroid Build Coastguard Worker operand = (inst & 0x700) >> 8;
1414*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1415*9880d681SAndroid Build Coastguard Worker break;
1416*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_loadrh_io:
1417*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_loadruh_io:
1418*9880d681SAndroid Build Coastguard Worker // Rd 3-0, Rs 7-4, u 10-8{3_1}
1419*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1420*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1421*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1422*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1423*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1424*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1425*9880d681SAndroid Build Coastguard Worker operand = ((inst & 0x700) >> 8) << 1;
1426*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1427*9880d681SAndroid Build Coastguard Worker break;
1428*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_loadrd_sp:
1429*9880d681SAndroid Build Coastguard Worker // Rdd 2-0, u 7-3{5_3}
1430*9880d681SAndroid Build Coastguard Worker operand = getDRegFromSubinstEncoding(inst & 0x7);
1431*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1432*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1433*9880d681SAndroid Build Coastguard Worker operand = ((inst & 0x0f8) >> 3) << 3;
1434*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1435*9880d681SAndroid Build Coastguard Worker break;
1436*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SL2_loadri_sp:
1437*9880d681SAndroid Build Coastguard Worker // Rd 3-0, u 8-4{5_2}
1438*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1439*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1440*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1441*9880d681SAndroid Build Coastguard Worker operand = ((inst & 0x1f0) >> 4) << 2;
1442*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1443*9880d681SAndroid Build Coastguard Worker break;
1444*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_addi:
1445*9880d681SAndroid Build Coastguard Worker // Rx 3-0 (x2), s7 10-4
1446*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1447*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1448*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1449*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1450*9880d681SAndroid Build Coastguard Worker operand = SignExtend64<7>((inst & 0x7f0) >> 4);
1451*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1452*9880d681SAndroid Build Coastguard Worker break;
1453*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_addrx:
1454*9880d681SAndroid Build Coastguard Worker // Rx 3-0 (x2), Rs 7-4
1455*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1456*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1457*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1458*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1459*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1460*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1461*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1462*9880d681SAndroid Build Coastguard Worker break;
1463*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_and1:
1464*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_dec:
1465*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_inc:
1466*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_sxtb:
1467*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_sxth:
1468*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_tfr:
1469*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_zxtb:
1470*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_zxth:
1471*9880d681SAndroid Build Coastguard Worker // Rd 3-0, Rs 7-4
1472*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1473*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1474*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1475*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1476*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1477*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1478*9880d681SAndroid Build Coastguard Worker break;
1479*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_addsp:
1480*9880d681SAndroid Build Coastguard Worker // Rd 3-0, u 9-4{6_2}
1481*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1482*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1483*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1484*9880d681SAndroid Build Coastguard Worker operand = ((inst & 0x3f0) >> 4) << 2;
1485*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1486*9880d681SAndroid Build Coastguard Worker break;
1487*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_seti:
1488*9880d681SAndroid Build Coastguard Worker // Rd 3-0, u 9-4
1489*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1490*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1491*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1492*9880d681SAndroid Build Coastguard Worker operand = (inst & 0x3f0) >> 4;
1493*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1494*9880d681SAndroid Build Coastguard Worker break;
1495*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_clrf:
1496*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_clrfnew:
1497*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_clrt:
1498*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_clrtnew:
1499*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_setin1:
1500*9880d681SAndroid Build Coastguard Worker // Rd 3-0
1501*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1502*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1503*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1504*9880d681SAndroid Build Coastguard Worker break;
1505*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_cmpeqi:
1506*9880d681SAndroid Build Coastguard Worker // Rs 7-4, u 1-0
1507*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1508*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1509*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1510*9880d681SAndroid Build Coastguard Worker operand = inst & 0x3;
1511*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1512*9880d681SAndroid Build Coastguard Worker break;
1513*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_combine0i:
1514*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_combine1i:
1515*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_combine2i:
1516*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_combine3i:
1517*9880d681SAndroid Build Coastguard Worker // Rdd 2-0, u 6-5
1518*9880d681SAndroid Build Coastguard Worker operand = getDRegFromSubinstEncoding(inst & 0x7);
1519*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1520*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1521*9880d681SAndroid Build Coastguard Worker operand = (inst & 0x060) >> 5;
1522*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1523*9880d681SAndroid Build Coastguard Worker break;
1524*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_combinerz:
1525*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SA1_combinezr:
1526*9880d681SAndroid Build Coastguard Worker // Rdd 2-0, Rs 7-4
1527*9880d681SAndroid Build Coastguard Worker operand = getDRegFromSubinstEncoding(inst & 0x7);
1528*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1529*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1530*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1531*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1532*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1533*9880d681SAndroid Build Coastguard Worker break;
1534*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SS1_storeb_io:
1535*9880d681SAndroid Build Coastguard Worker // Rs 7-4, u 11-8, Rt 3-0
1536*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1537*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1538*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1539*9880d681SAndroid Build Coastguard Worker operand = (inst & 0xf00) >> 8;
1540*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1541*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1542*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1543*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1544*9880d681SAndroid Build Coastguard Worker break;
1545*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SS1_storew_io:
1546*9880d681SAndroid Build Coastguard Worker // Rs 7-4, u 11-8{4_2}, Rt 3-0
1547*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1548*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1549*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1550*9880d681SAndroid Build Coastguard Worker operand = ((inst & 0xf00) >> 8) << 2;
1551*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1552*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1553*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1554*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1555*9880d681SAndroid Build Coastguard Worker break;
1556*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SS2_storebi0:
1557*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SS2_storebi1:
1558*9880d681SAndroid Build Coastguard Worker // Rs 7-4, u 3-0
1559*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1560*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1561*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1562*9880d681SAndroid Build Coastguard Worker operand = inst & 0xf;
1563*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1564*9880d681SAndroid Build Coastguard Worker break;
1565*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SS2_storewi0:
1566*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SS2_storewi1:
1567*9880d681SAndroid Build Coastguard Worker // Rs 7-4, u 3-0{4_2}
1568*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1569*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1570*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1571*9880d681SAndroid Build Coastguard Worker operand = (inst & 0xf) << 2;
1572*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1573*9880d681SAndroid Build Coastguard Worker break;
1574*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SS2_stored_sp:
1575*9880d681SAndroid Build Coastguard Worker // s 8-3{6_3}, Rtt 2-0
1576*9880d681SAndroid Build Coastguard Worker operand = SignExtend64<9>(((inst & 0x1f8) >> 3) << 3);
1577*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1578*9880d681SAndroid Build Coastguard Worker operand = getDRegFromSubinstEncoding(inst & 0x7);
1579*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1580*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1581*9880d681SAndroid Build Coastguard Worker break;
1582*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SS2_storeh_io:
1583*9880d681SAndroid Build Coastguard Worker // Rs 7-4, u 10-8{3_1}, Rt 3-0
1584*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1585*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1586*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1587*9880d681SAndroid Build Coastguard Worker operand = ((inst & 0x700) >> 8) << 1;
1588*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1589*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1590*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1591*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1592*9880d681SAndroid Build Coastguard Worker break;
1593*9880d681SAndroid Build Coastguard Worker case Hexagon::V4_SS2_storew_sp:
1594*9880d681SAndroid Build Coastguard Worker // u 8-4{5_2}, Rd 3-0
1595*9880d681SAndroid Build Coastguard Worker operand = ((inst & 0x1f0) >> 4) << 2;
1596*9880d681SAndroid Build Coastguard Worker HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1597*9880d681SAndroid Build Coastguard Worker operand = getRegFromSubinstEncoding(inst & 0xf);
1598*9880d681SAndroid Build Coastguard Worker Op = MCOperand::createReg(operand);
1599*9880d681SAndroid Build Coastguard Worker MI->addOperand(Op);
1600*9880d681SAndroid Build Coastguard Worker break;
1601*9880d681SAndroid Build Coastguard Worker default:
1602*9880d681SAndroid Build Coastguard Worker // don't crash with an invalid subinstruction
1603*9880d681SAndroid Build Coastguard Worker // llvm_unreachable("Invalid subinstruction in duplex instruction");
1604*9880d681SAndroid Build Coastguard Worker break;
1605*9880d681SAndroid Build Coastguard Worker }
1606*9880d681SAndroid Build Coastguard Worker }
1607