--- /dev/null
+// $Id$
+//***************************************************************************
+// File:
+// SparcInstrInfo.cpp
+//
+// Purpose:
+//
+// History:
+// 10/15/01 - Vikram Adve - Created
+//**************************************************************************/
+
+
+#include "SparcInternals.h"
+#include "SparcInstrSelectionSupport.h"
+#include "llvm/Target/Sparc.h"
+#include "llvm/CodeGen/InstrSelection.h"
+#include "llvm/CodeGen/InstrSelectionSupport.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/ConstPoolVals.h"
+#include "llvm/Type.h"
+
+
+//************************ Internal Functions ******************************/
+
+
+static inline MachineInstr*
+CreateIntSetInstruction(int64_t C, bool isSigned, Value* dest)
+{
+ MachineInstr* minstr;
+ if (isSigned)
+ {
+ minstr = new MachineInstr(SETSW);
+ minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
+ }
+ else
+ {
+ minstr = new MachineInstr(SETUW);
+ minstr->SetMachineOperand(0, MachineOperand::MO_UnextendedImmed, C);
+ }
+
+ minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, dest);
+
+ return minstr;
+}
+
+//************************* External Classes *******************************/
+
+//---------------------------------------------------------------------------
+// class UltraSparcInstrInfo
+//
+// Purpose:
+// Information about individual instructions.
+// Most information is stored in the SparcMachineInstrDesc array above.
+// Other information is computed on demand, and most such functions
+// default to member functions in base class MachineInstrInfo.
+//---------------------------------------------------------------------------
+
+/*ctor*/
+UltraSparcInstrInfo::UltraSparcInstrInfo()
+ : MachineInstrInfo(SparcMachineInstrDesc,
+ /*descSize = */ NUM_TOTAL_OPCODES,
+ /*numRealOpCodes = */ NUM_REAL_OPCODES)
+{
+}
+
+
+// Create an instruction sequence to put the constant `val' into
+// the virtual register `dest'. `val' may be a ConstPoolVal or a
+// GlobalValue, viz., the constant address of a global variable or function.
+// The generated instructions are returned in `minstrVec'.
+// Any temp. registers (TmpInstruction) created are returned in `tempVec'.
+//
+void
+UltraSparcInstrInfo::CreateCodeToLoadConst(Value* val,
+ Instruction* dest,
+ vector<MachineInstr*>& minstrVec,
+ vector<TmpInstruction*>& tempVec) const
+{
+ MachineInstr* minstr;
+
+ assert(isa<ConstPoolVal>(val) || isa<GlobalValue>(val) &&
+ "I only know about constant values and global addresses");
+
+ // Use a "set" instruction for known constants that can go in an integer reg.
+ // Use a "load" instruction for all other constants, in particular,
+ // floating point constants and addresses of globals.
+ //
+ const Type* valType = val->getType();
+
+ if (valType->isIntegral() || valType == Type::BoolTy)
+ {
+ bool isValidConstant;
+ int64_t C = GetConstantValueAsSignedInt(val, isValidConstant);
+ assert(isValidConstant && "Unrecognized constant");
+ minstr = CreateIntSetInstruction(C, valType->isSigned(), dest);
+ minstrVec.push_back(minstr);
+ }
+ else
+ {
+ // Make an instruction sequence to load the constant, viz:
+ // SETSW <addr-of-constant>, addrReg
+ // LOAD /*addr*/ addrReg, /*offset*/ 0, dest
+ // Only the SETSW is needed if `val' is a GlobalValue, i.e,. it is
+ // itself a constant address. Otherwise, both are needed.
+
+ Value* addrVal;
+ int64_t zeroOffset = 0; // to avoid ambiguity with (Value*) 0
+
+ if (isa<ConstPoolVal>(val))
+ {
+ // Create another TmpInstruction for the hidden integer register
+ TmpInstruction* addrReg =
+ new TmpInstruction(Instruction::UserOp1, val, NULL);
+ tempVec.push_back(addrReg);
+ addrVal = addrReg;
+ }
+ else
+ addrVal = dest;
+
+ minstr = new MachineInstr(SETUW);
+ minstr->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp, val);
+ minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister,addrVal);
+ minstrVec.push_back(minstr);
+
+ if (isa<ConstPoolVal>(val))
+ {
+ // addrVal->addMachineInstruction(minstr);
+
+ minstr = new MachineInstr(ChooseLoadInstruction(val->getType()));
+ minstr->SetMachineOperand(0, MachineOperand::MO_VirtualRegister,
+ addrVal);
+ minstr->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed,
+ zeroOffset);
+ minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,
+ dest);
+ minstrVec.push_back(minstr);
+ }
+ }
+}
+
+
+//************************ External Functions ******************************/
+