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
24using namespace llvm;
25
26#define DEBUG_TYPE "ve-disassembler"
27
28typedef MCDisassembler::DecodeStatus DecodeStatus;
29
30namespace {
31
32/// A disassembler class for VE.
33class VEDisassembler : public MCDisassembler {
34public:
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
45static MCDisassembler *createVEDisassembler(const Target &T,
46 const MCSubtargetInfo &STI,
47 MCContext &Ctx) {
48 return new VEDisassembler(STI, Ctx);
49}
50
51extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
52LLVMInitializeVEDisassembler() {
53 // Register the disassembler.
54 TargetRegistry::RegisterMCDisassembler(T&: getTheVETarget(),
55 Fn: createVEDisassembler);
56}
57
58static 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
70static 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
82static 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
94static 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
100static 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
110static 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
115static const unsigned VM512RegDecoderTable[] = {VE::VMP0, VE::VMP1, VE::VMP2,
116 VE::VMP3, VE::VMP4, VE::VMP5,
117 VE::VMP6, VE::VMP7};
118
119static 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
129static 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(Op: MCOperand::createReg(Reg));
136 return MCDisassembler::Success;
137}
138
139static 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(Op: MCOperand::createReg(Reg));
146 return MCDisassembler::Success;
147}
148
149static 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(Op: MCOperand::createReg(Reg));
156 return MCDisassembler::Success;
157}
158
159static 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(Op: MCOperand::createReg(Reg));
166 return MCDisassembler::Success;
167}
168
169static 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(Op: MCOperand::createReg(Reg));
180 return MCDisassembler::Success;
181}
182
183static 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(Op: MCOperand::createReg(Reg));
190 return MCDisassembler::Success;
191}
192
193static 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(Op: MCOperand::createReg(Reg));
200 return MCDisassembler::Success;
201}
202
203static 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(Op: MCOperand::createReg(Reg));
212 return MCDisassembler::Success;
213}
214
215static DecodeStatus DecodeASX(MCInst &Inst, uint64_t insn, uint64_t Address,
216 const MCDisassembler *Decoder);
217static DecodeStatus DecodeLoadI32(MCInst &Inst, uint64_t insn, uint64_t Address,
218 const MCDisassembler *Decoder);
219static DecodeStatus DecodeStoreI32(MCInst &Inst, uint64_t insn,
220 uint64_t Address,
221 const MCDisassembler *Decoder);
222static DecodeStatus DecodeLoadI64(MCInst &Inst, uint64_t insn, uint64_t Address,
223 const MCDisassembler *Decoder);
224static DecodeStatus DecodeStoreI64(MCInst &Inst, uint64_t insn,
225 uint64_t Address,
226 const MCDisassembler *Decoder);
227static DecodeStatus DecodeLoadF32(MCInst &Inst, uint64_t insn, uint64_t Address,
228 const MCDisassembler *Decoder);
229static DecodeStatus DecodeStoreF32(MCInst &Inst, uint64_t insn,
230 uint64_t Address,
231 const MCDisassembler *Decoder);
232static DecodeStatus DecodeLoadASI64(MCInst &Inst, uint64_t insn,
233 uint64_t Address,
234 const MCDisassembler *Decoder);
235static DecodeStatus DecodeStoreASI64(MCInst &Inst, uint64_t insn,
236 uint64_t Address,
237 const MCDisassembler *Decoder);
238static DecodeStatus DecodeTS1AMI64(MCInst &Inst, uint64_t insn,
239 uint64_t Address,
240 const MCDisassembler *Decoder);
241static DecodeStatus DecodeTS1AMI32(MCInst &Inst, uint64_t insn,
242 uint64_t Address,
243 const MCDisassembler *Decoder);
244static DecodeStatus DecodeCASI64(MCInst &Inst, uint64_t insn, uint64_t Address,
245 const MCDisassembler *Decoder);
246static DecodeStatus DecodeCASI32(MCInst &Inst, uint64_t insn, uint64_t Address,
247 const MCDisassembler *Decoder);
248static DecodeStatus DecodeCall(MCInst &Inst, uint64_t insn, uint64_t Address,
249 const MCDisassembler *Decoder);
250static DecodeStatus DecodeSIMM7(MCInst &Inst, uint64_t insn, uint64_t Address,
251 const MCDisassembler *Decoder);
252static DecodeStatus DecodeSIMM32(MCInst &Inst, uint64_t insn, uint64_t Address,
253 const MCDisassembler *Decoder);
254static DecodeStatus DecodeCCOperand(MCInst &Inst, uint64_t insn,
255 uint64_t Address,
256 const MCDisassembler *Decoder);
257static DecodeStatus DecodeRDOperand(MCInst &Inst, uint64_t insn,
258 uint64_t Address,
259 const MCDisassembler *Decoder);
260static DecodeStatus DecodeBranchCondition(MCInst &Inst, uint64_t insn,
261 uint64_t Address,
262 const MCDisassembler *Decoder);
263static 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.
270static 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
292DecodeStatus 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: isLittleEndian);
300 if (Result == MCDisassembler::Fail)
301 return MCDisassembler::Fail;
302
303 // Calling the auto-generated decoder function.
304
305 Result = decodeInstruction(DecodeTable: DecoderTableVE64, MI&: Instr, insn: Insn, Address, DisAsm: this, STI);
306
307 if (Result != MCDisassembler::Fail) {
308 Size = 8;
309 return Result;
310 }
311
312 return MCDisassembler::Fail;
313}
314
315typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned RegNo, uint64_t Address,
316 const MCDisassembler *Decoder);
317
318static DecodeStatus DecodeASX(MCInst &MI, uint64_t insn, uint64_t Address,
319 const MCDisassembler *Decoder) {
320 unsigned sy = fieldFromInstruction(insn, startBit: 40, numBits: 7);
321 bool cy = fieldFromInstruction(insn, startBit: 47, numBits: 1);
322 unsigned sz = fieldFromInstruction(insn, startBit: 32, numBits: 7);
323 bool cz = fieldFromInstruction(insn, startBit: 39, numBits: 1);
324 uint64_t simm32 = SignExtend64<32>(x: fieldFromInstruction(insn, startBit: 0, numBits: 32));
325 DecodeStatus status;
326
327 // Decode sz.
328 if (cz) {
329 status = DecodeI64RegisterClass(Inst&: MI, RegNo: sz, Address, Decoder);
330 if (status != MCDisassembler::Success)
331 return status;
332 } else {
333 MI.addOperand(Op: MCOperand::createImm(Val: 0));
334 }
335
336 // Decode sy.
337 if (cy) {
338 status = DecodeI64RegisterClass(Inst&: MI, RegNo: sy, Address, Decoder);
339 if (status != MCDisassembler::Success)
340 return status;
341 } else {
342 MI.addOperand(Op: MCOperand::createImm(Val: SignExtend32<7>(X: sy)));
343 }
344
345 // Decode simm32.
346 MI.addOperand(Op: MCOperand::createImm(Val: simm32));
347
348 return MCDisassembler::Success;
349}
350
351static DecodeStatus DecodeAS(MCInst &MI, uint64_t insn, uint64_t Address,
352 const MCDisassembler *Decoder) {
353 unsigned sz = fieldFromInstruction(insn, startBit: 32, numBits: 7);
354 bool cz = fieldFromInstruction(insn, startBit: 39, numBits: 1);
355 uint64_t simm32 = SignExtend64<32>(x: fieldFromInstruction(insn, startBit: 0, numBits: 32));
356 DecodeStatus status;
357
358 // Decode sz.
359 if (cz) {
360 status = DecodeI64RegisterClass(Inst&: MI, RegNo: sz, Address, Decoder);
361 if (status != MCDisassembler::Success)
362 return status;
363 } else {
364 MI.addOperand(Op: MCOperand::createImm(Val: 0));
365 }
366
367 // Decode simm32.
368 MI.addOperand(Op: MCOperand::createImm(Val: simm32));
369
370 return MCDisassembler::Success;
371}
372
373static DecodeStatus DecodeMem(MCInst &MI, uint64_t insn, uint64_t Address,
374 const MCDisassembler *Decoder, bool isLoad,
375 DecodeFunc DecodeSX) {
376 unsigned sx = fieldFromInstruction(insn, startBit: 48, numBits: 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
397static DecodeStatus DecodeMemAS(MCInst &MI, uint64_t insn, uint64_t Address,
398 const MCDisassembler *Decoder, bool isLoad,
399 DecodeFunc DecodeSX) {
400 unsigned sx = fieldFromInstruction(insn, startBit: 48, numBits: 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
421static DecodeStatus DecodeLoadI32(MCInst &Inst, uint64_t insn, uint64_t Address,
422 const MCDisassembler *Decoder) {
423 return DecodeMem(MI&: Inst, insn, Address, Decoder, isLoad: true, DecodeSX: DecodeI32RegisterClass);
424}
425
426static DecodeStatus DecodeStoreI32(MCInst &Inst, uint64_t insn,
427 uint64_t Address,
428 const MCDisassembler *Decoder) {
429 return DecodeMem(MI&: Inst, insn, Address, Decoder, isLoad: false, DecodeSX: DecodeI32RegisterClass);
430}
431
432static DecodeStatus DecodeLoadI64(MCInst &Inst, uint64_t insn, uint64_t Address,
433 const MCDisassembler *Decoder) {
434 return DecodeMem(MI&: Inst, insn, Address, Decoder, isLoad: true, DecodeSX: DecodeI64RegisterClass);
435}
436
437static DecodeStatus DecodeStoreI64(MCInst &Inst, uint64_t insn,
438 uint64_t Address,
439 const MCDisassembler *Decoder) {
440 return DecodeMem(MI&: Inst, insn, Address, Decoder, isLoad: false, DecodeSX: DecodeI64RegisterClass);
441}
442
443static DecodeStatus DecodeLoadF32(MCInst &Inst, uint64_t insn, uint64_t Address,
444 const MCDisassembler *Decoder) {
445 return DecodeMem(MI&: Inst, insn, Address, Decoder, isLoad: true, DecodeSX: DecodeF32RegisterClass);
446}
447
448static DecodeStatus DecodeStoreF32(MCInst &Inst, uint64_t insn,
449 uint64_t Address,
450 const MCDisassembler *Decoder) {
451 return DecodeMem(MI&: Inst, insn, Address, Decoder, isLoad: false, DecodeSX: DecodeF32RegisterClass);
452}
453
454static DecodeStatus DecodeLoadASI64(MCInst &Inst, uint64_t insn,
455 uint64_t Address,
456 const MCDisassembler *Decoder) {
457 return DecodeMemAS(MI&: Inst, insn, Address, Decoder, isLoad: true,
458 DecodeSX: DecodeI64RegisterClass);
459}
460
461static DecodeStatus DecodeStoreASI64(MCInst &Inst, uint64_t insn,
462 uint64_t Address,
463 const MCDisassembler *Decoder) {
464 return DecodeMemAS(MI&: Inst, insn, Address, Decoder, isLoad: false,
465 DecodeSX: DecodeI64RegisterClass);
466}
467
468static 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, startBit: 48, numBits: 7);
472 bool cy = fieldFromInstruction(insn, startBit: 47, numBits: 1);
473 unsigned sy = fieldFromInstruction(insn, startBit: 40, numBits: 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(Op: MCOperand::createImm(Val: sy));
494 else
495 MI.addOperand(Op: MCOperand::createImm(Val: SignExtend32<7>(X: 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
506static DecodeStatus DecodeTS1AMI64(MCInst &MI, uint64_t insn, uint64_t Address,
507 const MCDisassembler *Decoder) {
508 return DecodeCAS(MI, insn, Address, Decoder, isImmOnly: false, isUImm: true,
509 DecodeSX: DecodeI64RegisterClass);
510}
511
512static DecodeStatus DecodeTS1AMI32(MCInst &MI, uint64_t insn, uint64_t Address,
513 const MCDisassembler *Decoder) {
514 return DecodeCAS(MI, insn, Address, Decoder, isImmOnly: false, isUImm: true,
515 DecodeSX: DecodeI32RegisterClass);
516}
517
518static DecodeStatus DecodeCASI64(MCInst &MI, uint64_t insn, uint64_t Address,
519 const MCDisassembler *Decoder) {
520 return DecodeCAS(MI, insn, Address, Decoder, isImmOnly: false, isUImm: false,
521 DecodeSX: DecodeI64RegisterClass);
522}
523
524static DecodeStatus DecodeCASI32(MCInst &MI, uint64_t insn, uint64_t Address,
525 const MCDisassembler *Decoder) {
526 return DecodeCAS(MI, insn, Address, Decoder, isImmOnly: false, isUImm: false,
527 DecodeSX: DecodeI32RegisterClass);
528}
529
530static DecodeStatus DecodeCall(MCInst &Inst, uint64_t insn, uint64_t Address,
531 const MCDisassembler *Decoder) {
532 return DecodeMem(MI&: Inst, insn, Address, Decoder, isLoad: true, DecodeSX: DecodeI64RegisterClass);
533}
534
535static DecodeStatus DecodeSIMM7(MCInst &MI, uint64_t insn, uint64_t Address,
536 const MCDisassembler *Decoder) {
537 uint64_t tgt = SignExtend64<7>(x: insn);
538 MI.addOperand(Op: MCOperand::createImm(Val: tgt));
539 return MCDisassembler::Success;
540}
541
542static DecodeStatus DecodeSIMM32(MCInst &MI, uint64_t insn, uint64_t Address,
543 const MCDisassembler *Decoder) {
544 uint64_t tgt = SignExtend64<32>(x: insn);
545 MI.addOperand(Op: MCOperand::createImm(Val: tgt));
546 return MCDisassembler::Success;
547}
548
549static 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.
586static DecodeStatus DecodeCCOperand(MCInst &MI, uint64_t cf, uint64_t Address,
587 const MCDisassembler *Decoder) {
588 MI.addOperand(Op: MCOperand::createImm(Val: VEValToCondCode(Val: cf, IsInteger: isIntegerBCKind(MI))));
589 return MCDisassembler::Success;
590}
591
592// Decode RD Operand field.
593static DecodeStatus DecodeRDOperand(MCInst &MI, uint64_t cf, uint64_t Address,
594 const MCDisassembler *Decoder) {
595 MI.addOperand(Op: MCOperand::createImm(Val: VEValToRD(Val: cf)));
596 return MCDisassembler::Success;
597}
598
599// Decode branch condition instruction and CCOperand field in it.
600static DecodeStatus DecodeBranchCondition(MCInst &MI, uint64_t insn,
601 uint64_t Address,
602 const MCDisassembler *Decoder) {
603 unsigned cf = fieldFromInstruction(insn, startBit: 48, numBits: 4);
604 bool cy = fieldFromInstruction(insn, startBit: 47, numBits: 1);
605 unsigned sy = fieldFromInstruction(insn, startBit: 40, numBits: 7);
606
607 // Decode cf.
608 MI.addOperand(Op: MCOperand::createImm(Val: VEValToCondCode(Val: cf, IsInteger: isIntegerBCKind(MI))));
609
610 // Decode sy.
611 DecodeStatus status;
612 if (cy) {
613 status = DecodeI64RegisterClass(Inst&: MI, RegNo: sy, Address, Decoder);
614 if (status != MCDisassembler::Success)
615 return status;
616 } else {
617 MI.addOperand(Op: MCOperand::createImm(Val: SignExtend32<7>(X: sy)));
618 }
619
620 // Decode MEMri.
621 return DecodeAS(MI, insn, Address, Decoder);
622}
623
624static 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