mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-27 09:17:11 +00:00
Support multiple ValueTypes per RegisterClass, needed for upcoming vector
work. This change has no effect on generated code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24563 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -45,18 +45,15 @@ public:
|
|||||||
typedef const unsigned* const_iterator;
|
typedef const unsigned* const_iterator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const MVT::ValueType VT;
|
const MVT::ValueType* VTs;
|
||||||
const unsigned RegSize, Alignment; // Size & Alignment of register in bytes
|
const unsigned RegSize, Alignment; // Size & Alignment of register in bytes
|
||||||
const iterator RegsBegin, RegsEnd;
|
const iterator RegsBegin, RegsEnd;
|
||||||
public:
|
public:
|
||||||
TargetRegisterClass(MVT::ValueType vt, unsigned RS, unsigned Al, iterator RB, iterator RE)
|
TargetRegisterClass(const MVT::ValueType *vts, unsigned RS, unsigned Al,
|
||||||
: VT(vt), RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {}
|
iterator RB, iterator RE)
|
||||||
|
: VTs(vts), RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {}
|
||||||
virtual ~TargetRegisterClass() {} // Allow subclasses
|
virtual ~TargetRegisterClass() {} // Allow subclasses
|
||||||
|
|
||||||
/// getType - Return the declared value type for this register class.
|
|
||||||
///
|
|
||||||
MVT::ValueType getType() const { return VT; }
|
|
||||||
|
|
||||||
// begin/end - Return all of the registers in this class.
|
// begin/end - Return all of the registers in this class.
|
||||||
iterator begin() const { return RegsBegin; }
|
iterator begin() const { return RegsBegin; }
|
||||||
iterator end() const { return RegsEnd; }
|
iterator end() const { return RegsEnd; }
|
||||||
@@ -78,6 +75,15 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// hasType - return true if this TargetRegisterClass has the ValueType vt.
|
||||||
|
///
|
||||||
|
bool hasType(MVT::ValueType vt) const {
|
||||||
|
for(int i = 0; VTs[i] != MVT::Other; ++i)
|
||||||
|
if (VTs[i] == vt)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// allocation_order_begin/end - These methods define a range of registers
|
/// allocation_order_begin/end - These methods define a range of registers
|
||||||
/// which specify the registers in this class that are valid to register
|
/// which specify the registers in this class that are valid to register
|
||||||
/// allocate, and the preferred order to allocate them in. For example,
|
/// allocate, and the preferred order to allocate them in. For example,
|
||||||
|
|||||||
@@ -1208,7 +1208,7 @@ void SimpleSched::EmitNode(NodeInfo *NI) {
|
|||||||
// Pick the register class of the right type that contains this physreg.
|
// Pick the register class of the right type that contains this physreg.
|
||||||
for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(),
|
for (MRegisterInfo::regclass_iterator I = MRI.regclass_begin(),
|
||||||
E = MRI.regclass_end(); I != E; ++I)
|
E = MRI.regclass_end(); I != E; ++I)
|
||||||
if ((*I)->getType() == Node->getValueType(0) &&
|
if ((*I)->hasType(Node->getValueType(0)) &&
|
||||||
(*I)->contains(SrcReg)) {
|
(*I)->contains(SrcReg)) {
|
||||||
TRC = *I;
|
TRC = *I;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ def F30 : FPR<30, "$f30">; def F31 : FPR<31, "$f31">;
|
|||||||
// $28 is undefined after any and all calls
|
// $28 is undefined after any and all calls
|
||||||
|
|
||||||
/// Register classes
|
/// Register classes
|
||||||
def GPRC : RegisterClass<"Alpha", i64, 64,
|
def GPRC : RegisterClass<"Alpha", [i64], 64,
|
||||||
// Volatile
|
// Volatile
|
||||||
[R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22,
|
[R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22,
|
||||||
R23, R24, R25, R28,
|
R23, R24, R25, R28,
|
||||||
@@ -102,7 +102,7 @@ def GPRC : RegisterClass<"Alpha", i64, 64,
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
def F4RC : RegisterClass<"Alpha", f32, 64, [F0, F1,
|
def F4RC : RegisterClass<"Alpha", [f32], 64, [F0, F1,
|
||||||
F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
|
F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
|
||||||
F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30,
|
F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30,
|
||||||
// Saved:
|
// Saved:
|
||||||
@@ -120,7 +120,7 @@ def F4RC : RegisterClass<"Alpha", f32, 64, [F0, F1,
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
def F8RC : RegisterClass<"Alpha", f64, 64, [F0, F1,
|
def F8RC : RegisterClass<"Alpha", [f64], 64, [F0, F1,
|
||||||
F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
|
F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
|
||||||
F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30,
|
F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30,
|
||||||
// Saved:
|
// Saved:
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ def B6 : GR<0, "b6">;
|
|||||||
// FIXME/XXX we also reserve r22 for calculating addresses
|
// FIXME/XXX we also reserve r22 for calculating addresses
|
||||||
// in IA64RegisterInfo.cpp
|
// in IA64RegisterInfo.cpp
|
||||||
|
|
||||||
def GR : RegisterClass<"IA64", i64, 64,
|
def GR : RegisterClass<"IA64", [i64], 64,
|
||||||
[
|
[
|
||||||
|
|
||||||
//FIXME!: for readability, we don't want the out registers to be the first
|
//FIXME!: for readability, we don't want the out registers to be the first
|
||||||
@@ -282,7 +282,7 @@ def GR : RegisterClass<"IA64", i64, 64,
|
|||||||
|
|
||||||
|
|
||||||
// these are the scratch (+stacked) FP registers
|
// these are the scratch (+stacked) FP registers
|
||||||
def FP : RegisterClass<"IA64", f64, 64,
|
def FP : RegisterClass<"IA64", [f64], 64,
|
||||||
[F6, F7,
|
[F6, F7,
|
||||||
F8, F9, F10, F11, F12, F13, F14, F15,
|
F8, F9, F10, F11, F12, F13, F14, F15,
|
||||||
F32, F33, F34, F35, F36, F37, F38, F39,
|
F32, F33, F34, F35, F36, F37, F38, F39,
|
||||||
@@ -317,7 +317,7 @@ def FP : RegisterClass<"IA64", f64, 64,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// these are the predicate registers, p0 (1/TRUE) is not here
|
// these are the predicate registers, p0 (1/TRUE) is not here
|
||||||
def PR : RegisterClass<"IA64", i1, 64,
|
def PR : RegisterClass<"IA64", [i1], 64,
|
||||||
|
|
||||||
// for now, let's be wimps and only have the scratch predicate regs
|
// for now, let's be wimps and only have the scratch predicate regs
|
||||||
[p6, p7, p8, p9, p10, p11, p12, p13, p14, p15]> {
|
[p6, p7, p8, p9, p10, p11, p12, p13, p14, p15]> {
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ def VRSAVE: SPR<256, "VRsave">;
|
|||||||
/// Register classes
|
/// Register classes
|
||||||
// Allocate volatiles first
|
// Allocate volatiles first
|
||||||
// then nonvolatiles in reverse order since stmw/lmw save from rN to r31
|
// then nonvolatiles in reverse order since stmw/lmw save from rN to r31
|
||||||
def GPRC : RegisterClass<"PPC", i32, 32,
|
def GPRC : RegisterClass<"PPC", [i32], 32,
|
||||||
[R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12,
|
[R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12,
|
||||||
R30, R29, R28, R27, R26, R25, R24, R23, R22, R21, R20, R19, R18, R17,
|
R30, R29, R28, R27, R26, R25, R24, R23, R22, R21, R20, R19, R18, R17,
|
||||||
R16, R15, R14, R13, R31, R0, R1, LR]>
|
R16, R15, R14, R13, R31, R0, R1, LR]>
|
||||||
@@ -158,7 +158,7 @@ def GPRC : RegisterClass<"PPC", i32, 32,
|
|||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
def G8RC : RegisterClass<"PPC", i64, 64,
|
def G8RC : RegisterClass<"PPC", [i64], 64,
|
||||||
[X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12,
|
[X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12,
|
||||||
X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17,
|
X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17,
|
||||||
X16, X15, X14, X13, X31, X0, X1]>
|
X16, X15, X14, X13, X31, X0, X1]>
|
||||||
@@ -184,15 +184,16 @@ def G8RC : RegisterClass<"PPC", i64, 64,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def F8RC : RegisterClass<"PPC", f64, 64, [F0, F1, F2, F3, F4, F5, F6, F7,
|
def F8RC : RegisterClass<"PPC", [f64], 64, [F0, F1, F2, F3, F4, F5, F6, F7,
|
||||||
F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
|
F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
|
||||||
F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
||||||
def F4RC : RegisterClass<"PPC", f32, 32, [F0, F1, F2, F3, F4, F5, F6, F7,
|
def F4RC : RegisterClass<"PPC", [f32], 32, [F0, F1, F2, F3, F4, F5, F6, F7,
|
||||||
F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
|
F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
|
||||||
F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
||||||
|
|
||||||
def VRRC : RegisterClass<"PPC", v4f32, 128, [V0, V1, V2, V3, V4, V5, V6, V7, V8,
|
def VRRC : RegisterClass<"PPC", [v4f32], 128, [V0, V1, V2, V3, V4, V5, V6, V7,
|
||||||
V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23,
|
V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V20, V21, V22, V23,
|
||||||
V24, V25, V26, V27, V28, V29, V30, V31]>;
|
V24, V25, V26, V27, V28, V29, V30, V31]>;
|
||||||
|
|
||||||
def CRRC : RegisterClass<"PPC", i32, 32, [CR0, CR1, CR5, CR6, CR7, CR2, CR3, CR4]>;
|
def CRRC : RegisterClass<"PPC", [i32], 32, [CR0, CR1, CR5, CR6, CR7, CR2,
|
||||||
|
CR3, CR4]>;
|
||||||
|
|||||||
@@ -89,10 +89,10 @@ def TBU : SPR<5, "TBU">;
|
|||||||
|
|
||||||
/// Register classes: one for floats and another for non-floats.
|
/// Register classes: one for floats and another for non-floats.
|
||||||
///
|
///
|
||||||
def GPRC : RegisterClass<"Skeleton", i32, 32, [R0, R1, R2, R3, R4, R5, R6, R7,
|
def GPRC : RegisterClass<"Skeleton", [i32], 32, [R0, R1, R2, R3, R4, R5, R6, R7,
|
||||||
R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21,
|
R8, R9, R10, R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21,
|
||||||
R22, R23, R24, R25, R26, R27, R28, R29, R30, R31]>;
|
R22, R23, R24, R25, R26, R27, R28, R29, R30, R31]>;
|
||||||
def FPRC : RegisterClass<"Skeleton", f64, 64, [F0, F1, F2, F3, F4, F5, F6, F7,
|
def FPRC : RegisterClass<"Skeleton", [f64], 64, [F0, F1, F2, F3, F4, F5, F6, F7,
|
||||||
F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
|
F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21,
|
||||||
F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
F22, F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ def Y : Rs<0, "Y">;
|
|||||||
// FIXME: the register order should be defined in terms of the preferred
|
// FIXME: the register order should be defined in terms of the preferred
|
||||||
// allocation order...
|
// allocation order...
|
||||||
//
|
//
|
||||||
def IntRegs : RegisterClass<"V8", i32, 32, [L0, L1, L2, L3, L4, L5, L6, L7,
|
def IntRegs : RegisterClass<"V8", [i32], 32, [L0, L1, L2, L3, L4, L5, L6, L7,
|
||||||
I0, I1, I2, I3, I4, I5,
|
I0, I1, I2, I3, I4, I5,
|
||||||
G1,
|
G1,
|
||||||
O0, O1, O2, O3, O4, O5, O7,
|
O0, O1, O2, O3, O4, O5, O7,
|
||||||
@@ -109,9 +109,9 @@ def IntRegs : RegisterClass<"V8", i32, 32, [L0, L1, L2, L3, L4, L5, L6, L7,
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
def FPRegs : RegisterClass<"V8", f32, 32, [F0, F1, F2, F3, F4, F5, F6, F7, F8,
|
def FPRegs : RegisterClass<"V8", [f32], 32, [F0, F1, F2, F3, F4, F5, F6, F7, F8,
|
||||||
F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22,
|
F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22,
|
||||||
F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
||||||
|
|
||||||
def DFPRegs : RegisterClass<"V8", f64, 64, [D0, D1, D2, D3, D4, D5, D6, D7,
|
def DFPRegs : RegisterClass<"V8", [f64], 64, [D0, D1, D2, D3, D4, D5, D6, D7,
|
||||||
D8, D9, D10, D11, D12, D13, D14, D15]>;
|
D8, D9, D10, D11, D12, D13, D14, D15]>;
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ def Y : Rs<0, "Y">;
|
|||||||
// FIXME: the register order should be defined in terms of the preferred
|
// FIXME: the register order should be defined in terms of the preferred
|
||||||
// allocation order...
|
// allocation order...
|
||||||
//
|
//
|
||||||
def IntRegs : RegisterClass<"V8", i32, 32, [L0, L1, L2, L3, L4, L5, L6, L7,
|
def IntRegs : RegisterClass<"V8", [i32], 32, [L0, L1, L2, L3, L4, L5, L6, L7,
|
||||||
I0, I1, I2, I3, I4, I5,
|
I0, I1, I2, I3, I4, I5,
|
||||||
G1,
|
G1,
|
||||||
O0, O1, O2, O3, O4, O5, O7,
|
O0, O1, O2, O3, O4, O5, O7,
|
||||||
@@ -109,9 +109,9 @@ def IntRegs : RegisterClass<"V8", i32, 32, [L0, L1, L2, L3, L4, L5, L6, L7,
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
def FPRegs : RegisterClass<"V8", f32, 32, [F0, F1, F2, F3, F4, F5, F6, F7, F8,
|
def FPRegs : RegisterClass<"V8", [f32], 32, [F0, F1, F2, F3, F4, F5, F6, F7, F8,
|
||||||
F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22,
|
F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22,
|
||||||
F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
|
||||||
|
|
||||||
def DFPRegs : RegisterClass<"V8", f64, 64, [D0, D1, D2, D3, D4, D5, D6, D7,
|
def DFPRegs : RegisterClass<"V8", [f64], 64, [D0, D1, D2, D3, D4, D5, D6, D7,
|
||||||
D8, D9, D10, D11, D12, D13, D14, D15]>;
|
D8, D9, D10, D11, D12, D13, D14, D15]>;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "SparcV9RegisterInfo.h"
|
#include "SparcV9RegisterInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
|
#include "llvm/CodeGen/ValueTypes.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@@ -42,8 +43,9 @@ namespace {
|
|||||||
SparcV9::g2, SparcV9::g3, SparcV9::g4, SparcV9::g5, SparcV9::g6,
|
SparcV9::g2, SparcV9::g3, SparcV9::g4, SparcV9::g5, SparcV9::g6,
|
||||||
SparcV9::g7, SparcV9::o6
|
SparcV9::g7, SparcV9::o6
|
||||||
};
|
};
|
||||||
|
const MVT::ValueType IRVTs[] = { MVT::i64, MVT::Other };
|
||||||
struct IRClass : public TargetRegisterClass {
|
struct IRClass : public TargetRegisterClass {
|
||||||
IRClass() : TargetRegisterClass(MVT::i64, 8, 8, IR, IR + 32) {}
|
IRClass() : TargetRegisterClass(IRVTs, 8, 8, IR, IR + 32) {}
|
||||||
} IRInstance;
|
} IRInstance;
|
||||||
|
|
||||||
|
|
||||||
@@ -66,12 +68,13 @@ namespace {
|
|||||||
SparcV9::f58, SparcV9::f59, SparcV9::f60, SparcV9::f61,
|
SparcV9::f58, SparcV9::f59, SparcV9::f60, SparcV9::f61,
|
||||||
SparcV9::f62, SparcV9::f63
|
SparcV9::f62, SparcV9::f63
|
||||||
};
|
};
|
||||||
|
const MVT::ValueType FRVTs[] = { MVT::f32, MVT::Other };
|
||||||
// FIXME: The size is correct for the first 32 registers. The
|
// FIXME: The size is correct for the first 32 registers. The
|
||||||
// latter 32 do not all really exist; you can only access every other
|
// 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
|
// one (32, 34, ...), and they must contain double-fp or quad-fp
|
||||||
// values... see below about the aliasing problems.
|
// values... see below about the aliasing problems.
|
||||||
struct FRClass : public TargetRegisterClass {
|
struct FRClass : public TargetRegisterClass {
|
||||||
FRClass() : TargetRegisterClass(MVT::f32, 4, 8, FR, FR + 64) {}
|
FRClass() : TargetRegisterClass(FRVTs, 4, 8, FR, FR + 64) {}
|
||||||
} FRInstance;
|
} FRInstance;
|
||||||
|
|
||||||
|
|
||||||
@@ -79,8 +82,9 @@ namespace {
|
|||||||
const unsigned ICCR[] = {
|
const unsigned ICCR[] = {
|
||||||
SparcV9::xcc, SparcV9::icc, SparcV9::ccr
|
SparcV9::xcc, SparcV9::icc, SparcV9::ccr
|
||||||
};
|
};
|
||||||
|
const MVT::ValueType ICCRVTs[] = { MVT::i1, MVT::Other };
|
||||||
struct ICCRClass : public TargetRegisterClass {
|
struct ICCRClass : public TargetRegisterClass {
|
||||||
ICCRClass() : TargetRegisterClass(MVT::i1, 1, 8, ICCR, ICCR + 3) {}
|
ICCRClass() : TargetRegisterClass(ICCRVTs, 1, 8, ICCR, ICCR + 3) {}
|
||||||
} ICCRInstance;
|
} ICCRInstance;
|
||||||
|
|
||||||
|
|
||||||
@@ -88,8 +92,9 @@ namespace {
|
|||||||
const unsigned FCCR[] = {
|
const unsigned FCCR[] = {
|
||||||
SparcV9::fcc0, SparcV9::fcc1, SparcV9::fcc2, SparcV9::fcc3
|
SparcV9::fcc0, SparcV9::fcc1, SparcV9::fcc2, SparcV9::fcc3
|
||||||
};
|
};
|
||||||
|
const MVT::ValueType FCCRVTs[] = { MVT::i1, MVT::Other };
|
||||||
struct FCCRClass : public TargetRegisterClass {
|
struct FCCRClass : public TargetRegisterClass {
|
||||||
FCCRClass() : TargetRegisterClass(MVT::i1, 1, 8, FCCR, FCCR + 4) {}
|
FCCRClass() : TargetRegisterClass(FCCRVTs, 1, 8, FCCR, FCCR + 4) {}
|
||||||
} FCCRInstance;
|
} FCCRInstance;
|
||||||
|
|
||||||
|
|
||||||
@@ -97,8 +102,9 @@ namespace {
|
|||||||
const unsigned SR[] = {
|
const unsigned SR[] = {
|
||||||
SparcV9::fsr
|
SparcV9::fsr
|
||||||
};
|
};
|
||||||
|
const MVT::ValueType SRVTs[] = { MVT::i64, MVT::Other };
|
||||||
struct SRClass : public TargetRegisterClass {
|
struct SRClass : public TargetRegisterClass {
|
||||||
SRClass() : TargetRegisterClass(MVT::i64, 8, 8, SR, SR + 1) {}
|
SRClass() : TargetRegisterClass(SRVTs, 8, 8, SR, SR + 1) {}
|
||||||
} SRInstance;
|
} SRInstance;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ let Namespace = "SparcV9" in {
|
|||||||
// FIXME: the register order should be defined in terms of the preferred
|
// FIXME: the register order should be defined in terms of the preferred
|
||||||
// allocation order...
|
// allocation order...
|
||||||
//
|
//
|
||||||
def IntRegs : RegisterClass<"V9", i64, 64, [G0, G1, G2, G3, G4, G5, G6, G7,
|
def IntRegs : RegisterClass<"V9", [i64], 64, [G0, G1, G2, G3, G4, G5, G6, G7,
|
||||||
O0, O1, O2, O3, O4, O5, O6, O7,
|
O0, O1, O2, O3, O4, O5, O6, O7,
|
||||||
L0, L1, L2, L3, L4, L5, L6, L7,
|
L0, L1, L2, L3, L4, L5, L6, L7,
|
||||||
I0, I1, I2, I3, I4, I5, I6, I7]>;
|
I0, I1, I2, I3, I4, I5, I6, I7]>;
|
||||||
|
|||||||
@@ -90,19 +90,22 @@ class RegisterGroup<string n, list<Register> aliases> : Register<n> {
|
|||||||
// register classes. This also defines the default allocation order of
|
// register classes. This also defines the default allocation order of
|
||||||
// registers by register allocators.
|
// registers by register allocators.
|
||||||
//
|
//
|
||||||
class RegisterClass<string namespace, ValueType regType, int alignment,
|
class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
|
||||||
list<Register> regList> {
|
list<Register> regList> {
|
||||||
string Namespace = namespace;
|
string Namespace = namespace;
|
||||||
|
|
||||||
// RegType - Specify the ValueType of the registers in this register class.
|
// RegType - Specify the ValueType of the registers in this register class.
|
||||||
// Note that all registers in a register class must have the same ValueType.
|
// Note that all registers in a register class must have the same ValueType.
|
||||||
//
|
//
|
||||||
ValueType RegType = regType;
|
list<ValueType> RegTypes = regTypes;
|
||||||
|
|
||||||
|
// Size - Specify the spill size in bits of the registers. A default value of
|
||||||
|
// zero lets tablgen pick an appropriate size.
|
||||||
|
int Size = 0;
|
||||||
|
|
||||||
// Alignment - Specify the alignment required of the registers when they are
|
// Alignment - Specify the alignment required of the registers when they are
|
||||||
// stored or loaded to memory.
|
// stored or loaded to memory.
|
||||||
//
|
//
|
||||||
int Size = RegType.Size;
|
|
||||||
int Alignment = alignment;
|
int Alignment = alignment;
|
||||||
|
|
||||||
// MemberList - Specify which registers are in this class. If the
|
// MemberList - Specify which registers are in this class. If the
|
||||||
|
|||||||
@@ -72,9 +72,9 @@ let Namespace = "X86" in {
|
|||||||
// dependences between upper and lower parts of the register. BL and BH are
|
// dependences between upper and lower parts of the register. BL and BH are
|
||||||
// last because they are call clobbered. Both Athlon and P4 chips suffer this
|
// last because they are call clobbered. Both Athlon and P4 chips suffer this
|
||||||
// issue.
|
// issue.
|
||||||
def R8 : RegisterClass<"X86", i8, 8, [AL, CL, DL, AH, CH, DH, BL, BH]>;
|
def R8 : RegisterClass<"X86", [i8], 8, [AL, CL, DL, AH, CH, DH, BL, BH]>;
|
||||||
|
|
||||||
def R16 : RegisterClass<"X86", i16, 16, [AX, CX, DX, SI, DI, BX, BP, SP]> {
|
def R16 : RegisterClass<"X86", [i16], 16, [AX, CX, DX, SI, DI, BX, BP, SP]> {
|
||||||
let MethodProtos = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_end(MachineFunction &MF) const;
|
iterator allocation_order_end(MachineFunction &MF) const;
|
||||||
}];
|
}];
|
||||||
@@ -89,7 +89,8 @@ def R16 : RegisterClass<"X86", i16, 16, [AX, CX, DX, SI, DI, BX, BP, SP]> {
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
def R32 : RegisterClass<"X86", i32, 32, [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP]> {
|
def R32 : RegisterClass<"X86", [i32], 32,
|
||||||
|
[EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP]> {
|
||||||
let MethodProtos = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_end(MachineFunction &MF) const;
|
iterator allocation_order_end(MachineFunction &MF) const;
|
||||||
}];
|
}];
|
||||||
@@ -106,9 +107,9 @@ def R32 : RegisterClass<"X86", i32, 32, [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP]
|
|||||||
|
|
||||||
// V4F4, the 4 x f32 class, and V2F8, the 2 x f64 class, which we will use for
|
// V4F4, the 4 x f32 class, and V2F8, the 2 x f64 class, which we will use for
|
||||||
// Scalar SSE2 floating point support.
|
// Scalar SSE2 floating point support.
|
||||||
def V4F4 : RegisterClass<"X86", f32, 32,
|
def V4F4 : RegisterClass<"X86", [f32], 32,
|
||||||
[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>;
|
[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>;
|
||||||
def V2F8 : RegisterClass<"X86", f64, 64,
|
def V2F8 : RegisterClass<"X86", [f64], 64,
|
||||||
[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>;
|
[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>;
|
||||||
|
|
||||||
// FIXME: This sets up the floating point register files as though they are f64
|
// FIXME: This sets up the floating point register files as though they are f64
|
||||||
@@ -117,12 +118,12 @@ def V2F8 : RegisterClass<"X86", f64, 64,
|
|||||||
// faster on common hardware. In reality, this should be controlled by a
|
// faster on common hardware. In reality, this should be controlled by a
|
||||||
// command line option or something.
|
// command line option or something.
|
||||||
|
|
||||||
def RFP : RegisterClass<"X86", f64, 32, [FP0, FP1, FP2, FP3, FP4, FP5, FP6]>;
|
def RFP : RegisterClass<"X86", [f64], 32, [FP0, FP1, FP2, FP3, FP4, FP5, FP6]>;
|
||||||
|
|
||||||
// Floating point stack registers (these are not allocatable by the
|
// Floating point stack registers (these are not allocatable by the
|
||||||
// register allocator - the floating point stackifier is responsible
|
// register allocator - the floating point stackifier is responsible
|
||||||
// for transforming FPn allocations to STn registers)
|
// for transforming FPn allocations to STn registers)
|
||||||
def RST : RegisterClass<"X86", f64, 32,
|
def RST : RegisterClass<"X86", [f64], 32,
|
||||||
[ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7]> {
|
[ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7]> {
|
||||||
let MethodProtos = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_end(MachineFunction &MF) const;
|
iterator allocation_order_end(MachineFunction &MF) const;
|
||||||
|
|||||||
@@ -35,13 +35,20 @@ namespace llvm {
|
|||||||
Record *TheDef;
|
Record *TheDef;
|
||||||
std::string Namespace;
|
std::string Namespace;
|
||||||
std::vector<Record*> Elements;
|
std::vector<Record*> Elements;
|
||||||
|
std::vector<MVT::ValueType> VTs;
|
||||||
unsigned SpillSize;
|
unsigned SpillSize;
|
||||||
unsigned SpillAlignment;
|
unsigned SpillAlignment;
|
||||||
MVT::ValueType VT;
|
|
||||||
std::string MethodProtos, MethodBodies;
|
std::string MethodProtos, MethodBodies;
|
||||||
|
|
||||||
const std::string &getName() const;
|
const std::string &getName() const;
|
||||||
|
|
||||||
|
const MVT::ValueType getValueTypeNum(unsigned VTNum) const {
|
||||||
|
if (VTNum < VTs.size())
|
||||||
|
return VTs[VTNum];
|
||||||
|
assert(0 && "VTNum greater than number of ValueTypes in RegClass!");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
CodeGenRegisterClass(Record *R);
|
CodeGenRegisterClass(Record *R);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,13 +154,15 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
|
|||||||
R->setName("AnonRegClass_"+utostr(AnonCounter++));
|
R->setName("AnonRegClass_"+utostr(AnonCounter++));
|
||||||
}
|
}
|
||||||
|
|
||||||
Namespace = R->getValueAsString("Namespace");
|
std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes");
|
||||||
SpillSize = R->getValueAsInt("Size");
|
for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
|
||||||
SpillAlignment = R->getValueAsInt("Alignment");
|
Record *Type = TypeList[i];
|
||||||
VT = getValueType(R->getValueAsDef("RegType"));
|
if (!Type->isSubClassOf("ValueType"))
|
||||||
|
throw "RegTypes list member '" + Type->getName() +
|
||||||
MethodBodies = R->getValueAsCode("MethodBodies");
|
"' does not derive from the ValueType class!";
|
||||||
MethodProtos = R->getValueAsCode("MethodProtos");
|
VTs.push_back(getValueType(Type));
|
||||||
|
}
|
||||||
|
assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!");
|
||||||
|
|
||||||
std::vector<Record*> RegList = R->getValueAsListOfDefs("MemberList");
|
std::vector<Record*> RegList = R->getValueAsListOfDefs("MemberList");
|
||||||
for (unsigned i = 0, e = RegList.size(); i != e; ++i) {
|
for (unsigned i = 0, e = RegList.size(); i != e; ++i) {
|
||||||
@@ -170,6 +172,15 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
|
|||||||
"' does not derive from the Register class!";
|
"' does not derive from the Register class!";
|
||||||
Elements.push_back(Reg);
|
Elements.push_back(Reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow targets to override the size in bits of the RegisterClass.
|
||||||
|
unsigned Size = R->getValueAsInt("Size");
|
||||||
|
|
||||||
|
Namespace = R->getValueAsString("Namespace");
|
||||||
|
SpillSize = Size ? Size : MVT::getSizeInBits(VTs[0]);
|
||||||
|
SpillAlignment = R->getValueAsInt("Alignment");
|
||||||
|
MethodBodies = R->getValueAsCode("MethodBodies");
|
||||||
|
MethodProtos = R->getValueAsCode("MethodProtos");
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &CodeGenRegisterClass::getName() const {
|
const std::string &CodeGenRegisterClass::getName() const {
|
||||||
@@ -179,7 +190,8 @@ const std::string &CodeGenRegisterClass::getName() const {
|
|||||||
void CodeGenTarget::ReadLegalValueTypes() const {
|
void CodeGenTarget::ReadLegalValueTypes() const {
|
||||||
const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses();
|
const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses();
|
||||||
for (unsigned i = 0, e = RCs.size(); i != e; ++i)
|
for (unsigned i = 0, e = RCs.size(); i != e; ++i)
|
||||||
LegalValueTypes.push_back(RCs[i].VT);
|
for (unsigned ri = 0, re = RCs[i].VTs.size(); ri != re; ++ri)
|
||||||
|
LegalValueTypes.push_back(RCs[i].VTs[ri]);
|
||||||
|
|
||||||
// Remove duplicates.
|
// Remove duplicates.
|
||||||
std::sort(LegalValueTypes.begin(), LegalValueTypes.end());
|
std::sort(LegalValueTypes.begin(), LegalValueTypes.end());
|
||||||
|
|||||||
@@ -455,7 +455,9 @@ static unsigned char getIntrinsicType(Record *R, bool NotRegisters,
|
|||||||
// Check to see if this is a register or a register class...
|
// Check to see if this is a register or a register class...
|
||||||
if (R->isSubClassOf("RegisterClass")) {
|
if (R->isSubClassOf("RegisterClass")) {
|
||||||
if (NotRegisters) return MVT::isUnknown;
|
if (NotRegisters) return MVT::isUnknown;
|
||||||
return getValueType(R->getValueAsDef("RegType"));
|
const CodeGenRegisterClass &RC =
|
||||||
|
TP.getDAGISelEmitter().getTargetInfo().getRegisterClass(R);
|
||||||
|
return RC.getValueTypeNum(0);
|
||||||
} else if (R->isSubClassOf("PatFrag")) {
|
} else if (R->isSubClassOf("PatFrag")) {
|
||||||
// Pattern fragment types will be resolved when they are inlined.
|
// Pattern fragment types will be resolved when they are inlined.
|
||||||
return MVT::isUnknown;
|
return MVT::isUnknown;
|
||||||
@@ -538,7 +540,8 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
|
|||||||
const CodeGenRegisterClass &RC =
|
const CodeGenRegisterClass &RC =
|
||||||
TP.getDAGISelEmitter().getTargetInfo().getRegisterClass(ResultNode);
|
TP.getDAGISelEmitter().getTargetInfo().getRegisterClass(ResultNode);
|
||||||
|
|
||||||
bool MadeChange = UpdateNodeType(RC.VT, TP);
|
// Get the first ValueType in the RegClass, it's as good as any.
|
||||||
|
bool MadeChange = UpdateNodeType(RC.getValueTypeNum(0), TP);
|
||||||
|
|
||||||
if (getNumChildren() != Inst.getNumOperands())
|
if (getNumChildren() != Inst.getNumOperands())
|
||||||
TP.error("Instruction '" + getOperator()->getName() + " expects " +
|
TP.error("Instruction '" + getOperator()->getName() + " expects " +
|
||||||
@@ -550,7 +553,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
|
|||||||
if (OperandNode->isSubClassOf("RegisterClass")) {
|
if (OperandNode->isSubClassOf("RegisterClass")) {
|
||||||
const CodeGenRegisterClass &RC =
|
const CodeGenRegisterClass &RC =
|
||||||
TP.getDAGISelEmitter().getTargetInfo().getRegisterClass(OperandNode);
|
TP.getDAGISelEmitter().getTargetInfo().getRegisterClass(OperandNode);
|
||||||
VT = RC.VT;
|
VT = RC.getValueTypeNum(0);
|
||||||
} else if (OperandNode->isSubClassOf("Operand")) {
|
} else if (OperandNode->isSubClassOf("Operand")) {
|
||||||
VT = getValueType(OperandNode->getValueAsDef("Type"));
|
VT = getValueType(OperandNode->getValueAsDef("Type"));
|
||||||
} else {
|
} else {
|
||||||
@@ -1672,7 +1675,8 @@ void DAGISelEmitter::EmitMatchForPattern(TreePatternNode *N,
|
|||||||
<< ".Val)) goto P" << PatternNo << "Fail;\n";
|
<< ".Val)) goto P" << PatternNo << "Fail;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getRegisterValueType - Look up and return ValueType of specified record
|
/// getRegisterValueType - Look up and return the first ValueType of specified
|
||||||
|
/// RegisterClass record
|
||||||
static MVT::ValueType getRegisterValueType(Record *R, const CodeGenTarget &T) {
|
static MVT::ValueType getRegisterValueType(Record *R, const CodeGenTarget &T) {
|
||||||
const std::vector<CodeGenRegisterClass> &RegisterClasses =
|
const std::vector<CodeGenRegisterClass> &RegisterClasses =
|
||||||
T.getRegisterClasses();
|
T.getRegisterClasses();
|
||||||
@@ -1681,7 +1685,7 @@ static MVT::ValueType getRegisterValueType(Record *R, const CodeGenTarget &T) {
|
|||||||
const CodeGenRegisterClass &RC = RegisterClasses[i];
|
const CodeGenRegisterClass &RC = RegisterClasses[i];
|
||||||
for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) {
|
for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) {
|
||||||
if (R == RC.Elements[ei]) {
|
if (R == RC.Elements[ei]) {
|
||||||
return RC.VT;
|
return RC.getValueTypeNum(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
|
|||||||
// belongs to.
|
// belongs to.
|
||||||
std::multimap<Record*, const CodeGenRegisterClass*> RegClassesBelongedTo;
|
std::multimap<Record*, const CodeGenRegisterClass*> RegClassesBelongedTo;
|
||||||
|
|
||||||
|
// Emit the register enum value arrays for each RegisterClass
|
||||||
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
|
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
|
||||||
const CodeGenRegisterClass &RC = RegisterClasses[rc];
|
const CodeGenRegisterClass &RC = RegisterClasses[rc];
|
||||||
|
|
||||||
@@ -127,6 +128,22 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
|
|||||||
}
|
}
|
||||||
OS << "\n };\n\n";
|
OS << "\n };\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emit the ValueType arrays for each RegisterClass
|
||||||
|
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
|
||||||
|
const CodeGenRegisterClass &RC = RegisterClasses[rc];
|
||||||
|
|
||||||
|
// Give the register class a legal C name if it's anonymous.
|
||||||
|
std::string Name = RC.TheDef->getName() + "VTs";
|
||||||
|
|
||||||
|
// Emit the register list now.
|
||||||
|
OS << " // " << Name
|
||||||
|
<< " Register Class Value Types...\n const MVT::ValueType " << Name
|
||||||
|
<< "[] = {\n ";
|
||||||
|
for (unsigned i = 0, e = RC.VTs.size(); i != e; ++i)
|
||||||
|
OS << "MVT::" << RC.VTs[i] << ", ";
|
||||||
|
OS << "MVT::Other\n };\n\n";
|
||||||
|
}
|
||||||
OS << "} // end anonymous namespace\n\n";
|
OS << "} // end anonymous namespace\n\n";
|
||||||
|
|
||||||
// Now that all of the structs have been emitted, emit the instances.
|
// Now that all of the structs have been emitted, emit the instances.
|
||||||
@@ -141,7 +158,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
|
|||||||
const CodeGenRegisterClass &RC = RegisterClasses[i];
|
const CodeGenRegisterClass &RC = RegisterClasses[i];
|
||||||
OS << RC.MethodBodies << "\n";
|
OS << RC.MethodBodies << "\n";
|
||||||
OS << RC.getName() << "Class::" << RC.getName()
|
OS << RC.getName() << "Class::" << RC.getName()
|
||||||
<< "Class() : TargetRegisterClass(MVT::" << getEnumName(RC.VT) << ","
|
<< "Class() : TargetRegisterClass(" << RC.getName() + "VTs" << ", "
|
||||||
<< RC.SpillSize/8 << ", "
|
<< RC.SpillSize/8 << ", "
|
||||||
<< RC.SpillAlignment/8 << ", " << RC.getName() << ", "
|
<< RC.SpillAlignment/8 << ", " << RC.getName() << ", "
|
||||||
<< RC.getName() << " + " << RC.Elements.size() << ") {}\n";
|
<< RC.getName() << " + " << RC.Elements.size() << ") {}\n";
|
||||||
|
|||||||
Reference in New Issue
Block a user