Skip to content

Commit 8971842

Browse files
committed
[RISCV] Initial codegen support for ALU operations
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 llvm-svn: 316188
1 parent f27d161 commit 8971842

24 files changed

+1103
-11
lines changed

llvm/lib/Target/RISCV/CMakeLists.txt

+11
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,25 @@ set(LLVM_TARGET_DEFINITIONS RISCV.td)
33
tablegen(LLVM RISCVGenRegisterInfo.inc -gen-register-info)
44
tablegen(LLVM RISCVGenInstrInfo.inc -gen-instr-info)
55
tablegen(LLVM RISCVGenMCCodeEmitter.inc -gen-emitter)
6+
tablegen(LLVM RISCVGenMCPseudoLowering.inc -gen-pseudo-lowering)
67
tablegen(LLVM RISCVGenAsmMatcher.inc -gen-asm-matcher)
78
tablegen(LLVM RISCVGenAsmWriter.inc -gen-asm-writer)
9+
tablegen(LLVM RISCVGenCallingConv.inc -gen-callingconv)
10+
tablegen(LLVM RISCVGenDAGISel.inc -gen-dag-isel)
811
tablegen(LLVM RISCVGenSubtargetInfo.inc -gen-subtarget)
912
tablegen(LLVM RISCVGenDisassemblerTables.inc -gen-disassembler)
1013

1114
add_public_tablegen_target(RISCVCommonTableGen)
1215

1316
add_llvm_target(RISCVCodeGen
17+
RISCVAsmPrinter.cpp
18+
RISCVFrameLowering.cpp
19+
RISCVInstrInfo.cpp
20+
RISCVISelDAGToDAG.cpp
21+
RISCVISelLowering.cpp
22+
RISCVMCInstLower.cpp
23+
RISCVRegisterInfo.cpp
24+
RISCVSubtarget.cpp
1425
RISCVTargetMachine.cpp
1526
)
1627

llvm/lib/Target/RISCV/LLVMBuild.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@ has_disassembler = 1
3030
type = Library
3131
name = RISCVCodeGen
3232
parent = RISCV
33-
required_libraries = AsmPrinter Core CodeGen MC RISCVAsmPrinter RISCVDesc RISCVInfo Support Target
33+
required_libraries = AsmPrinter Core CodeGen MC RISCVAsmPrinter RISCVDesc
34+
RISCVInfo SelectionDAG Support Target
3435
add_to_library_groups = RISCV

llvm/lib/Target/RISCV/RISCV.h

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//===-- RISCV.h - Top-level interface for RISCV -----------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This file contains the entry points for global functions defined in the LLVM
11+
// RISC-V back-end.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_LIB_TARGET_RISCV_RISCV_H
16+
#define LLVM_LIB_TARGET_RISCV_RISCV_H
17+
18+
#include "MCTargetDesc/RISCVMCTargetDesc.h"
19+
#include "llvm/Target/TargetMachine.h"
20+
21+
namespace llvm {
22+
class RISCVTargetMachine;
23+
class MCInst;
24+
class MachineInstr;
25+
26+
void LowerRISCVMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI);
27+
28+
FunctionPass *createRISCVISelDag(RISCVTargetMachine &TM);
29+
}
30+
31+
#endif

llvm/lib/Target/RISCV/RISCV.td

+5-2
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ def RV64 : HwMode<"+64bit">;
2020
def RV32 : HwMode<"-64bit">;
2121

2222
//===----------------------------------------------------------------------===//
23-
// Register file, instruction descriptions.
23+
// Registers, calling conventions, instruction descriptions.
2424
//===----------------------------------------------------------------------===//
2525

2626
include "RISCVRegisterInfo.td"
27+
include "RISCVCallingConv.td"
2728
include "RISCVInstrInfo.td"
2829

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

41-
def RISCVInstrInfo : InstrInfo;
42+
def RISCVInstrInfo : InstrInfo {
43+
let guessInstructionProperties = 0;
44+
}
4245

