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
|
// $Id$
//***************************************************************************
// File:
// SparcInstrInfo.cpp
//
// Purpose:
//
// History:
// 10/15/01 - Vikram Adve - Created
//**************************************************************************/
#include "SparcInternals.h"
#include "SparcInstrSelectionSupport.h"
#include "llvm/Target/Sparc.h"
#include "llvm/CodeGen/InstrSelection.h"
#include "llvm/CodeGen/InstrSelectionSupport.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/ConstPoolVals.h"
#include "llvm/Type.h"
//************************ Internal Functions ******************************/
static inline MachineInstr*
CreateIntSetInstruction(int64_t C, bool isSigned, Value* dest)
{
MachineInstr* minstr;
if (isSigned)
{
minstr = new MachineInstr(SETSW);
minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
}
else
{
minstr = new MachineInstr(SETUW);
minstr->SetMachineOperand(0, MachineOperand::MO_UnextendedImmed, C);
}
minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, dest);
return minstr;
}
//************************* External Classes *******************************/
//---------------------------------------------------------------------------
// class UltraSparcInstrInfo
//
// Purpose:
// Information about individual instructions.
// Most information is stored in the SparcMachineInstrDesc array above.
// Other information is computed on demand, and most such functions
// default to member functions in base class MachineInstrInfo.
//---------------------------------------------------------------------------
/*ctor*/
UltraSparcInstrInfo::UltraSparcInstrInfo()
: MachineInstrInfo(SparcMachineInstrDesc,
/*descSize = */ NUM_TOTAL_OPCODES,
/*numRealOpCodes = */ NUM_REAL_OPCODES)
{
}
// Create an instruction sequence to put the constant `val' into
// the virtual register `dest'. `val' may be a ConstPoolVal or a
// GlobalValue, viz., the constant address of a global variable or function.
// The generated instructions are returned in `minstrVec'.
// Any temp. registers (TmpInstruction) created are returned in `tempVec'.
//
void
UltraSparcInstrInfo::CreateCodeToLoadConst(Value* val,
Instruction* dest,
vector<MachineInstr*>& minstrVec,
vector<TmpInstruction*>& tempVec) const
{
MachineInstr* minstr;
assert(isa<ConstPoolVal>(val) || isa<GlobalValue>(val) &&
"I only know about constant values and global addresses");
// Use a "set" instruction for known constants that can go in an integer reg.
// Use a "load" instruction for all other constants, in particular,
// floating point constants and addresses of globals.
//
const Type* valType = val->getType();
if (valType->isIntegral() || valType == Type::BoolTy)
{
bool isValidConstant;
int64_t C = GetConstantValueAsSignedInt(val, isValidConstant);
assert(isValidConstant && "Unrecognized constant");
minstr = CreateIntSetInstruction(C, valType->isSigned(), dest);
minstrVec.push_back(minstr);
}
else
{
// Make an instruction sequence to load the constant, viz:
// SETSW <addr-of-constant>, addrReg
// LOAD /*addr*/ addrReg, /*offset*/ 0, dest
// Only the SETSW is needed if `val' is a GlobalValue, i.e,. it is
// itself a constant address. Otherwise, both are needed.
Value* addrVal;
int64_t zeroOffset = 0; // to avoid ambiguity with (Value*) 0
if (isa<ConstPoolVal>(val))
{
// Create another TmpInstruction for the hidden integer register
TmpInstruction* addrReg =
new TmpInstruction(Instruction::UserOp1, val, NULL);
tempVec.push_back(addrReg);
addrVal = addrReg;
}
else
addrVal = dest;
minstr = new MachineInstr(SETUW);
minstr->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp, val);
minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,addrVal);
minstrVec.push_back(minstr);
if (isa<ConstPoolVal>(val))
{
// addrVal->addMachineInstruction(minstr);
minstr = new MachineInstr(ChooseLoadInstruction(val->getType()));
minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
addrVal);
minstr->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
zeroOffset);
minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
dest);
minstrVec.push_back(minstr);
}
}
}
//************************ External Functions ******************************/
|