1 //===-- VEISelLowering.cpp - VE DAG Lowering Implementation ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the interfaces that VE uses to lower LLVM code into a
10 // selection DAG.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "VEISelLowering.h"
15 #include "VERegisterInfo.h"
16 #include "VETargetMachine.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/CodeGen/CallingConvLower.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineModuleInfo.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/CodeGen/SelectionDAG.h"
25 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
26 #include "llvm/IR/DerivedTypes.h"
27 #include "llvm/IR/Function.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/Support/ErrorHandling.h"
30 #include "llvm/Support/KnownBits.h"
31 using namespace llvm;
32 
33 #define DEBUG_TYPE "ve-lower"
34 
35 //===----------------------------------------------------------------------===//
36 // Calling Convention Implementation
37 //===----------------------------------------------------------------------===//
38 
39 #include "VEGenCallingConv.inc"
40 
41 bool VETargetLowering::CanLowerReturn(
42     CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
43     const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
44   assert(!IsVarArg && "TODO implement var args");
45   assert(Outs.empty() && "TODO implement return values");
46   return true; // TODO support more than 'ret void'
47 }
48 
49 SDValue
50 VETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
51                               bool IsVarArg,
52                               const SmallVectorImpl<ISD::OutputArg> &Outs,
53                               const SmallVectorImpl<SDValue> &OutVals,
54                               const SDLoc &DL, SelectionDAG &DAG) const {
55   assert(!IsVarArg && "TODO implement var args");
56   assert(Outs.empty() && "TODO implement return values");
57   assert(OutVals.empty() && "TODO implement return values");
58 
59   SmallVector<SDValue, 4> RetOps(1, Chain);
60   RetOps[0] = Chain; // Update chain.
61   return DAG.getNode(VEISD::RET_FLAG, DL, MVT::Other, RetOps);
62 }
63 
64 SDValue VETargetLowering::LowerFormalArguments(
65     SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
66     const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
67     SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
68   assert(!IsVarArg && "TODO implement var args");
69   assert(Ins.empty() && "TODO implement input arguments");
70   return Chain;
71 }
72 
73 // FIXME? Maybe this could be a TableGen attribute on some registers and
74 // this table could be generated automatically from RegInfo.
75 Register VETargetLowering::getRegisterByName(const char *RegName, LLT VT,
76                                              const MachineFunction &MF) const {
77   Register Reg = StringSwitch<Register>(RegName)
78                      .Case("sp", VE::SX11)    // Stack pointer
79                      .Case("fp", VE::SX9)     // Frame pointer
80                      .Case("sl", VE::SX8)     // Stack limit
81                      .Case("lr", VE::SX10)    // Link regsiter
82                      .Case("tp", VE::SX14)    // Thread pointer
83                      .Case("outer", VE::SX12) // Outer regiser
84                      .Case("info", VE::SX17)  // Info area register
85                      .Case("got", VE::SX15)   // Global offset table register
86                      .Case("plt", VE::SX16) // Procedure linkage table register
87                      .Default(0);
88 
89   if (Reg)
90     return Reg;
91 
92   report_fatal_error("Invalid register name global variable");
93 }
94 
95 //===----------------------------------------------------------------------===//
96 // TargetLowering Implementation
97 //===----------------------------------------------------------------------===//
98 
99 VETargetLowering::VETargetLowering(const TargetMachine &TM,
100                                    const VESubtarget &STI)
101     : TargetLowering(TM), Subtarget(&STI) {
102   // Instructions which use registers as conditionals examine all the
103   // bits (as does the pseudo SELECT_CC expansion). I don't think it
104   // matters much whether it's ZeroOrOneBooleanContent, or
105   // ZeroOrNegativeOneBooleanContent, so, arbitrarily choose the
106   // former.
107   setBooleanContents(ZeroOrOneBooleanContent);
108   setBooleanVectorContents(ZeroOrOneBooleanContent);
109 
110   // Set up the register classes.
111   addRegisterClass(MVT::i64, &VE::I64RegClass);
112 
113   setStackPointerRegisterToSaveRestore(VE::SX11);
114 
115   // Set function alignment to 16 bytes
116   setMinFunctionAlignment(Align(16));
117 
118   // VE stores all argument by 8 bytes alignment
119   setMinStackArgumentAlignment(Align(8));
120 
121   computeRegisterProperties(Subtarget->getRegisterInfo());
122 }
123 
124 const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const {
125   switch ((VEISD::NodeType)Opcode) {
126   case VEISD::FIRST_NUMBER:
127     break;
128   case VEISD::RET_FLAG:
129     return "VEISD::RET_FLAG";
130   }
131   return nullptr;
132 }
133 
134 EVT VETargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &,
135                                          EVT VT) const {
136   return MVT::i64;
137 }
138