1 //===-- RISCVISelLowering.cpp - RISCV DAG Lowering Implementation --------===// 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 the interfaces that RISCV uses to lower LLVM code into a 11 // selection DAG. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "RISCVISelLowering.h" 16 #include "RISCV.h" 17 #include "RISCVRegisterInfo.h" 18 #include "RISCVSubtarget.h" 19 #include "RISCVTargetMachine.h" 20 #include "llvm/CodeGen/CallingConvLower.h" 21 #include "llvm/CodeGen/MachineFrameInfo.h" 22 #include "llvm/CodeGen/MachineFunction.h" 23 #include "llvm/CodeGen/MachineInstrBuilder.h" 24 #include "llvm/CodeGen/MachineRegisterInfo.h" 25 #include "llvm/CodeGen/SelectionDAGISel.h" 26 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 27 #include "llvm/CodeGen/ValueTypes.h" 28 #include "llvm/IR/DiagnosticInfo.h" 29 #include "llvm/IR/DiagnosticPrinter.h" 30 #include "llvm/Support/Debug.h" 31 #include "llvm/Support/ErrorHandling.h" 32 #include "llvm/Support/raw_ostream.h" 33 34 using namespace llvm; 35 36 #define DEBUG_TYPE "riscv-lower" 37 38 RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM, 39 const RISCVSubtarget &STI) 40 : TargetLowering(TM), Subtarget(STI) { 41 42 MVT XLenVT = Subtarget.getXLenVT(); 43 44 // Set up the register classes. 45 addRegisterClass(XLenVT, &RISCV::GPRRegClass); 46 47 // Compute derived properties from the register classes. 48 computeRegisterProperties(STI.getRegisterInfo()); 49 50 setStackPointerRegisterToSaveRestore(RISCV::X2); 51 52 // TODO: add all necessary setOperationAction calls. 53 54 setBooleanContents(ZeroOrOneBooleanContent); 55 56 // Function alignments (log2). 57 setMinFunctionAlignment(3); 58 setPrefFunctionAlignment(3); 59 } 60 61 SDValue RISCVTargetLowering::LowerOperation(SDValue Op, 62 SelectionDAG &DAG) const { 63 switch (Op.getOpcode()) { 64 default: 65 report_fatal_error("unimplemented operand"); 66 } 67 } 68 69 // Calling Convention Implementation. 70 #include "RISCVGenCallingConv.inc" 71 72 // Transform physical registers into virtual registers. 73 SDValue RISCVTargetLowering::LowerFormalArguments( 74 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, 75 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL, 76 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const { 77 78 switch (CallConv) { 79 default: 80 report_fatal_error("Unsupported calling convention"); 81 case CallingConv::C: 82 break; 83 } 84 85 MachineFunction &MF = DAG.getMachineFunction(); 86 MachineRegisterInfo &RegInfo = MF.getRegInfo(); 87 MVT XLenVT = Subtarget.getXLenVT(); 88 89 if (IsVarArg) 90 report_fatal_error("VarArg not supported"); 91 92 // Assign locations to all of the incoming arguments. 93 SmallVector<CCValAssign, 16> ArgLocs; 94 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); 95 CCInfo.AnalyzeFormalArguments(Ins, CC_RISCV32); 96 97 for (auto &VA : ArgLocs) { 98 if (!VA.isRegLoc()) 99 report_fatal_error("Defined with too many args"); 100 101 // Arguments passed in registers. 102 EVT RegVT = VA.getLocVT(); 103 if (RegVT != XLenVT) { 104 DEBUG(dbgs() << "LowerFormalArguments Unhandled argument type: " 105 << RegVT.getEVTString() << "\n"); 106 report_fatal_error("unhandled argument type"); 107 } 108 const unsigned VReg = 109 RegInfo.createVirtualRegister(&RISCV::GPRRegClass); 110 RegInfo.addLiveIn(VA.getLocReg(), VReg); 111 SDValue ArgIn = DAG.getCopyFromReg(Chain, DL, VReg, RegVT); 112 113 InVals.push_back(ArgIn); 114 } 115 return Chain; 116 } 117 118 SDValue 119 RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, 120 bool IsVarArg, 121 const SmallVectorImpl<ISD::OutputArg> &Outs, 122 const SmallVectorImpl<SDValue> &OutVals, 123 const SDLoc &DL, SelectionDAG &DAG) const { 124 if (IsVarArg) { 125 report_fatal_error("VarArg not supported"); 126 } 127 128 // Stores the assignment of the return value to a location. 129 SmallVector<CCValAssign, 16> RVLocs; 130 131 // Info about the registers and stack slot. 132 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, 133 *DAG.getContext()); 134 135 CCInfo.AnalyzeReturn(Outs, RetCC_RISCV32); 136 137 SDValue Flag; 138 SmallVector<SDValue, 4> RetOps(1, Chain); 139 140 // Copy the result values into the output registers. 141 for (unsigned i = 0, e = RVLocs.size(); i < e; ++i) { 142 CCValAssign &VA = RVLocs[i]; 143 assert(VA.isRegLoc() && "Can only return in registers!"); 144 145 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Flag); 146 147 // Guarantee that all emitted copies are stuck together. 148 Flag = Chain.getValue(1); 149 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 150 } 151 152 RetOps[0] = Chain; // Update chain. 153 154 // Add the flag if we have it. 155 if (Flag.getNode()) { 156 RetOps.push_back(Flag); 157 } 158 159 return DAG.getNode(RISCVISD::RET_FLAG, DL, MVT::Other, RetOps); 160 } 161 162 const char *RISCVTargetLowering::getTargetNodeName(unsigned Opcode) const { 163 switch ((RISCVISD::NodeType)Opcode) { 164 case RISCVISD::FIRST_NUMBER: 165 break; 166 case RISCVISD::RET_FLAG: 167 return "RISCVISD::RET_FLAG"; 168 } 169 return nullptr; 170 } 171