[AMDGPU] Check for immediate SrcC in mfma in AsmParser
[llvm-core.git] / lib / Target / Lanai / Disassembler / LanaiDisassembler.cpp
blob25ae7c521706a3cbdcc2060e72c8106b7c1be8a6
1 //===- LanaiDisassembler.cpp - Disassembler for Lanai -----------*- 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 Lanai Disassembler.
11 //===----------------------------------------------------------------------===//
13 #include "LanaiDisassembler.h"
15 #include "LanaiAluCode.h"
16 #include "LanaiCondCode.h"
17 #include "LanaiInstrInfo.h"
18 #include "TargetInfo/LanaiTargetInfo.h"
19 #include "llvm/MC/MCFixedLenDisassembler.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCSubtargetInfo.h"
22 #include "llvm/Support/MathExtras.h"
23 #include "llvm/Support/TargetRegistry.h"
25 using namespace llvm;
27 typedef MCDisassembler::DecodeStatus DecodeStatus;
29 namespace llvm {
30 Target &getTheLanaiTarget();
33 static MCDisassembler *createLanaiDisassembler(const Target & /*T*/,
34 const MCSubtargetInfo &STI,
35 MCContext &Ctx) {
36 return new LanaiDisassembler(STI, Ctx);
39 extern "C" void LLVMInitializeLanaiDisassembler() {
40 // Register the disassembler
41 TargetRegistry::RegisterMCDisassembler(getTheLanaiTarget(),
42 createLanaiDisassembler);
45 LanaiDisassembler::LanaiDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
46 : MCDisassembler(STI, Ctx) {}
48 // Forward declare because the autogenerated code will reference this.
49 // Definition is further down.
50 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
51 uint64_t Address,
52 const void *Decoder);
54 static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn,
55 uint64_t Address, const void *Decoder);
57 static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn,
58 uint64_t Address, const void *Decoder);
60 static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn,
61 uint64_t Address, const void *Decoder);
63 static DecodeStatus decodeBranch(MCInst &Inst, unsigned Insn, uint64_t Address,
64 const void *Decoder);
66 static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,
67 uint64_t Address,
68 const void *Decoder);
70 static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,
71 uint64_t Address, const void *Decoder);
73 #include "LanaiGenDisassemblerTables.inc"
75 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t &Size,
76 uint32_t &Insn) {
77 // We want to read exactly 4 bytes of data.
78 if (Bytes.size() < 4) {
79 Size = 0;
80 return MCDisassembler::Fail;
83 // Encoded as big-endian 32-bit word in the stream.
84 Insn =
85 (Bytes[0] << 24) | (Bytes[1] << 16) | (Bytes[2] << 8) | (Bytes[3] << 0);
87 return MCDisassembler::Success;
90 static void PostOperandDecodeAdjust(MCInst &Instr, uint32_t Insn) {
91 unsigned AluOp = LPAC::ADD;
92 // Fix up for pre and post operations.
93 int PqShift = -1;
94 if (isRMOpcode(Instr.getOpcode()))
95 PqShift = 16;
96 else if (isSPLSOpcode(Instr.getOpcode()))
97 PqShift = 10;
98 else if (isRRMOpcode(Instr.getOpcode())) {
99 PqShift = 16;
100 // Determine RRM ALU op.
101 AluOp = (Insn >> 8) & 0x7;
102 if (AluOp == 7)
103 // Handle JJJJJ
104 // 0b10000 or 0b11000
105 AluOp |= 0x20 | (((Insn >> 3) & 0xf) << 1);
108 if (PqShift != -1) {
109 unsigned PQ = (Insn >> PqShift) & 0x3;
110 switch (PQ) {
111 case 0x0:
112 if (Instr.getOperand(2).isReg()) {
113 Instr.getOperand(2).setReg(Lanai::R0);
115 if (Instr.getOperand(2).isImm())
116 Instr.getOperand(2).setImm(0);
117 break;
118 case 0x1:
119 AluOp = LPAC::makePostOp(AluOp);
120 break;
121 case 0x2:
122 break;
123 case 0x3:
124 AluOp = LPAC::makePreOp(AluOp);
125 break;
127 Instr.addOperand(MCOperand::createImm(AluOp));
131 DecodeStatus LanaiDisassembler::getInstruction(
132 MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address,
133 raw_ostream & /*VStream*/, raw_ostream & /*CStream*/) const {
134 uint32_t Insn;
136 DecodeStatus Result = readInstruction32(Bytes, Size, Insn);
138 if (Result == MCDisassembler::Fail)
139 return MCDisassembler::Fail;
141 // Call auto-generated decoder function
142 Result =
143 decodeInstruction(DecoderTableLanai32, Instr, Insn, Address, this, STI);
145 if (Result != MCDisassembler::Fail) {
146 PostOperandDecodeAdjust(Instr, Insn);
147 Size = 4;
148 return Result;
151 return MCDisassembler::Fail;
154 static const unsigned GPRDecoderTable[] = {
155 Lanai::R0, Lanai::R1, Lanai::PC, Lanai::R3, Lanai::SP, Lanai::FP,
156 Lanai::R6, Lanai::R7, Lanai::RV, Lanai::R9, Lanai::RR1, Lanai::RR2,
157 Lanai::R12, Lanai::R13, Lanai::R14, Lanai::RCA, Lanai::R16, Lanai::R17,
158 Lanai::R18, Lanai::R19, Lanai::R20, Lanai::R21, Lanai::R22, Lanai::R23,
159 Lanai::R24, Lanai::R25, Lanai::R26, Lanai::R27, Lanai::R28, Lanai::R29,
160 Lanai::R30, Lanai::R31};
162 DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
163 uint64_t /*Address*/,
164 const void * /*Decoder*/) {
165 if (RegNo > 31)
166 return MCDisassembler::Fail;
168 unsigned Reg = GPRDecoderTable[RegNo];
169 Inst.addOperand(MCOperand::createReg(Reg));
170 return MCDisassembler::Success;
173 static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn,
174 uint64_t Address, const void *Decoder) {
175 // RI memory values encoded using 23 bits:
176 // 5 bit register, 16 bit constant
177 unsigned Register = (Insn >> 18) & 0x1f;
178 Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
179 unsigned Offset = (Insn & 0xffff);
180 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
182 return MCDisassembler::Success;
185 static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn,
186 uint64_t Address, const void *Decoder) {
187 // RR memory values encoded using 20 bits:
188 // 5 bit register, 5 bit register, 2 bit PQ, 3 bit ALU operator, 5 bit JJJJJ
189 unsigned Register = (Insn >> 15) & 0x1f;
190 Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
191 Register = (Insn >> 10) & 0x1f;
192 Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
194 return MCDisassembler::Success;
197 static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn,
198 uint64_t Address, const void *Decoder) {
199 // RI memory values encoded using 17 bits:
200 // 5 bit register, 10 bit constant
201 unsigned Register = (Insn >> 12) & 0x1f;
202 Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
203 unsigned Offset = (Insn & 0x3ff);
204 Inst.addOperand(MCOperand::createImm(SignExtend32<10>(Offset)));
206 return MCDisassembler::Success;
209 static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch,
210 uint64_t Address, uint64_t Offset,
211 uint64_t Width, MCInst &MI,
212 const void *Decoder) {
213 const MCDisassembler *Dis = static_cast<const MCDisassembler *>(Decoder);
214 return Dis->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset,
215 Width);
218 static DecodeStatus decodeBranch(MCInst &MI, unsigned Insn, uint64_t Address,
219 const void *Decoder) {
220 if (!tryAddingSymbolicOperand(Insn + Address, false, Address, 2, 23, MI,
221 Decoder))
222 MI.addOperand(MCOperand::createImm(Insn));
223 return MCDisassembler::Success;
226 static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,
227 uint64_t Address, const void *Decoder) {
228 unsigned Offset = (Insn & 0xffff);
229 Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
231 return MCDisassembler::Success;
234 static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,
235 uint64_t Address,
236 const void *Decoder) {
237 if (Val >= LPCC::UNKNOWN)
238 return MCDisassembler::Fail;
239 Inst.addOperand(MCOperand::createImm(Val));
240 return MCDisassembler::Success;