xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/VE/Disassembler/VEDisassembler.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
1*5ffd83dbSDimitry Andric //===- VEDisassembler.cpp - Disassembler for VE -----------------*- C++ -*-===//
2*5ffd83dbSDimitry Andric //
3*5ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*5ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*5ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*5ffd83dbSDimitry Andric //
7*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
8*5ffd83dbSDimitry Andric //
9*5ffd83dbSDimitry Andric // This file is part of the VE Disassembler.
10*5ffd83dbSDimitry Andric //
11*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
12*5ffd83dbSDimitry Andric 
13*5ffd83dbSDimitry Andric #include "MCTargetDesc/VEMCTargetDesc.h"
14*5ffd83dbSDimitry Andric #include "TargetInfo/VETargetInfo.h"
15*5ffd83dbSDimitry Andric #include "VE.h"
16*5ffd83dbSDimitry Andric #include "llvm/MC/MCAsmInfo.h"
17*5ffd83dbSDimitry Andric #include "llvm/MC/MCContext.h"
18*5ffd83dbSDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
19*5ffd83dbSDimitry Andric #include "llvm/MC/MCFixedLenDisassembler.h"
20*5ffd83dbSDimitry Andric #include "llvm/MC/MCInst.h"
21*5ffd83dbSDimitry Andric #include "llvm/Support/TargetRegistry.h"
22*5ffd83dbSDimitry Andric 
23*5ffd83dbSDimitry Andric using namespace llvm;
24*5ffd83dbSDimitry Andric 
25*5ffd83dbSDimitry Andric #define DEBUG_TYPE "ve-disassembler"
26*5ffd83dbSDimitry Andric 
27*5ffd83dbSDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus;
28*5ffd83dbSDimitry Andric 
29*5ffd83dbSDimitry Andric namespace {
30*5ffd83dbSDimitry Andric 
31*5ffd83dbSDimitry Andric /// A disassembler class for VE.
32*5ffd83dbSDimitry Andric class VEDisassembler : public MCDisassembler {
33*5ffd83dbSDimitry Andric public:
34*5ffd83dbSDimitry Andric   VEDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
35*5ffd83dbSDimitry Andric       : MCDisassembler(STI, Ctx) {}
36*5ffd83dbSDimitry Andric   virtual ~VEDisassembler() {}
37*5ffd83dbSDimitry Andric 
38*5ffd83dbSDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
39*5ffd83dbSDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
40*5ffd83dbSDimitry Andric                               raw_ostream &CStream) const override;
41*5ffd83dbSDimitry Andric };
42*5ffd83dbSDimitry Andric } // namespace
43*5ffd83dbSDimitry Andric 
44*5ffd83dbSDimitry Andric static MCDisassembler *createVEDisassembler(const Target &T,
45*5ffd83dbSDimitry Andric                                             const MCSubtargetInfo &STI,
46*5ffd83dbSDimitry Andric                                             MCContext &Ctx) {
47*5ffd83dbSDimitry Andric   return new VEDisassembler(STI, Ctx);
48*5ffd83dbSDimitry Andric }
49*5ffd83dbSDimitry Andric 
50*5ffd83dbSDimitry Andric extern "C" void LLVMInitializeVEDisassembler() {
51*5ffd83dbSDimitry Andric   // Register the disassembler.
52*5ffd83dbSDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheVETarget(),
53*5ffd83dbSDimitry Andric                                          createVEDisassembler);
54*5ffd83dbSDimitry Andric }
55*5ffd83dbSDimitry Andric 
56*5ffd83dbSDimitry Andric static const unsigned I32RegDecoderTable[] = {
57*5ffd83dbSDimitry Andric     VE::SW0,  VE::SW1,  VE::SW2,  VE::SW3,  VE::SW4,  VE::SW5,  VE::SW6,
58*5ffd83dbSDimitry Andric     VE::SW7,  VE::SW8,  VE::SW9,  VE::SW10, VE::SW11, VE::SW12, VE::SW13,
59*5ffd83dbSDimitry Andric     VE::SW14, VE::SW15, VE::SW16, VE::SW17, VE::SW18, VE::SW19, VE::SW20,
60*5ffd83dbSDimitry Andric     VE::SW21, VE::SW22, VE::SW23, VE::SW24, VE::SW25, VE::SW26, VE::SW27,
61*5ffd83dbSDimitry Andric     VE::SW28, VE::SW29, VE::SW30, VE::SW31, VE::SW32, VE::SW33, VE::SW34,
62*5ffd83dbSDimitry Andric     VE::SW35, VE::SW36, VE::SW37, VE::SW38, VE::SW39, VE::SW40, VE::SW41,
63*5ffd83dbSDimitry Andric     VE::SW42, VE::SW43, VE::SW44, VE::SW45, VE::SW46, VE::SW47, VE::SW48,
64*5ffd83dbSDimitry Andric     VE::SW49, VE::SW50, VE::SW51, VE::SW52, VE::SW53, VE::SW54, VE::SW55,
65*5ffd83dbSDimitry Andric     VE::SW56, VE::SW57, VE::SW58, VE::SW59, VE::SW60, VE::SW61, VE::SW62,
66*5ffd83dbSDimitry Andric     VE::SW63};
67*5ffd83dbSDimitry Andric 
68*5ffd83dbSDimitry Andric static const unsigned I64RegDecoderTable[] = {
69*5ffd83dbSDimitry Andric     VE::SX0,  VE::SX1,  VE::SX2,  VE::SX3,  VE::SX4,  VE::SX5,  VE::SX6,
70*5ffd83dbSDimitry Andric     VE::SX7,  VE::SX8,  VE::SX9,  VE::SX10, VE::SX11, VE::SX12, VE::SX13,
71*5ffd83dbSDimitry Andric     VE::SX14, VE::SX15, VE::SX16, VE::SX17, VE::SX18, VE::SX19, VE::SX20,
72*5ffd83dbSDimitry Andric     VE::SX21, VE::SX22, VE::SX23, VE::SX24, VE::SX25, VE::SX26, VE::SX27,
73*5ffd83dbSDimitry Andric     VE::SX28, VE::SX29, VE::SX30, VE::SX31, VE::SX32, VE::SX33, VE::SX34,
74*5ffd83dbSDimitry Andric     VE::SX35, VE::SX36, VE::SX37, VE::SX38, VE::SX39, VE::SX40, VE::SX41,
75*5ffd83dbSDimitry Andric     VE::SX42, VE::SX43, VE::SX44, VE::SX45, VE::SX46, VE::SX47, VE::SX48,
76*5ffd83dbSDimitry Andric     VE::SX49, VE::SX50, VE::SX51, VE::SX52, VE::SX53, VE::SX54, VE::SX55,
77*5ffd83dbSDimitry Andric     VE::SX56, VE::SX57, VE::SX58, VE::SX59, VE::SX60, VE::SX61, VE::SX62,
78*5ffd83dbSDimitry Andric     VE::SX63};
79*5ffd83dbSDimitry Andric 
80*5ffd83dbSDimitry Andric static const unsigned F32RegDecoderTable[] = {
81*5ffd83dbSDimitry Andric     VE::SF0,  VE::SF1,  VE::SF2,  VE::SF3,  VE::SF4,  VE::SF5,  VE::SF6,
82*5ffd83dbSDimitry Andric     VE::SF7,  VE::SF8,  VE::SF9,  VE::SF10, VE::SF11, VE::SF12, VE::SF13,
83*5ffd83dbSDimitry Andric     VE::SF14, VE::SF15, VE::SF16, VE::SF17, VE::SF18, VE::SF19, VE::SF20,
84*5ffd83dbSDimitry Andric     VE::SF21, VE::SF22, VE::SF23, VE::SF24, VE::SF25, VE::SF26, VE::SF27,
85*5ffd83dbSDimitry Andric     VE::SF28, VE::SF29, VE::SF30, VE::SF31, VE::SF32, VE::SF33, VE::SF34,
86*5ffd83dbSDimitry Andric     VE::SF35, VE::SF36, VE::SF37, VE::SF38, VE::SF39, VE::SF40, VE::SF41,
87*5ffd83dbSDimitry Andric     VE::SF42, VE::SF43, VE::SF44, VE::SF45, VE::SF46, VE::SF47, VE::SF48,
88*5ffd83dbSDimitry Andric     VE::SF49, VE::SF50, VE::SF51, VE::SF52, VE::SF53, VE::SF54, VE::SF55,
89*5ffd83dbSDimitry Andric     VE::SF56, VE::SF57, VE::SF58, VE::SF59, VE::SF60, VE::SF61, VE::SF62,
90*5ffd83dbSDimitry Andric     VE::SF63};
91*5ffd83dbSDimitry Andric 
92*5ffd83dbSDimitry Andric static const unsigned F128RegDecoderTable[] = {
93*5ffd83dbSDimitry Andric     VE::Q0,  VE::Q1,  VE::Q2,  VE::Q3,  VE::Q4,  VE::Q5,  VE::Q6,  VE::Q7,
94*5ffd83dbSDimitry Andric     VE::Q8,  VE::Q9,  VE::Q10, VE::Q11, VE::Q12, VE::Q13, VE::Q14, VE::Q15,
95*5ffd83dbSDimitry Andric     VE::Q16, VE::Q17, VE::Q18, VE::Q19, VE::Q20, VE::Q21, VE::Q22, VE::Q23,
96*5ffd83dbSDimitry Andric     VE::Q24, VE::Q25, VE::Q26, VE::Q27, VE::Q28, VE::Q29, VE::Q30, VE::Q31};
97*5ffd83dbSDimitry Andric 
98*5ffd83dbSDimitry Andric static const unsigned MiscRegDecoderTable[] = {
99*5ffd83dbSDimitry Andric     VE::USRCC,      VE::PSW,        VE::SAR,        VE::NoRegister,
100*5ffd83dbSDimitry Andric     VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::PMMR,
101*5ffd83dbSDimitry Andric     VE::PMCR0,      VE::PMCR1,      VE::PMCR2,      VE::PMCR3,
102*5ffd83dbSDimitry Andric     VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::NoRegister,
103*5ffd83dbSDimitry Andric     VE::PMC0,       VE::PMC1,       VE::PMC2,       VE::PMC3,
104*5ffd83dbSDimitry Andric     VE::PMC4,       VE::PMC5,       VE::PMC6,       VE::PMC7,
105*5ffd83dbSDimitry Andric     VE::PMC8,       VE::PMC9,       VE::PMC10,      VE::PMC11,
106*5ffd83dbSDimitry Andric     VE::PMC12,      VE::PMC13,      VE::PMC14};
107*5ffd83dbSDimitry Andric 
108*5ffd83dbSDimitry Andric static DecodeStatus DecodeI32RegisterClass(MCInst &Inst, unsigned RegNo,
109*5ffd83dbSDimitry Andric                                            uint64_t Address,
110*5ffd83dbSDimitry Andric                                            const void *Decoder) {
111*5ffd83dbSDimitry Andric   if (RegNo > 63)
112*5ffd83dbSDimitry Andric     return MCDisassembler::Fail;
113*5ffd83dbSDimitry Andric   unsigned Reg = I32RegDecoderTable[RegNo];
114*5ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
115*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
116*5ffd83dbSDimitry Andric }
117*5ffd83dbSDimitry Andric 
118*5ffd83dbSDimitry Andric static DecodeStatus DecodeI64RegisterClass(MCInst &Inst, unsigned RegNo,
119*5ffd83dbSDimitry Andric                                            uint64_t Address,
120*5ffd83dbSDimitry Andric                                            const void *Decoder) {
121*5ffd83dbSDimitry Andric   if (RegNo > 63)
122*5ffd83dbSDimitry Andric     return MCDisassembler::Fail;
123*5ffd83dbSDimitry Andric   unsigned Reg = I64RegDecoderTable[RegNo];
124*5ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
125*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
126*5ffd83dbSDimitry Andric }
127*5ffd83dbSDimitry Andric 
128*5ffd83dbSDimitry Andric static DecodeStatus DecodeF32RegisterClass(MCInst &Inst, unsigned RegNo,
129*5ffd83dbSDimitry Andric                                            uint64_t Address,
130*5ffd83dbSDimitry Andric                                            const void *Decoder) {
131*5ffd83dbSDimitry Andric   if (RegNo > 63)
132*5ffd83dbSDimitry Andric     return MCDisassembler::Fail;
133*5ffd83dbSDimitry Andric   unsigned Reg = F32RegDecoderTable[RegNo];
134*5ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
135*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
136*5ffd83dbSDimitry Andric }
137*5ffd83dbSDimitry Andric 
138*5ffd83dbSDimitry Andric static DecodeStatus DecodeF128RegisterClass(MCInst &Inst, unsigned RegNo,
139*5ffd83dbSDimitry Andric                                             uint64_t Address,
140*5ffd83dbSDimitry Andric                                             const void *Decoder) {
141*5ffd83dbSDimitry Andric   if (RegNo % 2 || RegNo > 63)
142*5ffd83dbSDimitry Andric     return MCDisassembler::Fail;
143*5ffd83dbSDimitry Andric   unsigned Reg = F128RegDecoderTable[RegNo / 2];
144*5ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
145*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
146*5ffd83dbSDimitry Andric }
147*5ffd83dbSDimitry Andric 
148*5ffd83dbSDimitry Andric static DecodeStatus DecodeMISCRegisterClass(MCInst &Inst, unsigned RegNo,
149*5ffd83dbSDimitry Andric                                             uint64_t Address,
150*5ffd83dbSDimitry Andric                                             const void *Decoder) {
151*5ffd83dbSDimitry Andric   if (RegNo > 30)
152*5ffd83dbSDimitry Andric     return MCDisassembler::Fail;
153*5ffd83dbSDimitry Andric   unsigned Reg = MiscRegDecoderTable[RegNo];
154*5ffd83dbSDimitry Andric   if (Reg == VE::NoRegister)
155*5ffd83dbSDimitry Andric     return MCDisassembler::Fail;
156*5ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
157*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
158*5ffd83dbSDimitry Andric }
159*5ffd83dbSDimitry Andric 
160*5ffd83dbSDimitry Andric static DecodeStatus DecodeASX(MCInst &Inst, uint64_t insn, uint64_t Address,
161*5ffd83dbSDimitry Andric                               const void *Decoder);
162*5ffd83dbSDimitry Andric static DecodeStatus DecodeLoadI32(MCInst &Inst, uint64_t insn, uint64_t Address,
163*5ffd83dbSDimitry Andric                                   const void *Decoder);
164*5ffd83dbSDimitry Andric static DecodeStatus DecodeStoreI32(MCInst &Inst, uint64_t insn,
165*5ffd83dbSDimitry Andric                                    uint64_t Address, const void *Decoder);
166*5ffd83dbSDimitry Andric static DecodeStatus DecodeLoadI64(MCInst &Inst, uint64_t insn, uint64_t Address,
167*5ffd83dbSDimitry Andric                                   const void *Decoder);
168*5ffd83dbSDimitry Andric static DecodeStatus DecodeStoreI64(MCInst &Inst, uint64_t insn,
169*5ffd83dbSDimitry Andric                                    uint64_t Address, const void *Decoder);
170*5ffd83dbSDimitry Andric static DecodeStatus DecodeLoadF32(MCInst &Inst, uint64_t insn, uint64_t Address,
171*5ffd83dbSDimitry Andric                                   const void *Decoder);
172*5ffd83dbSDimitry Andric static DecodeStatus DecodeStoreF32(MCInst &Inst, uint64_t insn,
173*5ffd83dbSDimitry Andric                                    uint64_t Address, const void *Decoder);
174*5ffd83dbSDimitry Andric static DecodeStatus DecodeLoadASI64(MCInst &Inst, uint64_t insn,
175*5ffd83dbSDimitry Andric                                     uint64_t Address, const void *Decoder);
176*5ffd83dbSDimitry Andric static DecodeStatus DecodeStoreASI64(MCInst &Inst, uint64_t insn,
177*5ffd83dbSDimitry Andric                                      uint64_t Address, const void *Decoder);
178*5ffd83dbSDimitry Andric static DecodeStatus DecodeTS1AMI64(MCInst &Inst, uint64_t insn,
179*5ffd83dbSDimitry Andric                                    uint64_t Address, const void *Decoder);
180*5ffd83dbSDimitry Andric static DecodeStatus DecodeTS1AMI32(MCInst &Inst, uint64_t insn,
181*5ffd83dbSDimitry Andric                                    uint64_t Address, const void *Decoder);
182*5ffd83dbSDimitry Andric static DecodeStatus DecodeCASI64(MCInst &Inst, uint64_t insn, uint64_t Address,
183*5ffd83dbSDimitry Andric                                  const void *Decoder);
184*5ffd83dbSDimitry Andric static DecodeStatus DecodeCASI32(MCInst &Inst, uint64_t insn, uint64_t Address,
185*5ffd83dbSDimitry Andric                                  const void *Decoder);
186*5ffd83dbSDimitry Andric static DecodeStatus DecodeCall(MCInst &Inst, uint64_t insn, uint64_t Address,
187*5ffd83dbSDimitry Andric                                const void *Decoder);
188*5ffd83dbSDimitry Andric static DecodeStatus DecodeSIMM7(MCInst &Inst, uint64_t insn, uint64_t Address,
189*5ffd83dbSDimitry Andric                                 const void *Decoder);
190*5ffd83dbSDimitry Andric static DecodeStatus DecodeSIMM32(MCInst &Inst, uint64_t insn, uint64_t Address,
191*5ffd83dbSDimitry Andric                                  const void *Decoder);
192*5ffd83dbSDimitry Andric static DecodeStatus DecodeCCOperand(MCInst &Inst, uint64_t insn,
193*5ffd83dbSDimitry Andric                                     uint64_t Address, const void *Decoder);
194*5ffd83dbSDimitry Andric static DecodeStatus DecodeRDOperand(MCInst &Inst, uint64_t insn,
195*5ffd83dbSDimitry Andric                                     uint64_t Address, const void *Decoder);
196*5ffd83dbSDimitry Andric static DecodeStatus DecodeBranchCondition(MCInst &Inst, uint64_t insn,
197*5ffd83dbSDimitry Andric                                           uint64_t Address,
198*5ffd83dbSDimitry Andric                                           const void *Decoder);
199*5ffd83dbSDimitry Andric static DecodeStatus DecodeBranchConditionAlways(MCInst &Inst, uint64_t insn,
200*5ffd83dbSDimitry Andric                                                 uint64_t Address,
201*5ffd83dbSDimitry Andric                                                 const void *Decoder);
202*5ffd83dbSDimitry Andric 
203*5ffd83dbSDimitry Andric #include "VEGenDisassemblerTables.inc"
204*5ffd83dbSDimitry Andric 
205*5ffd83dbSDimitry Andric /// Read four bytes from the ArrayRef and return 32 bit word.
206*5ffd83dbSDimitry Andric static DecodeStatus readInstruction64(ArrayRef<uint8_t> Bytes, uint64_t Address,
207*5ffd83dbSDimitry Andric                                       uint64_t &Size, uint64_t &Insn,
208*5ffd83dbSDimitry Andric                                       bool IsLittleEndian) {
209*5ffd83dbSDimitry Andric   // We want to read exactly 8 Bytes of data.
210*5ffd83dbSDimitry Andric   if (Bytes.size() < 8) {
211*5ffd83dbSDimitry Andric     Size = 0;
212*5ffd83dbSDimitry Andric     return MCDisassembler::Fail;
213*5ffd83dbSDimitry Andric   }
214*5ffd83dbSDimitry Andric 
215*5ffd83dbSDimitry Andric   Insn = IsLittleEndian
216*5ffd83dbSDimitry Andric              ? ((uint64_t)Bytes[0] << 0) | ((uint64_t)Bytes[1] << 8) |
217*5ffd83dbSDimitry Andric                    ((uint64_t)Bytes[2] << 16) | ((uint64_t)Bytes[3] << 24) |
218*5ffd83dbSDimitry Andric                    ((uint64_t)Bytes[4] << 32) | ((uint64_t)Bytes[5] << 40) |
219*5ffd83dbSDimitry Andric                    ((uint64_t)Bytes[6] << 48) | ((uint64_t)Bytes[7] << 56)
220*5ffd83dbSDimitry Andric              : ((uint64_t)Bytes[7] << 0) | ((uint64_t)Bytes[6] << 8) |
221*5ffd83dbSDimitry Andric                    ((uint64_t)Bytes[5] << 16) | ((uint64_t)Bytes[4] << 24) |
222*5ffd83dbSDimitry Andric                    ((uint64_t)Bytes[3] << 32) | ((uint64_t)Bytes[2] << 40) |
223*5ffd83dbSDimitry Andric                    ((uint64_t)Bytes[1] << 48) | ((uint64_t)Bytes[0] << 56);
224*5ffd83dbSDimitry Andric 
225*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
226*5ffd83dbSDimitry Andric }
227*5ffd83dbSDimitry Andric 
228*5ffd83dbSDimitry Andric DecodeStatus VEDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
229*5ffd83dbSDimitry Andric                                             ArrayRef<uint8_t> Bytes,
230*5ffd83dbSDimitry Andric                                             uint64_t Address,
231*5ffd83dbSDimitry Andric                                             raw_ostream &CStream) const {
232*5ffd83dbSDimitry Andric   uint64_t Insn;
233*5ffd83dbSDimitry Andric   bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian();
234*5ffd83dbSDimitry Andric   DecodeStatus Result =
235*5ffd83dbSDimitry Andric       readInstruction64(Bytes, Address, Size, Insn, isLittleEndian);
236*5ffd83dbSDimitry Andric   if (Result == MCDisassembler::Fail)
237*5ffd83dbSDimitry Andric     return MCDisassembler::Fail;
238*5ffd83dbSDimitry Andric 
239*5ffd83dbSDimitry Andric   // Calling the auto-generated decoder function.
240*5ffd83dbSDimitry Andric 
241*5ffd83dbSDimitry Andric   Result = decodeInstruction(DecoderTableVE64, Instr, Insn, Address, this, STI);
242*5ffd83dbSDimitry Andric 
243*5ffd83dbSDimitry Andric   if (Result != MCDisassembler::Fail) {
244*5ffd83dbSDimitry Andric     Size = 8;
245*5ffd83dbSDimitry Andric     return Result;
246*5ffd83dbSDimitry Andric   }
247*5ffd83dbSDimitry Andric 
248*5ffd83dbSDimitry Andric   return MCDisassembler::Fail;
249*5ffd83dbSDimitry Andric }
250*5ffd83dbSDimitry Andric 
251*5ffd83dbSDimitry Andric typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned RegNo, uint64_t Address,
252*5ffd83dbSDimitry Andric                                    const void *Decoder);
253*5ffd83dbSDimitry Andric 
254*5ffd83dbSDimitry Andric static DecodeStatus DecodeASX(MCInst &MI, uint64_t insn, uint64_t Address,
255*5ffd83dbSDimitry Andric                               const void *Decoder) {
256*5ffd83dbSDimitry Andric   unsigned sy = fieldFromInstruction(insn, 40, 7);
257*5ffd83dbSDimitry Andric   bool cy = fieldFromInstruction(insn, 47, 1);
258*5ffd83dbSDimitry Andric   unsigned sz = fieldFromInstruction(insn, 32, 7);
259*5ffd83dbSDimitry Andric   bool cz = fieldFromInstruction(insn, 39, 1);
260*5ffd83dbSDimitry Andric   uint64_t simm32 = SignExtend64<32>(fieldFromInstruction(insn, 0, 32));
261*5ffd83dbSDimitry Andric   DecodeStatus status;
262*5ffd83dbSDimitry Andric 
263*5ffd83dbSDimitry Andric   // Decode sz.
264*5ffd83dbSDimitry Andric   if (cz) {
265*5ffd83dbSDimitry Andric     status = DecodeI64RegisterClass(MI, sz, Address, Decoder);
266*5ffd83dbSDimitry Andric     if (status != MCDisassembler::Success)
267*5ffd83dbSDimitry Andric       return status;
268*5ffd83dbSDimitry Andric   } else {
269*5ffd83dbSDimitry Andric     MI.addOperand(MCOperand::createImm(0));
270*5ffd83dbSDimitry Andric   }
271*5ffd83dbSDimitry Andric 
272*5ffd83dbSDimitry Andric   // Decode sy.
273*5ffd83dbSDimitry Andric   if (cy) {
274*5ffd83dbSDimitry Andric     status = DecodeI64RegisterClass(MI, sy, Address, Decoder);
275*5ffd83dbSDimitry Andric     if (status != MCDisassembler::Success)
276*5ffd83dbSDimitry Andric       return status;
277*5ffd83dbSDimitry Andric   } else {
278*5ffd83dbSDimitry Andric     MI.addOperand(MCOperand::createImm(SignExtend32<7>(sy)));
279*5ffd83dbSDimitry Andric   }
280*5ffd83dbSDimitry Andric 
281*5ffd83dbSDimitry Andric   // Decode simm32.
282*5ffd83dbSDimitry Andric   MI.addOperand(MCOperand::createImm(simm32));
283*5ffd83dbSDimitry Andric 
284*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
285*5ffd83dbSDimitry Andric }
286*5ffd83dbSDimitry Andric 
287*5ffd83dbSDimitry Andric static DecodeStatus DecodeAS(MCInst &MI, uint64_t insn, uint64_t Address,
288*5ffd83dbSDimitry Andric                              const void *Decoder) {
289*5ffd83dbSDimitry Andric   unsigned sz = fieldFromInstruction(insn, 32, 7);
290*5ffd83dbSDimitry Andric   bool cz = fieldFromInstruction(insn, 39, 1);
291*5ffd83dbSDimitry Andric   uint64_t simm32 = SignExtend64<32>(fieldFromInstruction(insn, 0, 32));
292*5ffd83dbSDimitry Andric   DecodeStatus status;
293*5ffd83dbSDimitry Andric 
294*5ffd83dbSDimitry Andric   // Decode sz.
295*5ffd83dbSDimitry Andric   if (cz) {
296*5ffd83dbSDimitry Andric     status = DecodeI64RegisterClass(MI, sz, Address, Decoder);
297*5ffd83dbSDimitry Andric     if (status != MCDisassembler::Success)
298*5ffd83dbSDimitry Andric       return status;
299*5ffd83dbSDimitry Andric   } else {
300*5ffd83dbSDimitry Andric     MI.addOperand(MCOperand::createImm(0));
301*5ffd83dbSDimitry Andric   }
302*5ffd83dbSDimitry Andric 
303*5ffd83dbSDimitry Andric   // Decode simm32.
304*5ffd83dbSDimitry Andric   MI.addOperand(MCOperand::createImm(simm32));
305*5ffd83dbSDimitry Andric 
306*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
307*5ffd83dbSDimitry Andric }
308*5ffd83dbSDimitry Andric 
309*5ffd83dbSDimitry Andric static DecodeStatus DecodeMem(MCInst &MI, uint64_t insn, uint64_t Address,
310*5ffd83dbSDimitry Andric                               const void *Decoder, bool isLoad,
311*5ffd83dbSDimitry Andric                               DecodeFunc DecodeSX) {
312*5ffd83dbSDimitry Andric   unsigned sx = fieldFromInstruction(insn, 48, 7);
313*5ffd83dbSDimitry Andric 
314*5ffd83dbSDimitry Andric   DecodeStatus status;
315*5ffd83dbSDimitry Andric   if (isLoad) {
316*5ffd83dbSDimitry Andric     status = DecodeSX(MI, sx, Address, Decoder);
317*5ffd83dbSDimitry Andric     if (status != MCDisassembler::Success)
318*5ffd83dbSDimitry Andric       return status;
319*5ffd83dbSDimitry Andric   }
320*5ffd83dbSDimitry Andric 
321*5ffd83dbSDimitry Andric   status = DecodeASX(MI, insn, Address, Decoder);
322*5ffd83dbSDimitry Andric   if (status != MCDisassembler::Success)
323*5ffd83dbSDimitry Andric     return status;
324*5ffd83dbSDimitry Andric 
325*5ffd83dbSDimitry Andric   if (!isLoad) {
326*5ffd83dbSDimitry Andric     status = DecodeSX(MI, sx, Address, Decoder);
327*5ffd83dbSDimitry Andric     if (status != MCDisassembler::Success)
328*5ffd83dbSDimitry Andric       return status;
329*5ffd83dbSDimitry Andric   }
330*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
331*5ffd83dbSDimitry Andric }
332*5ffd83dbSDimitry Andric 
333*5ffd83dbSDimitry Andric static DecodeStatus DecodeMemAS(MCInst &MI, uint64_t insn, uint64_t Address,
334*5ffd83dbSDimitry Andric                                 const void *Decoder, bool isLoad,
335*5ffd83dbSDimitry Andric                                 DecodeFunc DecodeSX) {
336*5ffd83dbSDimitry Andric   unsigned sx = fieldFromInstruction(insn, 48, 7);
337*5ffd83dbSDimitry Andric 
338*5ffd83dbSDimitry Andric   DecodeStatus status;
339*5ffd83dbSDimitry Andric   if (isLoad) {
340*5ffd83dbSDimitry Andric     status = DecodeSX(MI, sx, Address, Decoder);
341*5ffd83dbSDimitry Andric     if (status != MCDisassembler::Success)
342*5ffd83dbSDimitry Andric       return status;
343*5ffd83dbSDimitry Andric   }
344*5ffd83dbSDimitry Andric 
345*5ffd83dbSDimitry Andric   status = DecodeAS(MI, insn, Address, Decoder);
346*5ffd83dbSDimitry Andric   if (status != MCDisassembler::Success)
347*5ffd83dbSDimitry Andric     return status;
348*5ffd83dbSDimitry Andric 
349*5ffd83dbSDimitry Andric   if (!isLoad) {
350*5ffd83dbSDimitry Andric     status = DecodeSX(MI, sx, Address, Decoder);
351*5ffd83dbSDimitry Andric     if (status != MCDisassembler::Success)
352*5ffd83dbSDimitry Andric       return status;
353*5ffd83dbSDimitry Andric   }
354*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
355*5ffd83dbSDimitry Andric }
356*5ffd83dbSDimitry Andric 
357*5ffd83dbSDimitry Andric static DecodeStatus DecodeLoadI32(MCInst &Inst, uint64_t insn, uint64_t Address,
358*5ffd83dbSDimitry Andric                                   const void *Decoder) {
359*5ffd83dbSDimitry Andric   return DecodeMem(Inst, insn, Address, Decoder, true, DecodeI32RegisterClass);
360*5ffd83dbSDimitry Andric }
361*5ffd83dbSDimitry Andric 
362*5ffd83dbSDimitry Andric static DecodeStatus DecodeStoreI32(MCInst &Inst, uint64_t insn,
363*5ffd83dbSDimitry Andric                                    uint64_t Address, const void *Decoder) {
364*5ffd83dbSDimitry Andric   return DecodeMem(Inst, insn, Address, Decoder, false, DecodeI32RegisterClass);
365*5ffd83dbSDimitry Andric }
366*5ffd83dbSDimitry Andric 
367*5ffd83dbSDimitry Andric static DecodeStatus DecodeLoadI64(MCInst &Inst, uint64_t insn, uint64_t Address,
368*5ffd83dbSDimitry Andric                                   const void *Decoder) {
369*5ffd83dbSDimitry Andric   return DecodeMem(Inst, insn, Address, Decoder, true, DecodeI64RegisterClass);
370*5ffd83dbSDimitry Andric }
371*5ffd83dbSDimitry Andric 
372*5ffd83dbSDimitry Andric static DecodeStatus DecodeStoreI64(MCInst &Inst, uint64_t insn,
373*5ffd83dbSDimitry Andric                                    uint64_t Address, const void *Decoder) {
374*5ffd83dbSDimitry Andric   return DecodeMem(Inst, insn, Address, Decoder, false, DecodeI64RegisterClass);
375*5ffd83dbSDimitry Andric }
376*5ffd83dbSDimitry Andric 
377*5ffd83dbSDimitry Andric static DecodeStatus DecodeLoadF32(MCInst &Inst, uint64_t insn, uint64_t Address,
378*5ffd83dbSDimitry Andric                                   const void *Decoder) {
379*5ffd83dbSDimitry Andric   return DecodeMem(Inst, insn, Address, Decoder, true, DecodeF32RegisterClass);
380*5ffd83dbSDimitry Andric }
381*5ffd83dbSDimitry Andric 
382*5ffd83dbSDimitry Andric static DecodeStatus DecodeStoreF32(MCInst &Inst, uint64_t insn,
383*5ffd83dbSDimitry Andric                                    uint64_t Address, const void *Decoder) {
384*5ffd83dbSDimitry Andric   return DecodeMem(Inst, insn, Address, Decoder, false, DecodeF32RegisterClass);
385*5ffd83dbSDimitry Andric }
386*5ffd83dbSDimitry Andric 
387*5ffd83dbSDimitry Andric static DecodeStatus DecodeLoadASI64(MCInst &Inst, uint64_t insn,
388*5ffd83dbSDimitry Andric                                     uint64_t Address, const void *Decoder) {
389*5ffd83dbSDimitry Andric   return DecodeMemAS(Inst, insn, Address, Decoder, true,
390*5ffd83dbSDimitry Andric                      DecodeI64RegisterClass);
391*5ffd83dbSDimitry Andric }
392*5ffd83dbSDimitry Andric 
393*5ffd83dbSDimitry Andric static DecodeStatus DecodeStoreASI64(MCInst &Inst, uint64_t insn,
394*5ffd83dbSDimitry Andric                                      uint64_t Address, const void *Decoder) {
395*5ffd83dbSDimitry Andric   return DecodeMemAS(Inst, insn, Address, Decoder, false,
396*5ffd83dbSDimitry Andric                      DecodeI64RegisterClass);
397*5ffd83dbSDimitry Andric }
398*5ffd83dbSDimitry Andric 
399*5ffd83dbSDimitry Andric static DecodeStatus DecodeCAS(MCInst &MI, uint64_t insn, uint64_t Address,
400*5ffd83dbSDimitry Andric                               const void *Decoder, bool isImmOnly, bool isUImm,
401*5ffd83dbSDimitry Andric                               DecodeFunc DecodeSX) {
402*5ffd83dbSDimitry Andric   unsigned sx = fieldFromInstruction(insn, 48, 7);
403*5ffd83dbSDimitry Andric   bool cy = fieldFromInstruction(insn, 47, 1);
404*5ffd83dbSDimitry Andric   unsigned sy = fieldFromInstruction(insn, 40, 7);
405*5ffd83dbSDimitry Andric 
406*5ffd83dbSDimitry Andric   // Add $sx.
407*5ffd83dbSDimitry Andric   DecodeStatus status;
408*5ffd83dbSDimitry Andric   status = DecodeSX(MI, sx, Address, Decoder);
409*5ffd83dbSDimitry Andric   if (status != MCDisassembler::Success)
410*5ffd83dbSDimitry Andric     return status;
411*5ffd83dbSDimitry Andric 
412*5ffd83dbSDimitry Andric   // Add $disp($sz).
413*5ffd83dbSDimitry Andric   status = DecodeAS(MI, insn, Address, Decoder);
414*5ffd83dbSDimitry Andric   if (status != MCDisassembler::Success)
415*5ffd83dbSDimitry Andric     return status;
416*5ffd83dbSDimitry Andric 
417*5ffd83dbSDimitry Andric   // Add $sy.
418*5ffd83dbSDimitry Andric   if (cy && !isImmOnly) {
419*5ffd83dbSDimitry Andric     status = DecodeSX(MI, sy, Address, Decoder);
420*5ffd83dbSDimitry Andric     if (status != MCDisassembler::Success)
421*5ffd83dbSDimitry Andric       return status;
422*5ffd83dbSDimitry Andric   } else {
423*5ffd83dbSDimitry Andric     if (isUImm)
424*5ffd83dbSDimitry Andric       MI.addOperand(MCOperand::createImm(sy));
425*5ffd83dbSDimitry Andric     else
426*5ffd83dbSDimitry Andric       MI.addOperand(MCOperand::createImm(SignExtend32<7>(sy)));
427*5ffd83dbSDimitry Andric   }
428*5ffd83dbSDimitry Andric 
429*5ffd83dbSDimitry Andric   // Add $sd.
430*5ffd83dbSDimitry Andric   status = DecodeSX(MI, sx, Address, Decoder);
431*5ffd83dbSDimitry Andric   if (status != MCDisassembler::Success)
432*5ffd83dbSDimitry Andric     return status;
433*5ffd83dbSDimitry Andric 
434*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
435*5ffd83dbSDimitry Andric }
436*5ffd83dbSDimitry Andric 
437*5ffd83dbSDimitry Andric static DecodeStatus DecodeTS1AMI64(MCInst &MI, uint64_t insn, uint64_t Address,
438*5ffd83dbSDimitry Andric                                    const void *Decoder) {
439*5ffd83dbSDimitry Andric   return DecodeCAS(MI, insn, Address, Decoder, false, true,
440*5ffd83dbSDimitry Andric                    DecodeI64RegisterClass);
441*5ffd83dbSDimitry Andric }
442*5ffd83dbSDimitry Andric 
443*5ffd83dbSDimitry Andric static DecodeStatus DecodeTS1AMI32(MCInst &MI, uint64_t insn, uint64_t Address,
444*5ffd83dbSDimitry Andric                                    const void *Decoder) {
445*5ffd83dbSDimitry Andric   return DecodeCAS(MI, insn, Address, Decoder, false, true,
446*5ffd83dbSDimitry Andric                    DecodeI32RegisterClass);
447*5ffd83dbSDimitry Andric }
448*5ffd83dbSDimitry Andric 
449*5ffd83dbSDimitry Andric static DecodeStatus DecodeCASI64(MCInst &MI, uint64_t insn, uint64_t Address,
450*5ffd83dbSDimitry Andric                                  const void *Decoder) {
451*5ffd83dbSDimitry Andric   return DecodeCAS(MI, insn, Address, Decoder, false, false,
452*5ffd83dbSDimitry Andric                    DecodeI64RegisterClass);
453*5ffd83dbSDimitry Andric }
454*5ffd83dbSDimitry Andric 
455*5ffd83dbSDimitry Andric static DecodeStatus DecodeCASI32(MCInst &MI, uint64_t insn, uint64_t Address,
456*5ffd83dbSDimitry Andric                                  const void *Decoder) {
457*5ffd83dbSDimitry Andric   return DecodeCAS(MI, insn, Address, Decoder, false, false,
458*5ffd83dbSDimitry Andric                    DecodeI32RegisterClass);
459*5ffd83dbSDimitry Andric }
460*5ffd83dbSDimitry Andric 
461*5ffd83dbSDimitry Andric static DecodeStatus DecodeCall(MCInst &Inst, uint64_t insn, uint64_t Address,
462*5ffd83dbSDimitry Andric                                const void *Decoder) {
463*5ffd83dbSDimitry Andric   return DecodeMem(Inst, insn, Address, Decoder, true, DecodeI64RegisterClass);
464*5ffd83dbSDimitry Andric }
465*5ffd83dbSDimitry Andric 
466*5ffd83dbSDimitry Andric static DecodeStatus DecodeSIMM7(MCInst &MI, uint64_t insn, uint64_t Address,
467*5ffd83dbSDimitry Andric                                 const void *Decoder) {
468*5ffd83dbSDimitry Andric   uint64_t tgt = SignExtend64<7>(insn);
469*5ffd83dbSDimitry Andric   MI.addOperand(MCOperand::createImm(tgt));
470*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
471*5ffd83dbSDimitry Andric }
472*5ffd83dbSDimitry Andric 
473*5ffd83dbSDimitry Andric static DecodeStatus DecodeSIMM32(MCInst &MI, uint64_t insn, uint64_t Address,
474*5ffd83dbSDimitry Andric                                  const void *Decoder) {
475*5ffd83dbSDimitry Andric   uint64_t tgt = SignExtend64<32>(insn);
476*5ffd83dbSDimitry Andric   MI.addOperand(MCOperand::createImm(tgt));
477*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
478*5ffd83dbSDimitry Andric }
479*5ffd83dbSDimitry Andric 
480*5ffd83dbSDimitry Andric static bool isIntegerBCKind(MCInst &MI) {
481*5ffd83dbSDimitry Andric 
482*5ffd83dbSDimitry Andric #define BCm_kind(NAME)                                                         \
483*5ffd83dbSDimitry Andric   case NAME##rri:                                                              \
484*5ffd83dbSDimitry Andric   case NAME##rzi:                                                              \
485*5ffd83dbSDimitry Andric   case NAME##iri:                                                              \
486*5ffd83dbSDimitry Andric   case NAME##izi:                                                              \
487*5ffd83dbSDimitry Andric   case NAME##rri_nt:                                                           \
488*5ffd83dbSDimitry Andric   case NAME##rzi_nt:                                                           \
489*5ffd83dbSDimitry Andric   case NAME##iri_nt:                                                           \
490*5ffd83dbSDimitry Andric   case NAME##izi_nt:                                                           \
491*5ffd83dbSDimitry Andric   case NAME##rri_t:                                                            \
492*5ffd83dbSDimitry Andric   case NAME##rzi_t:                                                            \
493*5ffd83dbSDimitry Andric   case NAME##iri_t:                                                            \
494*5ffd83dbSDimitry Andric   case NAME##izi_t:
495*5ffd83dbSDimitry Andric 
496*5ffd83dbSDimitry Andric #define BCRm_kind(NAME)                                                        \
497*5ffd83dbSDimitry Andric   case NAME##rr:                                                               \
498*5ffd83dbSDimitry Andric   case NAME##ir:                                                               \
499*5ffd83dbSDimitry Andric   case NAME##rr_nt:                                                            \
500*5ffd83dbSDimitry Andric   case NAME##ir_nt:                                                            \
501*5ffd83dbSDimitry Andric   case NAME##rr_t:                                                             \
502*5ffd83dbSDimitry Andric   case NAME##ir_t:
503*5ffd83dbSDimitry Andric 
504*5ffd83dbSDimitry Andric   {
505*5ffd83dbSDimitry Andric     using namespace llvm::VE;
506*5ffd83dbSDimitry Andric     switch (MI.getOpcode()) {
507*5ffd83dbSDimitry Andric       BCm_kind(BCFL) BCm_kind(BCFW) BCRm_kind(BRCFL)
508*5ffd83dbSDimitry Andric           BCRm_kind(BRCFW) return true;
509*5ffd83dbSDimitry Andric     }
510*5ffd83dbSDimitry Andric   }
511*5ffd83dbSDimitry Andric #undef BCm_kind
512*5ffd83dbSDimitry Andric 
513*5ffd83dbSDimitry Andric   return false;
514*5ffd83dbSDimitry Andric }
515*5ffd83dbSDimitry Andric 
516*5ffd83dbSDimitry Andric // Decode CC Operand field.
517*5ffd83dbSDimitry Andric static DecodeStatus DecodeCCOperand(MCInst &MI, uint64_t cf, uint64_t Address,
518*5ffd83dbSDimitry Andric                                     const void *Decoder) {
519*5ffd83dbSDimitry Andric   MI.addOperand(MCOperand::createImm(VEValToCondCode(cf, isIntegerBCKind(MI))));
520*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
521*5ffd83dbSDimitry Andric }
522*5ffd83dbSDimitry Andric 
523*5ffd83dbSDimitry Andric // Decode RD Operand field.
524*5ffd83dbSDimitry Andric static DecodeStatus DecodeRDOperand(MCInst &MI, uint64_t cf, uint64_t Address,
525*5ffd83dbSDimitry Andric                                     const void *Decoder) {
526*5ffd83dbSDimitry Andric   MI.addOperand(MCOperand::createImm(VEValToRD(cf)));
527*5ffd83dbSDimitry Andric   return MCDisassembler::Success;
528*5ffd83dbSDimitry Andric }
529*5ffd83dbSDimitry Andric 
530*5ffd83dbSDimitry Andric // Decode branch condition instruction and CCOperand field in it.
531*5ffd83dbSDimitry Andric static DecodeStatus DecodeBranchCondition(MCInst &MI, uint64_t insn,
532*5ffd83dbSDimitry Andric                                           uint64_t Address,
533*5ffd83dbSDimitry Andric                                           const void *Decoder) {
534*5ffd83dbSDimitry Andric   unsigned cf = fieldFromInstruction(insn, 48, 4);
535*5ffd83dbSDimitry Andric   bool cy = fieldFromInstruction(insn, 47, 1);
536*5ffd83dbSDimitry Andric   unsigned sy = fieldFromInstruction(insn, 40, 7);
537*5ffd83dbSDimitry Andric 
538*5ffd83dbSDimitry Andric   // Decode cf.
539*5ffd83dbSDimitry Andric   MI.addOperand(MCOperand::createImm(VEValToCondCode(cf, isIntegerBCKind(MI))));
540*5ffd83dbSDimitry Andric 
541*5ffd83dbSDimitry Andric   // Decode sy.
542*5ffd83dbSDimitry Andric   DecodeStatus status;
543*5ffd83dbSDimitry Andric   if (cy) {
544*5ffd83dbSDimitry Andric     status = DecodeI64RegisterClass(MI, sy, Address, Decoder);
545*5ffd83dbSDimitry Andric     if (status != MCDisassembler::Success)
546*5ffd83dbSDimitry Andric       return status;
547*5ffd83dbSDimitry Andric   } else {
548*5ffd83dbSDimitry Andric     MI.addOperand(MCOperand::createImm(SignExtend32<7>(sy)));
549*5ffd83dbSDimitry Andric   }
550*5ffd83dbSDimitry Andric 
551*5ffd83dbSDimitry Andric   // Decode MEMri.
552*5ffd83dbSDimitry Andric   return DecodeAS(MI, insn, Address, Decoder);
553*5ffd83dbSDimitry Andric }
554*5ffd83dbSDimitry Andric 
555*5ffd83dbSDimitry Andric static DecodeStatus DecodeBranchConditionAlways(MCInst &MI, uint64_t insn,
556*5ffd83dbSDimitry Andric                                                 uint64_t Address,
557*5ffd83dbSDimitry Andric                                                 const void *Decoder) {
558*5ffd83dbSDimitry Andric   // Decode MEMri.
559*5ffd83dbSDimitry Andric   return DecodeAS(MI, insn, Address, Decoder);
560*5ffd83dbSDimitry Andric }
561