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/MCDisassembler/MCDisassembler.h"
19 #include "llvm/MC/MCFixedLenDisassembler.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/Support/TargetRegistry.h"
22 
23 using namespace llvm;
24 
25 #define DEBUG_TYPE "ve-disassembler"
26 
27 typedef MCDisassembler::DecodeStatus DecodeStatus;
28 
29 namespace {
30 
31 /// A disassembler class for VE.
32 class VEDisassembler : public MCDisassembler {
33 public:
34   VEDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
35       : MCDisassembler(STI, Ctx) {}
36   virtual ~VEDisassembler() {}
37 
38   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
39                               ArrayRef<uint8_t> Bytes, uint64_t Address,
40                               raw_ostream &CStream) const override;
41 };
42 } // namespace
43 
44 static MCDisassembler *createVEDisassembler(const Target &T,
45                                             const MCSubtargetInfo &STI,
46                                             MCContext &Ctx) {
47   return new VEDisassembler(STI, Ctx);
48 }
49 
50 extern "C" void LLVMInitializeVEDisassembler() {
51   // Register the disassembler.
52   TargetRegistry::RegisterMCDisassembler(getTheVETarget(),
53                                          createVEDisassembler);
54 }
55 
56 static const unsigned I32RegDecoderTable[] = {
57     VE::SW0,  VE::SW1,  VE::SW2,  VE::SW3,  VE::SW4,  VE::SW5,  VE::SW6,
58     VE::SW7,  VE::SW8,  VE::SW9,  VE::SW10, VE::SW11, VE::SW12, VE::SW13,
59     VE::SW14, VE::SW15, VE::SW16, VE::SW17, VE::SW18, VE::SW19, VE::SW20,
60     VE::SW21, VE::SW22, VE::SW23, VE::SW24, VE::SW25, VE::SW26, VE::SW27,
61     VE::SW28, VE::SW29, VE::SW30, VE::SW31, VE::SW32, VE::SW33, VE::SW34,
62     VE::SW35, VE::SW36, VE::SW37, VE::SW38, VE::SW39, VE::SW40, VE::SW41,
63     VE::SW42, VE::SW43, VE::SW44, VE::SW45, VE::SW46, VE::SW47, VE::SW48,
64     VE::SW49, VE::SW50, VE::SW51, VE::SW52, VE::SW53, VE::SW54, VE::SW55,
65     VE::SW56, VE::SW57, VE::SW58, VE::SW59, VE::SW60, VE::SW61, VE::SW62,
66     VE::SW63};
67 
68 static const unsigned I64RegDecoderTable[] = {
69     VE::SX0,  VE::SX1,  VE::SX2,  VE::SX3,  VE::SX4,  VE::SX5,  VE::SX6,
70     VE::SX7,  VE::SX8,  VE::SX9,  VE::SX10, VE::SX11, VE::SX12, VE::SX13,
71     VE::SX14, VE::SX15, VE::SX16, VE::SX17, VE::SX18, VE::SX19, VE::SX20,
72     VE::SX21, VE::SX22, VE::SX23, VE::SX24, VE::SX25, VE::SX26, VE::SX27,
73     VE::SX28, VE::SX29, VE::SX30, VE::SX31, VE::SX32, VE::SX33, VE::SX34,
74     VE::SX35, VE::SX36, VE::SX37, VE::SX38, VE::SX39, VE::SX40, VE::SX41,
75     VE::SX42, VE::SX43, VE::SX44, VE::SX45, VE::SX46, VE::SX47, VE::SX48,
76     VE::SX49, VE::SX50, VE::SX51, VE::SX52, VE::SX53, VE::SX54, VE::SX55,
77     VE::SX56, VE::SX57, VE::SX58, VE::SX59, VE::SX60, VE::SX61, VE::SX62,
78     VE::SX63};
79 
80 static const unsigned F32RegDecoderTable[] = {
81     VE::SF0,  VE::SF1,  VE::SF2,  VE::SF3,  VE::SF4,  VE::SF5,  VE::SF6,
82     VE::SF7,  VE::SF8,  VE::SF9,  VE::SF10, VE::SF11, VE::SF12, VE::SF13,
83     VE::SF14, VE::SF15, VE::SF16, VE::SF17, VE::SF18, VE::SF19, VE::SF20,
84     VE::SF21, VE::SF22, VE::SF23, VE::SF24, VE::SF25, VE::SF26, VE::SF27,
85     VE::SF28, VE::SF29, VE::SF30, VE::SF31, VE::SF32, VE::SF33, VE::SF34,
86     VE::SF35, VE::SF36, VE::SF37, VE::SF38, VE::SF39, VE::SF40, VE::SF41,
87     VE::SF42, VE::SF43, VE::SF44, VE::SF45, VE::SF46, VE::SF47, VE::SF48,
88     VE::SF49, VE::SF50, VE::SF51, VE::SF52, VE::SF53, VE::SF54, VE::SF55,
89     VE::SF56, VE::SF57, VE::SF58, VE::SF59, VE::SF60, VE::SF61, VE::SF62,
90     VE::SF63};
91 
92 static DecodeStatus DecodeI32RegisterClass(MCInst &Inst, unsigned RegNo,
93                                            uint64_t Address,
94                                            const void *Decoder) {
95   if (RegNo > 63)
96     return MCDisassembler::Fail;
97   unsigned Reg = I32RegDecoderTable[RegNo];
98   Inst.addOperand(MCOperand::createReg(Reg));
99   return MCDisassembler::Success;
100 }
101 
102 static DecodeStatus DecodeI64RegisterClass(MCInst &Inst, unsigned RegNo,
103                                            uint64_t Address,
104                                            const void *Decoder) {
105   if (RegNo > 63)
106     return MCDisassembler::Fail;
107   unsigned Reg = I64RegDecoderTable[RegNo];
108   Inst.addOperand(MCOperand::createReg(Reg));
109   return MCDisassembler::Success;
110 }
111 
112 static DecodeStatus DecodeF32RegisterClass(MCInst &Inst, unsigned RegNo,
113                                            uint64_t Address,
114                                            const void *Decoder) {
115   if (RegNo > 63)
116     return MCDisassembler::Fail;
117   unsigned Reg = F32RegDecoderTable[RegNo];
118   Inst.addOperand(MCOperand::createReg(Reg));
119   return MCDisassembler::Success;
120 }
121 
122 static DecodeStatus DecodeLoadI32(MCInst &Inst, uint64_t insn, uint64_t Address,
123                                   const void *Decoder);
124 static DecodeStatus DecodeStoreI32(MCInst &Inst, uint64_t insn,
125                                    uint64_t Address, const void *Decoder);
126 static DecodeStatus DecodeLoadI64(MCInst &Inst, uint64_t insn, uint64_t Address,
127                                   const void *Decoder);
128 static DecodeStatus DecodeStoreI64(MCInst &Inst, uint64_t insn,
129                                    uint64_t Address, const void *Decoder);
130 static DecodeStatus DecodeLoadF32(MCInst &Inst, uint64_t insn, uint64_t Address,
131                                   const void *Decoder);
132 static DecodeStatus DecodeStoreF32(MCInst &Inst, uint64_t insn,
133                                    uint64_t Address, const void *Decoder);
134 static DecodeStatus DecodeCall(MCInst &Inst, uint64_t insn, uint64_t Address,
135                                const void *Decoder);
136 static DecodeStatus DecodeSIMM7(MCInst &Inst, uint64_t insn, uint64_t Address,
137                                 const void *Decoder);
138 static DecodeStatus DecodeCCOperand(MCInst &Inst, uint64_t insn,
139                                     uint64_t Address, const void *Decoder);
140 static DecodeStatus DecodeBranchCondition(MCInst &Inst, uint64_t insn,
141                                           uint64_t Address,
142                                           const void *Decoder);
143 static DecodeStatus DecodeBranchConditionAlways(MCInst &Inst, uint64_t insn,
144                                                 uint64_t Address,
145                                                 const void *Decoder);
146 
147 #include "VEGenDisassemblerTables.inc"
148 
149 /// Read four bytes from the ArrayRef and return 32 bit word.
150 static DecodeStatus readInstruction64(ArrayRef<uint8_t> Bytes, uint64_t Address,
151                                       uint64_t &Size, uint64_t &Insn,
152                                       bool IsLittleEndian) {
153   // We want to read exactly 8 Bytes of data.
154   if (Bytes.size() < 8) {
155     Size = 0;
156     return MCDisassembler::Fail;
157   }
158 
159   Insn = IsLittleEndian
160              ? ((uint64_t)Bytes[0] << 0) | ((uint64_t)Bytes[1] << 8) |
161                    ((uint64_t)Bytes[2] << 16) | ((uint64_t)Bytes[3] << 24) |
162                    ((uint64_t)Bytes[4] << 32) | ((uint64_t)Bytes[5] << 40) |
163                    ((uint64_t)Bytes[6] << 48) | ((uint64_t)Bytes[7] << 56)
164              : ((uint64_t)Bytes[7] << 0) | ((uint64_t)Bytes[6] << 8) |
165                    ((uint64_t)Bytes[5] << 16) | ((uint64_t)Bytes[4] << 24) |
166                    ((uint64_t)Bytes[3] << 32) | ((uint64_t)Bytes[2] << 40) |
167                    ((uint64_t)Bytes[1] << 48) | ((uint64_t)Bytes[0] << 56);
168 
169   return MCDisassembler::Success;
170 }
171 
172 DecodeStatus VEDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
173                                             ArrayRef<uint8_t> Bytes,
174                                             uint64_t Address,
175                                             raw_ostream &CStream) const {
176   uint64_t Insn;
177   bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian();
178   DecodeStatus Result =
179       readInstruction64(Bytes, Address, Size, Insn, isLittleEndian);
180   if (Result == MCDisassembler::Fail)
181     return MCDisassembler::Fail;
182 
183   // Calling the auto-generated decoder function.
184 
185   Result = decodeInstruction(DecoderTableVE64, Instr, Insn, Address, this, STI);
186 
187   if (Result != MCDisassembler::Fail) {
188     Size = 8;
189     return Result;
190   }
191 
192   return MCDisassembler::Fail;
193 }
194 
195 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned RegNo, uint64_t Address,
196                                    const void *Decoder);
197 
198 static DecodeStatus DecodeASX(MCInst &MI, uint64_t insn, uint64_t Address,
199                               const void *Decoder) {
200   unsigned sy = fieldFromInstruction(insn, 40, 7);
201   bool cy = fieldFromInstruction(insn, 47, 1);
202   unsigned sz = fieldFromInstruction(insn, 32, 7);
203   bool cz = fieldFromInstruction(insn, 39, 1);
204   uint64_t simm32 = SignExtend64<32>(fieldFromInstruction(insn, 0, 32));
205   DecodeStatus status;
206 
207   // Decode sz.
208   if (cz) {
209     status = DecodeI64RegisterClass(MI, sz, Address, Decoder);
210     if (status != MCDisassembler::Success)
211       return status;
212   } else {
213     MI.addOperand(MCOperand::createImm(0));
214   }
215 
216   // Decode sy.
217   if (cy) {
218     status = DecodeI64RegisterClass(MI, sy, Address, Decoder);
219     if (status != MCDisassembler::Success)
220       return status;
221   } else {
222     MI.addOperand(MCOperand::createImm(SignExtend32<7>(sy)));
223   }
224 
225   // Decode simm32.
226   MI.addOperand(MCOperand::createImm(simm32));
227 
228   return MCDisassembler::Success;
229 }
230 
231 static DecodeStatus DecodeAS(MCInst &MI, uint64_t insn, uint64_t Address,
232                              const void *Decoder) {
233   unsigned sz = fieldFromInstruction(insn, 32, 7);
234   bool cz = fieldFromInstruction(insn, 39, 1);
235   uint64_t simm32 = SignExtend64<32>(fieldFromInstruction(insn, 0, 32));
236   DecodeStatus status;
237 
238   // Decode sz.
239   if (cz) {
240     status = DecodeI64RegisterClass(MI, sz, Address, Decoder);
241     if (status != MCDisassembler::Success)
242       return status;
243   } else {
244     MI.addOperand(MCOperand::createImm(0));
245   }
246 
247   // Decode simm32.
248   MI.addOperand(MCOperand::createImm(simm32));
249 
250   return MCDisassembler::Success;
251 }
252 
253 static DecodeStatus DecodeMem(MCInst &MI, uint64_t insn, uint64_t Address,
254                               const void *Decoder, bool isLoad,
255                               DecodeFunc DecodeSX) {
256   unsigned sx = fieldFromInstruction(insn, 48, 7);
257 
258   DecodeStatus status;
259   if (isLoad) {
260     status = DecodeSX(MI, sx, Address, Decoder);
261     if (status != MCDisassembler::Success)
262       return status;
263   }
264 
265   status = DecodeASX(MI, insn, Address, Decoder);
266   if (status != MCDisassembler::Success)
267     return status;
268 
269   if (!isLoad) {
270     status = DecodeSX(MI, sx, Address, Decoder);
271     if (status != MCDisassembler::Success)
272       return status;
273   }
274   return MCDisassembler::Success;
275 }
276 
277 static DecodeStatus DecodeLoadI32(MCInst &Inst, uint64_t insn, uint64_t Address,
278                                   const void *Decoder) {
279   return DecodeMem(Inst, insn, Address, Decoder, true, DecodeI32RegisterClass);
280 }
281 
282 static DecodeStatus DecodeStoreI32(MCInst &Inst, uint64_t insn,
283                                    uint64_t Address, const void *Decoder) {
284   return DecodeMem(Inst, insn, Address, Decoder, false, DecodeI32RegisterClass);
285 }
286 
287 static DecodeStatus DecodeLoadI64(MCInst &Inst, uint64_t insn, uint64_t Address,
288                                   const void *Decoder) {
289   return DecodeMem(Inst, insn, Address, Decoder, true, DecodeI64RegisterClass);
290 }
291 
292 static DecodeStatus DecodeStoreI64(MCInst &Inst, uint64_t insn,
293                                    uint64_t Address, const void *Decoder) {
294   return DecodeMem(Inst, insn, Address, Decoder, false, DecodeI64RegisterClass);
295 }
296 
297 static DecodeStatus DecodeLoadF32(MCInst &Inst, uint64_t insn, uint64_t Address,
298                                   const void *Decoder) {
299   return DecodeMem(Inst, insn, Address, Decoder, true, DecodeF32RegisterClass);
300 }
301 
302 static DecodeStatus DecodeStoreF32(MCInst &Inst, uint64_t insn,
303                                    uint64_t Address, const void *Decoder) {
304   return DecodeMem(Inst, insn, Address, Decoder, false, DecodeF32RegisterClass);
305 }
306 
307 static DecodeStatus DecodeCall(MCInst &Inst, uint64_t insn, uint64_t Address,
308                                const void *Decoder) {
309   return DecodeMem(Inst, insn, Address, Decoder, true, DecodeI64RegisterClass);
310 }
311 
312 static DecodeStatus DecodeSIMM7(MCInst &MI, uint64_t insn, uint64_t Address,
313                                 const void *Decoder) {
314   uint64_t tgt = SignExtend64<7>(insn);
315   MI.addOperand(MCOperand::createImm(tgt));
316   return MCDisassembler::Success;
317 }
318 
319 static bool isIntegerBCKind(MCInst &MI) {
320 
321 #define BCm_kind(NAME)                                                         \
322   case NAME##rri:                                                              \
323   case NAME##rzi:                                                              \
324   case NAME##iri:                                                              \
325   case NAME##izi:                                                              \
326   case NAME##rri_nt:                                                           \
327   case NAME##rzi_nt:                                                           \
328   case NAME##iri_nt:                                                           \
329   case NAME##izi_nt:                                                           \
330   case NAME##rri_t:                                                            \
331   case NAME##rzi_t:                                                            \
332   case NAME##iri_t:                                                            \
333   case NAME##izi_t:
334 
335 #define BCRm_kind(NAME)                                                        \
336   case NAME##rr:                                                               \
337   case NAME##ir:                                                               \
338   case NAME##rr_nt:                                                            \
339   case NAME##ir_nt:                                                            \
340   case NAME##rr_t:                                                             \
341   case NAME##ir_t:
342 
343   {
344     using namespace llvm::VE;
345     switch (MI.getOpcode()) {
346       BCm_kind(BCFL) BCm_kind(BCFW) BCRm_kind(BRCFL)
347           BCRm_kind(BRCFW) return true;
348     }
349   }
350 #undef BCm_kind
351 
352   return false;
353 }
354 
355 // Decode CC Operand field.
356 static DecodeStatus DecodeCCOperand(MCInst &MI, uint64_t cf, uint64_t Address,
357                                     const void *Decoder) {
358   MI.addOperand(MCOperand::createImm(VEValToCondCode(cf, isIntegerBCKind(MI))));
359   return MCDisassembler::Success;
360 }
361 
362 // Decode branch condition instruction and CCOperand field in it.
363 static DecodeStatus DecodeBranchCondition(MCInst &MI, uint64_t insn,
364                                           uint64_t Address,
365                                           const void *Decoder) {
366   unsigned cf = fieldFromInstruction(insn, 48, 4);
367   bool cy = fieldFromInstruction(insn, 47, 1);
368   unsigned sy = fieldFromInstruction(insn, 40, 7);
369 
370   // Decode cf.
371   MI.addOperand(MCOperand::createImm(VEValToCondCode(cf, isIntegerBCKind(MI))));
372 
373   // Decode sy.
374   DecodeStatus status;
375   if (cy) {
376     status = DecodeI64RegisterClass(MI, sy, Address, Decoder);
377     if (status != MCDisassembler::Success)
378       return status;
379   } else {
380     MI.addOperand(MCOperand::createImm(SignExtend32<7>(sy)));
381   }
382 
383   // Decode MEMri.
384   return DecodeAS(MI, insn, Address, Decoder);
385 }
386 
387 static DecodeStatus DecodeBranchConditionAlways(MCInst &MI, uint64_t insn,
388                                                 uint64_t Address,
389                                                 const void *Decoder) {
390   // Decode MEMri.
391   return DecodeAS(MI, insn, Address, Decoder);
392 }
393