4346
def RISCVAsmParser : AsmParser {
4447
let ShouldEmitMatchRegisterAltName = 1;
+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//===-- RISCVAsmPrinter.cpp - RISCV LLVM assembly writer ------------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This file contains a printer that converts from our internal representation
11+
// of machine-dependent LLVM code to the RISCV assembly language.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#include "RISCV.h"
16+
#include "InstPrinter/RISCVInstPrinter.h"
17+
#include "RISCVTargetMachine.h"
18+
#include "llvm/CodeGen/AsmPrinter.h"
19+
#include "llvm/CodeGen/MachineConstantPool.h"
20+
#include "llvm/CodeGen/MachineFunctionPass.h"
21+
#include "llvm/CodeGen/MachineInstr.h"
22+
#include "llvm/CodeGen/MachineModuleInfo.h"
23+
#include "llvm/MC/MCAsmInfo.h"
24+
#include "llvm/MC/MCInst.h"
25+
#include "llvm/MC/MCStreamer.h"
26+
#include "llvm/MC/MCSymbol.h"
27+
#include "llvm/Support/TargetRegistry.h"
28+
#include "llvm/Support/raw_ostream.h"
29+
using namespace llvm;
30+
31+
#define DEBUG_TYPE "asm-printer"
32+
33+
namespace {
34+
class RISCVAsmPrinter : public AsmPrinter {
35+
public:
36+
explicit RISCVAsmPrinter(TargetMachine &TM,
37+
std::unique_ptr<MCStreamer> Streamer)
38+
: AsmPrinter(TM, std::move(Streamer)) {}
39+
40+
StringRef getPassName() const override { return "RISCV Assembly Printer"; }
41+
42+
void EmitInstruction(const MachineInstr *MI) override;
43+
44+
bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
45+
const MachineInstr *MI);
46+
};
47+
}
48+
49+
// Simple pseudo-instructions have their lowering (with expansion to real
50+
// instructions) auto-generated.
51+
#include "RISCVGenMCPseudoLowering.inc"
52+
53+
void RISCVAsmPrinter::EmitInstruction(const MachineInstr *MI) {
54+
// Do any auto-generated pseudo lowerings.
55+
if (emitPseudoExpansionLowering(*OutStreamer, MI))
56+
return;
57+
58+
MCInst TmpInst;
59+
LowerRISCVMachineInstrToMCInst(MI, TmpInst);
60+
EmitToStreamer(*OutStreamer, TmpInst);
61+
}
62+
63+
// Force static initialization.
64+
extern "C" void LLVMInitializeRISCVAsmPrinter() {
65+
RegisterAsmPrinter<RISCVAsmPrinter> X(getTheRISCV32Target());
66+
RegisterAsmPrinter<RISCVAsmPrinter> Y(getTheRISCV64Target());
67+
}
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===-- RISCVCallingConv.td - Calling Conventions RISCV ----*- tablegen -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This describes the calling conventions for the RISCV architecture.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
// RISCV 32-bit C return-value convention.
15+
def RetCC_RISCV32 : CallingConv<[CCIfType<[i32], CCAssignToReg<[X10, X11]>>]>;
16+
17+
// RISCV 32-bit C Calling convention.
18+
def CC_RISCV32 : CallingConv<[
19+
// Promote i8/i16 args to i32
20+
CCIfType<[ i8, i16 ], CCPromoteToType<i32>>,
21+
22+
// All arguments get passed in integer registers if there is space.
23+
CCIfType<[i32], CCAssignToReg<[ X10, X11, X12, X13, X14, X15, X16, X17]>>,
24+
25+
// Could be assigned to the stack in 8-byte aligned units, but unsupported
26+
CCAssignToStack<8, 8>
27+
]>;
28+
29+
def CSR : CalleeSavedRegs<(add X1, X3, X4, X8, X9, (sequence "X%u", 18, 27))>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===-- RISCVFrameLowering.cpp - RISCV Frame Information ------------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This file contains the RISCV implementation of TargetFrameLowering class.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "RISCVFrameLowering.h"
15+
#include "RISCVSubtarget.h"
16+
#include "llvm/CodeGen/MachineFrameInfo.h"
17+
#include "llvm/CodeGen/MachineFunction.h"
18+
#include "llvm/CodeGen/MachineInstrBuilder.h"
19+
#include "llvm/CodeGen/MachineRegisterInfo.h"
20+
21+
using namespace llvm;
22+
23+
bool RISCVFrameLowering::hasFP(const MachineFunction &MF) const { return true; }
24+
25+
void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
26+
MachineBasicBlock &MBB) const {}
27+
28+
void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
29+
MachineBasicBlock &MBB) const {}
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===-- RISCVFrameLowering.h - Define frame lowering for RISCV -*- C++ -*--===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This class implements RISCV-specific bits of TargetFrameLowering class.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_LIB_TARGET_RISCV_RISCVFRAMELOWERING_H
15+
#define LLVM_LIB_TARGET_RISCV_RISCVFRAMELOWERING_H
16+
17+
#include "llvm/Target/TargetFrameLowering.h"
18+
19+
namespace llvm {
20+
class RISCVSubtarget;
21+
22+
class RISCVFrameLowering : public TargetFrameLowering {
23+
public:
24+
explicit RISCVFrameLowering(const RISCVSubtarget &STI)
25+
: TargetFrameLowering(StackGrowsDown,
26+
/*StackAlignment=*/16,
27+
/*LocalAreaOffset=*/0) {}
28+
29+
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
30+
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
31+
32+
bool hasFP(const MachineFunction &MF) const override;
33+
};
34+
}
35+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//===-- RISCVISelDAGToDAG.cpp - A dag to dag inst selector for RISCV ------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This file defines an instruction selector for the RISCV target.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "RISCV.h"
15+
#include "MCTargetDesc/RISCVMCTargetDesc.h"
16+
#include "RISCVTargetMachine.h"
17+
#include "llvm/CodeGen/SelectionDAGISel.h"
18+
#include "llvm/Support/Debug.h"
19+
#include "llvm/Support/MathExtras.h"
20+
#include "llvm/Support/raw_ostream.h"
21+
using namespace llvm;
22+
23+
#define DEBUG_TYPE "riscv-isel"
24+
25+
// RISCV-specific code to select RISCV machine instructions for
26+
// SelectionDAG operations.
27+
namespace {
28+
class RISCVDAGToDAGISel final : public SelectionDAGISel {
29+
public:
30+
explicit RISCVDAGToDAGISel(RISCVTargetMachine &TargetMachine)
31+
: SelectionDAGISel(TargetMachine) {}
32+
33+
StringRef getPassName() const override {
34+
return "RISCV DAG->DAG Pattern Instruction Selection";
35+
}
36+
37+
void Select(SDNode *Node) override;
38+
39+
// Include the pieces autogenerated from the target description.
40+
#include "RISCVGenDAGISel.inc"
41+
};
42+
}
43+
44+
void RISCVDAGToDAGISel::Select(SDNode *Node) {
45+
// Dump information about the Node being selected.
46+
DEBUG(dbgs() << "Selecting: "; Node->dump(CurDAG); dbgs() << "\n");
47+
48+
// If we have a custom node, we have already selected
49+
if (Node->isMachineOpcode()) {
50+
DEBUG(dbgs() << "== "; Node->dump(CurDAG); dbgs() << "\n");
51+
Node->setNodeId(-1);
52+
return;
53+
}
54+
55+
// Select the default instruction.
56+
SelectCode(Node);
57+
}
58+
59+
// This pass converts a legalized DAG into a RISCV-specific DAG, ready
60+
// for instruction scheduling.
61+
FunctionPass *llvm::createRISCVISelDag(RISCVTargetMachine &TM) {
62+
return new RISCVDAGToDAGISel(TM);
63+
}

0 commit comments

Comments
 (0)