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
|
//===-- SparcV9InstrInfo.h - Define TargetInstrInfo for SparcV9 -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class contains information about individual instructions.
// Most information is stored in the SparcV9MachineInstrDesc array above.
// Other information is computed on demand, and most such functions
// default to member functions in base class TargetInstrInfo.
//
//===----------------------------------------------------------------------===//
#ifndef SPARC_INSTRINFO_H
#define SPARC_INSTRINFO_H
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "SparcV9Internals.h"
namespace llvm {
struct SparcV9InstrInfo : public TargetInstrInfo {
SparcV9InstrInfo();
// All immediate constants are in position 1 except the
// store instructions and SETxx.
//
virtual int getImmedConstantPos(MachineOpCode opCode) const {
bool ignore;
if (this->maxImmedConstant(opCode, ignore) != 0) {
// 1st store opcode
assert(! this->isStore((MachineOpCode) V9::STBr - 1));
// last store opcode
assert(! this->isStore((MachineOpCode) V9::STXFSRi + 1));
if (opCode == V9::SETSW || opCode == V9::SETUW ||
opCode == V9::SETX || opCode == V9::SETHI)
return 0;
if (opCode >= V9::STBr && opCode <= V9::STXFSRi)
return 2;
return 1;
}
else
return -1;
}
virtual bool hasResultInterlock(MachineOpCode opCode) const
{
// All UltraSPARC instructions have interlocks (note that delay slots
// are not considered here).
// However, instructions that use the result of an FCMP produce a
// 9-cycle stall if they are issued less than 3 cycles after the FCMP.
// Force the compiler to insert a software interlock (i.e., gap of
// 2 other groups, including NOPs if necessary).
return (opCode == V9::FCMPS || opCode == V9::FCMPD || opCode == V9::FCMPQ);
}
//-------------------------------------------------------------------------
// Queries about representation of LLVM quantities (e.g., constants)
//-------------------------------------------------------------------------
virtual bool ConstantMayNotFitInImmedField(const Constant* CV,
const Instruction* I) const;
//-------------------------------------------------------------------------
// Code generation support for creating individual machine instructions
//-------------------------------------------------------------------------
// Get certain common op codes for the current target. This and all the
// Create* methods below should be moved to a machine code generation class
//
virtual MachineOpCode getNOPOpCode() const { return V9::NOP; }
// Get the value of an integral constant in the form that must
// be put into the machine register. The specified constant is interpreted
// as (i.e., converted if necessary to) the specified destination type. The
// result is always returned as an uint64_t, since the representation of
// int64_t and uint64_t are identical. The argument can be any known const.
//
// isValidConstant is set to true if a valid constant was found.
//
virtual uint64_t ConvertConstantToIntType(const TargetMachine &target,
const Value *V,
const Type *destType,
bool &isValidConstant) const;
// Create an instruction sequence to put the constant `val' into
// the virtual register `dest'. `val' may be a Constant or a
// GlobalValue, viz., the constant address of a global variable or function.
// The generated instructions are returned in `mvec'.
// Any temp. registers (TmpInstruction) created are recorded in mcfi.
// Any stack space required is allocated via mcff.
//
virtual void CreateCodeToLoadConst(const TargetMachine& target,
Function* F,
Value* val,
Instruction* dest,
std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) const;
// Create an instruction sequence to copy an integer value `val'
// to a floating point value `dest' by copying to memory and back.
// val must be an integral type. dest must be a Float or Double.
// The generated instructions are returned in `mvec'.
// Any temp. registers (TmpInstruction) created are recorded in mcfi.
// Any stack space required is allocated via mcff.
//
virtual void CreateCodeToCopyIntToFloat(const TargetMachine& target,
Function* F,
Value* val,
Instruction* dest,
std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) const;
// Similarly, create an instruction sequence to copy an FP value
// `val' to an integer value `dest' by copying to memory and back.
// The generated instructions are returned in `mvec'.
// Any temp. registers (TmpInstruction) created are recorded in mcfi.
// Any stack space required is allocated via mcff.
//
virtual void CreateCodeToCopyFloatToInt(const TargetMachine& target,
Function* F,
Value* val,
Instruction* dest,
std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) const;
// Create instruction(s) to copy src to dest, for arbitrary types
// The generated instructions are returned in `mvec'.
// Any temp. registers (TmpInstruction) created are recorded in mcfi.
// Any stack space required is allocated via mcff.
//
virtual void CreateCopyInstructionsByType(const TargetMachine& target,
Function* F,
Value* src,
Instruction* dest,
std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) const;
// Create instruction sequence to produce a sign-extended register value
// from an arbitrary sized value (sized in bits, not bytes).
// The generated instructions are appended to `mvec'.
// Any temp. registers (TmpInstruction) created are recorded in mcfi.
// Any stack space required is allocated via mcff.
//
virtual void CreateSignExtensionInstructions(const TargetMachine& target,
Function* F,
Value* srcVal,
Value* destVal,
unsigned int numLowBits,
std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) const;
// Create instruction sequence to produce a zero-extended register value
// from an arbitrary sized value (sized in bits, not bytes).
// The generated instructions are appended to `mvec'.
// Any temp. registers (TmpInstruction) created are recorded in mcfi.
// Any stack space required is allocated via mcff.
//
virtual void CreateZeroExtensionInstructions(const TargetMachine& target,
Function* F,
Value* srcVal,
Value* destVal,
unsigned int numLowBits,
std::vector<MachineInstr*>& mvec,
MachineCodeForInstruction& mcfi) const;
};
} // End llvm namespace
#endif
|