[llvm] r316188 - [RISCV] Initial codegen support for ALU operations

Alex Bradbury via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 19 14:37:38 PDT 2017


Author: asb
Date: Thu Oct 19 14:37:38 2017
New Revision: 316188

URL: http://llvm.org/viewvc/llvm-project?rev=316188&view=rev
Log:
[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

Added:
    llvm/trunk/lib/Target/RISCV/RISCV.h
    llvm/trunk/lib/Target/RISCV/RISCVAsmPrinter.cpp
    llvm/trunk/lib/Target/RISCV/RISCVCallingConv.td
    llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp
    llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.h
    llvm/trunk/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
    llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/trunk/lib/Target/RISCV/RISCVISelLowering.h
    llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.cpp
    llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.h
    llvm/trunk/lib/Target/RISCV/RISCVMCInstLower.cpp
    llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.cpp
    llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.h
    llvm/trunk/lib/Target/RISCV/RISCVSubtarget.cpp
    llvm/trunk/lib/Target/RISCV/RISCVSubtarget.h
    llvm/trunk/test/CodeGen/RISCV/
    llvm/trunk/test/CodeGen/RISCV/alu32.ll
    llvm/trunk/test/CodeGen/RISCV/lit.local.cfg
Modified:
    llvm/trunk/lib/Target/RISCV/CMakeLists.txt
    llvm/trunk/lib/Target/RISCV/LLVMBuild.txt
    llvm/trunk/lib/Target/RISCV/RISCV.td
    llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td
    llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td
    llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.cpp
    llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.h

Modified: llvm/trunk/lib/Target/RISCV/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/CMakeLists.txt?rev=316188&r1=316187&r2=316188&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/CMakeLists.txt (original)
+++ llvm/trunk/lib/Target/RISCV/CMakeLists.txt Thu Oct 19 14:37:38 2017
@@ -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
   )
 

Modified: llvm/trunk/lib/Target/RISCV/LLVMBuild.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/LLVMBuild.txt?rev=316188&r1=316187&r2=316188&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/LLVMBuild.txt (original)
+++ llvm/trunk/lib/Target/RISCV/LLVMBuild.txt Thu Oct 19 14:37:38 2017
@@ -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

Added: llvm/trunk/lib/Target/RISCV/RISCV.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCV.h?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCV.h (added)
+++ llvm/trunk/lib/Target/RISCV/RISCV.h Thu Oct 19 14:37:38 2017
@@ -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

Modified: llvm/trunk/lib/Target/RISCV/RISCV.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCV.td?rev=316188&r1=316187&r2=316188&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCV.td (original)
+++ llvm/trunk/lib/Target/RISCV/RISCV.td Thu Oct 19 14:37:38 2017
@@ -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"
 
 //===----------------------------------------------------------------------===//
@@ -38,7 +39,9 @@ def : ProcessorModel<"generic-rv64", NoS
 // Define the RISC-V target.
 //===----------------------------------------------------------------------===//
 
-def RISCVInstrInfo : InstrInfo;
+def RISCVInstrInfo : InstrInfo {
+  let guessInstructionProperties = 0;
+}
 
 def RISCVAsmParser : AsmParser {
   let ShouldEmitMatchRegisterAltName = 1;

Added: llvm/trunk/lib/Target/RISCV/RISCVAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVAsmPrinter.cpp?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVAsmPrinter.cpp (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVAsmPrinter.cpp Thu Oct 19 14:37:38 2017
@@ -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());
+}

Added: llvm/trunk/lib/Target/RISCV/RISCVCallingConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVCallingConv.td?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVCallingConv.td (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVCallingConv.td Thu Oct 19 14:37:38 2017
@@ -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))>;

Added: llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.cpp Thu Oct 19 14:37:38 2017
@@ -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 {}

Added: llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.h?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.h (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVFrameLowering.h Thu Oct 19 14:37:38 2017
@@ -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

Added: llvm/trunk/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVISelDAGToDAG.cpp?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVISelDAGToDAG.cpp (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVISelDAGToDAG.cpp Thu Oct 19 14:37:38 2017
@@ -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);
+}

