Skip to content

Commit

Permalink
[RISCV] Initial codegen support for ALU operations
Browse files Browse the repository at this point in the history
This adds the minimum necessary to support codegen for simple ALU operations
on RV32. Prolog and epilog insertion, support for memory operations etc etc 
follow in future patches.

Leave guessInstructionProperties=1 until https://reviews.llvm.org/D37065 is 
reviewed and lands.

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


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316188 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
asb committed Oct 19, 2017
1 parent ab16d0a commit 5a3d179
Show file tree
Hide file tree
Showing 24 changed files with 1,103 additions and 11 deletions.
11 changes: 11 additions & 0 deletions lib/Target/RISCV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,25 @@ set(LLVM_TARGET_DEFINITIONS RISCV.td)
tablegen(LLVM RISCVGenRegisterInfo.inc -gen-register-info)
tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter)
tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering)
tablegen(LLVM RISCVGenAsmMatcher.inc -gen-asm-matcher)
tablegen(LLVM RISCVGenAsmWriter.inc -gen-asm-writer)
tablegen(LLVM RISCVGenCallingConv.inc -gen-callingconv)
tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM RISCVGenSubtargetInfo.inc -gen-subtarget)
tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler)

add_public_tablegen_target(RISCVCommonTableGen)

add_llvm_target(RISCVCodeGen
RISCVAsmPrinter.cpp
RISCVFrameLowering.cpp
RISCVInstrInfo.cpp
RISCVISelDAGToDAG.cpp
RISCVISelLowering.cpp
RISCVMCInstLower.cpp
RISCVRegisterInfo.cpp
RISCVSubtarget.cpp
RISCVTargetMachine.cpp
)

Expand Down
3 changes: 2 additions & 1 deletion lib/Target/RISCV/LLVMBuild.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ has_disassembler = 1
type = Library
name = RISCVCodeGen
parent = RISCV
required_libraries = AsmPrinter Core CodeGen MC RISCVAsmPrinter RISCVDesc RISCVInfo Support Target
required_libraries = AsmPrinter Core CodeGen MC RISCVAsmPrinter RISCVDesc
RISCVInfo SelectionDAG Support Target
add_to_library_groups = RISCV
31 changes: 31 additions & 0 deletions lib/Target/RISCV/RISCV.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===-- RISCV.h - Top-level interface for RISCV -----------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the entry points for global functions defined in the LLVM
// RISC-V back-end.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_RISCV_RISCV_H
#define LLVM_LIB_TARGET_RISCV_RISCV_H

#include "MCTargetDesc/RISCVMCTargetDesc.h"
#include "llvm/Target/TargetMachine.h"

namespace llvm {
class RISCVTargetMachine;
class MCInst;
class MachineInstr;

void LowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI);

FunctionPass *createRISCVISelDag(RISCVTargetMachine &TM);
}

#endif
7 changes: 5 additions & 2 deletions lib/Target/RISCV/RISCV.td
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ def RV64 : HwMode<"+64bit">;
def RV32 : HwMode<"-64bit">;

//===----------------------------------------------------------------------===//
// Register file, instruction descriptions.
// Registers, calling conventions, instruction descriptions.
//===----------------------------------------------------------------------===//

include "RISCVRegisterInfo.td"
include "RISCVCallingConv.td"
include "RISCVInstrInfo.td"

//===----------------------------------------------------------------------===//
Expand All @@ -38,7 +39,9 @@ def : ProcessorModel<"generic-rv64", NoSchedModel, [Feature64Bit]>;
// Define the RISC-V target.
//===----------------------------------------------------------------------===//

def RISCVInstrInfo : InstrInfo;
def RISCVInstrInfo : InstrInfo {
let guessInstructionProperties = 0;
}

def RISCVAsmParser : AsmParser {
let ShouldEmitMatchRegisterAltName = 1;
Expand Down
67 changes: 67 additions & 0 deletions lib/Target/RISCV/RISCVAsmPrinter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//===-- RISCVAsmPrinter.cpp - RISCV LLVM assembly writer ------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
// of machine-dependent LLVM code to the RISCV assembly language.
//
//===----------------------------------------------------------------------===//

#include "RISCV.h"
#include "InstPrinter/RISCVInstPrinter.h"
#include "RISCVTargetMachine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "asm-printer"

namespace {
class RISCVAsmPrinter : public AsmPrinter {
public:
explicit RISCVAsmPrinter(TargetMachine &TM,
std::unique_ptr<MCStreamer> Streamer)
: AsmPrinter(TM, std::move(Streamer)) {}

StringRef getPassName() const override { return "RISCV Assembly Printer"; }

void EmitInstruction(const MachineInstr *MI) override;

bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
const MachineInstr *MI);
};
}

