Skip to content

Commit

Permalink
[RISCV] Assemble/Disassemble v-ext instructions.
Browse files Browse the repository at this point in the history
Assemble/disassemble RISC-V V extension instructions according to
latest version spec in https://github.com/riscv/riscv-v-spec/.

I have tested this patch using GNU toolchain. The encoding is aligned
to GNU assembler output. In this patch, there is a test case for each
instruction at least.

The V register definition is just for assemble/disassemble. Its type
is not important in this stage. I think it will be reviewed and modified
as we want to do codegen for scalable vector types.

This patch does not include Zvamo, Zvlsseg, and Zvediv.

Differential revision: https://reviews.llvm.org/D69987
  • Loading branch information
Hsiangkai committed Jun 27, 2020
1 parent f063410 commit 66da87d
Show file tree
Hide file tree
Showing 51 changed files with 6,868 additions and 6 deletions.
305 changes: 304 additions & 1 deletion llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Large diffs are not rendered by default.

36 changes: 33 additions & 3 deletions llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCFixedLenDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Endian.h"
Expand All @@ -31,10 +32,12 @@ typedef MCDisassembler::DecodeStatus DecodeStatus;

namespace {
class RISCVDisassembler : public MCDisassembler {
std::unique_ptr<MCInstrInfo const> const MCII;

public:
RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
: MCDisassembler(STI, Ctx) {}
RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
MCInstrInfo const *MCII)
: MCDisassembler(STI, Ctx), MCII(MCII) {}

DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
ArrayRef<uint8_t> Bytes, uint64_t Address,
Expand All @@ -45,7 +48,7 @@ class RISCVDisassembler : public MCDisassembler {
static MCDisassembler *createRISCVDisassembler(const Target &T,
const MCSubtargetInfo &STI,
MCContext &Ctx) {
return new RISCVDisassembler(STI, Ctx);
return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());
}

extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler() {
Expand Down Expand Up @@ -148,6 +151,33 @@ static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
return MCDisassembler::Success;
}

static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder) {
if (RegNo >= 32)
return MCDisassembler::Fail;

Register Reg = RISCV::V0 + RegNo;
Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}

static DecodeStatus decodeVMaskReg(MCInst &Inst, uint64_t RegNo,
uint64_t Address, const void *Decoder) {
Register Reg = RISCV::NoRegister;
switch (RegNo) {
default:
return MCDisassembler::Fail;
case 0:
Reg = RISCV::V0;
break;
case 1:
break;
}
Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}

// Add implied SP operand for instructions *SP compressed instructions. The SP
// operand isn't explicitly encoded in the instruction.
static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) {
Expand Down
33 changes: 33 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,39 @@ void RISCVInstPrinter::printAtomicMemOp(const MCInst *MI, unsigned OpNo,
return;
}

void RISCVInstPrinter::printVTypeI(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O) {
unsigned Imm = MI->getOperand(OpNo).getImm();
unsigned Sew = (Imm >> 2) & 0x7;
unsigned Lmul = Imm & 0x3;

Lmul = 0x1 << Lmul;
Sew = 0x1 << (Sew + 3);
O << "e" << Sew << ",m" << Lmul;
}

void RISCVInstPrinter::printVMaskReg(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
const MCOperand &MO = MI->getOperand(OpNo);

assert(MO.isReg() && "printVMaskReg can only print register operands");
if (MO.getReg() == RISCV::NoRegister)
return;
O << ", ";
printRegName(O, MO.getReg());
O << ".t";
}

void RISCVInstPrinter::printSImm5Plus1(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
const MCOperand &MO = MI->getOperand(OpNo);

assert(MO.isImm() && "printSImm5Plus1 can only print constant operands");
O << MO.getImm() + 1;
}

const char *RISCVInstPrinter::getRegisterName(unsigned RegNo) {
return getRegisterName(RegNo, ArchRegNames ? RISCV::NoRegAltName
: RISCV::ABIRegAltName);
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ class RISCVInstPrinter : public MCInstPrinter {
raw_ostream &O);
void printAtomicMemOp(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printVTypeI(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
raw_ostream &O);
void printVMaskReg(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printSImm5Plus1(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);

// Autogenerated by tblgen.
void printInstruction(const MCInst *MI, uint64_t Address,
Expand Down
20 changes: 20 additions & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ class RISCVMCCodeEmitter : public MCCodeEmitter {
unsigned getImmOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;

unsigned getVMaskReg(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
};
} // end anonymous namespace

Expand Down Expand Up @@ -374,4 +378,20 @@ unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
return 0;
}

unsigned RISCVMCCodeEmitter::getVMaskReg(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
MCOperand MO = MI.getOperand(OpNo);
assert(MO.isReg() && "Expected a register.");

switch (MO.getReg()) {
default:
llvm_unreachable("Invalid mask register.");
case RISCV::V0:
return 0;
case RISCV::NoRegister:
return 1;
}
}

#include "RISCVGenMCCodeEmitter.inc"
8 changes: 8 additions & 0 deletions llvm/lib/Target/RISCV/RISCV.td
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,14 @@ def HasRVCHints : Predicate<"Subtarget->enableRVCHintInstrs()">,
AssemblerPredicate<(all_of FeatureRVCHints),
"RVC Hint Instructions">;

def FeatureStdExtV
: SubtargetFeature<"experimental-v", "HasStdExtV", "true",
"'V' (Vector Instructions)",
[FeatureStdExtF]>;
def HasStdExtV : Predicate<"Subtarget->hasStdExtV()">,
AssemblerPredicate<(all_of FeatureStdExtV),
"'V' (Vector Instructions)">;

def Feature64Bit
: SubtargetFeature<"64bit", "HasRV64", "true", "Implements RV64">;
def IsRV64 : Predicate<"Subtarget->is64Bit()">,
Expand Down
18 changes: 18 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,19 @@ def InstFormatCB : InstFormat<15>;
def InstFormatCJ : InstFormat<16>;
def InstFormatOther : InstFormat<17>;

class RISCVVConstraint<bits<4> val> {
bits<4> Value = val;
}
def NoConstraint : RISCVVConstraint<0>;
def WidenV : RISCVVConstraint<1>;
def WidenW : RISCVVConstraint<2>;
def WidenCvt : RISCVVConstraint<3>;
def Narrow : RISCVVConstraint<4>;
def Iota : RISCVVConstraint<5>;
def SlideUp : RISCVVConstraint<6>;
def Vrgather : RISCVVConstraint<7>;
def Vcompress : RISCVVConstraint<8>;

// The following opcode names match those given in Table 19.1 in the
// RISC-V User-level ISA specification ("RISC-V base opcode map").
class RISCVOpcode<bits<7> val> {
Expand All @@ -71,6 +84,7 @@ def OPC_MSUB : RISCVOpcode<0b1000111>;
def OPC_NMSUB : RISCVOpcode<0b1001011>;
def OPC_NMADD : RISCVOpcode<0b1001111>;
def OPC_OP_FP : RISCVOpcode<0b1010011>;
def OPC_OP_V : RISCVOpcode<0b1010111>;
def OPC_BRANCH : RISCVOpcode<0b1100011>;
def OPC_JALR : RISCVOpcode<0b1100111>;
def OPC_JAL : RISCVOpcode<0b1101111>;
Expand Down Expand Up @@ -99,6 +113,10 @@ class RVInst<dag outs, dag ins, string opcodestr, string argstr,
let Pattern = pattern;

let TSFlags{4-0} = format.Value;

// Defaults
RISCVVConstraint RVVConstraint = NoConstraint;
let TSFlags{8-5} = RVVConstraint.Value;
}

// Pseudo instructions
Expand Down
Loading

0 comments on commit 66da87d

Please sign in to comment.