Added: llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVISelLowering.cpp Thu Oct 19 14:37:38 2017
@@ -0,0 +1,170 @@
+//===-- RISCVISelLowering.cpp - RISCV DAG Lowering Implementation  --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interfaces that RISCV uses to lower LLVM code into a
+// selection DAG.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCVISelLowering.h"
+#include "RISCV.h"
+#include "RISCVRegisterInfo.h"
+#include "RISCVSubtarget.h"
+#include "RISCVTargetMachine.h"
+#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "riscv-lower"
+
+RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
+                                         const RISCVSubtarget &STI)
+    : TargetLowering(TM), Subtarget(STI) {
+
+  MVT XLenVT = Subtarget.getXLenVT();
+
+  // Set up the register classes.
+  addRegisterClass(XLenVT, &RISCV::GPRRegClass);
+
+  // Compute derived properties from the register classes.
+  computeRegisterProperties(STI.getRegisterInfo());
+
+  setStackPointerRegisterToSaveRestore(RISCV::X2);
+
+  // TODO: add all necessary setOperationAction calls.
+
+  setBooleanContents(ZeroOrOneBooleanContent);
+
+  // Function alignments (log2).
+  setMinFunctionAlignment(3);
+  setPrefFunctionAlignment(3);
+}
+
+SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
+                                            SelectionDAG &DAG) const {
+  switch (Op.getOpcode()) {
+  default:
+    report_fatal_error("unimplemented operand");
+  }
+}
+
+// Calling Convention Implementation.
+#include "RISCVGenCallingConv.inc"
+
+// Transform physical registers into virtual registers.
+SDValue RISCVTargetLowering::LowerFormalArguments(
+    SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
+    const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
+    SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
+
+  switch (CallConv) {
+  default:
+    report_fatal_error("Unsupported calling convention");
+  case CallingConv::C:
+    break;
+  }
+
+  MachineFunction &MF = DAG.getMachineFunction();
+  MachineRegisterInfo &RegInfo = MF.getRegInfo();
+  MVT XLenVT = Subtarget.getXLenVT();
+
+  if (IsVarArg)
+    report_fatal_error("VarArg not supported");
+
+  // Assign locations to all of the incoming arguments.
+  SmallVector<CCValAssign, 16> ArgLocs;
+  CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
+  CCInfo.AnalyzeFormalArguments(Ins, CC_RISCV32);
+
+  for (auto &VA : ArgLocs) {
+    if (!VA.isRegLoc())
+      report_fatal_error("Defined with too many args");
+
+    // Arguments passed in registers.
+    EVT RegVT = VA.getLocVT();
+    if (RegVT != XLenVT) {
+      DEBUG(dbgs() << "LowerFormalArguments Unhandled argument type: "
+          << RegVT.getEVTString() << "\n");
+      report_fatal_error("unhandled argument type");
+    }
+    const unsigned VReg =
+      RegInfo.createVirtualRegister(&RISCV::GPRRegClass);
+    RegInfo.addLiveIn(VA.getLocReg(), VReg);
+    SDValue ArgIn = DAG.getCopyFromReg(Chain, DL, VReg, RegVT);
+
+    InVals.push_back(ArgIn);
+  }
+  return Chain;
+}
+
+SDValue
+RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
+                                 bool IsVarArg,
+                                 const SmallVectorImpl<ISD::OutputArg> &Outs,
+                                 const SmallVectorImpl<SDValue> &OutVals,
+                                 const SDLoc &DL, SelectionDAG &DAG) const {
+  if (IsVarArg) {
+    report_fatal_error("VarArg not supported");
+  }
+
+  // Stores the assignment of the return value to a location.
+  SmallVector<CCValAssign, 16> RVLocs;
+
+  // Info about the registers and stack slot.
+  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
+                 *DAG.getContext());
+
+  CCInfo.AnalyzeReturn(Outs, RetCC_RISCV32);
+
+  SDValue Flag;
+  SmallVector<SDValue, 4> RetOps(1, Chain);
+
+  // Copy the result values into the output registers.
+  for (unsigned i = 0, e = RVLocs.size(); i < e; ++i) {
+    CCValAssign &VA = RVLocs[i];
+    assert(VA.isRegLoc() && "Can only return in registers!");
+
+    Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Flag);
+
+    // Guarantee that all emitted copies are stuck together.
+    Flag = Chain.getValue(1);
+    RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
+  }
+
+  RetOps[0] = Chain; // Update chain.
+
+  // Add the flag if we have it.
+  if (Flag.getNode()) {
+    RetOps.push_back(Flag);
+  }
+
+  return DAG.getNode(RISCVISD::RET_FLAG, DL, MVT::Other, RetOps);
+}
+
+const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const {
+  switch ((RISCVISD::NodeType)Opcode) {
+  case RISCVISD::FIRST_NUMBER:
+    break;
+  case RISCVISD::RET_FLAG:
+    return "RISCVISD::RET_FLAG";
+  }
+  return nullptr;
+}

