blob: 318a9443bb124364b48cc2403888070e212c69bd [file] [log] [blame]
Vikram S. Adve30764b82001-10-18 00:01:48 +00001// $Id$
2//***************************************************************************
3// File:
4// SparcInstrInfo.cpp
5//
6// Purpose:
7//
8// History:
9// 10/15/01 - Vikram Adve - Created
10//**************************************************************************/
11
12
13#include "SparcInternals.h"
14#include "SparcInstrSelectionSupport.h"
15#include "llvm/Target/Sparc.h"
16#include "llvm/CodeGen/InstrSelection.h"
17#include "llvm/CodeGen/InstrSelectionSupport.h"
18#include "llvm/CodeGen/MachineInstr.h"
19#include "llvm/ConstPoolVals.h"
20#include "llvm/Type.h"
21
22
23//************************ Internal Functions ******************************/
24
25
26static inline MachineInstr*
Vikram S. Advea2a70942001-10-28 21:41:46 +000027CreateIntSetInstruction(int64_t C, bool isSigned, Value* dest,
28 vector<TmpInstruction*>& tempVec)
Vikram S. Adve30764b82001-10-18 00:01:48 +000029{
30 MachineInstr* minstr;
Vikram S. Advea2a70942001-10-28 21:41:46 +000031 uint64_t absC = (C >= 0)? C : -C;
32 if (absC > (unsigned int) ~0)
33 { // C does not fit in 32 bits
34 TmpInstruction* tmpReg =
35 new TmpInstruction(Instruction::UserOp1, NULL, NULL);
36 tempVec.push_back(tmpReg);
37
38 minstr = new MachineInstr(SETX);
39 minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
40 minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, tmpReg,
41 /*isdef*/ true);
42 minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,dest);
43 }
Vikram S. Adve30764b82001-10-18 00:01:48 +000044 if (isSigned)
45 {
46 minstr = new MachineInstr(SETSW);
47 minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
Vikram S. Advea2a70942001-10-28 21:41:46 +000048 minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, dest);
Vikram S. Adve30764b82001-10-18 00:01:48 +000049 }
50 else
51 {
52 minstr = new MachineInstr(SETUW);
53 minstr->SetMachineOperand(0, MachineOperand::MO_UnextendedImmed, C);
Vikram S. Advea2a70942001-10-28 21:41:46 +000054 minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, dest);
Vikram S. Adve30764b82001-10-18 00:01:48 +000055 }
56
Vikram S. Adve30764b82001-10-18 00:01:48 +000057 return minstr;
58}
59
60//************************* External Classes *******************************/
61
62//---------------------------------------------------------------------------
63// class UltraSparcInstrInfo
64//
65// Purpose:
66// Information about individual instructions.
67// Most information is stored in the SparcMachineInstrDesc array above.
68// Other information is computed on demand, and most such functions
69// default to member functions in base class MachineInstrInfo.
70//---------------------------------------------------------------------------
71
72/*ctor*/
73UltraSparcInstrInfo::UltraSparcInstrInfo()
74 : MachineInstrInfo(SparcMachineInstrDesc,
75 /*descSize = */ NUM_TOTAL_OPCODES,
76 /*numRealOpCodes = */ NUM_REAL_OPCODES)
77{
78}
79
80
81// Create an instruction sequence to put the constant `val' into
82// the virtual register `dest'. `val' may be a ConstPoolVal or a
83// GlobalValue, viz., the constant address of a global variable or function.
84// The generated instructions are returned in `minstrVec'.
85// Any temp. registers (TmpInstruction) created are returned in `tempVec'.
86//
87void
88UltraSparcInstrInfo::CreateCodeToLoadConst(Value* val,
89 Instruction* dest,
90 vector<MachineInstr*>& minstrVec,
91 vector<TmpInstruction*>& tempVec) const
92{
93 MachineInstr* minstr;
94
95 assert(isa<ConstPoolVal>(val) || isa<GlobalValue>(val) &&
96 "I only know about constant values and global addresses");
97
98 // Use a "set" instruction for known constants that can go in an integer reg.
99 // Use a "load" instruction for all other constants, in particular,
100 // floating point constants and addresses of globals.
101 //
102 const Type* valType = val->getType();
103
104 if (valType->isIntegral() || valType == Type::BoolTy)
105 {
106 bool isValidConstant;
107 int64_t C = GetConstantValueAsSignedInt(val, isValidConstant);
108 assert(isValidConstant && "Unrecognized constant");
Vikram S. Advea2a70942001-10-28 21:41:46 +0000109 minstr = CreateIntSetInstruction(C, valType->isSigned(), dest, tempVec);
Vikram S. Adve30764b82001-10-18 00:01:48 +0000110 minstrVec.push_back(minstr);
111 }
112 else
113 {
114 // Make an instruction sequence to load the constant, viz:
Vikram S. Advea2a70942001-10-28 21:41:46 +0000115 // SETX <addr-of-constant>, tmpReg, addrReg
Vikram S. Adve30764b82001-10-18 00:01:48 +0000116 // LOAD /*addr*/ addrReg, /*offset*/ 0, dest
Vikram S. Advea2a70942001-10-28 21:41:46 +0000117 // Only the SETX is needed if `val' is a GlobalValue, i.e,. it is
Vikram S. Adve30764b82001-10-18 00:01:48 +0000118 // itself a constant address. Otherwise, both are needed.
119
120 Value* addrVal;
121 int64_t zeroOffset = 0; // to avoid ambiguity with (Value*) 0
122
Vikram S. Advea2a70942001-10-28 21:41:46 +0000123 TmpInstruction* tmpReg =
124 new TmpInstruction(Instruction::UserOp1, val, NULL);
125 tempVec.push_back(tmpReg);
126
Vikram S. Adve30764b82001-10-18 00:01:48 +0000127 if (isa<ConstPoolVal>(val))
128 {
129 // Create another TmpInstruction for the hidden integer register
130 TmpInstruction* addrReg =
131 new TmpInstruction(Instruction::UserOp1, val, NULL);
132 tempVec.push_back(addrReg);
133 addrVal = addrReg;
134 }
135 else
136 addrVal = dest;
137
Vikram S. Advea2a70942001-10-28 21:41:46 +0000138 minstr = new MachineInstr(SETX);
Vikram S. Adve30764b82001-10-18 00:01:48 +0000139 minstr->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp, val);
Vikram S. Advea2a70942001-10-28 21:41:46 +0000140 minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, tmpReg,
141 /*isdef*/ true);
142 minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,addrVal);
Vikram S. Adve30764b82001-10-18 00:01:48 +0000143 minstrVec.push_back(minstr);
144
145 if (isa<ConstPoolVal>(val))
146 {
147 // addrVal->addMachineInstruction(minstr);
148
149 minstr = new MachineInstr(ChooseLoadInstruction(val->getType()));
150 minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
151 addrVal);
152 minstr->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
153 zeroOffset);
154 minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
155 dest);
156 minstrVec.push_back(minstr);
157 }
158 }
159}
160
161
162//************************ External Functions ******************************/
163