<commit_before>// $Id$
//***************************************************************************
// File:
//	SparcInstrInfo.cpp
// 
// Purpose:
//	
// History:
//	10/15/01	 -  <NAME>  -  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/Method.h"
#include "llvm/ConstantVals.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Type.h"


//************************ Internal Functions ******************************/


static inline MachineInstr*
CreateIntSetInstruction(int64_t C, bool isSigned, Value* dest,
                        vector<TmpInstruction*>& tempVec)
{
  MachineInstr* minstr;
  uint64_t absC = (C >= 0)? C : -C;
  if (absC > (unsigned int) ~0)
    { // C does not fit in 32 bits
      TmpInstruction* tmpReg =
        new TmpInstruction(Instruction::UserOp1, Type::IntTy, NULL, NULL);
      tempVec.push_back(tmpReg);
      
      minstr = new MachineInstr(SETX);
      minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
      minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, tmpReg,
                                   /*isdef*/ true);
      minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,dest);
    }
  if (isSigned)
    {
      minstr = new MachineInstr(SETSW);
      minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
      minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, dest);
    }
  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(const TargetMachine& tgt)
  : MachineInstrInfo(tgt, 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 Constant 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<Constant>(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, tempVec);
      minstrVec.push_back(minstr);
    }
  else
    {
      // Make an instruction sequence to load the constant, viz:
      //            SETX <addr-of-constant>, tmpReg, addrReg
      //            LOAD  /*addr*/ addrReg, /*offset*/ 0, dest
      // Only the SETX 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
      
      TmpInstruction* tmpReg =
        new TmpInstruction(Instruction::UserOp1,
                           PointerType::get(val->getType()), val, NULL);
      tempVec.push_back(tmpReg);
      
      if (isa<Constant>(val))
        {
          // Create another TmpInstruction for the hidden integer register
          TmpInstruction* addrReg =
            new TmpInstruction(Instruction::UserOp1,
                               PointerType::get(val->getType()), val, NULL);
          tempVec.push_back(addrReg);
          addrVal = addrReg;
        }
      else
        addrVal = dest;
      
      minstr = new MachineInstr(SETX);
      minstr->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp, val);
      minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, tmpReg,
                                   /*isdef*/ true);
      minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,addrVal);
      minstrVec.push_back(minstr);
      
      if (isa<Constant>(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);
        }
    }
}


// Create an instruction sequence to copy an integer value `val'
// to a floating point value `dest' by copying to memory and back.
// val must be an integral type.  dest must be a Float or Double.
// The generated instructions are returned in `minstrVec'.
// Any temp. registers (TmpInstruction) created are returned in `tempVec'.
// 
void
UltraSparcInstrInfo::CreateCodeToCopyIntToFloat(Method* method,
                                              Value* val,
                                              Instruction* dest,
                                              vector<MachineInstr*>& minstrVec,
                                              vector<TmpInstruction*>& tempVec,
                                              TargetMachine& target) const
{
  assert((val->getType()->isIntegral() || val->getType()->isPointerType())
         && "Source type must be integral");
  assert((dest->getType() ==Type::FloatTy || dest->getType() ==Type::DoubleTy)
         && "Dest type must be float/double");
  
  const MachineFrameInfo& frameInfo = ((UltraSparc&) target).getFrameInfo();
  
  MachineCodeForMethod& mcinfo = MachineCodeForMethod::get(method);
  int offset = mcinfo.allocateLocalVar(target, val); 
  
  // Store instruction stores `val' to [%fp+offset].
  // The store and load opCodes are based on the value being copied, and
  // they use integer and float types that accomodate the
  // larger of the source type and the destination type:
  // On SparcV9: int for float, long for double.
  // 
  Type* tmpType = (dest->getType() == Type::FloatTy)? Type::IntTy
                                                    : Type::LongTy;
  MachineInstr* store = new MachineInstr(ChooseStoreInstruction(tmpType));
  store->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, val);
  store->SetMachineOperand(1, target.getRegInfo().getFramePointer());
  store->SetMachineOperand(2, MachineOperand::MO_SignExtendedImmed, offset);
  minstrVec.push_back(store);

  // Load instruction loads [%fp+offset] to `dest'.
  // 
  MachineInstr* load =new MachineInstr(ChooseLoadInstruction(dest->getType()));
  load->SetMachineOperand(0, target.getRegInfo().getFramePointer());
  load->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed, offset);
  load->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, dest);
  minstrVec.push_back(load);
}


