Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This Disassembly support allows for 'round-trip' testing, and rv32i-valid.s has been updated appropriately. Differential Revision: https://reviews.llvm.org/D23567 llvm-svn: 313486
- Loading branch information
Showing
11 changed files
with
211 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
add_llvm_library(LLVMRISCVDisassembler | ||
RISCVDisassembler.cpp | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
;===- ./lib/Target/RISCV/Disassembler/LLVMBuild.txt ------------*- Conf -*--===; | ||
; | ||
; The LLVM Compiler Infrastructure | ||
; | ||
; This file is distributed under the University of Illinois Open Source | ||
; License. See LICENSE.TXT for details. | ||
; | ||
;===------------------------------------------------------------------------===; | ||
; | ||
; This is an LLVMBuild description file for the components in this subdirectory. | ||
; | ||
; For more information on the LLVMBuild system, please see: | ||
; | ||
; http://llvm.org/docs/LLVMBuild.html | ||
; | ||
;===------------------------------------------------------------------------===; | ||
|
||
[component_0] | ||
type = Library | ||
name = RISCVDisassembler | ||
parent = RISCV | ||
required_libraries = MCDisassembler RISCVInfo Support | ||
add_to_library_groups = RISCV | ||
|
135 changes: 135 additions & 0 deletions
135
llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
//===-- RISCVDisassembler.cpp - Disassembler for RISCV --------------------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file implements the RISCVDisassembler class. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "MCTargetDesc/RISCVMCTargetDesc.h" | ||
#include "llvm/MC/MCContext.h" | ||
#include "llvm/MC/MCDisassembler/MCDisassembler.h" | ||
#include "llvm/MC/MCFixedLenDisassembler.h" | ||
#include "llvm/MC/MCInst.h" | ||
#include "llvm/MC/MCRegisterInfo.h" | ||
#include "llvm/MC/MCSubtargetInfo.h" | ||
#include "llvm/Support/Endian.h" | ||
#include "llvm/Support/TargetRegistry.h" | ||
|
||
using namespace llvm; | ||
|
||
#define DEBUG_TYPE "riscv-disassembler" | ||
|
||
typedef MCDisassembler::DecodeStatus DecodeStatus; | ||
|
||
namespace { | ||
class RISCVDisassembler : public MCDisassembler { | ||
|
||
public: | ||
RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) | ||
: MCDisassembler(STI, Ctx) {} | ||
|
||
DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, | ||
ArrayRef<uint8_t> Bytes, uint64_t Address, | ||
raw_ostream &VStream, | ||
raw_ostream &CStream) const override; | ||
}; | ||
} // end anonymous namespace | ||
|
||
static MCDisassembler *createRISCVDisassembler(const Target &T, | ||
const MCSubtargetInfo &STI, | ||
MCContext &Ctx) { | ||
return new RISCVDisassembler(STI, Ctx); | ||
} | ||
|
||
extern "C" void LLVMInitializeRISCVDisassembler() { | ||
// Register the disassembler for each target. | ||
TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(), | ||
createRISCVDisassembler); | ||
TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(), | ||
createRISCVDisassembler); | ||
} | ||
|
||
static const unsigned GPRDecoderTable[] = { | ||
RISCV::X0_32, RISCV::X1_32, RISCV::X2_32, RISCV::X3_32, | ||
RISCV::X4_32, RISCV::X5_32, RISCV::X6_32, RISCV::X7_32, | ||
RISCV::X8_32, RISCV::X9_32, RISCV::X10_32, RISCV::X11_32, | ||
RISCV::X12_32, RISCV::X13_32, RISCV::X14_32, RISCV::X15_32, | ||
RISCV::X16_32, RISCV::X17_32, RISCV::X18_32, RISCV::X19_32, | ||
RISCV::X20_32, RISCV::X21_32, RISCV::X22_32, RISCV::X23_32, | ||
RISCV::X24_32, RISCV::X25_32, RISCV::X26_32, RISCV::X27_32, | ||
RISCV::X28_32, RISCV::X29_32, RISCV::X30_32, RISCV::X31_32 | ||
}; | ||
|
||
static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo, | ||
uint64_t Address, | ||
const void *Decoder) { | ||
if (RegNo > sizeof(GPRDecoderTable)) { | ||
return MCDisassembler::Fail; | ||
} | ||
|
||
// We must define our own mapping from RegNo to register identifier. | ||
// Accessing index RegNo in the register class will work in the case that | ||
// registers were added in ascending order, but not in general. | ||
unsigned Reg = GPRDecoderTable[RegNo]; | ||
Inst.addOperand(MCOperand::createReg(Reg)); | ||
return MCDisassembler::Success; | ||
} | ||
|
||
template <unsigned N> | ||
static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, | ||
int64_t Address, const void *Decoder) { | ||
assert(isUInt<N>(Imm) && "Invalid immediate"); | ||
Inst.addOperand(MCOperand::createImm(Imm)); | ||
return MCDisassembler::Success; | ||
} | ||
|
||
template <unsigned N> | ||
static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, | ||
int64_t Address, const void *Decoder) { | ||
assert(isUInt<N>(Imm) && "Invalid immediate"); | ||
// Sign-extend the number in the bottom N bits of Imm | ||
Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); | ||
return MCDisassembler::Success; | ||
} | ||
|
||
template <unsigned N> | ||
static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm, | ||
int64_t Address, | ||
const void *Decoder) { | ||
assert(isUInt<N>(Imm) && "Invalid immediate"); | ||
// Sign-extend the number in the bottom N bits of Imm after accounting for | ||
// the fact that the N bit immediate is stored in N-1 bits (the LSB is | ||
// always zero) | ||
Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1))); | ||
return MCDisassembler::Success; | ||
} | ||
|
||
#include "RISCVGenDisassemblerTables.inc" | ||
|
||
DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, | ||
ArrayRef<uint8_t> Bytes, | ||
uint64_t Address, | ||
raw_ostream &OS, | ||
raw_ostream &CS) const { | ||
// TODO: although assuming 4-byte instructions is sufficient for RV32 and | ||
// RV64, this will need modification when supporting the compressed | ||
// instruction set extension (RVC) which uses 16-bit instructions. Other | ||
// instruction set extensions have the option of defining instructions up to | ||
// 176 bits wide. | ||
Size = 4; | ||
if (Bytes.size() < 4) { | ||
Size = 0; | ||
return MCDisassembler::Fail; | ||
} | ||
|
||
// Get the four bytes of the instruction. | ||
uint32_t Inst = support::endian::read32le(Bytes.data()); | ||
|
||
return decodeInstruction(DecoderTable32, MI, Inst, Address, this, STI); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters