[RISCV] Add RISCVInstPrinter and basic MC assembler tests

With the addition of RISCVInstPrinter, it is now possible to test the basic 
operation of the RISCV MC layer.

Differential Revision: https://reviews.llvm.org/D23564

llvm-svn: 310917
This commit is contained in:
Alex Bradbury 2017-08-15 13:08:29 +00:00
parent 1e23dd6315
commit 2fee9ead7e
11 changed files with 237 additions and 4 deletions

View File

@ -4,6 +4,7 @@ tablegen(LLVM RISCVGenRegisterInfo.inc -gen-register-info)
tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter)
tablegen(LLVM RISCVGenAsmMatcher.inc -gen-asm-matcher)
tablegen(LLVM RISCVGenAsmWriter.inc -gen-asm-writer)
add_public_tablegen_target(RISCVCommonTableGen)
@ -12,5 +13,6 @@ add_llvm_target(RISCVCodeGen
)
add_subdirectory(AsmParser)
add_subdirectory(TargetInfo)
add_subdirectory(InstPrinter)
add_subdirectory(MCTargetDesc)
add_subdirectory(TargetInfo)

View File

@ -0,0 +1,3 @@
add_llvm_library(LLVMRISCVAsmPrinter
RISCVInstPrinter.cpp
)

View File

@ -0,0 +1,23 @@
;===- ./lib/Target/RISCV/InstPrinter/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 = RISCVAsmPrinter
parent = RISCV
required_libraries = MC Support
add_to_library_groups = RISCV

View File

@ -0,0 +1,55 @@
//===-- RISCVInstPrinter.cpp - Convert RISCV MCInst to asm syntax ---------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class prints an RISCV MCInst to a .s file.
//
//===----------------------------------------------------------------------===//
#include "RISCVInstPrinter.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;
#define DEBUG_TYPE "asm-printer"
// Include the auto-generated portion of the assembly writer.
#include "RISCVGenAsmWriter.inc"
void RISCVInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
StringRef Annot, const MCSubtargetInfo &STI) {
printInstruction(MI, O);
printAnnotation(O, Annot);
}
void RISCVInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const {
O << getRegisterName(RegNo);
}
void RISCVInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O, const char *Modifier) {
assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
const MCOperand &MO = MI->getOperand(OpNo);
if (MO.isReg()) {
printRegName(O, MO.getReg());
return;
}
if (MO.isImm()) {
O << MO.getImm();
return;
}
assert(MO.isExpr() && "Unknown operand kind in printOperand");
MO.getExpr()->print(O, &MAI);
}

View File

@ -0,0 +1,43 @@
//===-- RISCVInstPrinter.h - Convert RISCV MCInst to asm syntax ---*- C++ -*--//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class prints a RISCV MCInst to a .s file.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_RISCV_INSTPRINTER_RISCVINSTPRINTER_H
#define LLVM_LIB_TARGET_RISCV_INSTPRINTER_RISCVINSTPRINTER_H
#include "MCTargetDesc/RISCVMCTargetDesc.h"
#include "llvm/MC/MCInstPrinter.h"
namespace llvm {
class MCOperand;
class RISCVInstPrinter : public MCInstPrinter {
public:
RISCVInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
const MCRegisterInfo &MRI)
: MCInstPrinter(MAI, MII, MRI) {}
void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot,
const MCSubtargetInfo &STI) override;
void printRegName(raw_ostream &O, unsigned RegNo) const override;
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
const char *Modifier = nullptr);
// Autogenerated by tblgen.
void printInstruction(const MCInst *MI, raw_ostream &O);
static const char *getRegisterName(unsigned RegNo,
unsigned AltIdx = RISCV::ABIRegAltName);
};
}
#endif

View File

@ -16,17 +16,18 @@
;===------------------------------------------------------------------------===;
[common]
subdirectories = AsmParser TargetInfo MCTargetDesc
subdirectories = AsmParser InstPrinter TargetInfo MCTargetDesc
[component_0]
type = TargetGroup
name = RISCV
parent = Target
has_asmparser = 1
has_asmprinter = 1
[component_1]
type = Library
name = RISCVCodeGen
parent = RISCV
required_libraries = Core CodeGen RISCVInfo Support Target
required_libraries = AsmPrinter Core CodeGen MC RISCVAsmPrinter RISCVDesc RISCVInfo Support Target
add_to_library_groups = RISCV

View File

@ -19,5 +19,5 @@
type = Library
name = RISCVDesc
parent = RISCV
required_libraries = MC RISCVInfo Support
required_libraries = MC RISCVAsmPrinter RISCVInfo Support
add_to_library_groups = RISCV

View File

