//===-- SparcInternals.h - Header file for Sparc backend ---------*- C++ -*--=//
//
// This file defines stuff that is to be private to the Sparc backend, but is
// shared among different portions of the backend.
//
//===----------------------------------------------------------------------===//
#ifndef SPARC_INTERNALS_H
#define SPARC_INTERNALS_H
#include "SparcRegClassInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/MachineInstrInfo.h"
#include "llvm/Target/MachineSchedInfo.h"
#include "llvm/CodeGen/RegClass.h"
#include "llvm/Type.h"
#include <sys/types.h>
class UltraSparc;
// OpCodeMask definitions for the Sparc V9
//
const OpCodeMask Immed = 0x00002000; // immed or reg operand?
const OpCodeMask Annul = 0x20000000; // annul delay instr?
const OpCodeMask PredictTaken = 0x00080000; // predict branch taken?
enum SparcInstrSchedClass {
SPARC_NONE, /* Instructions with no scheduling restrictions */
SPARC_IEUN, /* Integer class that can use IEU0 or IEU1 */
SPARC_IEU0, /* Integer class IEU0 */
SPARC_IEU1, /* Integer class IEU1 */
SPARC_FPM, /* FP Multiply or Divide instructions */
SPARC_FPA, /* All other FP instructions */
SPARC_CTI, /* Control-transfer instructions */
SPARC_LD, /* Load instructions */
SPARC_ST, /* Store instructions */
SPARC_SINGLE, /* Instructions that must issue by themselves */
SPARC_INV, /* This should stay at the end for the next value */
SPARC_NUM_SCHED_CLASSES = SPARC_INV
};
//---------------------------------------------------------------------------
// enum SparcMachineOpCode.
// const MachineInstrDescriptor SparcMachineInstrDesc[]
//
// Purpose:
// Description of UltraSparc machine instructions.
//
//---------------------------------------------------------------------------
enum SparcMachineOpCode {
#define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS) \
ENUM,
#include "SparcInstr.def"
// End-of-array marker
INVALID_OPCODE,
NUM_REAL_OPCODES = PHI, // number of valid opcodes
NUM_TOTAL_OPCODES = INVALID_OPCODE
};
// Array of machine instruction descriptions...
extern const MachineInstrDescriptor SparcMachineInstrDesc[];
//---------------------------------------------------------------------------
// 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.
//---------------------------------------------------------------------------
class UltraSparcInstrInfo : public MachineInstrInfo {
public:
/*ctor*/ UltraSparcInstrInfo();
virtual bool hasResultInterlock (MachineOpCode opCode) const
{
// All UltraSPARC instructions have interlocks (note that delay slots
// are not considered here).
// However, instructions that use the result of an FCMP produce a
// 9-cycle stall if they are issued less than 3 cycles after the FCMP.
// Force the compiler to insert a software interlock (i.e., gap of
// 2 other groups, including NOPs if necessary).
return (opCode == FCMPS || opCode == FCMPD || opCode == FCMPQ);
}
//-------------------------------------------------------------------------
// Code generation support for creating individual machine instructions
//-------------------------------------------------------------------------
// Create an instruction sequence to put the constant `val' into
// the virtual register `dest'. The generated instructions are
// returned in `minstrVec'. Any temporary registers (TmpInstruction)
// created are returned in `tempVec'.
//
virtual void CreateCodeToLoadConst(Value* val,
Instruction* dest,
vector<MachineInstr*>& minstrVec,
vector<TmpInstruction*>& tempVec) const;
};
//----------------------------------------------------------------------------
// class UltraSparcRegInfo
//
//----------------------------------------------------------------------------
class LiveRange;
class UltraSparc;
class PhyRegAlloc;
class UltraSparcRegInfo : public MachineRegInfo
{
private:
// The actual register classes in the Sparc
enum RegClassIDs {
IntRegClassID,
FloatRegClassID,
IntCCRegClassID,
FloatCCRegClassID
};
// Type of registers available in Sparc. There can be several reg types
// in the same class. For instace, the float reg class has Single/Double
// types
enum RegTypes {
IntRegType,
FPSingleRegType,
FPDoubleRegType,
IntCCRegType,
FloatCCRegType
};
// the size of a value (int, float, etc..) stored in the stack frame
// WARNING: If the above enum order must be changed, also modify
// getRegisterClassOfValue method below since it assumes this particular
// order for efficiency.
// reverse pointer to get info about the ultra sparc machine
const UltraSparc *const UltraSparcInfo;
// Both int and float rguments can be passed in 6 int regs -
// %o0 to %o5 (cannot be changed)
unsigned const NumOfIntArgRegs;
unsigned