blob: 5fbced0f9f1096a0e03486d9ad6ce0799f76db6d [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"
Chris Lattnercb0a1202002-02-03 07:49:49 +000018#include "llvm/CodeGen/MachineCodeForMethod.h"
Vikram S. Adve242a8082002-05-19 15:25:51 +000019#include "llvm/CodeGen/MachineCodeForInstruction.h"
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000020#include "llvm/Function.h"
Vikram S. Adve242a8082002-05-19 15:25:51 +000021#include "llvm/BasicBlock.h"
22#include "llvm/Instruction.h"
Chris Lattner31bcdb82002-04-28 19:55:58 +000023#include "llvm/Constants.h"
Vikram S. Adveb9c38632001-11-08 04:57:53 +000024#include "llvm/DerivedTypes.h"
Vikram S. Adve30764b82001-10-18 00:01:48 +000025
26
27//************************ Internal Functions ******************************/
28
29
Vikram S. Adve242a8082002-05-19 15:25:51 +000030static inline void
31CreateIntSetInstruction(const TargetMachine& target, Function* F,
32 int64_t C, Instruction* dest,
33 std::vector<MachineInstr*>& mvec,
34 MachineCodeForInstruction& mcfi)
Vikram S. Adve30764b82001-10-18 00:01:48 +000035{
Vikram S. Adve242a8082002-05-19 15:25:51 +000036 assert(dest->getType()->isSigned() && "Use CreateUIntSetInstruction()");
37
38 MachineInstr* M;
Vikram S. Advea2a70942001-10-28 21:41:46 +000039 uint64_t absC = (C >= 0)? C : -C;
40 if (absC > (unsigned int) ~0)
41 { // C does not fit in 32 bits
Chris Lattnercb0a1202002-02-03 07:49:49 +000042 TmpInstruction* tmpReg = new TmpInstruction(Type::IntTy);
Vikram S. Adve242a8082002-05-19 15:25:51 +000043 mcfi.addTemp(tmpReg);
Vikram S. Advea2a70942001-10-28 21:41:46 +000044
Vikram S. Adve242a8082002-05-19 15:25:51 +000045 M = new MachineInstr(SETX);
46 M->SetMachineOperandConst(0,MachineOperand::MO_SignExtendedImmed,C);
47 M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tmpReg,
48 /*isdef*/ true);
49 M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,dest);
50 mvec.push_back(M);
Vikram S. Advea2a70942001-10-28 21:41:46 +000051 }
Vikram S. Advecee9d1c2001-12-15 00:33:36 +000052 else
Vikram S. Adve30764b82001-10-18 00:01:48 +000053 {
Vikram S. Adve242a8082002-05-19 15:25:51 +000054 M = Create2OperandInstr_SImmed(SETSW, C, dest);
55 mvec.push_back(M);
Vikram S. Adve30764b82001-10-18 00:01:48 +000056 }
Vikram S. Advecee9d1c2001-12-15 00:33:36 +000057}
58
Vikram S. Adve242a8082002-05-19 15:25:51 +000059static inline void
60CreateUIntSetInstruction(const TargetMachine& target, Function* F,
61 uint64_t C, Instruction* dest,
62 std::vector<MachineInstr*>& mvec,
63 MachineCodeForInstruction& mcfi)
Vikram S. Advecee9d1c2001-12-15 00:33:36 +000064{
Vikram S. Adve242a8082002-05-19 15:25:51 +000065 assert(! dest->getType()->isSigned() && "Use CreateIntSetInstruction()");
66 unsigned destSize = target.DataLayout.getTypeSize(dest->getType());
67 MachineInstr* M;
68
Vikram S. Advecee9d1c2001-12-15 00:33:36 +000069 if (C > (unsigned int) ~0)
70 { // C does not fit in 32 bits
Vikram S. Advef7cedec2002-03-31 00:13:12 +000071 assert(dest->getType() == Type::ULongTy && "Sign extension problems");
Chris Lattnercb0a1202002-02-03 07:49:49 +000072 TmpInstruction *tmpReg = new TmpInstruction(Type::IntTy);
Vikram S. Adve242a8082002-05-19 15:25:51 +000073 mcfi.addTemp(tmpReg);
Vikram S. Advecee9d1c2001-12-15 00:33:36 +000074
Vikram S. Adve242a8082002-05-19 15:25:51 +000075 M = new MachineInstr(SETX);
76 M->SetMachineOperandConst(0, MachineOperand::MO_UnextendedImmed, C);
77 M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tmpReg,
78 /*isdef*/ true);
79 M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, dest);
80 mvec.push_back(M);
Vikram S. Advecee9d1c2001-12-15 00:33:36 +000081 }
Vikram S. Adve242a8082002-05-19 15:25:51 +000082 else
Vikram S. Adve30764b82001-10-18 00:01:48 +000083 {
Vikram S. Adve242a8082002-05-19 15:25:51 +000084 // If the destination is smaller than the standard integer reg. size,
85 // we have to extend the sign-bit into upper bits of dest, so we
86 // need to put the result of the SETUW into a temporary.
87 //
88 Value* setuwDest = dest;
89 if (destSize < target.DataLayout.getIntegerRegize())
90 {
91 setuwDest = new TmpInstruction(dest, NULL, "setTmp");
92 mcfi.addTemp(setuwDest);
93 }
94
95 M = Create2OperandInstr_UImmed(SETUW, C, setuwDest);
96 mvec.push_back(M);
97
98 if (setuwDest != dest)
99 { // extend the sign-bit of the result into all upper bits of dest
100 assert(8*destSize <= 32 &&
101 "Unexpected type size > 4 and < IntRegSize?");
102 target.getInstrInfo().
103 CreateSignExtensionInstructions(target, F,
104 setuwDest, 8*destSize, dest,
105 mvec, mcfi);
106 }
Vikram S. Advef7cedec2002-03-31 00:13:12 +0000107 }
Vikram S. Adve242a8082002-05-19 15:25:51 +0000108
109#define USE_DIRECT_SIGN_EXTENSION_INSTRS
110#ifndef USE_DIRECT_SIGN_EXTENSION_INSTRS
Vikram S. Advef7cedec2002-03-31 00:13:12 +0000111 else
112 { // cast to signed type of the right length and use signed op (SETSW)
113 // to get correct sign extension
114 //
115 minstr = new MachineInstr(SETSW);
116 minstr->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,dest);
117
118 switch (dest->getType()->getPrimitiveID())
119 {
120 case Type::UIntTyID:
121 minstr->SetMachineOperandConst(0,
122 MachineOperand::MO_SignExtendedImmed,
123 (int) C);
124 break;
125 case Type::UShortTyID:
126 minstr->SetMachineOperandConst(0,
127 MachineOperand::MO_SignExtendedImmed,
128 (short) C);
129 break;
130 case Type::UByteTyID:
131 minstr->SetMachineOperandConst(0,
132 MachineOperand::MO_SignExtendedImmed,
133 (char) C);
134 break;
135 default:
136 assert(0 && "Unexpected unsigned type");
137 break;
138 }
Vikram S. Adve30764b82001-10-18 00:01:48 +0000139 }
Vikram S. Adve242a8082002-05-19 15:25:51 +0000140#endif USE_DIRECT_SIGN_EXTENSION_INSTRS
Vikram S. Adve30764b82001-10-18 00:01:48 +0000141}
142
143//************************* External Classes *******************************/
144
145//---------------------------------------------------------------------------
146// class UltraSparcInstrInfo
147//
148// Purpose:
149// Information about individual instructions.
150// Most information is stored in the SparcMachineInstrDesc array above.
151// Other information is computed on demand, and most such functions
152// default to member functions in base class MachineInstrInfo.
153//---------------------------------------------------------------------------
154
155/*ctor*/
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000156UltraSparcInstrInfo::UltraSparcInstrInfo(const TargetMachine& tgt)
157 : MachineInstrInfo(tgt, SparcMachineInstrDesc,
Vikram S. Adve30764b82001-10-18 00:01:48 +0000158 /*descSize = */ NUM_TOTAL_OPCODES,
159 /*numRealOpCodes = */ NUM_REAL_OPCODES)
160{
161}
162
Vikram S. Advee76af292002-03-18 03:09:15 +0000163//
Vikram S. Adve30764b82001-10-18 00:01:48 +0000164// Create an instruction sequence to put the constant `val' into
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000165// the virtual register `dest'. `val' may be a Constant or a
Vikram S. Adve30764b82001-10-18 00:01:48 +0000166// GlobalValue, viz., the constant address of a global variable or function.
Vikram S. Adve242a8082002-05-19 15:25:51 +0000167// The generated instructions are returned in `mvec'.
168// Any temp. registers (TmpInstruction) created are recorded in mcfi.
169// Any stack space required is allocated via MachineCodeForMethod.
Vikram S. Adve30764b82001-10-18 00:01:48 +0000170//
171void
Vikram S. Adve242a8082002-05-19 15:25:51 +0000172UltraSparcInstrInfo::CreateCodeToLoadConst(const TargetMachine& target,
173 Function* F,
174 Value* val,
Vikram S. Advee76af292002-03-18 03:09:15 +0000175 Instruction* dest,
Vikram S. Adve242a8082002-05-19 15:25:51 +0000176 std::vector<MachineInstr*>& mvec,
177 MachineCodeForInstruction& mcfi) const
Vikram S. Adve30764b82001-10-18 00:01:48 +0000178{
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000179 assert(isa<Constant>(val) || isa<GlobalValue>(val) &&
Vikram S. Adve30764b82001-10-18 00:01:48 +0000180 "I only know about constant values and global addresses");
181
182 // Use a "set" instruction for known constants that can go in an integer reg.
183 // Use a "load" instruction for all other constants, in particular,
184 // floating point constants and addresses of globals.
185 //
186 const Type* valType = val->getType();
187
188 if (valType->isIntegral() || valType == Type::BoolTy)
189 {
Vikram S. Adve242a8082002-05-19 15:25:51 +0000190 if (! val->getType()->isSigned())
Vikram S. Advecee9d1c2001-12-15 00:33:36 +0000191 {
Vikram S. Adve242a8082002-05-19 15:25:51 +0000192 uint64_t C = cast<ConstantUInt>(val)->getValue();
193 CreateUIntSetInstruction(target, F, C, dest, mvec, mcfi);
Vikram S. Advecee9d1c2001-12-15 00:33:36 +0000194 }
195 else
196 {
197 bool isValidConstant;
198 int64_t C = GetConstantValueAsSignedInt(val, isValidConstant);
199 assert(isValidConstant && "Unrecognized constant");
Vikram S. Adve242a8082002-05-19 15:25:51 +0000200 CreateIntSetInstruction(target, F, C, dest, mvec, mcfi);
Vikram S. Advecee9d1c2001-12-15 00:33:36 +0000201 }
Vikram S. Adve30764b82001-10-18 00:01:48 +0000202 }
203 else
204 {
205 // Make an instruction sequence to load the constant, viz:
Vikram S. Advea2a70942001-10-28 21:41:46 +0000206 // SETX <addr-of-constant>, tmpReg, addrReg
Vikram S. Adve30764b82001-10-18 00:01:48 +0000207 // LOAD /*addr*/ addrReg, /*offset*/ 0, dest
Vikram S. Advea2a70942001-10-28 21:41:46 +0000208 // Only the SETX is needed if `val' is a GlobalValue, i.e,. it is
Vikram S. Adve30764b82001-10-18 00:01:48 +0000209 // itself a constant address. Otherwise, both are needed.
210
211 Value* addrVal;
212 int64_t zeroOffset = 0; // to avoid ambiguity with (Value*) 0
213
Vikram S. Advea2a70942001-10-28 21:41:46 +0000214 TmpInstruction* tmpReg =
Chris Lattnercb0a1202002-02-03 07:49:49 +0000215 new TmpInstruction(PointerType::get(val->getType()), val);
Vikram S. Adve242a8082002-05-19 15:25:51 +0000216 mcfi.addTemp(tmpReg);
Vikram S. Advea2a70942001-10-28 21:41:46 +0000217
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000218 if (isa<Constant>(val))
Vikram S. Adve30764b82001-10-18 00:01:48 +0000219 {
220 // Create another TmpInstruction for the hidden integer register
221 TmpInstruction* addrReg =
Chris Lattnercb0a1202002-02-03 07:49:49 +0000222 new TmpInstruction(PointerType::get(val->getType()), val);
Vikram S. Adve242a8082002-05-19 15:25:51 +0000223 mcfi.addTemp(addrReg);
Vikram S. Adve30764b82001-10-18 00:01:48 +0000224 addrVal = addrReg;
225 }
226 else
227 addrVal = dest;
228
Vikram S. Adve242a8082002-05-19 15:25:51 +0000229 MachineInstr* M = new MachineInstr(SETX);
230 M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp, val);
231 M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tmpReg,
232 /*isdef*/ true);
233 M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, addrVal);
234 mvec.push_back(M);
Vikram S. Adve30764b82001-10-18 00:01:48 +0000235
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000236 if (isa<Constant>(val))
Vikram S. Adve30764b82001-10-18 00:01:48 +0000237 {
Vikram S. Advee76af292002-03-18 03:09:15 +0000238 // Make sure constant is emitted to constant pool in assembly code.
Vikram S. Adve242a8082002-05-19 15:25:51 +0000239 MachineCodeForMethod::get(F).addToConstantPool(cast<Constant>(val));
Vikram S. Advee76af292002-03-18 03:09:15 +0000240
241 // Generate the load instruction
Vikram S. Adve242a8082002-05-19 15:25:51 +0000242 M = Create3OperandInstr_SImmed(ChooseLoadInstruction(val->getType()),
243 addrVal, zeroOffset, dest);
244 mvec.push_back(M);
Vikram S. Adve30764b82001-10-18 00:01:48 +0000245 }
246 }
247}
248
249
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000250// Create an instruction sequence to copy an integer value `val'
251// to a floating point value `dest' by copying to memory and back.
252// val must be an integral type. dest must be a Float or Double.
Vikram S. Adve242a8082002-05-19 15:25:51 +0000253// The generated instructions are returned in `mvec'.
254// Any temp. registers (TmpInstruction) created are recorded in mcfi.
255// Any stack space required is allocated via MachineCodeForMethod.
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000256//
257void
Vikram S. Adve242a8082002-05-19 15:25:51 +0000258UltraSparcInstrInfo::CreateCodeToCopyIntToFloat(const TargetMachine& target,
259 Function* F,
260 Value* val,
261 Instruction* dest,
262 std::vector<MachineInstr*>& mvec,
263 MachineCodeForInstruction& mcfi) const
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000264{
Chris Lattner9b625032002-05-06 16:15:30 +0000265 assert((val->getType()->isIntegral() || isa<PointerType>(val->getType()))
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000266 && "Source type must be integral");
Chris Lattner9b625032002-05-06 16:15:30 +0000267 assert(dest->getType()->isFloatingPoint()
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000268 && "Dest type must be float/double");
269
Vikram S. Adve242a8082002-05-19 15:25:51 +0000270 int offset = MachineCodeForMethod::get(F).allocateLocalVar(target, val);
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000271
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000272 // Store instruction stores `val' to [%fp+offset].
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000273 // The store and load opCodes are based on the value being copied, and
Vikram S. Adveb9959d82001-11-15 14:59:56 +0000274 // they use integer and float types that accomodate the
275 // larger of the source type and the destination type:
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000276 // On SparcV9: int for float, long for double.
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000277 //
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000278 Type* tmpType = (dest->getType() == Type::FloatTy)? Type::IntTy
279 : Type::LongTy;
280 MachineInstr* store = new MachineInstr(ChooseStoreInstruction(tmpType));
Vikram S. Advee76af292002-03-18 03:09:15 +0000281 store->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, val);
282 store->SetMachineOperandReg(1, target.getRegInfo().getFramePointer());
Vikram S. Adve242a8082002-05-19 15:25:51 +0000283 store->SetMachineOperandConst(2,MachineOperand::MO_SignExtendedImmed,offset);
284 mvec.push_back(store);
Vikram S. Adve30764b82001-10-18 00:01:48 +0000285
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000286 // Load instruction loads [%fp+offset] to `dest'.
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000287 //
Vikram S. Adveb9959d82001-11-15 14:59:56 +0000288 MachineInstr* load =new MachineInstr(ChooseLoadInstruction(dest->getType()));
Vikram S. Advee76af292002-03-18 03:09:15 +0000289 load->SetMachineOperandReg(0, target.getRegInfo().getFramePointer());
290 load->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,offset);
291 load->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, dest);
Vikram S. Adve242a8082002-05-19 15:25:51 +0000292 mvec.push_back(load);
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000293}
294
295
296// Similarly, create an instruction sequence to copy an FP value
297// `val' to an integer value `dest' by copying to memory and back.
Vikram S. Adve242a8082002-05-19 15:25:51 +0000298// The generated instructions are returned in `mvec'.
299// Any temp. registers (TmpInstruction) created are recorded in mcfi.
300// Any stack space required is allocated via MachineCodeForMethod.
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000301//
302void
Vikram S. Adve242a8082002-05-19 15:25:51 +0000303UltraSparcInstrInfo::CreateCodeToCopyFloatToInt(const TargetMachine& target,
304 Function* F,
Chris Lattner697954c2002-01-20 22:54:45 +0000305 Value* val,
306 Instruction* dest,
Vikram S. Adve242a8082002-05-19 15:25:51 +0000307 std::vector<MachineInstr*>& mvec,
308 MachineCodeForInstruction& mcfi) const
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000309{
Chris Lattner9b625032002-05-06 16:15:30 +0000310 assert(val->getType()->isFloatingPoint()
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000311 && "Source type must be float/double");
Chris Lattner9b625032002-05-06 16:15:30 +0000312 assert((dest->getType()->isIntegral() || isa<PointerType>(dest->getType()))
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000313 && "Dest type must be integral");
314
Vikram S. Adve242a8082002-05-19 15:25:51 +0000315 int offset = MachineCodeForMethod::get(F).allocateLocalVar(target, val);
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000316
317 // Store instruction stores `val' to [%fp+offset].
318 // The store and load opCodes are based on the value being copied, and
319 // they use the integer type that matches the source type in size:
320 // On SparcV9: int for float, long for double.
321 //
322 Type* tmpType = (val->getType() == Type::FloatTy)? Type::IntTy
323 : Type::LongTy;
Vikram S. Adveb9959d82001-11-15 14:59:56 +0000324 MachineInstr* store=new MachineInstr(ChooseStoreInstruction(val->getType()));
Vikram S. Advee76af292002-03-18 03:09:15 +0000325 store->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, val);
326 store->SetMachineOperandReg(1, target.getRegInfo().getFramePointer());
327 store->SetMachineOperandConst(2,MachineOperand::MO_SignExtendedImmed,offset);
Vikram S. Adve242a8082002-05-19 15:25:51 +0000328 mvec.push_back(store);
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000329
330 // Load instruction loads [%fp+offset] to `dest'.
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000331 //
332 MachineInstr* load = new MachineInstr(ChooseLoadInstruction(tmpType));
Vikram S. Advee76af292002-03-18 03:09:15 +0000333 load->SetMachineOperandReg(0, target.getRegInfo().getFramePointer());
Vikram S. Adve242a8082002-05-19 15:25:51 +0000334 load->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,offset);
Vikram S. Advee76af292002-03-18 03:09:15 +0000335 load->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, dest);
Vikram S. Adve242a8082002-05-19 15:25:51 +0000336 mvec.push_back(load);
337}
338
339
340// Create instruction(s) to copy src to dest, for arbitrary types
341// The generated instructions are returned in `mvec'.
342// Any temp. registers (TmpInstruction) created are recorded in mcfi.
343// Any stack space required is allocated via MachineCodeForMethod.
344//
345void
346UltraSparcInstrInfo::CreateCopyInstructionsByType(const TargetMachine& target,
347 Function *F,
348 Value* src,
349 Instruction* dest,
350 vector<MachineInstr*>& mvec,
351 MachineCodeForInstruction& mcfi) const
352{
353 bool loadConstantToReg = false;
354
355 const Type* resultType = dest->getType();
356
357 MachineOpCode opCode = ChooseAddInstructionByType(resultType);
358 if (opCode == INVALID_OPCODE)
359 {
360 assert(0 && "Unsupported result type in CreateCopyInstructionsByType()");
361 return;
362 }
363
364 // if `src' is a constant that doesn't fit in the immed field or if it is
365 // a global variable (i.e., a constant address), generate a load
366 // instruction instead of an add
367 //
368 if (isa<Constant>(src))
369 {
370 unsigned int machineRegNum;
371 int64_t immedValue;
372 MachineOperand::MachineOperandType opType =
373 ChooseRegOrImmed(src, opCode, target, /*canUseImmed*/ true,
374 machineRegNum, immedValue);
375
376 if (opType == MachineOperand::MO_VirtualRegister)
377 loadConstantToReg = true;
378 }
379 else if (isa<GlobalValue>(src))
380 loadConstantToReg = true;
381
382 if (loadConstantToReg)
383 { // `src' is constant and cannot fit in immed field for the ADD
384 // Insert instructions to "load" the constant into a register
385 target.getInstrInfo().CreateCodeToLoadConst(target, F, src, dest,
386 mvec, mcfi);
387 }
388 else
389 { // Create an add-with-0 instruction of the appropriate type.
390 // Make `src' the second operand, in case it is a constant
391 // Use (unsigned long) 0 for a NULL pointer value.
392 //
393 const Type* zeroValueType =
394 isa<PointerType>(resultType) ? Type::ULongTy : resultType;
395 MachineInstr* minstr =
396 Create3OperandInstr(opCode, Constant::getNullValue(zeroValueType),
397 src, dest);
398 mvec.push_back(minstr);
399 }
400}
401
402
403// Create instruction sequence to produce a sign-extended register value
404// from an arbitrary sized value (sized in bits, not bytes).
405// For SPARC v9, we sign-extend the given unsigned operand using SLL; SRA.
406// The generated instructions are returned in `mvec'.
407// Any temp. registers (TmpInstruction) created are recorded in mcfi.
408// Any stack space required is allocated via MachineCodeForMethod.
409//
410void
411UltraSparcInstrInfo::CreateSignExtensionInstructions(
412 const TargetMachine& target,
413 Function* F,
414 Value* unsignedSrcVal,
415 unsigned int srcSizeInBits,
416 Value* dest,
417 vector<MachineInstr*>& mvec,
418 MachineCodeForInstruction& mcfi) const
419{
420 MachineInstr* M;
421
422 assert(srcSizeInBits > 0 && srcSizeInBits <= 32
423 && "Hmmm... srcSizeInBits > 32 unexpected but could be handled here.");
424
425 if (srcSizeInBits < 32)
426 { // SLL is needed since operand size is < 32 bits.
427 TmpInstruction *tmpI = new TmpInstruction(dest->getType(),
428 unsignedSrcVal, dest,"make32");
429 mcfi.addTemp(tmpI);
430 M = Create3OperandInstr_UImmed(SLL,unsignedSrcVal,32-srcSizeInBits,tmpI);
431 mvec.push_back(M);
432 unsignedSrcVal = tmpI;
433 }
434
435 M = Create3OperandInstr_UImmed(SRA, unsignedSrcVal, 32-srcSizeInBits, dest);
436 mvec.push_back(M);
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000437}