// Similarly, create an instruction sequence to copy an FP value
// `val' to an integer value `dest' by copying to memory and back.
// See the previous function for information about return values.
// 
void
UltraSparcInstrInfo::CreateCodeToCopyFloatToInt(Method* method,
                                              Value* val,
                                              Instruction* dest,
                                              vector<MachineInstr*>& minstrVec,
                                              vector<TmpInstruction*>& tempVec,
                                              TargetMachine& target) const
{
  assert((val->getType() ==Type::FloatTy || val->getType() ==Type::DoubleTy)
         && "Source type must be float/double");
  assert((dest->getType()->isIntegral() || dest->getType()->isPointerType())
         && "Dest type must be integral");
  
  const MachineFrameInfo& frameInfo = ((UltraSparc&) target).getFrameInfo();
  
  MachineCodeForMethod& mcinfo = MachineCodeForMethod::get(method);
  int offset = mcinfo.allocateLocalVar(target, val); 
  
  // Store instruction stores `val' to [%fp+offset].
  // The store and load opCodes are based on the value being copied, and
  // they use the integer type that matches the source type in size:
  // On SparcV9: int for float, long for double.
  // 
  Type* tmpType = (val->getType() == Type::FloatTy)? Type::IntTy
                                                   : Type::LongTy;
  MachineInstr* store=new MachineInstr(ChooseStoreInstruction(val->getType()));
  store->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, val);
  store->SetMachineOperand(1, target.getRegInfo().getFramePointer());
  store->SetMachineOperand(2, MachineOperand::MO_SignExtendedImmed, offset);
  minstrVec.push_back(store);
  
  // Load instruction loads [%fp+offset] to `dest'.
  // 
  MachineInstr* load = new MachineInstr(ChooseLoadInstruction(tmpType));
  load->SetMachineOperand(0, target.getRegInfo().getFramePointer());
  load->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed, offset);
  load->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, dest);
  minstrVec.push_back(load);
}
<commit_msg>Remove int hack to allow unsigned numbers greater than 2^63 - 1...<commit_after>// $Id$
//***************************************************************************
// File:
//	SparcInstrInfo.cpp
// 
// Purpose:
//	
// History:
//	10/15/01	 -  <NAME>  -  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/Method.h"
#include "llvm/ConstantVals.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Type.h"


//************************ Internal Functions ******************************/


static inline MachineInstr*
CreateIntSetInstruction(int64_t C, Value* dest,
                        vector<TmpInstruction*>& tempVec)
{
  MachineInstr* minstr;
  uint64_t absC = (C >= 0)? C : -C;
  if (absC > (unsigned int) ~0)
    { // C does not fit in 32 bits
      TmpInstruction* tmpReg =
        new TmpInstruction(Instruction::UserOp1, Type::IntTy, NULL, NULL);
      tempVec.push_back(tmpReg);
      
      minstr = new MachineInstr(SETX);
      minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
      minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, tmpReg,
                                   /*isdef*/ true);
      minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,dest);
    }
  else
    {
      minstr = new MachineInstr(SETSW);
      minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
      minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, dest);
    }
  
  return minstr;
}

static inline MachineInstr*
CreateUIntSetInstruction(uint64_t C, Value* dest,
                         vector<TmpInstruction*>& tempVec)
{
  MachineInstr* minstr;
  if (C > (unsigned int) ~0)
    { // C does not fit in 32 bits
      TmpInstruction* tmpReg =
        new TmpInstruction(Instruction::UserOp1, Type::IntTy, NULL, NULL);
      tempVec.push_back(tmpReg);
      
      minstr = new MachineInstr(SETX);
      minstr->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, C);
      minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, tmpReg,
                                   /*isdef*/ true);
      minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,dest);
    }
  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(const TargetMachine& tgt)
  : MachineInstrInfo(tgt, 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 Constant 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<Constant>(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)
    {
      if (ConstantUInt* uval = dyn_cast<ConstantUInt>(val))
        {
          uint64_t C = uval->getValue();
          minstr = CreateUIntSetInstruction(C, dest, tempVec);
        }
      else
        {
          bool isValidConstant;
          int64_t C = GetConstantValueAsSignedInt(val, isValidConstant);
          assert(isValidConstant && "Unrecognized constant");
          minstr = CreateIntSetInstruction(C, dest, tempVec);
        }
      minstrVec.push_back(minstr);
    }
  else
    {
      // Make an instruction sequence to load the constant, viz:
      //            SETX <addr-of-constant>, tmpReg, addrReg
      //            LOAD  /*addr*/ addrReg, /*offset*/ 0, dest
      // Only the SETX 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
      
      TmpInstruction* tmpReg =
        new TmpInstruction(Instruction::UserOp1,
                           PointerType::get(val->getType()), val, NULL);
      tempVec.push_back(tmpReg);
      
      if (isa<Constant>(val))
        {
          // Create another TmpInstruction for the hidden integer register
          TmpInstruction* addrReg =
            new TmpInstruction(Instruction::UserOp1,
                               PointerType::get(val->getType()), val, NULL);
          tempVec.push_back(addrReg);
          addrVal = addrReg;
        }
      else
        addrVal = dest;
      
      minstr = new MachineInstr(SETX);
      minstr->SetMachineOperand(0, MachineOperand::MO_PCRelativeDisp, val);
      minstr->SetMachineOperand(1, MachineOperand::MO_VirtualRegister, tmpReg,
                                   /*isdef*/ true);
      minstr->SetMachineOperand(2, MachineOperand::MO_VirtualRegister,addrVal);
      minstrVec.push_back(minstr);
      
      if (isa<Constant>(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);
        }
    }
}


