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