@ -13,6 +13,7 @@
#include "RISCVMCTargetDesc.h"
#include "RISCVMCAsmInfo.h"
#include "InstPrinter/RISCVInstPrinter.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInstrInfo.h"
@ -47,6 +48,14 @@ static MCAsmInfo *createRISCVMCAsmInfo(const MCRegisterInfo &MRI,
return new RISCVMCAsmInfo(TT);
}
static MCInstPrinter *createRISCVMCInstPrinter(const Triple &T,
unsigned SyntaxVariant,
const MCAsmInfo &MAI,
const MCInstrInfo &MII,
const MCRegisterInfo &MRI) {
return new RISCVInstPrinter(MAI, MII, MRI);
}
extern "C" void LLVMInitializeRISCVTargetMC() {
for (Target *T : {&getTheRISCV32Target(), &getTheRISCV64Target()}) {
TargetRegistry::RegisterMCAsmInfo(*T, createRISCVMCAsmInfo);
@ -54,5 +63,6 @@ extern "C" void LLVMInitializeRISCVTargetMC() {
TargetRegistry::RegisterMCRegInfo(*T, createRISCVMCRegisterInfo);
TargetRegistry::RegisterMCAsmBackend(*T, createRISCVAsmBackend);
TargetRegistry::RegisterMCCodeEmitter(*T, createRISCVMCCodeEmitter);
TargetRegistry::RegisterMCInstPrinter(*T, createRISCVMCInstPrinter);
}
}

View File

@ -0,0 +1,3 @@
if not 'RISCV' in config.root.targets:
config.unsupported = True

View File

@ -0,0 +1,30 @@
# RUN: not llvm-mc -triple riscv32 < %s 2>&1 | FileCheck %s
# Out of range immediates
ori a0, a1, -2049 # CHECK: :[[@LINE]]:13: error: immediate must be an integer in the range [-2048, 2047]
andi ra, sp, 2048 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [-2048, 2047]
# Invalid mnemonics
subs t0, t2, t1 # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic
nandi t0, zero, 0 # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic
# Invalid register names
addi foo, sp, 10 # CHECK: :[[@LINE]]:6: error: unknown operand
slti a10, a2, 0x20 # CHECK: :[[@LINE]]:6: error: unknown operand
slt x32, s0, s0 # CHECK: :[[@LINE]]:5: error: unknown operand
# RV64I mnemonics
addiw a0, sp, 100 # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic
sraw t0, s2, zero # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic
# Invalid operand types
xori sp, 22, 220 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction
sub t0, t2, 1 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction
# Too many operands
add ra, zero, zero, zero # CHECK: :[[@LINE]]:21: error: invalid operand for instruction
sltiu s2, s3, 0x50, 0x60 # CHECK: :[[@LINE]]:21: error: invalid operand for instruction
# Too few operands
ori a0, a1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
xor s2, s2 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

View File

@ -0,0 +1,63 @@
# RUN: llvm-mc %s -triple=riscv32 -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
# RUN: llvm-mc %s -triple=riscv64 -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
# CHECK-INST: addi ra, sp, 2
# CHECK: encoding: [0x93,0x00,0x21,0x00]
addi ra, sp, 2
# CHECK-INST: slti a0, a2, -20
# CHECK: encoding: [0x13,0x25,0xc6,0xfe]
slti a0, a2, -20
# CHECK-INST: sltiu s2, s3, 80
# CHECK: encoding: [0x13,0xb9,0x09,0x05]
sltiu s2, s3, 0x50
# CHECK-INST: xori tp, t1, -99
# CHECK: encoding: [0x13,0x42,0xd3,0xf9]
xori tp, t1, -99
# CHECK-INST: ori a0, a1, -2048
# CHECK: encoding: [0x13,0xe5,0x05,0x80]
ori a0, a1, -2048
# CHECK-INST: andi ra, sp, 2047
# CHECK: encoding: [0x93,0x70,0xf1,0x7f]
andi ra, sp, 2047
# CHECK-INST: andi ra, sp, 2047
# CHECK: encoding: [0x93,0x70,0xf1,0x7f]
andi x1, x2, 2047
# CHECK-INST: add ra, zero, zero
# CHECK: encoding: [0xb3,0x00,0x00,0x00]
add ra, zero, zero
# CHECK-INST: add ra, zero, zero
# CHECK: encoding: [0xb3,0x00,0x00,0x00]
add x1, x0, x0
# CHECK-INST: sub t0, t2, t1
# CHECK: encoding: [0xb3,0x82,0x63,0x40]
sub t0, t2, t1
# CHECK-INST: sll a5, a4, a3
# CHECK: encoding: [0xb3,0x17,0xd7,0x00]
sll a5, a4, a3
# CHECK-INST: slt s0, s0, s0
# CHECK: encoding: [0x33,0x24,0x84,0x00]
slt s0, s0, s0
# CHECK-INST: sltu gp, a0, a1
# CHECK: encoding: [0xb3,0x31,0xb5,0x00]
sltu gp, a0, a1
# CHECK-INST: xor s2, s2, s8
# CHECK: encoding: [0x33,0x49,0x89,0x01]
xor s2, s2, s8
# CHECK-INST: xor s2, s2, s8
# CHECK: encoding: [0x33,0x49,0x89,0x01]
xor x18, x18, x24
# CHECK-INST: srl a0, s0, t0
# CHECK: encoding: [0x33,0x55,0x54,0x00]
srl a0, s0, t0
# CHECK-INST: sra t0, s2, zero
# CHECK: encoding: [0xb3,0x52,0x09,0x40]
sra t0, s2, zero
# CHECK-INST: or s10, t1, ra
# CHECK: encoding: [0x33,0x6d,0x13,0x00]
or s10, t1, ra
# CHECK-INST: and a0, s2, s3
# CHECK: encoding: [0x33,0x75,0x39,0x01]
and a0, s2, s3