blob: 7adf9e4081a5af9ebf7386d9eee0b4f324615bff [file] [log] [blame]
Vikram S. Adve30764b82001-10-18 00:01:48 +00001//***************************************************************************
2// File:
3// SparcInstrInfo.cpp
4//
5// Purpose:
6//
7// History:
8// 10/15/01 - Vikram Adve - Created
9//**************************************************************************/
10
11
12#include "SparcInternals.h"
13#include "SparcInstrSelectionSupport.h"
14#include "llvm/Target/Sparc.h"
15#include "llvm/CodeGen/InstrSelection.h"
16#include "llvm/CodeGen/InstrSelectionSupport.h"
Chris Lattnercb0a1202002-02-03 07:49:49 +000017#include "llvm/CodeGen/MachineCodeForMethod.h"
Vikram S. Adve242a8082002-05-19 15:25:51 +000018#include "llvm/CodeGen/MachineCodeForInstruction.h"
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000019#include "llvm/Function.h"
Vikram S. Adve242a8082002-05-19 15:25:51 +000020#include "llvm/BasicBlock.h"
21#include "llvm/Instruction.h"
Chris Lattner31bcdb82002-04-28 19:55:58 +000022#include "llvm/Constants.h"
Vikram S. Adveb9c38632001-11-08 04:57:53 +000023#include "llvm/DerivedTypes.h"
Anand Shuklacfb22d32002-06-25 20:55:50 +000024using std::vector;
Vikram S. Adve30764b82001-10-18 00:01:48 +000025
26//************************ Internal Functions ******************************/
27
28
Vikram S. Adve242a8082002-05-19 15:25:51 +000029static inline void
30CreateIntSetInstruction(const TargetMachine& target, Function* F,
31 int64_t C, Instruction* dest,
32 std::vector<MachineInstr*>& mvec,
33 MachineCodeForInstruction& mcfi)
Vikram S. Adve30764b82001-10-18 00:01:48 +000034{
Vikram S. Adve242a8082002-05-19 15:25:51 +000035 assert(dest->getType()->isSigned() && "Use CreateUIntSetInstruction()");
36
37 MachineInstr* M;
Vikram S. Advea2a70942001-10-28 21:41:46 +000038 uint64_t absC = (C >= 0)? C : -C;
39 if (absC > (unsigned int) ~0)
40 { // C does not fit in 32 bits
Chris Lattnercb0a1202002-02-03 07:49:49 +000041 TmpInstruction* tmpReg = new TmpInstruction(Type::IntTy);
Vikram S. Adve242a8082002-05-19 15:25:51 +000042 mcfi.addTemp(tmpReg);
Vikram S. Advea2a70942001-10-28 21:41:46 +000043
Vikram S. Adve242a8082002-05-19 15:25:51 +000044 M = new MachineInstr(SETX);
45 M->SetMachineOperandConst(0,MachineOperand::MO_SignExtendedImmed,C);
46 M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tmpReg,
47 /*isdef*/ true);
48 M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister,dest);
49 mvec.push_back(M);
Vikram S. Advea2a70942001-10-28 21:41:46 +000050 }
Vikram S. Advecee9d1c2001-12-15 00:33:36 +000051 else
Vikram S. Adve30764b82001-10-18 00:01:48 +000052 {
Vikram S. Adve242a8082002-05-19 15:25:51 +000053 M = Create2OperandInstr_SImmed(SETSW, C, dest);
54 mvec.push_back(M);
Vikram S. Adve30764b82001-10-18 00:01:48 +000055 }
Vikram S. Advecee9d1c2001-12-15 00:33:36 +000056}
57
Vikram S. Adve242a8082002-05-19 15:25:51 +000058static inline void
59CreateUIntSetInstruction(const TargetMachine& target, Function* F,
60 uint64_t C, Instruction* dest,
61 std::vector<MachineInstr*>& mvec,
62 MachineCodeForInstruction& mcfi)
Vikram S. Advecee9d1c2001-12-15 00:33:36 +000063{
Vikram S. Adve242a8082002-05-19 15:25:51 +000064 assert(! dest->getType()->isSigned() && "Use CreateIntSetInstruction()");
65 unsigned destSize = target.DataLayout.getTypeSize(dest->getType());
66 MachineInstr* M;
67
Vikram S. Advecee9d1c2001-12-15 00:33:36 +000068 if (C > (unsigned int) ~0)
69 { // C does not fit in 32 bits
Vikram S. Advef7cedec2002-03-31 00:13:12 +000070 assert(dest->getType() == Type::ULongTy && "Sign extension problems");
Chris Lattnercb0a1202002-02-03 07:49:49 +000071 TmpInstruction *tmpReg = new TmpInstruction(Type::IntTy);
Vikram S. Adve242a8082002-05-19 15:25:51 +000072 mcfi.addTemp(tmpReg);
Vikram S. Advecee9d1c2001-12-15 00:33:36 +000073
Vikram S. Adve242a8082002-05-19 15:25:51 +000074 M = new MachineInstr(SETX);
75 M->SetMachineOperandConst(0, MachineOperand::MO_UnextendedImmed, C);
76 M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tmpReg,
77 /*isdef*/ true);
78 M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, dest);
79 mvec.push_back(M);
Vikram S. Advecee9d1c2001-12-15 00:33:36 +000080 }
Vikram S. Adve242a8082002-05-19 15:25:51 +000081 else
Vikram S. Adve30764b82001-10-18 00:01:48 +000082 {
Vikram S. Adve242a8082002-05-19 15:25:51 +000083 // If the destination is smaller than the standard integer reg. size,
84 // we have to extend the sign-bit into upper bits of dest, so we
85 // need to put the result of the SETUW into a temporary.
86 //
87 Value* setuwDest = dest;
88 if (destSize < target.DataLayout.getIntegerRegize())
89 {
90 setuwDest = new TmpInstruction(dest, NULL, "setTmp");
91 mcfi.addTemp(setuwDest);
92 }
93
94 M = Create2OperandInstr_UImmed(SETUW, C, setuwDest);
95 mvec.push_back(M);
96
97 if (setuwDest != dest)
98 { // extend the sign-bit of the result into all upper bits of dest
99 assert(8*destSize <= 32 &&
100 "Unexpected type size > 4 and < IntRegSize?");
101 target.getInstrInfo().
102 CreateSignExtensionInstructions(target, F,
103 setuwDest, 8*destSize, dest,
104 mvec, mcfi);
105 }
Vikram S. Advef7cedec2002-03-31 00:13:12 +0000106 }
Vikram S. Adve242a8082002-05-19 15:25:51 +0000107
108#define USE_DIRECT_SIGN_EXTENSION_INSTRS
109#ifndef USE_DIRECT_SIGN_EXTENSION_INSTRS
Vikram S. Advef7cedec2002-03-31 00:13:12 +0000110 else
111 { // cast to signed type of the right length and use signed op (SETSW)
112 // to get correct sign extension
113 //
114 minstr = new MachineInstr(SETSW);
115 minstr->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister,dest);
116
117 switch (dest->getType()->getPrimitiveID())
118 {
119 case Type::UIntTyID:
120 minstr->SetMachineOperandConst(0,
121 MachineOperand::MO_SignExtendedImmed,
122 (int) C);
123 break;
124 case Type::UShortTyID:
125 minstr->SetMachineOperandConst(0,
126 MachineOperand::MO_SignExtendedImmed,
127 (short) C);
128 break;
129 case Type::UByteTyID:
130 minstr->SetMachineOperandConst(0,
131 MachineOperand::MO_SignExtendedImmed,
132 (char) C);
133 break;
134 default:
135 assert(0 && "Unexpected unsigned type");
136 break;
137 }
Vikram S. Adve30764b82001-10-18 00:01:48 +0000138 }
Vikram S. Adve242a8082002-05-19 15:25:51 +0000139#endif USE_DIRECT_SIGN_EXTENSION_INSTRS
Vikram S. Adve30764b82001-10-18 00:01:48 +0000140}
141
142//************************* External Classes *******************************/
143
144//---------------------------------------------------------------------------
145// class UltraSparcInstrInfo
146//
147// Purpose:
148// Information about individual instructions.
149// Most information is stored in the SparcMachineInstrDesc array above.
150// Other information is computed on demand, and most such functions
151// default to member functions in base class MachineInstrInfo.
152//---------------------------------------------------------------------------
153
154/*ctor*/
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000155UltraSparcInstrInfo::UltraSparcInstrInfo(const TargetMachine& tgt)
156 : MachineInstrInfo(tgt, SparcMachineInstrDesc,
Vikram S. Adve30764b82001-10-18 00:01:48 +0000157 /*descSize = */ NUM_TOTAL_OPCODES,
158 /*numRealOpCodes = */ NUM_REAL_OPCODES)
159{
160}
161
Vikram S. Advee76af292002-03-18 03:09:15 +0000162//
Vikram S. Adve30764b82001-10-18 00:01:48 +0000163// Create an instruction sequence to put the constant `val' into
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000164// the virtual register `dest'. `val' may be a Constant or a
Vikram S. Adve30764b82001-10-18 00:01:48 +0000165// GlobalValue, viz., the constant address of a global variable or function.
Vikram S. Adve242a8082002-05-19 15:25:51 +0000166// The generated instructions are returned in `mvec'.
167// Any temp. registers (TmpInstruction) created are recorded in mcfi.
168// Any stack space required is allocated via MachineCodeForMethod.
Vikram S. Adve30764b82001-10-18 00:01:48 +0000169//
170void
Vikram S. Adve242a8082002-05-19 15:25:51 +0000171UltraSparcInstrInfo::CreateCodeToLoadConst(const TargetMachine& target,
172 Function* F,
173 Value* val,
Vikram S. Advee76af292002-03-18 03:09:15 +0000174 Instruction* dest,
Vikram S. Adve242a8082002-05-19 15:25:51 +0000175 std::vector<MachineInstr*>& mvec,
176 MachineCodeForInstruction& mcfi) const
Vikram S. Adve30764b82001-10-18 00:01:48 +0000177{
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000178 assert(isa<Constant>(val) || isa<GlobalValue>(val) &&
Vikram S. Adve30764b82001-10-18 00:01:48 +0000179 "I only know about constant values and global addresses");
180
181 // Use a "set" instruction for known constants that can go in an integer reg.
182 // Use a "load" instruction for all other constants, in particular,
183 // floating point constants and addresses of globals.
184 //
185 const Type* valType = val->getType();
186
187 if (valType->isIntegral() || valType == Type::BoolTy)
188 {
Vikram S. Adve242a8082002-05-19 15:25:51 +0000189 if (! val->getType()->isSigned())
Vikram S. Advecee9d1c2001-12-15 00:33:36 +0000190 {
Vikram S. Adve242a8082002-05-19 15:25:51 +0000191 uint64_t C = cast<ConstantUInt>(val)->getValue();
192 CreateUIntSetInstruction(target, F, C, dest, mvec, mcfi);
Vikram S. Advecee9d1c2001-12-15 00:33:36 +0000193 }
194 else
195 {
196 bool isValidConstant;
197 int64_t C = GetConstantValueAsSignedInt(val, isValidConstant);
198 assert(isValidConstant && "Unrecognized constant");
Vikram S. Adve242a8082002-05-19 15:25:51 +0000199 CreateIntSetInstruction(target, F, C, dest, mvec, mcfi);
Vikram S. Advecee9d1c2001-12-15 00:33:36 +0000200 }
Vikram S. Adve30764b82001-10-18 00:01:48 +0000201 }
202 else
203 {
204 // Make an instruction sequence to load the constant, viz:
Vikram S. Advea2a70942001-10-28 21:41:46 +0000205 // SETX <addr-of-constant>, tmpReg, addrReg
Vikram S. Adve30764b82001-10-18 00:01:48 +0000206 // LOAD /*addr*/ addrReg, /*offset*/ 0, dest
Vikram S. Advea2a70942001-10-28 21:41:46 +0000207 // Only the SETX is needed if `val' is a GlobalValue, i.e,. it is
Vikram S. Adve30764b82001-10-18 00:01:48 +0000208 // itself a constant address. Otherwise, both are needed.
209
210 Value* addrVal;
211 int64_t zeroOffset = 0; // to avoid ambiguity with (Value*) 0
212
Vikram S. Advea2a70942001-10-28 21:41:46 +0000213 TmpInstruction* tmpReg =
Chris Lattnercb0a1202002-02-03 07:49:49 +0000214 new TmpInstruction(PointerType::get(val->getType()), val);
Vikram S. Adve242a8082002-05-19 15:25:51 +0000215 mcfi.addTemp(tmpReg);
Vikram S. Advea2a70942001-10-28 21:41:46 +0000216
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000217 if (isa<Constant>(val))
Vikram S. Adve30764b82001-10-18 00:01:48 +0000218 {
219 // Create another TmpInstruction for the hidden integer register
220 TmpInstruction* addrReg =
Chris Lattnercb0a1202002-02-03 07:49:49 +0000221 new TmpInstruction(PointerType::get(val->getType()), val);
Vikram S. Adve242a8082002-05-19 15:25:51 +0000222 mcfi.addTemp(addrReg);
Vikram S. Adve30764b82001-10-18 00:01:48 +0000223 addrVal = addrReg;
224 }
225 else
226 addrVal = dest;
227
Vikram S. Adve242a8082002-05-19 15:25:51 +0000228 MachineInstr* M = new MachineInstr(SETX);
229 M->SetMachineOperandVal(0, MachineOperand::MO_PCRelativeDisp, val);
230 M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tmpReg,
231 /*isdef*/ true);
232 M->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, addrVal);
233 mvec.push_back(M);
Vikram S. Adve30764b82001-10-18 00:01:48 +0000234
Chris Lattnere9bb2df2001-12-03 22:26:30 +0000235 if (isa<Constant>(val))
Vikram S. Adve30764b82001-10-18 00:01:48 +0000236 {
Vikram S. Advee76af292002-03-18 03:09:15 +0000237 // Make sure constant is emitted to constant pool in assembly code.
Vikram S. Adve242a8082002-05-19 15:25:51 +0000238 MachineCodeForMethod::get(F).addToConstantPool(cast<Constant>(val));
Vikram S. Advee76af292002-03-18 03:09:15 +0000239
240 // Generate the load instruction
Vikram S. Adve242a8082002-05-19 15:25:51 +0000241 M = Create3OperandInstr_SImmed(ChooseLoadInstruction(val->getType()),
242 addrVal, zeroOffset, dest);
243 mvec.push_back(M);
Vikram S. Adve30764b82001-10-18 00:01:48 +0000244 }
245 }
246}
247
248
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000249// Create an instruction sequence to copy an integer value `val'
250// to a floating point value `dest' by copying to memory and back.
251// val must be an integral type. dest must be a Float or Double.
Vikram S. Adve242a8082002-05-19 15:25:51 +0000252// The generated instructions are returned in `mvec'.
253// Any temp. registers (TmpInstruction) created are recorded in mcfi.
254// Any stack space required is allocated via MachineCodeForMethod.
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000255//
256void
Vikram S. Adve242a8082002-05-19 15:25:51 +0000257UltraSparcInstrInfo::CreateCodeToCopyIntToFloat(const TargetMachine& target,
258 Function* F,
259 Value* val,
260 Instruction* dest,
261 std::vector<MachineInstr*>& mvec,
262 MachineCodeForInstruction& mcfi) const
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000263{
Chris Lattner9b625032002-05-06 16:15:30 +0000264 assert((val->getType()->isIntegral() || isa<PointerType>(val->getType()))
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000265 && "Source type must be integral");
Chris Lattner9b625032002-05-06 16:15:30 +0000266 assert(dest->getType()->isFloatingPoint()
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000267 && "Dest type must be float/double");
268
Vikram S. Adve242a8082002-05-19 15:25:51 +0000269 int offset = MachineCodeForMethod::get(F).allocateLocalVar(target, val);
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000270
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000271 // Store instruction stores `val' to [%fp+offset].
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000272 // The store and load opCodes are based on the value being copied, and
Vikram S. Adveb9959d82001-11-15 14:59:56 +0000273 // they use integer and float types that accomodate the
274 // larger of the source type and the destination type:
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000275 // On SparcV9: int for float, long for double.
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000276 //
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000277 Type* tmpType = (dest->getType() == Type::FloatTy)? Type::IntTy
278 : Type::LongTy;
279 MachineInstr* store = new MachineInstr(ChooseStoreInstruction(tmpType));
Vikram S. Advee76af292002-03-18 03:09:15 +0000280 store->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, val);
281 store->SetMachineOperandReg(1, target.getRegInfo().getFramePointer());
Vikram S. Adve242a8082002-05-19 15:25:51 +0000282 store->SetMachineOperandConst(2,MachineOperand::MO_SignExtendedImmed,offset);
283 mvec.push_back(store);
Vikram S. Adve30764b82001-10-18 00:01:48 +0000284
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000285 // Load instruction loads [%fp+offset] to `dest'.
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000286 //
Vikram S. Adveb9959d82001-11-15 14:59:56 +0000287 MachineInstr* load =new MachineInstr(ChooseLoadInstruction(dest->getType()));
Vikram S. Advee76af292002-03-18 03:09:15 +0000288 load->SetMachineOperandReg(0, target.getRegInfo().getFramePointer());
289 load->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,offset);
290 load->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, dest);
Vikram S. Adve242a8082002-05-19 15:25:51 +0000291 mvec.push_back(load);
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000292}
293
294
295// Similarly, create an instruction sequence to copy an FP value
296// `val' to an integer value `dest' by copying to memory and back.
Vikram S. Adve242a8082002-05-19 15:25:51 +0000297// The generated instructions are returned in `mvec'.
298// Any temp. registers (TmpInstruction) created are recorded in mcfi.
299// Any stack space required is allocated via MachineCodeForMethod.
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000300//
301void
Vikram S. Adve242a8082002-05-19 15:25:51 +0000302UltraSparcInstrInfo::CreateCodeToCopyFloatToInt(const TargetMachine& target,
303 Function* F,
Chris Lattner697954c2002-01-20 22:54:45 +0000304 Value* val,
305 Instruction* dest,
Vikram S. Adve242a8082002-05-19 15:25:51 +0000306 std::vector<MachineInstr*>& mvec,
307 MachineCodeForInstruction& mcfi) const
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000308{
Chris Lattner9b625032002-05-06 16:15:30 +0000309 assert(val->getType()->isFloatingPoint()
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000310 && "Source type must be float/double");
Chris Lattner9b625032002-05-06 16:15:30 +0000311 assert((dest->getType()->isIntegral() || isa<PointerType>(dest->getType()))
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000312 && "Dest type must be integral");
313
Vikram S. Adve242a8082002-05-19 15:25:51 +0000314 int offset = MachineCodeForMethod::get(F).allocateLocalVar(target, val);
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000315
316 // Store instruction stores `val' to [%fp+offset].
317 // The store and load opCodes are based on the value being copied, and
318 // they use the integer type that matches the source type in size:
319 // On SparcV9: int for float, long for double.
320 //
321 Type* tmpType = (val->getType() == Type::FloatTy)? Type::IntTy
322 : Type::LongTy;
Vikram S. Adveb9959d82001-11-15 14:59:56 +0000323 MachineInstr* store=new MachineInstr(ChooseStoreInstruction(val->getType()));
Vikram S. Advee76af292002-03-18 03:09:15 +0000324 store->SetMachineOperandVal(0, MachineOperand::MO_VirtualRegister, val);
325 store->SetMachineOperandReg(1, target.getRegInfo().getFramePointer());
326 store->SetMachineOperandConst(2,MachineOperand::MO_SignExtendedImmed,offset);
Vikram S. Adve242a8082002-05-19 15:25:51 +0000327 mvec.push_back(store);
Vikram S. Adve5b6082e2001-11-09 02:16:40 +0000328
329 // Load instruction loads [%fp+offset] to `dest'.
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000330 //
331 MachineInstr* load = new MachineInstr(ChooseLoadInstruction(tmpType));
Vikram S. Advee76af292002-03-18 03:09:15 +0000332 load->SetMachineOperandReg(0, target.getRegInfo().getFramePointer());
Vikram S. Adve242a8082002-05-19 15:25:51 +0000333 load->SetMachineOperandConst(1, MachineOperand::MO_SignExtendedImmed,offset);
Vikram S. Advee76af292002-03-18 03:09:15 +0000334 load->SetMachineOperandVal(2, MachineOperand::MO_VirtualRegister, dest);
Vikram S. Adve242a8082002-05-19 15:25:51 +0000335 mvec.push_back(load);
336}
337
338
339// Create instruction(s) to copy src to dest, for arbitrary types
340// The generated instructions are returned in `mvec'.
341// Any temp. registers (TmpInstruction) created are recorded in mcfi.
342// Any stack space required is allocated via MachineCodeForMethod.
343//
344void
345UltraSparcInstrInfo::CreateCopyInstructionsByType(const TargetMachine& target,
346 Function *F,
347 Value* src,
348 Instruction* dest,
349 vector<MachineInstr*>& mvec,
350 MachineCodeForInstruction& mcfi) const
351{
352 bool loadConstantToReg = false;
353
354 const Type* resultType = dest->getType();
355
356 MachineOpCode opCode = ChooseAddInstructionByType(resultType);
357 if (opCode == INVALID_OPCODE)
358 {
359 assert(0 && "Unsupported result type in CreateCopyInstructionsByType()");
360 return;
361 }
362
363 // if `src' is a constant that doesn't fit in the immed field or if it is
364 // a global variable (i.e., a constant address), generate a load
365 // instruction instead of an add
366 //
367 if (isa<Constant>(src))
368 {
369 unsigned int machineRegNum;
370 int64_t immedValue;
371 MachineOperand::MachineOperandType opType =
372 ChooseRegOrImmed(src, opCode, target, /*canUseImmed*/ true,
373 machineRegNum, immedValue);
374
375 if (opType == MachineOperand::MO_VirtualRegister)
376 loadConstantToReg = true;
377 }
378 else if (isa<GlobalValue>(src))
379 loadConstantToReg = true;
380
381 if (loadConstantToReg)
382 { // `src' is constant and cannot fit in immed field for the ADD
383 // Insert instructions to "load" the constant into a register
384 target.getInstrInfo().CreateCodeToLoadConst(target, F, src, dest,
385 mvec, mcfi);
386 }
387 else
388 { // Create an add-with-0 instruction of the appropriate type.
389 // Make `src' the second operand, in case it is a constant
390 // Use (unsigned long) 0 for a NULL pointer value.
391 //
392 const Type* zeroValueType =
393 isa<PointerType>(resultType) ? Type::ULongTy : resultType;
394 MachineInstr* minstr =
395 Create3OperandInstr(opCode, Constant::getNullValue(zeroValueType),
396 src, dest);
397 mvec.push_back(minstr);
398 }
399}
400
401
402// Create instruction sequence to produce a sign-extended register value
403// from an arbitrary sized value (sized in bits, not bytes).
404// For SPARC v9, we sign-extend the given unsigned operand using SLL; SRA.
405// The generated instructions are returned in `mvec'.
406// Any temp. registers (TmpInstruction) created are recorded in mcfi.
407// Any stack space required is allocated via MachineCodeForMethod.
408//
409void
410UltraSparcInstrInfo::CreateSignExtensionInstructions(
411 const TargetMachine& target,
412 Function* F,
413 Value* unsignedSrcVal,
414 unsigned int srcSizeInBits,
415 Value* dest,
416 vector<MachineInstr*>& mvec,
417 MachineCodeForInstruction& mcfi) const
418{
419 MachineInstr* M;
420
421 assert(srcSizeInBits > 0 && srcSizeInBits <= 32
422 && "Hmmm... srcSizeInBits > 32 unexpected but could be handled here.");
423
424 if (srcSizeInBits < 32)
425 { // SLL is needed since operand size is < 32 bits.
426 TmpInstruction *tmpI = new TmpInstruction(dest->getType(),
427 unsignedSrcVal, dest,"make32");
428 mcfi.addTemp(tmpI);
429 M = Create3OperandInstr_UImmed(SLL,unsignedSrcVal,32-srcSizeInBits,tmpI);
430 mvec.push_back(M);
431 unsignedSrcVal = tmpI;
432 }
433
434 M = Create3OperandInstr_UImmed(SRA, unsignedSrcVal, 32-srcSizeInBits, dest);
435 mvec.push_back(M);
Vikram S. Adveb9c38632001-11-08 04:57:53 +0000436}