+ // Set the low 10 bits in dest
+ MI = Create3OperandInstr(OR, dest, val, dest);
+ MI->setOperandLo32(1);
+ mvec.push_back(MI);
+}
+
+
+//----------------------------------------------------------------------------
+// Function: CreateSETXLabel
+//
+// Set a 64-bit constant (given by a symbolic label) in the register `dest'.
+//----------------------------------------------------------------------------
+
+static inline void
+CreateSETXLabel(const TargetMachine& target,
+ Value* val, Instruction* tmpReg, Instruction* dest,
+ vector<MachineInstr*>& mvec)
+{
+ assert(isa<Constant>(val) || isa<GlobalValue>(val) &&
+ "I only know about constant values and global addresses");
+
+ MachineInstr* MI;
+
+ MI = Create2OperandInstr_Addr(SETHI, val, tmpReg);
+ MI->setOperandHi64(0);
+ mvec.push_back(MI);
+
+ MI = Create3OperandInstr_Addr(OR, tmpReg, val, tmpReg);
+ MI->setOperandLo64(1);
+ mvec.push_back(MI);
+
+ MI = Create3OperandInstr_UImmed(SLLX, tmpReg, 32, tmpReg);
+ mvec.push_back(MI);
+
+ MI = Create2OperandInstr_Addr(SETHI, val, dest);
+ MI->setOperandHi32(0);
+ mvec.push_back(MI);
+
+ MI = Create3OperandInstr(OR, dest, tmpReg, dest);
+ mvec.push_back(MI);
+
+ MI = Create3OperandInstr_Addr(OR, dest, val, dest);
+ MI->setOperandLo32(1);
+ mvec.push_back(MI);
+}
+
+
+//----------------------------------------------------------------------------
+// Function: CreateUIntSetInstruction
+//
+// Create code to Set an unsigned constant in the register `dest'.
+// Uses CreateSETUWConst, CreateSETSWConst or CreateSETXConst as needed.
+// CreateSETSWConst is an optimization for the case that the unsigned value
+// has all ones in the 33 high bits (so that sign-extension sets them all).
+//----------------------------------------------------------------------------
+
+static inline void
+CreateUIntSetInstruction(const TargetMachine& target,
+ uint64_t C, Instruction* dest,
+ std::vector<MachineInstr*>& mvec,
+ MachineCodeForInstruction& mcfi)
+{
+ static const uint64_t lo32 = (uint32_t) ~0;
+ if (C <= lo32) // High 32 bits are 0. Set low 32 bits.
+ CreateSETUWConst(target, (uint32_t) C, dest, mvec);
+ else if ((C & ~lo32) == ~lo32 && (C & (1 << 31)))
+ { // All high 33 (not 32) bits are 1s: sign-extension will take care
+ // of high 32 bits, so use the sequence for signed int
+ CreateSETSWConst(target, (int32_t) C, dest, mvec);
+ }
+ else if (C > lo32)
+ { // C does not fit in 32 bits
+ TmpInstruction* tmpReg = new TmpInstruction(Type::IntTy);
+ mcfi.addTemp(tmpReg);
+ CreateSETXConst(target, C, tmpReg, dest, mvec);
+ }
+}
+
+
+//----------------------------------------------------------------------------
+// Function: CreateIntSetInstruction
+//
+// Create code to Set a signed constant in the register `dest'.
+// Really the same as CreateUIntSetInstruction.
+//----------------------------------------------------------------------------
+
+static inline void
+CreateIntSetInstruction(const TargetMachine& target,
+ int64_t C, Instruction* dest,
+ std::vector<MachineInstr*>& mvec,
+ MachineCodeForInstruction& mcfi)
+{
+ CreateUIntSetInstruction(target, (uint64_t) C, dest, mvec, mcfi);
+}
+
+
+//---------------------------------------------------------------------------
+// Create a table of LLVM opcode -> max. immediate constant likely to
+// be usable for that operation.
+//---------------------------------------------------------------------------
+
+// Entry == 0 ==> no immediate constant field exists at all.
+// Entry > 0 ==> abs(immediate constant) <= Entry
+//
+vector<int> MaxConstantsTable(Instruction::OtherOpsEnd);
+
+static int
+MaxConstantForInstr(unsigned llvmOpCode)
+{
+ int modelOpCode = -1;
+
+ if (llvmOpCode >= Instruction::BinaryOpsBegin &&
+ llvmOpCode < Instruction::BinaryOpsEnd)
+ modelOpCode = ADD;
+ else
+ switch(llvmOpCode) {
+ case Instruction::Ret: modelOpCode = JMPLCALL; break;
+
+ case Instruction::Malloc:
+ case Instruction::Alloca:
+ case Instruction::GetElementPtr:
+ case Instruction::PHINode:
+ case Instruction::Cast:
+ case Instruction::Call: modelOpCode = ADD; break;
+
+ case Instruction::Shl:
+ case Instruction::Shr: modelOpCode = SLLX; break;
+
+ default: break;
+ };
+
+ return (modelOpCode < 0)? 0: SparcMachineInstrDesc[modelOpCode].maxImmedConst;
+}
+
+static void
+InitializeMaxConstantsTable()
+{
+ unsigned op;
+ assert(MaxConstantsTable.size() == Instruction::OtherOpsEnd &&
+ "assignments below will be illegal!");
+ for (op = Instruction::TermOpsBegin; op < Instruction::TermOpsEnd; ++op)
+ MaxConstantsTable[op] = MaxConstantForInstr(op);
+ for (op = Instruction::BinaryOpsBegin; op < Instruction::BinaryOpsEnd; ++op)
+ MaxConstantsTable[op] = MaxConstantForInstr(op);
+ for (op = Instruction::MemoryOpsBegin; op < Instruction::MemoryOpsEnd; ++op)
+ MaxConstantsTable[op] = MaxConstantForInstr(op);
+ for (op = Instruction::OtherOpsBegin; op < Instruction::OtherOpsEnd; ++op)
+ MaxConstantsTable[op] = MaxConstantForInstr(op);