Added: llvm/trunk/lib/Target/RISCV/RISCVISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVISelLowering.h?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVISelLowering.h (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVISelLowering.h Thu Oct 19 14:37:38 2017
@@ -0,0 +1,62 @@
+//===-- RISCVISelLowering.h - RISCV DAG Lowering Interface ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interfaces that RISCV uses to lower LLVM code into a
+// selection DAG.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_RISCV_RISCVISELLOWERING_H
+#define LLVM_LIB_TARGET_RISCV_RISCVISELLOWERING_H
+
+#include "RISCV.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/Target/TargetLowering.h"
+
+namespace llvm {
+class RISCVSubtarget;
+namespace RISCVISD {
+enum NodeType : unsigned {
+  FIRST_NUMBER = ISD::BUILTIN_OP_END,
+  RET_FLAG
+};
+}
+
+class RISCVTargetLowering : public TargetLowering {
+  const RISCVSubtarget &Subtarget;
+
+public:
+  explicit RISCVTargetLowering(const TargetMachine &TM,
+                               const RISCVSubtarget &STI);
+
+  // Provide custom lowering hooks for some operations.
+  SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
+
+  // This method returns the name of a target specific DAG node.
+  const char *getTargetNodeName(unsigned Opcode) const override;
+
+private:
+  // Lower incoming arguments, copy physregs into vregs
+  SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
+                               bool IsVarArg,
+                               const SmallVectorImpl<ISD::InputArg> &Ins,
+                               const SDLoc &DL, SelectionDAG &DAG,
+                               SmallVectorImpl<SDValue> &InVals) const override;
+  SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
+                      const SmallVectorImpl<ISD::OutputArg> &Outs,
+                      const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
+                      SelectionDAG &DAG) const override;
+  bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
+                                         Type *Ty) const override {
+    return true;
+  }
+};
+}
+
+#endif

