blob: 3e56b9e9b8837dcd235949606fdef1d3934247bd [file] [log] [blame]
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +00001//===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is part of the Sparc Disassembler.
11//
12//===----------------------------------------------------------------------===//
13
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +000014#include "Sparc.h"
15#include "SparcRegisterInfo.h"
16#include "SparcSubtarget.h"
17#include "llvm/MC/MCDisassembler.h"
18#include "llvm/MC/MCFixedLenDisassembler.h"
Pete Cooper3de83e42015-05-15 21:58:42 +000019#include "llvm/MC/MCInst.h"
Douglas Katzman9160e782015-04-29 20:30:57 +000020#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCAsmInfo.h"
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +000022#include "llvm/Support/TargetRegistry.h"
23
24using namespace llvm;
25
Chandler Carruth84e68b22014-04-22 02:41:26 +000026#define DEBUG_TYPE "sparc-disassembler"
27
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +000028typedef MCDisassembler::DecodeStatus DecodeStatus;
29
30namespace {
31
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000032/// A disassembler class for Sparc.
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +000033class SparcDisassembler : public MCDisassembler {
34public:
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000035 SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
36 : MCDisassembler(STI, Ctx) {}
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +000037 virtual ~SparcDisassembler() {}
38
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000039 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +000040 ArrayRef<uint8_t> Bytes, uint64_t Address,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000041 raw_ostream &VStream,
42 raw_ostream &CStream) const override;
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +000043};
Alexander Kornienkof00654e2015-06-23 09:49:53 +000044}
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +000045
46namespace llvm {
Douglas Katzman9160e782015-04-29 20:30:57 +000047extern Target TheSparcTarget, TheSparcV9Target, TheSparcelTarget;
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +000048}
49
Douglas Katzman9160e782015-04-29 20:30:57 +000050static MCDisassembler *createSparcDisassembler(const Target &T,
51 const MCSubtargetInfo &STI,
52 MCContext &Ctx) {
Lang Hamesa1bc0f52014-04-15 04:40:56 +000053 return new SparcDisassembler(STI, Ctx);
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +000054}
55
56
57extern "C" void LLVMInitializeSparcDisassembler() {
58 // Register the disassembler.
59 TargetRegistry::RegisterMCDisassembler(TheSparcTarget,
60 createSparcDisassembler);
61 TargetRegistry::RegisterMCDisassembler(TheSparcV9Target,
62 createSparcDisassembler);
Douglas Katzman9160e782015-04-29 20:30:57 +000063 TargetRegistry::RegisterMCDisassembler(TheSparcelTarget,
64 createSparcDisassembler);
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +000065}
66
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +000067static const unsigned IntRegDecoderTable[] = {
68 SP::G0, SP::G1, SP::G2, SP::G3,
69 SP::G4, SP::G5, SP::G6, SP::G7,
70 SP::O0, SP::O1, SP::O2, SP::O3,
71 SP::O4, SP::O5, SP::O6, SP::O7,
72 SP::L0, SP::L1, SP::L2, SP::L3,
73 SP::L4, SP::L5, SP::L6, SP::L7,
74 SP::I0, SP::I1, SP::I2, SP::I3,
75 SP::I4, SP::I5, SP::I6, SP::I7 };
76
77static const unsigned FPRegDecoderTable[] = {
78 SP::F0, SP::F1, SP::F2, SP::F3,
79 SP::F4, SP::F5, SP::F6, SP::F7,
80 SP::F8, SP::F9, SP::F10, SP::F11,
81 SP::F12, SP::F13, SP::F14, SP::F15,
82 SP::F16, SP::F17, SP::F18, SP::F19,
83 SP::F20, SP::F21, SP::F22, SP::F23,
84 SP::F24, SP::F25, SP::F26, SP::F27,
85 SP::F28, SP::F29, SP::F30, SP::F31 };
86
87static const unsigned DFPRegDecoderTable[] = {
88 SP::D0, SP::D16, SP::D1, SP::D17,
89 SP::D2, SP::D18, SP::D3, SP::D19,
90 SP::D4, SP::D20, SP::D5, SP::D21,
91 SP::D6, SP::D22, SP::D7, SP::D23,
92 SP::D8, SP::D24, SP::D9, SP::D25,
93 SP::D10, SP::D26, SP::D11, SP::D27,
94 SP::D12, SP::D28, SP::D13, SP::D29,
95 SP::D14, SP::D30, SP::D15, SP::D31 };
96
97static const unsigned QFPRegDecoderTable[] = {
Venkatraman Govindaraju0b9debf2014-01-12 04:34:31 +000098 SP::Q0, SP::Q8, ~0U, ~0U,
99 SP::Q1, SP::Q9, ~0U, ~0U,
100 SP::Q2, SP::Q10, ~0U, ~0U,
101 SP::Q3, SP::Q11, ~0U, ~0U,
102 SP::Q4, SP::Q12, ~0U, ~0U,
103 SP::Q5, SP::Q13, ~0U, ~0U,
104 SP::Q6, SP::Q14, ~0U, ~0U,
105 SP::Q7, SP::Q15, ~0U, ~0U } ;
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000106
Venkatraman Govindaraju81aae572014-03-02 03:39:39 +0000107static const unsigned FCCRegDecoderTable[] = {
108 SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 };
109
James Y Knight807563d2015-05-18 16:29:48 +0000110static const unsigned ASRRegDecoderTable[] = {
111 SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
112 SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
113 SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
114 SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
115 SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
116 SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
117 SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
118 SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
119
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000120static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst,
121 unsigned RegNo,
122 uint64_t Address,
123 const void *Decoder) {
124 if (RegNo > 31)
125 return MCDisassembler::Fail;
126 unsigned Reg = IntRegDecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000127 Inst.addOperand(MCOperand::createReg(Reg));
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000128 return MCDisassembler::Success;
129}
130
131static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst,
132 unsigned RegNo,
133 uint64_t Address,
134 const void *Decoder) {
135 if (RegNo > 31)
136 return MCDisassembler::Fail;
137 unsigned Reg = IntRegDecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000138 Inst.addOperand(MCOperand::createReg(Reg));
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000139 return MCDisassembler::Success;
140}
141
142
143static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst,
144 unsigned RegNo,
145 uint64_t Address,
146 const void *Decoder) {
147 if (RegNo > 31)
148 return MCDisassembler::Fail;
149 unsigned Reg = FPRegDecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000150 Inst.addOperand(MCOperand::createReg(Reg));
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000151 return MCDisassembler::Success;
152}
153
154
155static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst,
156 unsigned RegNo,
157 uint64_t Address,
158 const void *Decoder) {
159 if (RegNo > 31)
160 return MCDisassembler::Fail;
161 unsigned Reg = DFPRegDecoderTable[RegNo];
Jim Grosbache9119e42015-05-13 18:37:00 +0000162 Inst.addOperand(MCOperand::createReg(Reg));
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000163 return MCDisassembler::Success;
164}
165
166
167static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst,
168 unsigned RegNo,
169 uint64_t Address,
170 const void *Decoder) {
171 if (RegNo > 31)
172 return MCDisassembler::Fail;
173
174 unsigned Reg = QFPRegDecoderTable[RegNo];
Venkatraman Govindaraju0b9debf2014-01-12 04:34:31 +0000175 if (Reg == ~0U)
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000176 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +0000177 Inst.addOperand(MCOperand::createReg(Reg));
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000178 return MCDisassembler::Success;
179}
180
Venkatraman Govindaraju81aae572014-03-02 03:39:39 +0000181static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo,
182 uint64_t Address,
183 const void *Decoder) {
184 if (RegNo > 3)
185 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +0000186 Inst.addOperand(MCOperand::createReg(FCCRegDecoderTable[RegNo]));
Venkatraman Govindaraju81aae572014-03-02 03:39:39 +0000187 return MCDisassembler::Success;
188}
189
James Y Knight807563d2015-05-18 16:29:48 +0000190static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo,
191 uint64_t Address,
192 const void *Decoder) {
193 if (RegNo > 31)
194 return MCDisassembler::Fail;
195 Inst.addOperand(MCOperand::createReg(ASRRegDecoderTable[RegNo]));
196 return MCDisassembler::Success;
197}
198
Venkatraman Govindaraju81aae572014-03-02 03:39:39 +0000199
Venkatraman Govindarajufb548212014-03-01 07:46:33 +0000200static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
201 const void *Decoder);
202static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
203 const void *Decoder);
204static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
205 const void *Decoder);
206static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
207 const void *Decoder);
208static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
209 uint64_t Address, const void *Decoder);
210static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn,
211 uint64_t Address, const void *Decoder);
212static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
213 uint64_t Address, const void *Decoder);
214static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
215 uint64_t Address, const void *Decoder);
Venkatraman Govindaraju78df2de2014-03-01 08:30:58 +0000216static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn,
217 uint64_t Address, const void *Decoder);
Venkatraman Govindaraju484ca1a2014-03-01 09:11:57 +0000218static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn,
219 uint64_t Address, const void *Decoder);
Venkatraman Govindaraju4fa2ab22014-03-02 21:17:44 +0000220static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address,
221 const void *Decoder);
Venkatraman Govindaraju07d3af22014-03-02 22:55:53 +0000222static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
223 const void *Decoder);
Venkatraman Govindarajuf7031322014-03-09 23:32:07 +0000224static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address,
225 const void *Decoder);
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000226
227#include "SparcGenDisassemblerTables.inc"
228
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000229/// Read four bytes from the ArrayRef and return 32 bit word.
230static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
Douglas Katzman9160e782015-04-29 20:30:57 +0000231 uint64_t &Size, uint32_t &Insn,
232 bool IsLittleEndian) {
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000233 // We want to read exactly 4 Bytes of data.
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000234 if (Bytes.size() < 4) {
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000235 Size = 0;
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000236 return MCDisassembler::Fail;
237 }
238
Douglas Katzman9160e782015-04-29 20:30:57 +0000239 Insn = IsLittleEndian
240 ? (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
241 (Bytes[3] << 24)
242 : (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) |
243 (Bytes[0] << 24);
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000244
245 return MCDisassembler::Success;
246}
247
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000248DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000249 ArrayRef<uint8_t> Bytes,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000250 uint64_t Address,
251 raw_ostream &VStream,
252 raw_ostream &CStream) const {
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000253 uint32_t Insn;
Douglas Katzman9160e782015-04-29 20:30:57 +0000254 bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian();
255 DecodeStatus Result =
256 readInstruction32(Bytes, Address, Size, Insn, isLittleEndian);
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000257 if (Result == MCDisassembler::Fail)
258 return MCDisassembler::Fail;
259
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000260 // Calling the auto-generated decoder function.
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000261 Result =
262 decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI);
Venkatraman Govindarajudfcccc72014-01-06 08:08:58 +0000263
264 if (Result != MCDisassembler::Fail) {
265 Size = 4;
266 return Result;
267 }
268
269 return MCDisassembler::Fail;
270}
Venkatraman Govindarajufb548212014-03-01 07:46:33 +0000271
272
273typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
274 const void *Decoder);
275
276static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address,
277 const void *Decoder,
278 bool isLoad, DecodeFunc DecodeRD) {
279 unsigned rd = fieldFromInstruction(insn, 25, 5);
280 unsigned rs1 = fieldFromInstruction(insn, 14, 5);
281 bool isImm = fieldFromInstruction(insn, 13, 1);
James Y Knight24060be2015-05-18 16:35:04 +0000282 bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field)
283 unsigned asi = fieldFromInstruction(insn, 5, 8);
Venkatraman Govindarajufb548212014-03-01 07:46:33 +0000284 unsigned rs2 = 0;
285 unsigned simm13 = 0;
286 if (isImm)
287 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
288 else
289 rs2 = fieldFromInstruction(insn, 0, 5);
290
291 DecodeStatus status;
292 if (isLoad) {
293 status = DecodeRD(MI, rd, Address, Decoder);
294 if (status != MCDisassembler::Success)
295 return status;
296 }
297
298 // Decode rs1.
299 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
300 if (status != MCDisassembler::Success)
301 return status;
302
303 // Decode imm|rs2.
304 if (isImm)
Jim Grosbache9119e42015-05-13 18:37:00 +0000305 MI.addOperand(MCOperand::createImm(simm13));
Venkatraman Govindarajufb548212014-03-01 07:46:33 +0000306 else {
307 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
308 if (status != MCDisassembler::Success)
309 return status;
310 }
311
James Y Knight24060be2015-05-18 16:35:04 +0000312 if (hasAsi)
313 MI.addOperand(MCOperand::createImm(asi));
314
Venkatraman Govindarajufb548212014-03-01 07:46:33 +0000315 if (!isLoad) {
316 status = DecodeRD(MI, rd, Address, Decoder);
317 if (status != MCDisassembler::Success)
318 return status;
319 }
320 return MCDisassembler::Success;
321}
322
323static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
324 const void *Decoder) {
325 return DecodeMem(Inst, insn, Address, Decoder, true,
326 DecodeIntRegsRegisterClass);
327}
328
329static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
330 const void *Decoder) {
331 return DecodeMem(Inst, insn, Address, Decoder, true,
332 DecodeFPRegsRegisterClass);
333}
334
335static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
336 const void *Decoder) {
337 return DecodeMem(Inst, insn, Address, Decoder, true,
338 DecodeDFPRegsRegisterClass);
339}
340
341static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
342 const void *Decoder) {
343 return DecodeMem(Inst, insn, Address, Decoder, true,
344 DecodeQFPRegsRegisterClass);
345}
346
347static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
348 uint64_t Address, const void *Decoder) {
349 return DecodeMem(Inst, insn, Address, Decoder, false,
350 DecodeIntRegsRegisterClass);
351}
352
353static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address,
354 const void *Decoder) {
355 return DecodeMem(Inst, insn, Address, Decoder, false,
356 DecodeFPRegsRegisterClass);
357}
358
359static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
360 uint64_t Address, const void *Decoder) {
361 return DecodeMem(Inst, insn, Address, Decoder, false,
362 DecodeDFPRegsRegisterClass);
363}
364
365static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
366 uint64_t Address, const void *Decoder) {
367 return DecodeMem(Inst, insn, Address, Decoder, false,
368 DecodeQFPRegsRegisterClass);
369}
Venkatraman Govindaraju78df2de2014-03-01 08:30:58 +0000370
371static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
372 uint64_t Address, uint64_t Offset,
373 uint64_t Width, MCInst &MI,
374 const void *Decoder) {
375 const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
376 return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
377 Offset, Width);
378}
379
380static DecodeStatus DecodeCall(MCInst &MI, unsigned insn,
381 uint64_t Address, const void *Decoder) {
382 unsigned tgt = fieldFromInstruction(insn, 0, 30);
383 tgt <<= 2;
384 if (!tryAddingSymbolicOperand(tgt+Address, false, Address,
385 0, 30, MI, Decoder))
Jim Grosbache9119e42015-05-13 18:37:00 +0000386 MI.addOperand(MCOperand::createImm(tgt));
Venkatraman Govindaraju78df2de2014-03-01 08:30:58 +0000387 return MCDisassembler::Success;
388}
Venkatraman Govindaraju484ca1a2014-03-01 09:11:57 +0000389
390static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn,
391 uint64_t Address, const void *Decoder) {
392 unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
Jim Grosbache9119e42015-05-13 18:37:00 +0000393 MI.addOperand(MCOperand::createImm(tgt));
Venkatraman Govindaraju484ca1a2014-03-01 09:11:57 +0000394 return MCDisassembler::Success;
395}
Venkatraman Govindaraju4fa2ab22014-03-02 21:17:44 +0000396
397static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address,
398 const void *Decoder) {
399
400 unsigned rd = fieldFromInstruction(insn, 25, 5);
401 unsigned rs1 = fieldFromInstruction(insn, 14, 5);
402 unsigned isImm = fieldFromInstruction(insn, 13, 1);
403 unsigned rs2 = 0;
404 unsigned simm13 = 0;
405 if (isImm)
406 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
407 else
408 rs2 = fieldFromInstruction(insn, 0, 5);
409
410 // Decode RD.
411 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
412 if (status != MCDisassembler::Success)
413 return status;
414
415 // Decode RS1.
416 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
417 if (status != MCDisassembler::Success)
418 return status;
419
420 // Decode RS1 | SIMM13.
421 if (isImm)
Jim Grosbache9119e42015-05-13 18:37:00 +0000422 MI.addOperand(MCOperand::createImm(simm13));
Venkatraman Govindaraju4fa2ab22014-03-02 21:17:44 +0000423 else {
424 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
425 if (status != MCDisassembler::Success)
426 return status;
427 }
428 return MCDisassembler::Success;
429}
Venkatraman Govindaraju07d3af22014-03-02 22:55:53 +0000430
431static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
432 const void *Decoder) {
433
434 unsigned rs1 = fieldFromInstruction(insn, 14, 5);
435 unsigned isImm = fieldFromInstruction(insn, 13, 1);
436 unsigned rs2 = 0;
437 unsigned simm13 = 0;
438 if (isImm)
439 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
440 else
441 rs2 = fieldFromInstruction(insn, 0, 5);
442
443 // Decode RS1.
444 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
445 if (status != MCDisassembler::Success)
446 return status;
447
448 // Decode RS2 | SIMM13.
449 if (isImm)
Jim Grosbache9119e42015-05-13 18:37:00 +0000450 MI.addOperand(MCOperand::createImm(simm13));
Venkatraman Govindaraju07d3af22014-03-02 22:55:53 +0000451 else {
452 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
453 if (status != MCDisassembler::Success)
454 return status;
455 }
456 return MCDisassembler::Success;
457}
Venkatraman Govindarajuf7031322014-03-09 23:32:07 +0000458
459static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address,
460 const void *Decoder) {
461
462 unsigned rd = fieldFromInstruction(insn, 25, 5);
463 unsigned rs1 = fieldFromInstruction(insn, 14, 5);
464 unsigned isImm = fieldFromInstruction(insn, 13, 1);
James Y Knight24060be2015-05-18 16:35:04 +0000465 bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field)
466 unsigned asi = fieldFromInstruction(insn, 5, 8);
Venkatraman Govindarajuf7031322014-03-09 23:32:07 +0000467 unsigned rs2 = 0;
468 unsigned simm13 = 0;
469 if (isImm)
470 simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
471 else
472 rs2 = fieldFromInstruction(insn, 0, 5);
473
474 // Decode RD.
475 DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
476 if (status != MCDisassembler::Success)
477 return status;
478
479 // Decode RS1.
480 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
481 if (status != MCDisassembler::Success)
482 return status;
483
484 // Decode RS1 | SIMM13.
485 if (isImm)
Jim Grosbache9119e42015-05-13 18:37:00 +0000486 MI.addOperand(MCOperand::createImm(simm13));
Venkatraman Govindarajuf7031322014-03-09 23:32:07 +0000487 else {
488 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
489 if (status != MCDisassembler::Success)
490 return status;
491 }
James Y Knight24060be2015-05-18 16:35:04 +0000492
493 if (hasAsi)
494 MI.addOperand(MCOperand::createImm(asi));
495
Venkatraman Govindarajuf7031322014-03-09 23:32:07 +0000496 return MCDisassembler::Success;
497}