blob: 6b6a40627f1a462b455baa659e8914b6e83ecc4c [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*
27CreateIntSetInstruction(int64_t C, bool isSigned, Value* dest)
28{
29 MachineInstr* minstr;
30 if (isSigned)
31 {
32 minstr = new MachineInstr(SETSW);
33 minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
34 }
35 else
36 {
37 minstr = new MachineInstr(SETUW);
38 minstr->SetMachineOperand(0, MachineOperand::MO_UnextendedImmed, C);
39 }
40
41 minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, dest);
42
43 return minstr;
44}
45
46//************************* External Classes *******************************/
47
48//---------------------------------------------------------------------------
49// class UltraSparcInstrInfo
50//
51// Purpose:
52// Information about individual instructions.
53// Most information is stored in the SparcMachineInstrDesc array above.
54// Other information is computed on demand, and most such functions
55// default to member functions in base class MachineInstrInfo.
56//---------------------------------------------------------------------------
57
58/*ctor*/
59UltraSparcInstrInfo::UltraSparcInstrInfo()
60 : MachineInstrInfo(SparcMachineInstrDesc,
61 /*descSize = */ NUM_TOTAL_OPCODES,
62 /*numRealOpCodes = */ NUM_REAL_OPCODES)
63{
64}
65
66
67// Create an instruction sequence to put the constant `val' into
68// the virtual register `dest'. `val' may be a ConstPoolVal or a
69// GlobalValue, viz., the constant address of a global variable or function.
70// The generated instructions are returned in `minstrVec'.
71// Any temp. registers (TmpInstruction) created are returned in `tempVec'.
72//
73void
74UltraSparcInstrInfo::CreateCodeToLoadConst(Value* val,
75 Instruction* dest,
76 vector<MachineInstr*>& minstrVec,
77 vector<TmpInstruction*>& tempVec) const
78{
79 MachineInstr* minstr;
80
81 assert(isa<ConstPoolVal>(val) || isa<GlobalValue>(val) &&
82 "I only know about constant values and global addresses");
83
84 // Use a "set" instruction for known constants that can go in an integer reg.
85 // Use a "load" instruction for all other constants, in particular,
86 // floating point constants and addresses of globals.
87 //
88 const Type* valType = val->getType();
89
90 if (valType->isIntegral() || valType == Type::BoolTy)
91 {
92 bool isValidConstant;
93 int64_t C = GetConstantValueAsSignedInt(val, isValidConstant);
94 assert(isValidConstant && "Unrecognized constant");
95 minstr = CreateIntSetInstruction(C, valType->isSigned(), dest);
96 minstrVec.push_back(minstr);
97 }
98 else
99 {
100 // Make an instruction sequence to load the constant, viz:
101 // SETSW <addr-of-constant>, addrReg
102 // LOAD /*addr*/ addrReg, /*offset*/ 0, dest
103 // Only the SETSW is needed if `val' is a GlobalValue, i.e,. it is
104 // itself a constant address. Otherwise, both are needed.
105
106 Value* addrVal;
107 int64_t zeroOffset = 0; // to avoid ambiguity with (Value*) 0
108
109 if (isa<ConstPoolVal>(val))
110 {
111 // Create another TmpInstruction for the hidden integer register
112 TmpInstruction* addrReg =
113 new TmpInstruction(Instruction::UserOp1, val, NULL);
114 tempVec.push_back(addrReg);
115 addrVal = addrReg;
116 }
117 else
118 addrVal = dest;
119
120 minstr = new MachineInstr(SETUW);
121 minstr->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp, val);
122 minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,addrVal);
123 minstrVec.push_back(minstr);
124
125 if (isa<ConstPoolVal>(val))
126 {
127 // addrVal->addMachineInstruction(minstr);
128
129 minstr = new MachineInstr(ChooseLoadInstruction(val->getType()));
130 minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
131 addrVal);
132 minstr->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
133 zeroOffset);
134 minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
135 dest);
136 minstrVec.push_back(minstr);
137 }
138 }
139}
140
141
142//************************ External Functions ******************************/
143