2004-04-25 08:32:05 +02:00
|
|
|
//===- SparcV9RegisterInfo.cpp - SparcV9 Register Information ---*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file was developed by the LLVM research group and is distributed under
|
|
|
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file contains the SparcV9 implementation of the MRegisterInfo class.
|
|
|
|
// It also contains stuff needed to instantiate that class, which would
|
|
|
|
// ordinarily be provided by TableGen.
|
|
|
|
//
|
|
|
|
// This is NOT used by the SparcV9 backend to do register allocation, yet.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// The first section of this file (immediately following) is what
|
|
|
|
// you would find in SparcV9GenRegisterInfo.inc, if we were using
|
|
|
|
// TableGen to generate the register file description automatically.
|
|
|
|
// It consists of register classes and register class instances
|
|
|
|
// for the SparcV9 target.
|
2005-04-22 01:30:14 +02:00
|
|
|
//
|
2004-04-25 08:32:05 +02:00
|
|
|
// FIXME: the alignments listed here are wild guesses.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "SparcV9RegisterInfo.h"
|
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
// IR Register Class...
|
|
|
|
const unsigned IR[] = {
|
|
|
|
SparcV9::o0, SparcV9::o1, SparcV9::o2, SparcV9::o3, SparcV9::o4,
|
|
|
|
SparcV9::o5, SparcV9::o7, SparcV9::l0, SparcV9::l1, SparcV9::l2,
|
|
|
|
SparcV9::l3, SparcV9::l4, SparcV9::l5, SparcV9::l6, SparcV9::l7,
|
|
|
|
SparcV9::i0, SparcV9::i1, SparcV9::i2, SparcV9::i3, SparcV9::i4,
|
|
|
|
SparcV9::i5, SparcV9::i6, SparcV9::i7, SparcV9::g0, SparcV9::g1,
|
|
|
|
SparcV9::g2, SparcV9::g3, SparcV9::g4, SparcV9::g5, SparcV9::g6,
|
|
|
|
SparcV9::g7, SparcV9::o6
|
|
|
|
};
|
|
|
|
struct IRClass : public TargetRegisterClass {
|
|
|
|
IRClass() : TargetRegisterClass(8, 8, IR, IR + 32) {}
|
|
|
|
} IRInstance;
|
|
|
|
|
|
|
|
|
|
|
|
// FR Register Class...
|
|
|
|
const unsigned FR[] = {
|
|
|
|
SparcV9::f0, SparcV9::f1, SparcV9::f2, SparcV9::f3, SparcV9::f4,
|
|
|
|
SparcV9::f5, SparcV9::f6, SparcV9::f7, SparcV9::f8, SparcV9::f9,
|
|
|
|
SparcV9::f10, SparcV9::f11, SparcV9::f12, SparcV9::f13,
|
|
|
|
SparcV9::f14, SparcV9::f15, SparcV9::f16, SparcV9::f17,
|
|
|
|
SparcV9::f18, SparcV9::f19, SparcV9::f20, SparcV9::f21,
|
|
|
|
SparcV9::f22, SparcV9::f23, SparcV9::f24, SparcV9::f25,
|
|
|
|
SparcV9::f26, SparcV9::f27, SparcV9::f28, SparcV9::f29,
|
|
|
|
SparcV9::f30, SparcV9::f31, SparcV9::f32, SparcV9::f33,
|
|
|
|
SparcV9::f34, SparcV9::f35, SparcV9::f36, SparcV9::f37,
|
|
|
|
SparcV9::f38, SparcV9::f39, SparcV9::f40, SparcV9::f41,
|
|
|
|
SparcV9::f42, SparcV9::f43, SparcV9::f44, SparcV9::f45,
|
|
|
|
SparcV9::f46, SparcV9::f47, SparcV9::f48, SparcV9::f49,
|
|
|
|
SparcV9::f50, SparcV9::f51, SparcV9::f52, SparcV9::f53,
|
|
|
|
SparcV9::f54, SparcV9::f55, SparcV9::f56, SparcV9::f57,
|
|
|
|
SparcV9::f58, SparcV9::f59, SparcV9::f60, SparcV9::f61,
|
|
|
|
SparcV9::f62, SparcV9::f63
|
|
|
|
};
|
|
|
|
// FIXME: The size is correct for the first 32 registers. The
|
|
|
|
// latter 32 do not all really exist; you can only access every other
|
|
|
|
// one (32, 34, ...), and they must contain double-fp or quad-fp
|
|
|
|
// values... see below about the aliasing problems.
|
|
|
|
struct FRClass : public TargetRegisterClass {
|
|
|
|
FRClass() : TargetRegisterClass(4, 8, FR, FR + 64) {}
|
|
|
|
} FRInstance;
|
|
|
|
|
|
|
|
|
|
|
|
// ICCR Register Class...
|
|
|
|
const unsigned ICCR[] = {
|
|
|
|
SparcV9::xcc, SparcV9::icc, SparcV9::ccr
|
|
|
|
};
|
|
|
|
struct ICCRClass : public TargetRegisterClass {
|
|
|
|
ICCRClass() : TargetRegisterClass(1, 8, ICCR, ICCR + 3) {}
|
|
|
|
} ICCRInstance;
|
|
|
|
|
|
|
|
|
|
|
|
// FCCR Register Class...
|
|
|
|
const unsigned FCCR[] = {
|
|
|
|
SparcV9::fcc0, SparcV9::fcc1, SparcV9::fcc2, SparcV9::fcc3
|
|
|
|
};
|
|
|
|
struct FCCRClass : public TargetRegisterClass {
|
|
|
|
FCCRClass() : TargetRegisterClass(1, 8, FCCR, FCCR + 4) {}
|
|
|
|
} FCCRInstance;
|
|
|
|
|
|
|
|
|
|
|
|
// SR Register Class...
|
|
|
|
const unsigned SR[] = {
|
|
|
|
SparcV9::fsr
|
|
|
|
};
|
|
|
|
struct SRClass : public TargetRegisterClass {
|
|
|
|
SRClass() : TargetRegisterClass(8, 8, SR, SR + 1) {}
|
|
|
|
} SRInstance;
|
|
|
|
|
|
|
|
|
|
|
|
// Register Classes...
|
|
|
|
const TargetRegisterClass* const RegisterClasses[] = {
|
|
|
|
&IRInstance,
|
|
|
|
&FRInstance,
|
|
|
|
&ICCRInstance,
|
|
|
|
&FCCRInstance,
|
|
|
|
&SRInstance
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Register Alias Sets...
|
|
|
|
// FIXME: Note that the SparcV9 backend does not currently abstract
|
|
|
|
// very well over the way that double-fp and quad-fp values may alias
|
|
|
|
// single-fp values in registers. Therefore those aliases are NOT
|
|
|
|
// reflected here.
|
|
|
|
const unsigned Empty_AliasSet[] = { 0 };
|
|
|
|
const unsigned fcc3_AliasSet[] = { SparcV9::fsr, 0 };
|
|
|
|
const unsigned fcc2_AliasSet[] = { SparcV9::fsr, 0 };
|
|
|
|
const unsigned fcc1_AliasSet[] = { SparcV9::fsr, 0 };
|
|
|
|
const unsigned fcc0_AliasSet[] = { SparcV9::fsr, 0 };
|
|
|
|
const unsigned fsr_AliasSet[] = { SparcV9::fcc3, SparcV9::fcc2,
|
|
|
|
SparcV9::fcc1, SparcV9::fcc0, 0 };
|
|
|
|
const unsigned xcc_AliasSet[] = { SparcV9::ccr, 0 };
|
|
|
|
const unsigned icc_AliasSet[] = { SparcV9::ccr, 0 };
|
|
|
|
const unsigned ccr_AliasSet[] = { SparcV9::xcc, SparcV9::icc, 0 };
|
|
|
|
|
|
|
|
const MRegisterDesc RegisterDescriptors[] = { // Descriptors
|
|
|
|
{ "o0", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "o1", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "o2", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "o3", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "o4", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "o5", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "o7", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "l0", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "l1", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "l2", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "l3", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "l4", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "l5", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "l6", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "l7", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "i0", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "i1", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "i2", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "i3", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "i4", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "i5", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "i6", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "i7", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "g0", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "g1", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "g2", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "g3", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "g4", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "g5", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "g6", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "g7", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "o6", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f0", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f1", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f2", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f3", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f4", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f5", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f6", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f7", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f8", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f9", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f10", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f11", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f12", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f13", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f14", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f15", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f16", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f17", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f18", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f19", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f20", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f21", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f22", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f23", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f24", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f25", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f26", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f27", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f28", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f29", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f30", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f31", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f32", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f33", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f34", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f35", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f36", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f37", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f38", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f39", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f40", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f41", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f42", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f43", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f44", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f45", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f46", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f47", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f48", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f49", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f50", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f51", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f52", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f53", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f54", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f55", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f56", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f57", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f58", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f59", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f60", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f61", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f62", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "f63", Empty_AliasSet, 0, 0 },
|
|
|
|
{ "xcc", xcc_AliasSet, 0, 0 },
|
|
|
|
{ "icc", icc_AliasSet, 0, 0 },
|
|
|
|
{ "ccr", ccr_AliasSet, 0, 0 },
|
|
|
|
{ "fcc0", fcc0_AliasSet, 0, 0 },
|
|
|
|
{ "fcc1", fcc1_AliasSet, 0, 0 },
|
|
|
|
{ "fcc2", fcc2_AliasSet, 0, 0 },
|
|
|
|
{ "fcc3", fcc3_AliasSet, 0, 0 },
|
|
|
|
{ "fsr", fsr_AliasSet, 0, 0 },
|
|
|
|
};
|
|
|
|
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
|
|
namespace SparcV9 { // Register classes
|
|
|
|
TargetRegisterClass *IRRegisterClass = &IRInstance;
|
|
|
|
TargetRegisterClass *FRRegisterClass = &FRInstance;
|
|
|
|
TargetRegisterClass *ICCRRegisterClass = &ICCRInstance;
|
|
|
|
TargetRegisterClass *FCCRRegisterClass = &FCCRInstance;
|
|
|
|
TargetRegisterClass *SRRegisterClass = &SRInstance;
|
|
|
|
} // end namespace SparcV9
|
|
|
|
|
|
|
|
const unsigned *SparcV9RegisterInfo::getCalleeSaveRegs() const {
|
|
|
|
// FIXME: This should be verified against the SparcV9 ABI at some point.
|
|
|
|
// These are the registers which the SparcV9 backend considers
|
|
|
|
// "non-volatile".
|
|
|
|
static const unsigned CalleeSaveRegs[] = {
|
|
|
|
SparcV9::l0, SparcV9::l1, SparcV9::l2, SparcV9::l3, SparcV9::l4,
|
|
|
|
SparcV9::l5, SparcV9::l6, SparcV9::l7, SparcV9::i0, SparcV9::i1,
|
|
|
|
SparcV9::i2, SparcV9::i3, SparcV9::i4, SparcV9::i5, SparcV9::i6,
|
|
|
|
SparcV9::i7, SparcV9::g0, SparcV9::g1, SparcV9::g2, SparcV9::g3,
|
|
|
|
SparcV9::g4, SparcV9::g5, SparcV9::g6, SparcV9::g7, SparcV9::o6,
|
|
|
|
0
|
|
|
|
};
|
|
|
|
return CalleeSaveRegs;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // end namespace llvm
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// The second section of this file (immediately following) contains the
|
|
|
|
// SparcV9 implementation of the MRegisterInfo class. It currently consists
|
|
|
|
// entirely of stub functions, because the SparcV9 target does not use the
|
|
|
|
// same register allocator that the X86 target uses.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
SparcV9RegisterInfo::SparcV9RegisterInfo ()
|
|
|
|
: MRegisterInfo (RegisterDescriptors, 104, RegisterClasses,
|
|
|
|
RegisterClasses + 5) {
|
|
|
|
}
|
|
|
|
|
2004-08-16 00:15:11 +02:00
|
|
|
void SparcV9RegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
2004-04-25 08:32:05 +02:00
|
|
|
MachineBasicBlock::iterator MI,
|
2004-08-15 23:56:44 +02:00
|
|
|
unsigned SrcReg, int FrameIndex) const{
|
2004-04-25 08:32:05 +02:00
|
|
|
abort ();
|
|
|
|
}
|
|
|
|
|
2004-08-16 00:15:11 +02:00
|
|
|
void SparcV9RegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
2004-04-25 08:32:05 +02:00
|
|
|
MachineBasicBlock::iterator MI,
|
2004-08-15 23:56:44 +02:00
|
|
|
unsigned DestReg, int FrameIndex) const {
|
2004-04-25 08:32:05 +02:00
|
|
|
abort ();
|
|
|
|
}
|
|
|
|
|
2004-08-16 00:15:11 +02:00
|
|
|
void SparcV9RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
|
2004-04-25 08:32:05 +02:00
|
|
|
MachineBasicBlock::iterator MI,
|
|
|
|
unsigned DestReg, unsigned SrcReg,
|
|
|
|
const TargetRegisterClass *RC) const {
|
|
|
|
abort ();
|
|
|
|
}
|
|
|
|
|
2005-04-22 01:30:14 +02:00
|
|
|
void SparcV9RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI)
|
2004-08-15 00:03:29 +02:00
|
|
|
const {
|
2004-04-25 08:32:05 +02:00
|
|
|
abort ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SparcV9RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|
|
|
abort ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SparcV9RegisterInfo::emitEpilogue(MachineFunction &MF,
|
|
|
|
MachineBasicBlock &MBB) const {
|
|
|
|
abort ();
|
|
|
|
}
|