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
CanLowerReturn(CallingConv::ID CallConv,MachineFunction & MF,bool IsVarArg,const SmallVectorImpl<ISD::OutputArg> & Outs,LLVMContext & Context) const41 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
LowerReturn(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::OutputArg> & Outs,const SmallVectorImpl<SDValue> & OutVals,const SDLoc & DL,SelectionDAG & DAG) const50 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
LowerFormalArguments(SDValue Chain,CallingConv::ID CallConv,bool IsVarArg,const SmallVectorImpl<ISD::InputArg> & Ins,const SDLoc & DL,SelectionDAG & DAG,SmallVectorImpl<SDValue> & InVals) const64 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.
getRegisterByName(const char * RegName,LLT VT,const MachineFunction & MF) const75 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
VETargetLowering(const TargetMachine & TM,const VESubtarget & STI)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
getTargetNodeName(unsigned Opcode) const124 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
getSetCCResultType(const DataLayout &,LLVMContext &,EVT VT) const134 EVT VETargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &,
135 EVT VT) const {
136 return MVT::i64;
137 }
138