Added: llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.cpp?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.cpp (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.cpp Thu Oct 19 14:37:38 2017
@@ -0,0 +1,31 @@
+//===-- RISCVInstrInfo.cpp - RISCV Instruction Information ------*- 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 RISCV implementation of the TargetInstrInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCVInstrInfo.h"
+#include "RISCV.h"
+#include "RISCVSubtarget.h"
+#include "RISCVTargetMachine.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/TargetRegistry.h"
+
+#define GET_INSTRINFO_CTOR_DTOR
+#include "RISCVGenInstrInfo.inc"
+
+using namespace llvm;
+
+RISCVInstrInfo::RISCVInstrInfo() : RISCVGenInstrInfo() {}

Added: llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.h?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.h (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.h Thu Oct 19 14:37:38 2017
@@ -0,0 +1,32 @@
+//===-- RISCVInstrInfo.h - RISCV Instruction Information --------*- 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 RISCV implementation of the TargetInstrInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H
+#define LLVM_LIB_TARGET_RISCV_RISCVINSTRINFO_H
+
+#include "RISCVRegisterInfo.h"
+#include "llvm/Target/TargetInstrInfo.h"
+
+#define GET_INSTRINFO_HEADER
+#include "RISCVGenInstrInfo.inc"
+
+namespace llvm {
+
+class RISCVInstrInfo : public RISCVGenInstrInfo {
+
+public:
+  RISCVInstrInfo();
+};
+}
+
+#endif

Modified: llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td?rev=316188&r1=316187&r2=316188&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVInstrInfo.td Thu Oct 19 14:37:38 2017
@@ -14,6 +14,13 @@
 include "RISCVInstrFormats.td"
 
 //===----------------------------------------------------------------------===//
+// RISC-V specific DAG Nodes.
+//===----------------------------------------------------------------------===//
+
+def RetFlag : SDNode<"RISCVISD::RET_FLAG", SDTNone,
+                     [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
+
+//===----------------------------------------------------------------------===//
 // Operand and SDNode transformation definitions.
 //===----------------------------------------------------------------------===//
 
@@ -43,12 +50,12 @@ def fencearg : Operand<XLenVT> {
   let DecoderMethod = "decodeUImmOperand<4>";
 }
 
-def uimm5 : Operand<XLenVT> {
+def uimm5 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]> {
   let ParserMatchClass = UImmAsmOperand<5>;
   let DecoderMethod = "decodeUImmOperand<5>";
 }
 
-def simm12 : Operand<XLenVT> {
+def simm12 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<12>(Imm);}]> {
   let ParserMatchClass = SImmAsmOperand<12>;
   let EncoderMethod = "getImmOpValue";
   let DecoderMethod = "decodeSImmOperand<12>";
@@ -231,3 +238,52 @@ def CSRRC : CSR_ir<0b011, "csrrc">;
 def CSRRWI : CSR_ii<0b101, "csrrwi">;
 def CSRRSI : CSR_ii<0b110, "csrrsi">;
 def CSRRCI : CSR_ii<0b111, "csrrci">;
+
+//===----------------------------------------------------------------------===//
+// Pseudo-instructions and codegen patterns
+//
+// Naming convention: For 'generic' pattern classes, we use the naming
+// convention PatTy1Ty2. For pattern classes which offer a more complex
+// expension, prefix the class name, e.g. BccPat.
+//===----------------------------------------------------------------------===//
+
+/// Generic pattern classes
+
+class PatGprGpr<SDPatternOperator OpNode, RVInstR Inst>
+    : Pat<(OpNode GPR:$rs1, GPR:$rs2), (Inst GPR:$rs1, GPR:$rs2)>;
+class PatGprSimm12<SDPatternOperator OpNode, RVInstI Inst>
+    : Pat<(OpNode GPR:$rs1, simm12:$imm12), (Inst GPR:$rs1, simm12:$imm12)>;
+class PatGprUimm5<SDPatternOperator OpNode, RVInstIShift Inst>
+    : Pat<(OpNode GPR:$rs1, uimm5:$shamt),
+          (Inst GPR:$rs1, uimm5:$shamt)>;
+
+/// Simple arithmetic operations
+
+def : PatGprGpr<add, ADD>;
+def : PatGprSimm12<add, ADDI>;
+def : PatGprGpr<sub, SUB>;
+def : PatGprGpr<or, OR>;
+def : PatGprSimm12<or, ORI>;
+def : PatGprGpr<and, AND>;
+def : PatGprSimm12<and, ANDI>;
+def : PatGprGpr<xor, XOR>;
+def : PatGprSimm12<xor, XORI>;
+def : PatGprGpr<shl, SLL>;
+def : PatGprUimm5<shl, SLLI>;
+def : PatGprGpr<srl, SRL>;
+def : PatGprUimm5<srl, SRLI>;
+def : PatGprGpr<sra, SRA>;
+def : PatGprUimm5<sra, SRAI>;
+
+/// Setcc
+
+def : PatGprGpr<setlt, SLT>;
+def : PatGprSimm12<setlt, SLTI>;
+def : PatGprGpr<setult, SLTU>;
+def : PatGprSimm12<setult, SLTIU>;
+
+/// Branches and jumps
+
+let isBarrier = 1, isReturn = 1, isTerminator = 1 in
+def PseudoRET : Pseudo<(outs), (ins), [(RetFlag)]>,
+                PseudoInstExpansion<(JALR X0, X1, 0)>;

Added: llvm/trunk/lib/Target/RISCV/RISCVMCInstLower.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVMCInstLower.cpp?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVMCInstLower.cpp (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVMCInstLower.cpp Thu Oct 19 14:37:38 2017
@@ -0,0 +1,50 @@
+//===-- RISCVMCInstLower.cpp - Convert RISCV MachineInstr to an MCInst ------=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains code to lower RISCV MachineInstrs to their corresponding
+// MCInst records.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCV.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+void llvm::LowerRISCVMachineInstrToMCInst(const MachineInstr *MI,
+                                          MCInst &OutMI) {
+  OutMI.setOpcode(MI->getOpcode());
+
+  for (const MachineOperand &MO : MI->operands()) {
+    MCOperand MCOp;
+    switch (MO.getType()) {
+    default:
+      report_fatal_error(
+          "LowerRISCVMachineInstrToMCInst: unknown operand type");
+    case MachineOperand::MO_Register:
+      // Ignore all implicit register operands.
+      if (MO.isImplicit())
+        continue;
+      MCOp = MCOperand::createReg(MO.getReg());
+      break;
+    case MachineOperand::MO_Immediate:
+      MCOp = MCOperand::createImm(MO.getImm());
+      break;
+    }
+
+    OutMI.addOperand(MCOp);
+  }
+}

Added: llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.cpp?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.cpp (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.cpp Thu Oct 19 14:37:38 2017
@@ -0,0 +1,61 @@
+//===-- RISCVRegisterInfo.cpp - RISCV Register Information ------*- 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 RISCV implementation of the TargetRegisterInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCVRegisterInfo.h"
+#include "RISCV.h"
+#include "RISCVSubtarget.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Target/TargetFrameLowering.h"
+#include "llvm/Target/TargetInstrInfo.h"
+
+#define GET_REGINFO_TARGET_DESC
+#include "RISCVGenRegisterInfo.inc"
+
+using namespace llvm;
+
+RISCVRegisterInfo::RISCVRegisterInfo(unsigned HwMode)
+    : RISCVGenRegisterInfo(RISCV::X1, /*DwarfFlavour*/0, /*EHFlavor*/0,
+                           /*PC*/0, HwMode) {}
+
+const MCPhysReg *
+RISCVRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
+  return CSR_SaveList;
+}
+
+BitVector RISCVRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
+  BitVector Reserved(getNumRegs());
+
+  // Use markSuperRegs to ensure any register aliases are also reserved
+  markSuperRegs(Reserved, RISCV::X0); // zero
+  markSuperRegs(Reserved, RISCV::X1); // ra
+  markSuperRegs(Reserved, RISCV::X2); // sp
+  markSuperRegs(Reserved, RISCV::X3); // gp
+  markSuperRegs(Reserved, RISCV::X4); // tp
+  markSuperRegs(Reserved, RISCV::X8); // fp
+  assert(checkAllSuperRegsMarked(Reserved));
+  return Reserved;
+}
+
+void RISCVRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
+                                            int SPAdj, unsigned FIOperandNum,
+                                            RegScavenger *RS) const {
+  report_fatal_error("Subroutines not supported yet");
+}
+
+unsigned RISCVRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
+  return RISCV::X8;
+}

