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
| //===-- PPCRegisterInfo.h - PowerPC Register Information Impl ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the TargetRegisterInfo
// class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_POWERPC_PPCREGISTERINFO_H
#define LLVM_LIB_TARGET_POWERPC_PPCREGISTERINFO_H
#include "MCTargetDesc/PPCMCTargetDesc.h"
#include "llvm/ADT/DenseMap.h"
#define GET_REGINFO_HEADER
#include "PPCGenRegisterInfo.inc"
namespace llvm {
class PPCTargetMachine;
inline static unsigned getCRFromCRBit(unsigned SrcReg) {
unsigned Reg = 0;
if (SrcReg == PPC::CR0LT || SrcReg == PPC::CR0GT ||
SrcReg == PPC::CR0EQ || SrcReg == PPC::CR0UN)
Reg = PPC::CR0;
else if (SrcReg == PPC::CR1LT || SrcReg == PPC::CR1GT ||
SrcReg == PPC::CR1EQ || SrcReg == PPC::CR1UN)
Reg = PPC::CR1;
else if (SrcReg == PPC::CR2LT || SrcReg == PPC::CR2GT ||
SrcReg == PPC::CR2EQ || SrcReg == PPC::CR2UN)
Reg = PPC::CR2;
else if (SrcReg == PPC::CR3LT || SrcReg == PPC::CR3GT ||
SrcReg == PPC::CR3EQ || SrcReg == PPC::CR3UN)
Reg = PPC::CR3;
else if (SrcReg == PPC::CR4LT || SrcReg == PPC::CR4GT ||
SrcReg == PPC::CR4EQ || SrcReg == PPC::CR4UN)
Reg = PPC::CR4;
else if (SrcReg == PPC::CR5LT || SrcReg == PPC::CR5GT ||
SrcReg == PPC::CR5EQ || SrcReg == PPC::CR5UN)
Reg = PPC::CR5;
else if (SrcReg == PPC::CR6LT || SrcReg == PPC::CR6GT ||
SrcReg == PPC::CR6EQ || SrcReg == PPC::CR6UN)
Reg = PPC::CR6;
else if (SrcReg == PPC::CR7LT || SrcReg == PPC::CR7GT ||
SrcReg == PPC::CR7EQ || SrcReg == PPC::CR7UN)
Reg = PPC::CR7;
assert(Reg != 0 && "Invalid CR bit register");
return Reg;
}
class PPCRegisterInfo : public PPCGenRegisterInfo {
DenseMap<unsigned, unsigned> ImmToIdxMap;
const PPCTargetMachine &TM;
public:
PPCRegisterInfo(const PPCTargetMachine &TM);
/// getMappedIdxOpcForImmOpc - Return the mapped index form load/store opcode
/// for a given imm form load/store opcode \p ImmFormOpcode.
/// FIXME: move this to PPCInstrInfo class.
unsigned getMappedIdxOpcForImmOpc(unsigned ImmOpcode) const {
if (!ImmToIdxMap.count(ImmOpcode))
return PPC::INSTRUCTION_LIST_END;
return ImmToIdxMap.find(ImmOpcode)->second;
}
/// getPointerRegClass - Return the register class to use to hold pointers.
/// This is used for addressing modes.
const TargetRegisterClass *
getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override;
unsigned getRegPressureLimit(const TargetRegisterClass *RC,
MachineFunction &MF) const override;
const TargetRegisterClass *
getLargestLegalSuperClass(const TargetRegisterClass *RC,
const MachineFunction &MF) const override;
/// Code Generation virtual methods...
const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
const uint32_t *getCallPreservedMask(const MachineFunction &MF,
CallingConv::ID CC) const override;
const uint32_t *getNoPreservedMask() const override;
void adjustStackMapLiveOutMask(uint32_t *Mask) const override;
BitVector getReservedRegs(const MachineFunction &MF) const override;
bool isCallerPreservedPhysReg(unsigned PhysReg, const MachineFunction &MF) const override;
/// We require the register scavenger.
bool requiresRegisterScavenging(const MachineFunction &MF) const override {
return true;
}
bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override {
return true;
}
bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override {
return true;
}
void lowerDynamicAlloc(MachineBasicBlock::iterator II) const;
void lowerDynamicAreaOffset(MachineBasicBlock::iterator II) const;
void lowerCRSpilling(MachineBasicBlock::iterator II,
unsigned FrameIndex) const;
void lowerCRRestore(MachineBasicBlock::iterator II,
unsigned FrameIndex) const;
void lowerCRBitSpilling(MachineBasicBlock::iterator II,
unsigned FrameIndex) const;
void lowerCRBitRestore(MachineBasicBlock::iterator II,
unsigned FrameIndex) const;
void lowerVRSAVESpilling(MachineBasicBlock::iterator II,
unsigned FrameIndex) const;
void lowerVRSAVERestore(MachineBasicBlock::iterator II,
unsigned FrameIndex) const;
bool hasReservedSpillSlot(const MachineFunction &MF, unsigned Reg,
int &FrameIdx) const override;
void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
unsigned FIOperandNum,
RegScavenger *RS = nullptr) const override;
// Support for virtual base registers.
bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
void materializeFrameBaseRegister(MachineBasicBlock *MBB,
unsigned BaseReg, int FrameIdx,
int64_t Offset) const override;
void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
int64_t Offset) const override;
bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg,
int64_t Offset) const override;
// Debug information queries.
Register getFrameRegister(const MachineFunction &MF) const override;
// Base pointer (stack realignment) support.
Register getBaseRegister(const MachineFunction &MF) const;
bool hasBasePointer(const MachineFunction &MF) const;
/// stripRegisterPrefix - This method strips the character prefix from a
/// register name so that only the number is left. Used by for linux asm.
static const char *stripRegisterPrefix(const char *RegName) {
switch (RegName[0]) {
case 'r':
case 'f':
case 'q': // for QPX
case 'v':
if (RegName[1] == 's')
return RegName + 2;
return RegName + 1;
case 'c': if (RegName[1] == 'r') return RegName + 2;
}
return RegName;
}
};
} // end namespace llvm
#endif
|