// Create an instruction sequence to copy an integer value `val'
// to a floating point value `dest' by copying to memory and back.
// val must be an integral type.  dest must be a Float or Double.
// The generated instructions are returned in `minstrVec'.
// Any temp. registers (TmpInstruction) created are returned in `tempVec'.
// 
void
UltraSparcInstrInfo::CreateCodeToCopyIntToFloat(Method* method,
                                              Value* val,
                                              Instruction* dest,
                                              vector<MachineInstr*>& minstrVec,
                                              vector<TmpInstruction*>& tempVec,
                                              TargetMachine& target) const
{
  assert((val->getType()->isIntegral() || val->getType()->isPointerType())
         && "Source type must be integral");
  assert((dest->getType() ==Type::FloatTy || dest->getType() ==Type::DoubleTy)
         && "Dest type must be float/double");
  
  const MachineFrameInfo& frameInfo = ((UltraSparc&) target).getFrameInfo();
  
  MachineCodeForMethod& mcinfo = MachineCodeForMethod::get(method);
  int offset = mcinfo.allocateLocalVar(target, val); 
  
  // Store instruction stores `val' to [%fp+offset].
  // The store and load opCodes are based on the value being copied, and
  // they use integer and float types that accomodate the
  // larger of the source type and the destination type:
  // On SparcV9: int for float, long for double.
  // 
  Type* tmpType = (dest->getType() == Type::FloatTy)? Type::IntTy
                                                    : Type::LongTy;
  MachineInstr* store = new MachineInstr(ChooseStoreInstruction(tmpType));
  store->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, val);
  store->SetMachineOperand(1, target.getRegInfo().getFramePointer());
  store->SetMachineOperand(2, MachineOperand::MO_SignExtendedImmed, offset);
  minstrVec.push_back(store);

  // Load instruction loads [%fp+offset] to `dest'.
  // 
  MachineInstr* load =new MachineInstr(ChooseLoadInstruction(dest->getType()));
  load->SetMachineOperand(0, target.getRegInfo().getFramePointer());
  load->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed, offset);
  load->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, dest);
  minstrVec.push_back(load);
}


// Similarly, create an instruction sequence to copy an FP value
// `val' to an integer value `dest' by copying to memory and back.
// See the previous function for information about return values.
// 
void
UltraSparcInstrInfo::CreateCodeToCopyFloatToInt(Method* method,
                                              Value* val,
                                              Instruction* dest,
                                              vector<MachineInstr*>& minstrVec,
                                              vector<TmpInstruction*>& tempVec,
                                              TargetMachine& target) const
{
  assert((val->getType() ==Type::FloatTy || val->getType() ==Type::DoubleTy)
         && "Source type must be float/double");
  assert((dest->getType()->isIntegral() || dest->getType()->isPointerType())
         && "Dest type must be integral");
  
  const MachineFrameInfo& frameInfo = ((UltraSparc&) target).getFrameInfo();
  
  MachineCodeForMethod& mcinfo = MachineCodeForMethod::get(method);
  int offset = mcinfo.allocateLocalVar(target, val); 
  
  // Store instruction stores `val' to [%fp+offset].
  // The store and load opCodes are based on the value being copied, and
  // they use the integer type that matches the source type in size:
  // On SparcV9: int for float, long for double.
  // 
  Type* tmpType = (val->getType() == Type::FloatTy)? Type::IntTy
                                                   : Type::LongTy;
  MachineInstr* store=new MachineInstr(ChooseStoreInstruction(val->getType()));
  store->SetMachineOperand(0, MachineOperand::MO_VirtualRegister, val);
  store->SetMachineOperand(1, target.getRegInfo().getFramePointer());
  store->SetMachineOperand(2, MachineOperand::MO_SignExtendedImmed, offset);
  minstrVec.push_back(store);
  
  // Load instruction loads [%fp+offset] to `dest'.
  // 
  MachineInstr* load = new MachineInstr(ChooseLoadInstruction(tmpType));
  load->SetMachineOperand(0, target.getRegInfo().getFramePointer());
  load->SetMachineOperand(1, MachineOperand::MO_SignExtendedImmed, offset);
  load->SetMachineOperand(2, MachineOperand::MO_VirtualRegister, dest);
  minstrVec.push_back(load);
}

{'fraction_non_alphanumeric': 0.1445271947641616, 'fraction_numerical': 0.005280974949221395, 'mean_word_length': 2.5359080753271623, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 135, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 65, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7044846', 'n_tokens_mistral': 6113, 'n_tokens_neox': 6039, 'n_words': 1494}