Path: blob/main/contrib/llvm-project/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp
35295 views
//===- LanaiDisassembler.cpp - Disassembler for Lanai -----------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is part of the Lanai Disassembler.9//10//===----------------------------------------------------------------------===//1112#include "LanaiDisassembler.h"1314#include "LanaiAluCode.h"15#include "LanaiCondCode.h"16#include "LanaiInstrInfo.h"17#include "TargetInfo/LanaiTargetInfo.h"18#include "llvm/MC/MCDecoderOps.h"19#include "llvm/MC/MCInst.h"20#include "llvm/MC/MCSubtargetInfo.h"21#include "llvm/MC/TargetRegistry.h"22#include "llvm/Support/MathExtras.h"2324using namespace llvm;2526typedef MCDisassembler::DecodeStatus DecodeStatus;2728static MCDisassembler *createLanaiDisassembler(const Target & /*T*/,29const MCSubtargetInfo &STI,30MCContext &Ctx) {31return new LanaiDisassembler(STI, Ctx);32}3334extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLanaiDisassembler() {35// Register the disassembler36TargetRegistry::RegisterMCDisassembler(getTheLanaiTarget(),37createLanaiDisassembler);38}3940LanaiDisassembler::LanaiDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)41: MCDisassembler(STI, Ctx) {}4243// Forward declare because the autogenerated code will reference this.44// Definition is further down.45static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,46uint64_t Address,47const MCDisassembler *Decoder);4849static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn,50uint64_t Address,51const MCDisassembler *Decoder);5253static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn,54uint64_t Address,55const MCDisassembler *Decoder);5657static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn,58uint64_t Address,59const MCDisassembler *Decoder);6061static DecodeStatus decodeBranch(MCInst &Inst, unsigned Insn, uint64_t Address,62const MCDisassembler *Decoder);6364static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,65uint64_t Address,66const MCDisassembler *Decoder);6768static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,69uint64_t Address,70const MCDisassembler *Decoder);7172#include "LanaiGenDisassemblerTables.inc"7374static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t &Size,75uint32_t &Insn) {76// We want to read exactly 4 bytes of data.77if (Bytes.size() < 4) {78Size = 0;79return MCDisassembler::Fail;80}8182// Encoded as big-endian 32-bit word in the stream.83Insn =84(Bytes[0] << 24) | (Bytes[1] << 16) | (Bytes[2] << 8) | (Bytes[3] << 0);8586return MCDisassembler::Success;87}8889static void PostOperandDecodeAdjust(MCInst &Instr, uint32_t Insn) {90unsigned AluOp = LPAC::ADD;91// Fix up for pre and post operations.92int PqShift = -1;93if (isRMOpcode(Instr.getOpcode()))94PqShift = 16;95else if (isSPLSOpcode(Instr.getOpcode()))96PqShift = 10;97else if (isRRMOpcode(Instr.getOpcode())) {98PqShift = 16;99// Determine RRM ALU op.100AluOp = (Insn >> 8) & 0x7;101if (AluOp == 7)102// Handle JJJJJ103// 0b10000 or 0b11000104AluOp |= 0x20 | (((Insn >> 3) & 0xf) << 1);105}106107if (PqShift != -1) {108unsigned PQ = (Insn >> PqShift) & 0x3;109switch (PQ) {110case 0x0:111if (Instr.getOperand(2).isReg()) {112Instr.getOperand(2).setReg(Lanai::R0);113}114if (Instr.getOperand(2).isImm())115Instr.getOperand(2).setImm(0);116break;117case 0x1:118AluOp = LPAC::makePostOp(AluOp);119break;120case 0x2:121break;122case 0x3:123AluOp = LPAC::makePreOp(AluOp);124break;125}126Instr.addOperand(MCOperand::createImm(AluOp));127}128}129130DecodeStatus131LanaiDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,132ArrayRef<uint8_t> Bytes, uint64_t Address,133raw_ostream & /*CStream*/) const {134uint32_t Insn;135136DecodeStatus Result = readInstruction32(Bytes, Size, Insn);137138if (Result == MCDisassembler::Fail)139return MCDisassembler::Fail;140141// Call auto-generated decoder function142Result =143decodeInstruction(DecoderTableLanai32, Instr, Insn, Address, this, STI);144145if (Result != MCDisassembler::Fail) {146PostOperandDecodeAdjust(Instr, Insn);147Size = 4;148return Result;149}150151return MCDisassembler::Fail;152}153154static const unsigned GPRDecoderTable[] = {155Lanai::R0, Lanai::R1, Lanai::PC, Lanai::R3, Lanai::SP, Lanai::FP,156Lanai::R6, Lanai::R7, Lanai::RV, Lanai::R9, Lanai::RR1, Lanai::RR2,157Lanai::R12, Lanai::R13, Lanai::R14, Lanai::RCA, Lanai::R16, Lanai::R17,158Lanai::R18, Lanai::R19, Lanai::R20, Lanai::R21, Lanai::R22, Lanai::R23,159Lanai::R24, Lanai::R25, Lanai::R26, Lanai::R27, Lanai::R28, Lanai::R29,160Lanai::R30, Lanai::R31};161162DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,163uint64_t /*Address*/,164const MCDisassembler * /*Decoder*/) {165if (RegNo > 31)166return MCDisassembler::Fail;167168unsigned Reg = GPRDecoderTable[RegNo];169Inst.addOperand(MCOperand::createReg(Reg));170return MCDisassembler::Success;171}172173static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn,174uint64_t Address,175const MCDisassembler *Decoder) {176// RI memory values encoded using 23 bits:177// 5 bit register, 16 bit constant178unsigned Register = (Insn >> 18) & 0x1f;179Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));180unsigned Offset = (Insn & 0xffff);181Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));182183return MCDisassembler::Success;184}185186static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn,187uint64_t Address,188const MCDisassembler *Decoder) {189// RR memory values encoded using 20 bits:190// 5 bit register, 5 bit register, 2 bit PQ, 3 bit ALU operator, 5 bit JJJJJ191unsigned Register = (Insn >> 15) & 0x1f;192Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));193Register = (Insn >> 10) & 0x1f;194Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));195196return MCDisassembler::Success;197}198199static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn,200uint64_t Address,201const MCDisassembler *Decoder) {202// RI memory values encoded using 17 bits:203// 5 bit register, 10 bit constant204unsigned Register = (Insn >> 12) & 0x1f;205Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));206unsigned Offset = (Insn & 0x3ff);207Inst.addOperand(MCOperand::createImm(SignExtend32<10>(Offset)));208209return MCDisassembler::Success;210}211212static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch,213uint64_t Address, uint64_t Offset,214uint64_t Width, MCInst &MI,215const MCDisassembler *Decoder) {216return Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset,217Width, /*InstSize=*/0);218}219220static DecodeStatus decodeBranch(MCInst &MI, unsigned Insn, uint64_t Address,221const MCDisassembler *Decoder) {222if (!tryAddingSymbolicOperand(Insn + Address, false, Address, 2, 23, MI,223Decoder))224MI.addOperand(MCOperand::createImm(Insn));225return MCDisassembler::Success;226}227228static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,229uint64_t Address,230const MCDisassembler *Decoder) {231unsigned Offset = (Insn & 0xffff);232Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));233234return MCDisassembler::Success;235}236237static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,238uint64_t Address,239const MCDisassembler *Decoder) {240if (Val >= LPCC::UNKNOWN)241return MCDisassembler::Fail;242Inst.addOperand(MCOperand::createImm(Val));243return MCDisassembler::Success;244}245246247