// Simple pseudo-instructions have their lowering (with expansion to real
// instructions) auto-generated.
#include "RISCVGenMCPseudoLowering.inc"

void RISCVAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// Do any auto-generated pseudo lowerings.
if (emitPseudoExpansionLowering(*OutStreamer, MI))
return;

MCInst TmpInst;
LowerRISCVMachineInstrToMCInst(MI, TmpInst);
EmitToStreamer(*OutStreamer, TmpInst);
}

// Force static initialization.
extern "C" void LLVMInitializeRISCVAsmPrinter() {
RegisterAsmPrinter<RISCVAsmPrinter> X(getTheRISCV32Target());
RegisterAsmPrinter<RISCVAsmPrinter> Y(getTheRISCV64Target());
}
29 changes: 29 additions & 0 deletions lib/Target/RISCV/RISCVCallingConv.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===-- RISCVCallingConv.td - Calling Conventions RISCV ----*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This describes the calling conventions for the RISCV architecture.
//
//===----------------------------------------------------------------------===//

// RISCV 32-bit C return-value convention.
def RetCC_RISCV32 : CallingConv<[CCIfType<[i32], CCAssignToReg<[X10, X11]>>]>;

// RISCV 32-bit C Calling convention.
def CC_RISCV32 : CallingConv<[
// Promote i8/i16 args to i32
CCIfType<[ i8, i16 ], CCPromoteToType<i32>>,

// All arguments get passed in integer registers if there is space.
CCIfType<[i32], CCAssignToReg<[ X10, X11, X12, X13, X14, X15, X16, X17]>>,

// Could be assigned to the stack in 8-byte aligned units, but unsupported
CCAssignToStack<8, 8>
]>;

def CSR : CalleeSavedRegs<(add X1, X3, X4, X8, X9, (sequence "X%u", 18, 27))>;
29 changes: 29 additions & 0 deletions lib/Target/RISCV/RISCVFrameLowering.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===-- RISCVFrameLowering.cpp - RISCV Frame Information ------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the RISCV implementation of TargetFrameLowering class.
//
//===----------------------------------------------------------------------===//

#include "RISCVFrameLowering.h"
#include "RISCVSubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"

using namespace llvm;

bool RISCVFrameLowering::hasFP(const MachineFunction &MF) const { return true; }

void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {}

void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {}
35 changes: 35 additions & 0 deletions lib/Target/RISCV/RISCVFrameLowering.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//===-- RISCVFrameLowering.h - Define frame lowering for RISCV -*- C++ -*--===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class implements RISCV-specific bits of TargetFrameLowering class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_RISCV_RISCVFRAMELOWERING_H
#define LLVM_LIB_TARGET_RISCV_RISCVFRAMELOWERING_H

#include "llvm/Target/TargetFrameLowering.h"

namespace llvm {
class RISCVSubtarget;

class RISCVFrameLowering : public TargetFrameLowering {
public:
explicit RISCVFrameLowering(const RISCVSubtarget &STI)
: TargetFrameLowering(StackGrowsDown,
/*StackAlignment=*/16,
/*LocalAreaOffset=*/0) {}

void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;

bool hasFP(const MachineFunction &MF) const override;
};
}
#endif
63 changes: 63 additions & 0 deletions lib/Target/RISCV/RISCVISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//===-- RISCVISelDAGToDAG.cpp - A dag to dag inst selector 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 defines an instruction selector for the RISCV target.
//
//===----------------------------------------------------------------------===//

#include "RISCV.h"
#include "MCTargetDesc/RISCVMCTargetDesc.h"
#include "RISCVTargetMachine.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "riscv-isel"

// RISCV-specific code to select RISCV machine instructions for
// SelectionDAG operations.
namespace {
class RISCVDAGToDAGISel final : public SelectionDAGISel {
public:
explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine)
: SelectionDAGISel(TargetMachine) {}

StringRef getPassName() const override {
return "RISCV DAG->DAG Pattern Instruction Selection";
}

void Select(SDNode *Node) override;

// Include the pieces autogenerated from the target description.
#include "RISCVGenDAGISel.inc"
};
}

void RISCVDAGToDAGISel::Select(SDNode *Node) {
// Dump information about the Node being selected.
DEBUG(dbgs() << "Selecting: "; Node->dump(CurDAG); dbgs() << "\n");

// If we have a custom node, we have already selected
if (Node->isMachineOpcode()) {
DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n");
Node->setNodeId(-1);
return;
}

// Select the default instruction.
SelectCode(Node);
}

// This pass converts a legalized DAG into a RISCV-specific DAG, ready
// for instruction scheduling.
FunctionPass *llvm::createRISCVISelDag(RISCVTargetMachine &TM) {
return new RISCVDAGToDAGISel(TM);
}
Loading

0 comments on commit 5a3d179

Please sign in to comment.