Added: llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.h?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.h (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.h Thu Oct 19 14:37:38 2017
@@ -0,0 +1,40 @@
+//===-- RISCVRegisterInfo.h - RISCV Register Information Impl ---*- 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 RISCV implementation of the TargetRegisterInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_RISCV_RISCVREGISTERINFO_H
+#define LLVM_LIB_TARGET_RISCV_RISCVREGISTERINFO_H
+
+#include "llvm/Target/TargetRegisterInfo.h"
+
+#define GET_REGINFO_HEADER
+#include "RISCVGenRegisterInfo.inc"
+
+namespace llvm {
+
+struct RISCVRegisterInfo : public RISCVGenRegisterInfo {
+
+  RISCVRegisterInfo(unsigned HwMode);
+
+  const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
+
+  BitVector getReservedRegs(const MachineFunction &MF) const override;
+
+  void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
+                           unsigned FIOperandNum,
+                           RegScavenger *RS = nullptr) const override;
+
+  unsigned getFrameRegister(const MachineFunction &MF) const override;
+};
+}
+
+#endif

Modified: llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td?rev=316188&r1=316187&r2=316188&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVRegisterInfo.td Thu Oct 19 14:37:38 2017
@@ -58,10 +58,15 @@ let RegAltNameIndices = [ABIRegAltName]
 def XLenVT : ValueTypeByHwMode<[RV32, RV64, DefaultMode],
                                [i32,  i64,  i32]>;
 
