forked from Hoernchen/Epiphany
-
Notifications
You must be signed in to change notification settings - Fork 2
/
EpiphanyISelLowering.h
216 lines (175 loc) · 8.29 KB
/
EpiphanyISelLowering.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
//==-- EpiphanyISelLowering.h - Epiphany 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 Epiphany uses to lower LLVM code into a
// selection DAG.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TARGET_EPIPHANY_ISELLOWERING_H
#define LLVM_TARGET_EPIPHANY_ISELLOWERING_H
#include "EpiphanyConfig.h"
#include "MCTargetDesc/EpiphanyABIInfo.h"
#include "Epiphany.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/IR/Function.h"
#include "llvm/Target/TargetLowering.h"
#include <deque>
namespace llvm {
namespace EpiphanyISD {
enum NodeType {
// Start the numbering from where ISD NodeType finishes.
FIRST_NUMBER = ISD::BUILTIN_OP_END,
// A node to be selected to an actual call operation: either BL or BLR in
// the absence of tail calls.
Call,
// Simply a convenient node inserted during ISelLowering to represent
// procedure return. Will almost certainly be selected to "RTS" or "RTI".
RTS,
RTI,
// Wrapper for mov, movt and mov<cc> instructions
MOV,
MOVT,
MOVCC,
// Conditional branch wrapper
BRCC,
BRCC64,
// FIX/FLOAT wrappers
FIX,
FLOAT,
// Store and load instruction wrappers
STORE,
LOAD,
// CMP instruction
CMP
};
}
//===--------------------------------------------------------------------===//
// TargetLowering Implementation
//===--------------------------------------------------------------------===//
class EpiphanyMachineFunctionInfo;
class EpiphanySubtarget;
class EpiphanyTargetLowering : public TargetLowering {
public:
explicit EpiphanyTargetLowering(const EpiphanyTargetMachine &TM,
const EpiphanySubtarget &STI);
/// getTargetNodeName - This method returns the name of a target specific
// DAG node.
const char *getTargetNodeName(unsigned Opcode) const override;
// Offset handling for arrays for non-PIC mode
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
// Overriding operation and custom inserter lowering
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override;
protected:
/// ByValArgInfo - Byval argument information.
struct ByValArgInfo {
unsigned FirstIdx; // Index of the first register used.
unsigned NumRegs; // Number of registers used for this argument.
unsigned Address; // Offset of the stack area used to pass this argument.
ByValArgInfo() : FirstIdx(0), NumRegs(0), Address(0) {}
};
/// EpiphanyCC - This class provides methods used to analyze formal and call
/// arguments and inquire about calling convention information.
class EpiphanyCC {
public:
enum SpecialCallingConvType {
NoSpecialCallingConv
};
EpiphanyCC(CallingConv::ID CallConv, bool IsE16, CCState &Info,
SpecialCallingConvType SpecialCallingConv = NoSpecialCallingConv);
void analyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
bool IsSoftFloat, const Type *RetTy) const;
const CCState &getCCInfo() const { return CCInfo; }
/// hasByValArg - Returns true if function has byval arguments.
bool hasByValArg() const { return !ByValArgs.empty(); }
/// reservedArgArea - The size of the area the caller reserves for
/// register arguments. This is 16-byte if ABI is O32.
unsigned reservedArgArea() const;
typedef SmallVectorImpl<ByValArgInfo>::const_iterator byval_iterator;
byval_iterator byval_begin() const { return ByValArgs.begin(); }
byval_iterator byval_end() const { return ByValArgs.end(); }
private:
/// Return the type of the register which is used to pass an argument or
/// return a value. This function returns f64 if the argument is an i64
/// value which has been generated as a result of softening an f128 value.
/// Otherwise, it just returns VT.
MVT getRegVT(MVT VT, const Type *OrigTy, const SDNode *CallNode,
bool IsSoftFloat) const;
template<typename Ty>
void analyzeReturn(const SmallVectorImpl<Ty> &RetVals, bool IsSoftFloat,
const SDNode *CallNode, const Type *RetTy) const;
CCState &CCInfo;
CallingConv::ID CallConv;
bool IsE16;
SmallVector<ByValArgInfo, 2> ByValArgs;
};
// Subtarget Info
const EpiphanySubtarget &Subtarget;
// Cache the ABI from the TargetMachine, we use it everywhere.
const EpiphanyABIInfo &ABI;
private:
// Lower Operand specifics
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBuildVector(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerExtractVectorElt(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFpExtend(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFpRound(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFpToInt(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerIntToFp(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFastDiv(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSelectCC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSelect(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSetCC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBrCC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBrCond(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerAdd64(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSub64(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerAdde(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSube(SDValue Op, SelectionDAG &DAG) const;
// Custom inserters
MachineBasicBlock *emitBrCC(MachineInstr &MI, MachineBasicBlock *MBB) const;
//- must be exist even without function all
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;
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
const SDLoc &DL, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
// TODO: For now - no
bool IsEligibleForTailCallOptimization(SDValue Callee,
CallingConv::ID CalleeCC,
bool IsVarArg,
bool IsCalleeStructRet,
bool IsCallerStructRet,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals,
const SmallVectorImpl<ISD::InputArg> &Ins,
SelectionDAG& DAG) const { return false;}
std::pair<unsigned, const TargetRegisterClass *> parseRegForInlineAsmConstraint(StringRef C, MVT VT) const;
std::pair<unsigned, const TargetRegisterClass *> getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
StringRef Constraint, MVT VT) const override;
};
} // namespace llvm
#endif // LLVM_TARGET_EPIPHANY_ISELLOWERING_H