-// TODO: once codegen is implemented, registers should be listed in an order
-// reflecting the preferred register allocation sequence.
-def GPR : RegisterClass< "RISCV", [XLenVT], 32, (add
-    (sequence "X%u", 0, 31)
+// The order of registers represents the preferred allocation sequence.
+// Registers are listed in the order caller-save, callee-save, specials.
+def GPR : RegisterClass<"RISCV", [XLenVT], 32, (add
+    (sequence "X%u", 10, 17),
+    (sequence "X%u", 5, 7),
+    (sequence "X%u", 28, 31),
+    (sequence "X%u", 8, 9),
+    (sequence "X%u", 18, 27),
+    (sequence "X%u", 0, 4)
   )> {
   let RegInfos = RegInfoByHwMode<
       [RV32,              RV64,              DefaultMode],

Added: llvm/trunk/lib/Target/RISCV/RISCVSubtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVSubtarget.cpp?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVSubtarget.cpp (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVSubtarget.cpp Thu Oct 19 14:37:38 2017
@@ -0,0 +1,48 @@
+//===-- RISCVSubtarget.cpp - RISCV Subtarget Information ------------------===//
+//
+//                     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 RISCV specific subclass of TargetSubtargetInfo.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCVSubtarget.h"
+#include "RISCV.h"
+#include "RISCVFrameLowering.h"
+#include "llvm/Support/TargetRegistry.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "riscv-subtarget"
+
+#define GET_SUBTARGETINFO_TARGET_DESC
+#define GET_SUBTARGETINFO_CTOR
+#include "RISCVGenSubtargetInfo.inc"
+
+void RISCVSubtarget::anchor() {}
+
+RISCVSubtarget &RISCVSubtarget::initializeSubtargetDependencies(StringRef CPU,
+                                                                StringRef FS,
+                                                                bool Is64Bit) {
+  // Determine default and user-specified characteristics
+  std::string CPUName = CPU;
+  if (CPUName.empty())
+    CPUName = Is64Bit ? "generic-rv64" : "generic-rv32";
+  ParseSubtargetFeatures(CPUName, FS);
+  if (Is64Bit) {
+    XLenVT = MVT::i64;
+    XLen = 64;
+  }
+  return *this;
+}
+
+RISCVSubtarget::RISCVSubtarget(const Triple &TT, const std::string &CPU,
+                               const std::string &FS, const TargetMachine &TM)
+    : RISCVGenSubtargetInfo(TT, CPU, FS),
+      FrameLowering(initializeSubtargetDependencies(CPU, FS, TT.isArch64Bit())),
+      InstrInfo(), RegInfo(getHwMode()), TLInfo(TM, *this) {}

Added: llvm/trunk/lib/Target/RISCV/RISCVSubtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVSubtarget.h?rev=316188&view=auto
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVSubtarget.h (added)
+++ llvm/trunk/lib/Target/RISCV/RISCVSubtarget.h Thu Oct 19 14:37:38 2017
@@ -0,0 +1,75 @@
+//===-- RISCVSubtarget.h - Define Subtarget for the 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 declares the RISCV specific subclass of TargetSubtargetInfo.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_RISCV_RISCVSUBTARGET_H
+#define LLVM_LIB_TARGET_RISCV_RISCVSUBTARGET_H
+
+#include "RISCVFrameLowering.h"
+#include "RISCVISelLowering.h"
+#include "RISCVInstrInfo.h"
+#include "llvm/CodeGen/SelectionDAGTargetInfo.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
+
+#define GET_SUBTARGETINFO_HEADER
+#include "RISCVGenSubtargetInfo.inc"
+
+namespace llvm {
+class StringRef;
+
+class RISCVSubtarget : public RISCVGenSubtargetInfo {
+  virtual void anchor();
+  bool HasRV64 = false;
+  unsigned XLen = 32;
+  MVT XLenVT = MVT::i32;
+  RISCVFrameLowering FrameLowering;
+  RISCVInstrInfo InstrInfo;
+  RISCVRegisterInfo RegInfo;
+  RISCVTargetLowering TLInfo;
+  SelectionDAGTargetInfo TSInfo;
+
+  /// Initializes using the passed in CPU and feature strings so that we can
+  /// use initializer lists for subtarget initialization.
+  RISCVSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS,
+                                                  bool Is64Bit);
+
+public:
+  // Initializes the data members to match that of the specified triple.
+  RISCVSubtarget(const Triple &TT, const std::string &CPU,
+                 const std::string &FS, const TargetMachine &TM);
+
+  // Parses features string setting specified subtarget options. The
+  // definition of this function is auto-generated by tblgen.
+  void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
+
+  const RISCVFrameLowering *getFrameLowering() const override {
+    return &FrameLowering;
+  }
+  const RISCVInstrInfo *getInstrInfo() const override { return &InstrInfo; }
+  const RISCVRegisterInfo *getRegisterInfo() const override {
+    return &RegInfo;
+  }
+  const RISCVTargetLowering *getTargetLowering() const override {
+    return &TLInfo;
+  }
+  const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
+    return &TSInfo;
+  }
+  bool is64Bit() const { return HasRV64; }
+  MVT getXLenVT() const { return XLenVT; }
+  unsigned getXLen() const { return XLen; }
+};
+} // End llvm namespace
+
+#endif

Modified: llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.cpp?rev=316188&r1=316187&r2=316188&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.cpp Thu Oct 19 14:37:38 2017
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "RISCV.h"
 #include "RISCVTargetMachine.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/CodeGen/Passes.h"
@@ -58,10 +59,31 @@ RISCVTargetMachine::RISCVTargetMachine(c
     : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
                         getEffectiveRelocModel(TT, RM),
                         getEffectiveCodeModel(CM), OL),
-      TLOF(make_unique<TargetLoweringObjectFileELF>()) {
+      TLOF(make_unique<TargetLoweringObjectFileELF>()),
+      Subtarget(TT, CPU, FS, *this) {
   initAsmInfo();
 }
 
+namespace {
+class RISCVPassConfig : public TargetPassConfig {
+public:
+  RISCVPassConfig(RISCVTargetMachine &TM, PassManagerBase &PM)
+      : TargetPassConfig(TM, PM) {}
+
+  RISCVTargetMachine &getRISCVTargetMachine() const {
+    return getTM<RISCVTargetMachine>();
+  }
+
+  bool addInstSelector() override;
+};
+}
+
 TargetPassConfig *RISCVTargetMachine::createPassConfig(PassManagerBase &PM) {
-  return new TargetPassConfig(*this, PM);
+  return new RISCVPassConfig(*this, PM);
+}
+
+bool RISCVPassConfig::addInstSelector() {
+  addPass(createRISCVISelDag(getRISCVTargetMachine()));
+
+  return false;
 }

Modified: llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.h?rev=316188&r1=316187&r2=316188&view=diff
==============================================================================
--- llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.h (original)
+++ llvm/trunk/lib/Target/RISCV/RISCVTargetMachine.h Thu Oct 19 14:37:38 2017
@@ -15,6 +15,7 @@
 #define LLVM_LIB_TARGET_RISCV_RISCVTARGETMACHINE_H
 
 #include "MCTargetDesc/RISCVMCTargetDesc.h"
+#include "RISCVSubtarget.h"
 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/Target/TargetMachine.h"
@@ -22,6 +23,7 @@
 namespace llvm {
 class RISCVTargetMachine : public LLVMTargetMachine {
   std::unique_ptr<TargetLoweringObjectFile> TLOF;
+  RISCVSubtarget Subtarget;
 
 public:
   RISCVTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
@@ -29,6 +31,10 @@ public:
                      Optional<Reloc::Model> RM, Optional<CodeModel::Model> CM,
                      CodeGenOpt::Level OL, bool JIT);
 
+  const RISCVSubtarget *getSubtargetImpl(const Function &) const override {
+    return &Subtarget;
+  }
+
   TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
 
   TargetLoweringObjectFile *getObjFileLowering() const override {

Added: llvm/trunk/test/CodeGen/RISCV/alu32.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/alu32.ll?rev=316188&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/alu32.ll (added)
+++ llvm/trunk/test/CodeGen/RISCV/alu32.ll Thu Oct 19 14:37:38 2017
@@ -0,0 +1,163 @@
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
+; RUN:   | FileCheck %s -check-prefix=RV32I
+
+; Register-immediate instructions
+
+define i32 @addi(i32 %a) nounwind {
+; RV32I-LABEL: addi:
+; RV32I: addi a0, a0, 1
+; RV32I: jalr zero, ra, 0
+; TODO: check support for materialising larger constants
+  %1 = add i32 %a, 1
+  ret i32 %1
+}
+
+define i32 @slti(i32 %a) nounwind {
+; RV32I-LABEL: slti:
+; RV32I: slti a0, a0, 2
+; RV32I: jalr zero, ra, 0
+  %1 = icmp slt i32 %a, 2
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
+define i32 @sltiu(i32 %a) nounwind {
+; RV32I-LABEL: sltiu:
+; RV32I: sltiu a0, a0, 3
+; RV32I: jalr zero, ra, 0
+  %1 = icmp ult i32 %a, 3
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
+define i32 @xori(i32 %a) nounwind {
+; RV32I-LABEL: xori:
+; RV32I: xori a0, a0, 4
+; RV32I: jalr zero, ra, 0
+  %1 = xor i32 %a, 4
+  ret i32 %1
+}
+
+define i32 @ori(i32 %a) nounwind {
+; RV32I-LABEL: ori:
+; RV32I: ori a0, a0, 5
+; RV32I: jalr zero, ra, 0
+  %1 = or i32 %a, 5
+  ret i32 %1
+}
+
+define i32 @andi(i32 %a) nounwind {
+; RV32I-LABEL: andi:
+; RV32I: andi a0, a0, 6
+; RV32I: jalr zero, ra, 0
+  %1 = and i32 %a, 6
+  ret i32 %1
+}
+
+define i32 @slli(i32 %a) nounwind {
+; RV32I-LABEL: slli:
+; RV32I: slli a0, a0, 7
+; RV32I: jalr zero, ra, 0
+  %1 = shl i32 %a, 7
+  ret i32 %1
+}
+
+define i32 @srli(i32 %a) nounwind {
+; RV32I-LABEL: srli:
+; RV32I: srli a0, a0, 8
+; RV32I: jalr zero, ra, 0
+  %1 = lshr i32 %a, 8
+  ret i32 %1
+}
+
+define i32 @srai(i32 %a) nounwind {
+; RV32I-LABEL: srai:
+; RV32I: srai a0, a0, 9
+; RV32I: jalr zero, ra, 0
+  %1 = ashr i32 %a, 9
+  ret i32 %1
+}
+
+; Register-register instructions
+
+define i32 @add(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: add:
+; RV32I: add a0, a0, a1
+; RV32I: jalr zero, ra, 0
+  %1 = add i32 %a, %b
+  ret i32 %1
+}
+
+define i32 @sub(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: sub:
+; RV32I: sub a0, a0, a1
+; RV32I: jalr zero, ra, 0
+  %1 = sub i32 %a, %b
+  ret i32 %1
+}
+
+define i32 @sll(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: sll:
+; RV32I: sll a0, a0, a1
+; RV32I: jalr zero, ra, 0
+  %1 = shl i32 %a, %b
+  ret i32 %1
+}
+
+define i32 @slt(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: slt:
+; RV32I: slt a0, a0, a1
+; RV32I: jalr zero, ra, 0
+  %1 = icmp slt i32 %a, %b
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
+define i32 @sltu(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: sltu:
+; RV32I: sltu a0, a0, a1
+; RV32I: jalr zero, ra, 0
+  %1 = icmp ult i32 %a, %b
+  %2 = zext i1 %1 to i32
+  ret i32 %2
+}
+
+define i32 @xor(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: xor:
+; RV32I: xor a0, a0, a1
+; RV32I: jalr zero, ra, 0
+  %1 = xor i32 %a, %b
+  ret i32 %1
+}
+
+define i32 @srl(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: srl:
+; RV32I: srl a0, a0, a1
+; RV32I: jalr zero, ra, 0
+  %1 = lshr i32 %a, %b
+  ret i32 %1
+}
+
+define i32 @sra(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: sra:
+; RV32I: sra a0, a0, a1
+; RV32I: jalr zero, ra, 0
+  %1 = ashr i32 %a, %b
+  ret i32 %1
+}
+
+define i32 @or(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: or:
+; RV32I: or a0, a0, a1
+; RV32I: jalr zero, ra, 0
+  %1 = or i32 %a, %b
+  ret i32 %1
+}
+
+define i32 @and(i32 %a, i32 %b) nounwind {
+; RV32I-LABEL: and:
+; RV32I: and a0, a0, a1
+; RV32I: jalr zero, ra, 0
+  %1 = and i32 %a, %b
+  ret i32 %1
+}

Added: llvm/trunk/test/CodeGen/RISCV/lit.local.cfg
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/RISCV/lit.local.cfg?rev=316188&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/RISCV/lit.local.cfg (added)
+++ llvm/trunk/test/CodeGen/RISCV/lit.local.cfg Thu Oct 19 14:37:38 2017
@@ -0,0 +1,2 @@
+if not 'RISCV' in config.root.targets:
+    config.unsupported = True




More information about the llvm-commits mailing list