Use set operations instead of plain lists to enumerate register classes.

This simplifies many of the target description files since it is common
for register classes to be related or contain sequences of numbered
registers.

I have verified that this doesn't change the files generated by TableGen
for ARM and X86. It alters the allocation order of MBlaze GPR and Mips
FGR32 registers, but I believe the change is benign.

llvm-svn: 133105
This commit is contained in:
Jakob Stoklund Olesen 2011-06-15 23:28:14 +00:00
parent d70fb9812a
commit 99f35eab45
15 changed files with 254 additions and 546 deletions

View File

@ -706,8 +706,7 @@ classes using the following class:
<div class="doc_code">
<pre>
class RegisterClass&lt;string namespace,
list&lt;ValueType&gt; regTypes, int alignment,
list&lt;Register&gt; regList&gt; {
list&lt;ValueType&gt; regTypes, int alignment, dag regList&gt; {
string Namespace = namespace;
list&lt;ValueType&gt; RegTypes = regTypes;
int Size = 0; // spill size, in bits; zero lets tblgen pick the size
@ -717,7 +716,7 @@ list&lt;ValueType&gt; regTypes, int alignment,
// default value 1 means a single instruction
// A negative value means copying is extremely expensive or impossible
int CopyCost = 1;
list&lt;Register&gt; MemberList = regList;
dag MemberList = regList;
// for register classes that are subregisters of this class
list&lt;RegisterClass&gt; SubRegClassList = [];
@ -749,9 +748,11 @@ list&lt;ValueType&gt; regTypes, int alignment,
memory.</li>
<li>The final argument, <tt>regList</tt>, specifies which registers are in this
class. If an <tt>allocation_order_*</tt> method is not specified,
then <tt>regList</tt> also defines the order of allocation used by the
register allocator.</li>
class. If an alternative allocation order method is not specified, then
<tt>regList</tt> also defines the order of allocation used by the register
allocator. Besides simply listing registers with <tt>(add R0, R1, ...)</tt>,
more advanced set operators are available. See
<tt>include/llvm/Target/Target.td</tt> for more information.</li>
</ul>
<p>
@ -761,22 +762,20 @@ classes, the first argument defines the namespace with the string
'<tt>SP</tt>'. <tt>FPRegs</tt> defines a group of 32 single-precision
floating-point registers (<tt>F0</tt> to <tt>F31</tt>); <tt>DFPRegs</tt> defines
a group of 16 double-precision registers
(<tt>D0-D15</tt>). For <tt>IntRegs</tt>, the <tt>MethodProtos</tt>
and <tt>MethodBodies</tt> methods are used by TableGen to insert the specified
code into generated output.
(<tt>D0-D15</tt>).
</p>
<div class="doc_code">
<pre>
def FPRegs : RegisterClass&lt;"SP", [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, F23, F24, F25, F26, F27, F28, F29, F30, F31]&gt;;
// F0, F1, F2, ..., F31
def FPRegs : RegisterClass&lt;"SP", [f32], 32, (sequence "F%u", 0, 31)&gt;;
def DFPRegs : RegisterClass&lt;"SP", [f64], 64,
[D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15]&gt;;
(add D0, D1, D2, D3, D4, D5, D6, D7, D8,
D9, D10, D11, D12, D13, D14, D15)&gt;;
&nbsp;
def IntRegs : RegisterClass&lt;"SP", [i32], 32,
[L0, L1, L2, L3, L4, L5, L6, L7,
(add L0, L1, L2, L3, L4, L5, L6, L7,
I0, I1, I2, I3, I4, I5,
O0, O1, O2, O3, O4, O5, O7,
G1,
@ -787,18 +786,7 @@ def IntRegs : RegisterClass&lt;"SP", [i32], 32,
I7, // return address
G0, // constant zero
G5, G6, G7 // reserved for kernel
]&gt; {
let MethodProtos = [{
iterator allocation_order_end(const MachineFunction &amp;MF) const;
}];
let MethodBodies = [{
IntRegsClass::iterator
IntRegsClass::allocation_order_end(const MachineFunction &amp;MF) const {
return end() - 10 // Don't allocate special registers
-1;
}
}];
}
)&gt;;
</pre>
</div>
@ -820,10 +808,7 @@ which is included at the bottom of <tt>SparcRegisterInfo.cpp</tt>, the SPARC
register implementation. The code below shows only the generated integer
registers and associated register classes. The order of registers
in <tt>IntRegs</tt> reflects the order in the definition of <tt>IntRegs</tt> in
the target description file. Take special note of the use
of <tt>MethodBodies</tt> in <tt>SparcRegisterInfo.td</tt> to create code in
<tt>SparcGenRegisterInfo.inc</tt>. <tt>MethodProtos</tt> generates similar code
in <tt>SparcGenRegisterInfo.h.inc</tt>.
the target description file.
</p>
<div class="doc_code">
@ -866,12 +851,6 @@ namespace SP { // Register class instances
static const TargetRegisterClass* const IntRegsSuperclasses [] = {
NULL
};
...
IntRegsClass::iterator
IntRegsClass::allocation_order_end(const MachineFunction &amp;MF) const {
return end()-10 // Don't allocate special registers
-1;
}
IntRegsClass::IntRegsClass() : TargetRegisterClass(IntRegsRegClassID,
IntRegsVTs, IntRegsSubclasses, IntRegsSuperclasses, IntRegsSubRegClasses,
@ -880,6 +859,13 @@ namespace SP { // Register class instances
</pre>
</div>
<p>
The register allocators will avoid using reserved registers, and callee saved
registers are not used until all the volatile registers have been used. That
is usually good enough, but in some cases it may be necessary to provide custom
allocation orders.
</p>
</div>
<!-- ======================================================================= -->

View File

@ -92,7 +92,7 @@ class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
// registers by register allocators.
//
class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
list<Register> regList> {
dag regList> {
string Namespace = namespace;
// RegType - Specify the list ValueType of the registers in this register
@ -122,7 +122,7 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// allocation_order_* method are not specified, this also defines the order of
// allocation used by the register allocator.
//
list<Register> MemberList = regList;
dag MemberList = regList;
// SubRegClasses - Specify the register class of subregisters as a list of
// dags: (RegClass SubRegIndex, SubRegindex, ...)
@ -140,6 +140,39 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
code MethodBodies = [{}];
}
// The memberList in a RegisterClass is a dag of set operations. TableGen
// evaluates these set operations and expand them into register lists. These
// are the most common operation, see test/TableGen/SetTheory.td for more
// examples of what is possible:
//
// (add R0, R1, R2) - Set Union. Each argument can be an individual register, a
// register class, or a sub-expression. This is also the way to simply list
// registers.
//
// (sub GPR, SP) - Set difference. Subtract the last arguments from the first.
//
// (and GPR, CSR) - Set intersection. All registers from the first set that are
// also in the second set.
//
// (sequence "R%u", 0, 15) -> [R0, R1, ..., R15]. Generate a sequence of
// numbered registers.
//
// (shl GPR, 4) - Remove the first N elements.
//
// (trunc GPR, 4) - Truncate after the first N elements.
//
// (rotl GPR, 1) - Rotate N places to the left.
//
// (rotr GPR, 1) - Rotate N places to the right.
//
// (decimate GPR, 2) - Pick every N'th element, starting with the first.
//
// All of these operators work on ordered sets, not lists. That means
// duplicates are removed from sub-expressions.
// Set operators. The rest is defined in TargetSelectionDAG.td.
def sequence;
def decimate;
//===----------------------------------------------------------------------===//
// DwarfRegNum - This class provides a mapping of the llvm register enumeration

View File

@ -200,9 +200,8 @@ def FPEXC : ARMReg<8, "fpexc">;
// r11 == Frame Pointer (arm-style backtraces)
// r10 == Stack Limit
//
def GPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6,
R7, R8, R9, R10, R11, R12,
SP, LR, PC]> {
def GPR : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12),
SP, LR, PC)> {
let MethodProtos = [{
iterator allocation_order_begin(const MachineFunction &MF) const;
iterator allocation_order_end(const MachineFunction &MF) const;
@ -246,8 +245,7 @@ def GPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6,
// register range for operands, but have undefined behaviours when PC
// or SP (R13 or R15) are used. The ARM ISA refers to these operands
// via the BadReg() pseudo-code description.
def rGPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6,
R7, R8, R9, R10, R11, R12, LR]> {
def rGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, SP, PC)> {
let MethodProtos = [{
iterator allocation_order_begin(const MachineFunction &MF) const;
iterator allocation_order_end(const MachineFunction &MF) const;
@ -291,13 +289,13 @@ def rGPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6,
// Thumb registers are R0-R7 normally. Some instructions can still use
// the general GPR register class above (MOV, e.g.)
def tGPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6, R7]> {}
def tGPR : RegisterClass<"ARM", [i32], 32, (trunc GPR, 8)>;
// For tail calls, we can't use callee-saved registers, as they are restored
// to the saved value before the tail call, which would clobber a call address.
// Note, getMinimalPhysRegClass(R0) returns tGPR because of the names of
// this class and the preceding one(!) This is what we want.
def tcGPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R9, R12]> {
def tcGPR : RegisterClass<"ARM", [i32], 32, (add R0, R1, R2, R3, R9, R12)> {
let MethodProtos = [{
iterator allocation_order_begin(const MachineFunction &MF) const;
iterator allocation_order_end(const MachineFunction &MF) const;
@ -345,25 +343,18 @@ def tcGPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R9, R12]> {
// Scalar single precision floating point register class..
def SPR : RegisterClass<"ARM", [f32], 32, [S0, S1, S2, S3, S4, S5, S6, S7, S8,
S9, S10, S11, S12, S13, S14, S15, S16, S17, S18, S19, S20, S21, S22,
S23, S24, S25, S26, S27, S28, S29, S30, S31]>;
def SPR : RegisterClass<"ARM", [f32], 32, (sequence "S%u", 0, 31)>;
// Subset of SPR which can be used as a source of NEON scalars for 16-bit
// operations
def SPR_8 : RegisterClass<"ARM", [f32], 32,
[S0, S1, S2, S3, S4, S5, S6, S7,
S8, S9, S10, S11, S12, S13, S14, S15]>;
def SPR_8 : RegisterClass<"ARM", [f32], 32, (trunc SPR, 16)>;
// Scalar double precision floating point / generic 64-bit vector register
// class.
// ARM requires only word alignment for double. It's more performant if it
// is double-word alignment though.
def DPR : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64,
[D0, D1, D2, D3, D4, D5, D6, D7,
D8, D9, D10, D11, D12, D13, D14, D15,
D16, D17, D18, D19, D20, D21, D22, D23,
D24, D25, D26, D27, D28, D29, D30, D31]> {
(sequence "D%u", 0, 31)> {
let MethodProtos = [{
iterator allocation_order_begin(const MachineFunction &MF) const;
iterator allocation_order_end(const MachineFunction &MF) const;
@ -411,22 +402,20 @@ def DPR : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64,
// Subset of DPR that are accessible with VFP2 (and so that also have
// 32-bit SPR subregs).
def DPR_VFP2 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64,
[D0, D1, D2, D3, D4, D5, D6, D7,
D8, D9, D10, D11, D12, D13, D14, D15]> {
(trunc DPR, 16)> {
let SubRegClasses = [(SPR ssub_0, ssub_1)];
}
// Subset of DPR which can be used as a source of NEON scalars for 16-bit
// operations
def DPR_8 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32], 64,
[D0, D1, D2, D3, D4, D5, D6, D7]> {
(trunc DPR, 8)> {
let SubRegClasses = [(SPR_8 ssub_0, ssub_1)];
}
// Generic 128-bit vector register class.
def QPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128,
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7,
Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15]> {
(sequence "Q%u", 0, 15)> {
let SubRegClasses = [(DPR dsub_0, dsub_1)];
let MethodProtos = [{
iterator allocation_order_begin(const MachineFunction &MF) const;
@ -455,25 +444,21 @@ def QPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], 128,
// Subset of QPR that have 32-bit SPR subregs.
def QPR_VFP2 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
128,
[Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7]> {
128, (trunc QPR, 8)> {
let SubRegClasses = [(SPR ssub_0, ssub_1, ssub_2, ssub_3),
(DPR_VFP2 dsub_0, dsub_1)];
}
// Subset of QPR that have DPR_8 and SPR_8 subregs.
def QPR_8 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
128,
[Q0, Q1, Q2, Q3]> {
128, (trunc QPR, 4)> {
let SubRegClasses = [(SPR_8 ssub_0, ssub_1, ssub_2, ssub_3),
(DPR_8 dsub_0, dsub_1)];
}
// Pseudo 256-bit vector register class to model pairs of Q registers
// (4 consecutive D registers).
def QQPR : RegisterClass<"ARM", [v4i64],
256,
[QQ0, QQ1, QQ2, QQ3, QQ4, QQ5, QQ6, QQ7]> {
def QQPR : RegisterClass<"ARM", [v4i64], 256, (sequence "QQ%u", 0, 7)> {
let SubRegClasses = [(DPR dsub_0, dsub_1, dsub_2, dsub_3),
(QPR qsub_0, qsub_1)];
let MethodProtos = [{
@ -500,9 +485,7 @@ def QQPR : RegisterClass<"ARM", [v4i64],
}
// Subset of QQPR that have 32-bit SPR subregs.
def QQPR_VFP2 : RegisterClass<"ARM", [v4i64],
256,
[QQ0, QQ1, QQ2, QQ3]> {
def QQPR_VFP2 : RegisterClass<"ARM", [v4i64], 256, (trunc QQPR, 4)> {
let SubRegClasses = [(SPR ssub_0, ssub_1, ssub_2, ssub_3),
(DPR_VFP2 dsub_0, dsub_1, dsub_2, dsub_3),
(QPR_VFP2 qsub_0, qsub_1)];
@ -511,9 +494,7 @@ def QQPR_VFP2 : RegisterClass<"ARM", [v4i64],
// Pseudo 512-bit vector register class to model 4 consecutive Q registers
// (8 consecutive D registers).
def QQQQPR : RegisterClass<"ARM", [v8i64],
256,
[QQQQ0, QQQQ1, QQQQ2, QQQQ3]> {
def QQQQPR : RegisterClass<"ARM", [v8i64], 256, (sequence "QQQQ%u", 0, 3)> {
let SubRegClasses = [(DPR dsub_0, dsub_1, dsub_2, dsub_3,
dsub_4, dsub_5, dsub_6, dsub_7),
(QPR qsub_0, qsub_1, qsub_2, qsub_3)];
@ -540,6 +521,6 @@ def QQQQPR : RegisterClass<"ARM", [v8i64],
}
// Condition code registers.
def CCR : RegisterClass<"ARM", [i32], 32, [CPSR]> {
def CCR : RegisterClass<"ARM", [i32], 32, (add CPSR)> {
let isAllocatable = 0;
}

View File

@ -110,9 +110,9 @@ def F31 : FPR<31, "$f31">, DwarfRegNum<[64]>;
// $28 is undefined after any and all calls
/// Register classes
def GPRC : RegisterClass<"Alpha", [i64], 64,
def GPRC : RegisterClass<"Alpha", [i64], 64, (add
// 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,
//Special meaning, but volatile
R27, //procedure address
@ -121,18 +121,13 @@ def GPRC : RegisterClass<"Alpha", [i64], 64,
// Non-volatile
R9, R10, R11, R12, R13, R14,
// Don't allocate 15, 30, 31
R15, R30, R31 ]>; //zero
R15, R30, R31)>; //zero
def F4RC : RegisterClass<"Alpha", [f32], 64, [F0, F1,
def F4RC : RegisterClass<"Alpha", [f32], 64, (add F0, F1,
F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30,
// Saved:
F2, F3, F4, F5, F6, F7, F8, F9,
F31 ]>; //zero
F31)>; //zero
def F8RC : RegisterClass<"Alpha", [f64], 64, [F0, F1,
F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30,
// Saved:
F2, F3, F4, F5, F6, F7, F8, F9,
F31 ]>; //zero
def F8RC : RegisterClass<"Alpha", [f64], 64, (add F4RC)>;

View File

@ -195,95 +195,66 @@ def LB0 : Ri<6, 2, "lb0">, DwarfRegNum<[48]>;
def LB1 : Ri<6, 5, "lb1">, DwarfRegNum<[49]>;
// Register classes.
def D16 : RegisterClass<"BF", [i16], 16,
[R0H, R0L, R1H, R1L, R2H, R2L, R3H, R3L,
R4H, R4L, R5H, R5L, R6H, R6L, R7H, R7L]>;
def D16L : RegisterClass<"BF", [i16], 16, (sequence "R%uL", 0, 7)>;
def D16L : RegisterClass<"BF", [i16], 16,
[R0L, R1L, R2L, R3L, R4L, R5L, R6L, R7L]>;
def D16H : RegisterClass<"BF", [i16], 16, (sequence "R%uH", 0, 7)>;
def D16H : RegisterClass<"BF", [i16], 16,
[R0H, R1H, R2H, R3H, R4H, R5H, R6H, R7H]>;
def P16 : RegisterClass<"BF", [i16], 16,
[P0H, P0L, P1H, P1L, P2H, P2L, P3H, P3L,
P4H, P4L, P5H, P5L, SPH, SPL, FPH, FPL]>;
def D16 : RegisterClass<"BF", [i16], 16, (add D16L, D16H)>;
def P16L : RegisterClass<"BF", [i16], 16,
[P0L, P1L, P2L, P3L, P4L, P5L, SPL, FPL]>;
(add (sequence "P%uL", 0, 5), SPL, FPL)>;
def P16H : RegisterClass<"BF", [i16], 16,
[P0H, P1H, P2H, P3H, P4H, P5H, SPH, FPH]>;
(add (sequence "P%uH", 0, 5), SPH, FPH)>;
def DP16 : RegisterClass<"BF", [i16], 16,
[R0H, R0L, R1H, R1L, R2H, R2L, R3H, R3L,
R4H, R4L, R5H, R5L, R6H, R6L, R7H, R7L,
P0H, P0L, P1H, P1L, P2H, P2L, P3H, P3L,
P4H, P4L, P5H, P5L, SPH, SPL, FPH, FPL]>;
def P16 : RegisterClass<"BF", [i16], 16, (add P16L, P16H)>;
def DP16L : RegisterClass<"BF", [i16], 16,
[R0L, R1L, R2L, R3L, R4L, R5L, R6L, R7L,
P0L, P1L, P2L, P3L, P4L, P5L, SPL, FPL]>;
def DP16 : RegisterClass<"BF", [i16], 16, (add D16, P16)>;
def DP16H : RegisterClass<"BF", [i16], 16,
[R0H, R1H, R2H, R3H, R4H, R5H, R6H, R7H,
P0H, P1H, P2H, P3H, P4H, P5H, SPH, FPH]>;
def DP16L : RegisterClass<"BF", [i16], 16, (add D16L, P16L)>;
def DP16H : RegisterClass<"BF", [i16], 16, (add D16H, P16H)>;
def GR16 : RegisterClass<"BF", [i16], 16,
[R0H, R0L, R1H, R1L, R2H, R2L, R3H, R3L,
R4H, R4L, R5H, R5L, R6H, R6L, R7H, R7L,
P0H, P0L, P1H, P1L, P2H, P2L, P3H, P3L,
P4H, P4L, P5H, P5L, SPH, SPL, FPH, FPL,
(add DP16,
I0H, I0L, I1H, I1L, I2H, I2L, I3H, I3L,
M0H, M0L, M1H, M1L, M2H, M2L, M3H, M3L,
B0H, B0L, B1H, B1L, B2H, B2L, B3H, B3L,
L0H, L0L, L1H, L1L, L2H, L2L, L3H, L3L]>;
L0H, L0L, L1H, L1L, L2H, L2L, L3H, L3L)>;
def D : RegisterClass<"BF", [i32], 32, [R0, R1, R2, R3, R4, R5, R6, R7]> {
def D : RegisterClass<"BF", [i32], 32, (sequence "R%u", 0, 7)> {
let SubRegClasses = [(D16L lo16), (D16H hi16)];
}
def P : RegisterClass<"BF", [i32], 32, [P0, P1, P2, P3, P4, P5, FP, SP]> {
def P : RegisterClass<"BF", [i32], 32, (add (sequence "P%u", 0, 5), FP, SP)> {
let SubRegClasses = [(P16L lo16), (P16H hi16)];
}
def I : RegisterClass<"BF", [i32], 32, [I0, I1, I2, I3]>;
def M : RegisterClass<"BF", [i32], 32, [M0, M1, M2, M3]>;
def B : RegisterClass<"BF", [i32], 32, [B0, B1, B2, B3]>;
def L : RegisterClass<"BF", [i32], 32, [L0, L1, L2, L3]>;
def DP : RegisterClass<"BF", [i32], 32,
[R0, R1, R2, R3, R4, R5, R6, R7,
P0, P1, P2, P3, P4, P5, FP, SP]> {
def DP : RegisterClass<"BF", [i32], 32, (add D, P)> {
let SubRegClasses = [(DP16L lo16), (DP16H hi16)];
}
def GR : RegisterClass<"BF", [i32], 32,
[R0, R1, R2, R3, R4, R5, R6, R7,
P0, P1, P2, P3, P4, P5,
I0, I1, I2, I3, M0, M1, M2, M3,
B0, B1, B2, B3, L0, L1, L2, L3,
FP, SP]>;
def I : RegisterClass<"BF", [i32], 32, (add I0, I1, I2, I3)>;
def M : RegisterClass<"BF", [i32], 32, (add M0, M1, M2, M3)>;
def B : RegisterClass<"BF", [i32], 32, (add B0, B1, B2, B3)>;
def L : RegisterClass<"BF", [i32], 32, (add L0, L1, L2, L3)>;
def GR : RegisterClass<"BF", [i32], 32, (add DP, I, M, B, L)>;
def ALL : RegisterClass<"BF", [i32], 32,
[R0, R1, R2, R3, R4, R5, R6, R7,
P0, P1, P2, P3, P4, P5,
I0, I1, I2, I3, M0, M1, M2, M3,
B0, B1, B2, B3, L0, L1, L2, L3,
FP, SP,
(add GR,
A0X, A0W, A1X, A1W, ASTAT, RETS,
LC0, LT0, LB0, LC1, LT1, LB1, CYCLES, CYCLES2,
USP, SEQSTAT, SYSCFG, RETI, RETX, RETN, RETE, EMUDAT]>;
USP, SEQSTAT, SYSCFG, RETI, RETX, RETN, RETE, EMUDAT)>;
def PI : RegisterClass<"BF", [i32], 32,
[P0, P1, P2, P3, P4, P5, I0, I1, I2, I3, FP, SP]>;
def PI : RegisterClass<"BF", [i32], 32, (add P, I)>;
// We are going to pretend that CC and !CC are 32-bit registers, even though
// they only can hold 1 bit.
let CopyCost = -1, Size = 8 in {
def JustCC : RegisterClass<"BF", [i32], 8, [CC]>;
def NotCC : RegisterClass<"BF", [i32], 8, [NCC]>;
def AnyCC : RegisterClass<"BF", [i32], 8, [CC, NCC]> {
def JustCC : RegisterClass<"BF", [i32], 8, (add CC)>;
def NotCC : RegisterClass<"BF", [i32], 8, (add NCC)>;
def AnyCC : RegisterClass<"BF", [i32], 8, (add CC, NCC)> {
let MethodProtos = [{
iterator allocation_order_end(const MachineFunction &MF) const;
}];
@ -295,8 +266,8 @@ def AnyCC : RegisterClass<"BF", [i32], 8, [CC, NCC]> {
}];
}
def StatBit : RegisterClass<"BF", [i1], 8,
[AZ, AN, CC, AQ, AC0, AC1, AV0, AV0S, AV1, AV1S, V, VS]>;
(add AZ, AN, CC, AQ, AC0, AC1, AV0, AV0S, AV1, AV1S, V, VS)>;
}
// Should be i40, but that isn't defined. It is not a legal type yet anyway.
def Accu : RegisterClass<"BF", [i64], 64, [A0, A1]>;
def Accu : RegisterClass<"BF", [i64], 64, (add A0, A1)>;

View File

@ -155,147 +155,29 @@ def R127 : SPUVecReg<127, "$127">, DwarfRegNum<[127]>;
// The SPU's registers as 128-bit wide entities, and can function as general
// purpose registers, where the operands are in the "preferred slot":
// The non-volatile registers are allocated in reverse order, like PPC does it.
def GPRC : RegisterClass<"SPU", [i128], 128,
[
/* volatile register */
R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
R77, R78, R79,
/* non-volatile register: take hint from PPC and allocate in reverse order */
R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
R86, R85, R84, R83, R82, R81, R80,
/* environment ptr, SP, LR */
R2, R1, R0 ]>;
(add (sequence "R%u", 0, 79),
(sequence "R%u", 127, 80))>;
// The SPU's registers as 64-bit wide (double word integer) "preferred slot":
def R64C : RegisterClass<"SPU", [i64], 128,
[
/* volatile register */
R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
R77, R78, R79,
/* non-volatile register: take hint from PPC and allocate in reverse order */
R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
R86, R85, R84, R83, R82, R81, R80,
/* environment ptr, SP, LR */
R2, R1, R0 ]>;
def R64C : RegisterClass<"SPU", [i64], 128, (add GPRC)>;
// The SPU's registers as 64-bit wide (double word) FP "preferred slot":
def R64FP : RegisterClass<"SPU", [f64], 128,
[
/* volatile register */
R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
R77, R78, R79,
/* non-volatile register: take hint from PPC and allocate in reverse order */
R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
R86, R85, R84, R83, R82, R81, R80,
/* environment ptr, SP, LR */
R2, R1, R0 ]>;
def R64FP : RegisterClass<"SPU", [f64], 128, (add GPRC)>;
// The SPU's registers as 32-bit wide (word) "preferred slot":
def R32C : RegisterClass<"SPU", [i32], 128,
[
/* volatile register */
R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
R77, R78, R79,
/* non-volatile register: take hint from PPC and allocate in reverse order */
R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
R86, R85, R84, R83, R82, R81, R80,
/* environment ptr, SP, LR */
R2, R1, R0 ]>;
def R32C : RegisterClass<"SPU", [i32], 128, (add GPRC)>;
// The SPU's registers as single precision floating point "preferred slot":
def R32FP : RegisterClass<"SPU", [f32], 128,
[
/* volatile register */
R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
R77, R78, R79,
/* non-volatile register: take hint from PPC and allocate in reverse order */
R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
R86, R85, R84, R83, R82, R81, R80,
/* environment ptr, SP, LR */
R2, R1, R0 ]>;
def R32FP : RegisterClass<"SPU", [f32], 128, (add GPRC)>;
// The SPU's registers as 16-bit wide (halfword) "preferred slot":
def R16C : RegisterClass<"SPU", [i16], 128,
[
/* volatile register */
R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
R77, R78, R79,
/* non-volatile register: take hint from PPC and allocate in reverse order */
R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
R86, R85, R84, R83, R82, R81, R80,
/* environment ptr, SP, LR */
R2, R1, R0 ]>;
def R16C : RegisterClass<"SPU", [i16], 128, (add GPRC)>;
// The SPU's registers as 8-bit wide (byte) "preferred slot":
def R8C : RegisterClass<"SPU", [i8], 128,
[
/* volatile register */
R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
R77, R78, R79,
/* non-volatile register: take hint from PPC and allocate in reverse order */
R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
R86, R85, R84, R83, R82, R81, R80,
/* environment ptr, SP, LR */
R2, R1, R0 ]>;
def R8C : RegisterClass<"SPU", [i8], 128, (add GPRC)>;
// The SPU's registers as vector registers:
def VECREG : RegisterClass<"SPU",
[v16i8,v8i16,v4i32,v4f32,v2i64,v2f64],
128,
[
/* volatile register */
R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
R77, R78, R79,
/* non-volatile register: take hint from PPC and allocate in reverse order */
R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
R86, R85, R84, R83, R82, R81, R80,
/* environment ptr, SP, LR */
R2, R1, R0 ]>;
def VECREG : RegisterClass<"SPU", [v16i8,v8i16,v4i32,v4f32,v2i64,v2f64], 128,
(add GPRC)>;

View File

@ -109,32 +109,9 @@ let Namespace = "MBlaze" in {
// Register Classes
//===----------------------------------------------------------------------===//
def GPR : RegisterClass<"MBlaze", [i32,f32], 32,
[
// Return Values and Arguments
R3, R4, R5, R6, R7, R8, R9, R10,
def GPR : RegisterClass<"MBlaze", [i32,f32], 32, (sequence "R%u", 0, 31)>;
// Not preserved across procedure calls
R11, R12,
// Callee save
R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
// Reserved
R0, // Always zero
R1, // The stack pointer
R2, // Read-only small data area anchor
R13, // Read-write small data area anchor
R14, // Return address for interrupts
R15, // Return address for sub-routines
R16, // Return address for trap
R17, // Return address for exceptions
R18, // Reserved for assembler
R19 // The frame-pointer
]>;
def SPR : RegisterClass<"MBlaze", [i32], 32,
[
def SPR : RegisterClass<"MBlaze", [i32], 32, (add
// Reserved
RPC,
RMSR,
@ -160,12 +137,12 @@ def SPR : RegisterClass<"MBlaze", [i32], 32,
RPVR9,
RPVR10,
RPVR11
]>
)>
{
// None of the special purpose registers are allocatable.
let isAllocatable = 0;
}
def CRC : RegisterClass<"MBlaze", [i32], 32, [CARRY]> {
def CRC : RegisterClass<"MBlaze", [i32], 32, (add CARRY)> {
let CopyCost = -1;
}

View File

@ -66,19 +66,19 @@ def R15W : MSP430RegWithSubregs<15, "r15", [R15B]>;
def GR8 : RegisterClass<"MSP430", [i8], 8,
// Volatile registers
[R12B, R13B, R14B, R15B, R11B, R10B, R9B, R8B, R7B, R6B, R5B,
(add R12B, R13B, R14B, R15B, R11B, R10B, R9B, R8B, R7B, R6B, R5B,
// Frame pointer, sometimes allocable
FPB,
// Volatile, but not allocable
PCB, SPB, SRB, CGB]>;
PCB, SPB, SRB, CGB)>;
def GR16 : RegisterClass<"MSP430", [i16], 16,
// Volatile registers
[R12W, R13W, R14W, R15W, R11W, R10W, R9W, R8W, R7W, R6W, R5W,
(add R12W, R13W, R14W, R15W, R11W, R10W, R9W, R8W, R7W, R6W, R5W,
// Frame pointer, sometimes allocable
FPW,
// Volatile, but not allocable
PCW, SPW, SRW, CGW]>
PCW, SPW, SRW, CGW)>
{
let SubRegClasses = [(GR8 subreg_8bit)];
}

View File

@ -157,15 +157,15 @@ let Namespace = "Mips" in {
// Register Classes
//===----------------------------------------------------------------------===//
def CPURegs : RegisterClass<"Mips", [i32], 32,
def CPURegs : RegisterClass<"Mips", [i32], 32, (add
// Return Values and Arguments
[V0, V1, A0, A1, A2, A3,
V0, V1, A0, A1, A2, A3,
// Not preserved across procedure calls
T0, T1, T2, T3, T4, T5, T6, T7, T8, T9,
// Callee save
S0, S1, S2, S3, S4, S5, S6, S7,
// Reserved
ZERO, AT, K0, K1, GP, SP, FP, RA]>;
ZERO, AT, K0, K1, GP, SP, FP, RA)>;
// 64bit fp:
// * FGR64 - 32 64-bit registers
@ -174,33 +174,25 @@ def CPURegs : RegisterClass<"Mips", [i32], 32,
// 32bit fp:
// * FGR32 - 16 32-bit even registers
// * FGR32 - 32 32-bit registers (single float only mode)
def FGR32 : RegisterClass<"Mips", [f32], 32,
// Return Values and Arguments
[F0, F1, F2, F3, F12, F13, F14, F15,
// Not preserved across procedure calls
F4, F5, F6, F7, F8, F9, F10, F11, F16, F17, F18, F19,
// Callee save
F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F30,
// Reserved
F31]>;
def FGR32 : RegisterClass<"Mips", [f32], 32, (sequence "F%u", 0, 31)>;
def AFGR64 : RegisterClass<"Mips", [f64], 64,
def AFGR64 : RegisterClass<"Mips", [f64], 64, (add
// Return Values and Arguments
[D0, D1, D6, D7,
D0, D1, D6, D7,
// Not preserved across procedure calls
D2, D3, D4, D5, D8, D9,
// Callee save
D10, D11, D12, D13, D14,
// Reserved
D15]> {
D15)> {
let SubRegClasses = [(FGR32 sub_fpeven, sub_fpodd)];
}
// Condition Register for floating point operations
def CCR : RegisterClass<"Mips", [i32], 32, [FCR31]>;
def CCR : RegisterClass<"Mips", [i32], 32, (add FCR31)>;
// Hi/Lo Registers
def HILO : RegisterClass<"Mips", [i32], 32, [HI, LO]>;
def HILO : RegisterClass<"Mips", [i32], 32, (add HI, LO)>;
// Hardware registers
def HWRegs : RegisterClass<"Mips", [i32], 32, [HWR29]>;
def HWRegs : RegisterClass<"Mips", [i32], 32, (add HWR29)>;

View File

@ -430,62 +430,9 @@ def FD63 : PTXReg<"fd63">;
// Register classes
//===----------------------------------------------------------------------===//
def Preds : RegisterClass<"PTX", [i1], 8,
[P0, P1, P2, P3, P4, P5, P6, P7,
P8, P9, P10, P11, P12, P13, P14, P15,
P16, P17, P18, P19, P20, P21, P22, P23,
P24, P25, P26, P27, P28, P29, P30, P31,
P32, P33, P34, P35, P36, P37, P38, P39,
P40, P41, P42, P43, P44, P45, P46, P47,
P48, P49, P50, P51, P52, P53, P54, P55,
P56, P57, P58, P59, P60, P61, P62, P63]>;
def RRegu16 : RegisterClass<"PTX", [i16], 16,
[RH0, RH1, RH2, RH3, RH4, RH5, RH6, RH7,
RH8, RH9, RH10, RH11, RH12, RH13, RH14, RH15,
RH16, RH17, RH18, RH19, RH20, RH21, RH22, RH23,
RH24, RH25, RH26, RH27, RH28, RH29, RH30, RH31,
RH32, RH33, RH34, RH35, RH36, RH37, RH38, RH39,
RH40, RH41, RH42, RH43, RH44, RH45, RH46, RH47,
RH48, RH49, RH50, RH51, RH52, RH53, RH54, RH55,
RH56, RH57, RH58, RH59, RH60, RH61, RH62, RH63]>;
def RRegu32 : RegisterClass<"PTX", [i32], 32,
[R0, R1, R2, R3, R4, R5, R6, R7,
R8, R9, R10, R11, R12, R13, R14, R15,
R16, R17, R18, R19, R20, R21, R22, R23,
R24, R25, R26, R27, R28, R29, R30, R31,
R32, R33, R34, R35, R36, R37, R38, R39,
R40, R41, R42, R43, R44, R45, R46, R47,
R48, R49, R50, R51, R52, R53, R54, R55,
R56, R57, R58, R59, R60, R61, R62, R63]>;
def RRegu64 : RegisterClass<"PTX", [i64], 64,
[RD0, RD1, RD2, RD3, RD4, RD5, RD6, RD7,
RD8, RD9, RD10, RD11, RD12, RD13, RD14, RD15,
RD16, RD17, RD18, RD19, RD20, RD21, RD22, RD23,
RD24, RD25, RD26, RD27, RD28, RD29, RD30, RD31,
RD32, RD33, RD34, RD35, RD36, RD37, RD38, RD39,
RD40, RD41, RD42, RD43, RD44, RD45, RD46, RD47,
RD48, RD49, RD50, RD51, RD52, RD53, RD54, RD55,
RD56, RD57, RD58, RD59, RD60, RD61, RD62, RD63]>;
def RRegf32 : RegisterClass<"PTX", [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, F23,
F24, F25, F26, F27, F28, F29, F30, F31,
F32, F33, F34, F35, F36, F37, F38, F39,
F40, F41, F42, F43, F44, F45, F46, F47,
F48, F49, F50, F51, F52, F53, F54, F55,
F56, F57, F58, F59, F60, F61, F62, F63]>;
def RRegf64 : RegisterClass<"PTX", [f64], 64,
[FD0, FD1, FD2, FD3, FD4, FD5, FD6, FD7,
FD8, FD9, FD10, FD11, FD12, FD13, FD14, FD15,
FD16, FD17, FD18, FD19, FD20, FD21, FD22, FD23,
FD24, FD25, FD26, FD27, FD28, FD29, FD30, FD31,
FD32, FD33, FD34, FD35, FD36, FD37, FD38, FD39,
FD40, FD41, FD42, FD43, FD44, FD45, FD46, FD47,
FD48, FD49, FD50, FD51, FD52, FD53, FD54, FD55,
FD56, FD57, FD58, FD59, FD60, FD61, FD62, FD63]>;
def Preds : RegisterClass<"PTX", [i1], 8, (sequence "P%u", 0, 63)>;
def RRegu16 : RegisterClass<"PTX", [i16], 16, (sequence "RH%u", 0, 63)>;
def RRegu32 : RegisterClass<"PTX", [i32], 32, (sequence "R%u", 0, 63)>;
def RRegu64 : RegisterClass<"PTX", [i64], 64, (sequence "RD%u", 0, 63)>;
def RRegf32 : RegisterClass<"PTX", [f32], 32, (sequence "F%u", 0, 63)>;
def RRegf64 : RegisterClass<"PTX", [f64], 64, (sequence "FD%u", 0, 63)>;

View File

@ -276,15 +276,13 @@ def RM: SPR<512, "**ROUNDING MODE**">;
/// Register classes
// Allocate volatiles first
// then nonvolatiles in reverse order since stmw/lmw save from rN to r31
def GPRC : RegisterClass<"PPC", [i32], 32,
[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,
R16, R15, R14, R13, R31, R0, R1, LR]>;
def GPRC : RegisterClass<"PPC", [i32], 32, (add (sequence "R%u", 2, 12),
(sequence "R%u", 30, 13),
R31, R0, R1, LR)>;
def G8RC : RegisterClass<"PPC", [i64], 64,
[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,
X16, X15, X14, X31, X13, X0, X1, LR8]>;
def G8RC : RegisterClass<"PPC", [i64], 64, (add (sequence "X%u", 2, 12),
(sequence "X%u", 30, 14),
X31, X13, X0, X1, LR8)>;
// Allocate volatiles first, then non-volatiles in reverse order. With the SVR4
// ABI the size of the Floating-point register save area is determined by the
@ -293,41 +291,36 @@ def G8RC : RegisterClass<"PPC", [i64], 64,
// previous stack frame. By allocating non-volatiles in reverse order we make
// sure that the Floating-point register save area is always as small as
// possible because there aren't any unused spill slots.
def F8RC : RegisterClass<"PPC", [f64], 64, [F0, F1, F2, F3, F4, F5, F6, F7,
F8, F9, F10, F11, F12, F13, F31, F30, F29, F28, F27, F26, F25, F24, F23,
F22, F21, F20, F19, F18, F17, F16, F15, F14]>;
def F4RC : RegisterClass<"PPC", [f32], 32, [F0, F1, F2, F3, F4, F5, F6, F7,
F8, F9, F10, F11, F12, F13, F31, F30, F29, F28, F27, F26, F25, F24, F23,
F22, F21, F20, F19, F18, F17, F16, F15, F14]>;
def F8RC : RegisterClass<"PPC", [f64], 64, (add (sequence "F%u", 0, 13),
(sequence "F%u", 31, 14))>;
def F4RC : RegisterClass<"PPC", [f32], 32, (add F8RC)>;
def VRRC : RegisterClass<"PPC", [v16i8,v8i16,v4i32,v4f32], 128,
[V2, V3, V4, V5, V0, V1,
V6, V7, V8, V9, V10, V11, V12, V13, V14, V15, V16, V17, V18, V19, V31, V30,
V29, V28, V27, V26, V25, V24, V23, V22, V21, V20]>;
(add V2, V3, V4, V5, V0, V1, V6, V7, V8, V9, V10, V11,
V12, V13, V14, V15, V16, V17, V18, V19, V31, V30,
V29, V28, V27, V26, V25, V24, V23, V22, V21, V20)>;
def CRBITRC : RegisterClass<"PPC", [i32], 32,
[CR0LT, CR0GT, CR0EQ, CR0UN,
(add CR0LT, CR0GT, CR0EQ, CR0UN,
CR1LT, CR1GT, CR1EQ, CR1UN,
CR2LT, CR2GT, CR2EQ, CR2UN,
CR3LT, CR3GT, CR3EQ, CR3UN,
CR4LT, CR4GT, CR4EQ, CR4UN,
CR5LT, CR5GT, CR5EQ, CR5UN,
CR6LT, CR6GT, CR6EQ, CR6UN,
CR7LT, CR7GT, CR7EQ, CR7UN
]>
CR7LT, CR7GT, CR7EQ, CR7UN)>
{
let CopyCost = -1;
}
def CRRC : RegisterClass<"PPC", [i32], 32, [CR0, CR1, CR5, CR6, CR7, CR2,
CR3, CR4]>
{
def CRRC : RegisterClass<"PPC", [i32], 32, (add CR0, CR1, CR5, CR6,
CR7, CR2, CR3, CR4)> {
let SubRegClasses = [(CRBITRC sub_lt, sub_gt, sub_eq, sub_un)];
}
def CTRRC : RegisterClass<"PPC", [i32], 32, [CTR]>;
def CTRRC8 : RegisterClass<"PPC", [i64], 64, [CTR8]>;
def VRSAVERC : RegisterClass<"PPC", [i32], 32, [VRSAVE]>;
def CARRYRC : RegisterClass<"PPC", [i32], 32, [CARRY]> {
def CTRRC : RegisterClass<"PPC", [i32], 32, (add CTR)>;
def CTRRC8 : RegisterClass<"PPC", [i64], 64, (add CTR8)>;
def VRSAVERC : RegisterClass<"PPC", [i32], 32, (add VRSAVE)>;
def CARRYRC : RegisterClass<"PPC", [i32], 32, (add CARRY)> {
let CopyCost = -1;
}

View File

@ -139,8 +139,9 @@ def D15 : Rd<30, "F30", [F30, F31]>, DwarfRegNum<[87]>;
// FIXME: the register order should be defined in terms of the preferred
// allocation order...
//
def IntRegs : RegisterClass<"SP", [i32], 32, [L0, L1, L2, L3, L4, L5, L6, L7,
I0, I1, I2, I3, I4, I5,
def IntRegs : RegisterClass<"SP", [i32], 32,
(add L0, L1, L2, L3, L4, L5, L6,
L7, I0, I1, I2, I3, I4, I5,
O0, O1, O2, O3, O4, O5, O7,
G1,
// Non-allocatable regs:
@ -151,11 +152,8 @@ def IntRegs : RegisterClass<"SP", [i32], 32, [L0, L1, L2, L3, L4, L5, L6, L7,
I7, // return address
G0, // constant zero
G5, G6, G7 // reserved for kernel
]>;
)>;
def FPRegs : RegisterClass<"SP", [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,
F23, F24, F25, F26, F27, F28, F29, F30, F31]>;
def FPRegs : RegisterClass<"SP", [f32], 32, (sequence "F%u", 0, 31)>;
def DFPRegs : RegisterClass<"SP", [f64], 64, [D0, D1, D2, D3, D4, D5, D6, D7,
D8, D9, D10, D11, D12, D13, D14, D15]>;
def DFPRegs : RegisterClass<"SP", [f64], 64, (sequence "D%u", 0, 15)>;

View File

@ -162,66 +162,38 @@ def F15L : FPRL<15, "f15", [F15S]>;
def PSW : SystemZReg<"psw">;
/// Register classes
def GR32 : RegisterClass<"SystemZ", [i32], 32,
// Volatile registers
[R0W, R1W, R2W, R3W, R4W, R5W, R6W, R7W, R8W, R9W, R10W, R12W, R13W,
// Frame pointer, sometimes allocable
R11W,
// Volatile, but not allocable
R14W, R15W]>;
def GR32 : RegisterClass<"SystemZ", [i32], 32, (sequence "R%uW", 0, 15)>;
/// Registers used to generate address. Everything except R0.
def ADDR32 : RegisterClass<"SystemZ", [i32], 32,
// Volatile registers
[R1W, R2W, R3W, R4W, R5W, R6W, R7W, R8W, R9W, R10W, R12W, R13W,
// Frame pointer, sometimes allocable
R11W,
// Volatile, but not allocable
R14W, R15W]>;
def ADDR32 : RegisterClass<"SystemZ", [i32], 32, (sub GR32, R0W)>;
def GR64 : RegisterClass<"SystemZ", [i64], 64,
// Volatile registers
[R0D, R1D, R2D, R3D, R4D, R5D, R6D, R7D, R8D, R9D, R10D, R12D, R13D,
// Frame pointer, sometimes allocable
R11D,
// Volatile, but not allocable
R14D, R15D]> {
def GR64 : RegisterClass<"SystemZ", [i64], 64, (sequence "R%uD", 0, 15)> {
let SubRegClasses = [(GR32 subreg_32bit)];
}
def ADDR64 : RegisterClass<"SystemZ", [i64], 64,
// Volatile registers
[R1D, R2D, R3D, R4D, R5D, R6D, R7D, R8D, R9D, R10D, R12D, R13D,
// Frame pointer, sometimes allocable
R11D,
// Volatile, but not allocable
R14D, R15D]> {
def ADDR64 : RegisterClass<"SystemZ", [i64], 64, (sub GR64, R0D)> {
let SubRegClasses = [(ADDR32 subreg_32bit)];
}
// Even-odd register pairs
def GR64P : RegisterClass<"SystemZ", [v2i32], 64,
[R0P, R2P, R4P, R6P, R8P, R10P, R12P, R14P]> {
def GR64P : RegisterClass<"SystemZ", [v2i32], 64, (add R0P, R2P, R4P, R6P, R8P,
R10P, R12P, R14P)> {
let SubRegClasses = [(GR32 subreg_32bit, subreg_odd32)];
}
def GR128 : RegisterClass<"SystemZ", [v2i64], 128,
[R0Q, R2Q, R4Q, R6Q, R8Q, R10Q, R12Q, R14Q]> {
def GR128 : RegisterClass<"SystemZ", [v2i64], 128, (add R0Q, R2Q, R4Q, R6Q, R8Q,
R10Q, R12Q, R14Q)> {
let SubRegClasses = [(GR32 subreg_32bit, subreg_odd32),
(GR64 subreg_even, subreg_odd)];
}
def FP32 : RegisterClass<"SystemZ", [f32], 32,
[F0S, F1S, F2S, F3S, F4S, F5S, F6S, F7S,
F8S, F9S, F10S, F11S, F12S, F13S, F14S, F15S]>;
def FP32 : RegisterClass<"SystemZ", [f32], 32, (sequence "F%uS", 0, 15)>;
def FP64 : RegisterClass<"SystemZ", [f64], 64,
[F0L, F1L, F2L, F3L, F4L, F5L, F6L, F7L,
F8L, F9L, F10L, F11L, F12L, F13L, F14L, F15L]> {
def FP64 : RegisterClass<"SystemZ", [f64], 64, (sequence "F%uL", 0, 15)> {
let SubRegClasses = [(FP32 subreg_32bit)];
}
// Status flags registers.
def CCR : RegisterClass<"SystemZ", [i64], 64, [PSW]> {
def CCR : RegisterClass<"SystemZ", [i64], 64, (add PSW)> {
let CopyCost = -1; // Don't allow copying of status registers.
}

View File

@ -279,8 +279,8 @@ let Namespace = "X86" in {
// require a REX prefix. For example, "addb %ah, %dil" and "movzbl %ah, %r8d"
// cannot be encoded.
def GR8 : RegisterClass<"X86", [i8], 8,
[AL, CL, DL, AH, CH, DH, BL, BH, SIL, DIL, BPL, SPL,
R8B, R9B, R10B, R11B, R14B, R15B, R12B, R13B]> {
(add AL, CL, DL, AH, CH, DH, BL, BH, SIL, DIL, BPL, SPL,
R8B, R9B, R10B, R11B, R14B, R15B, R12B, R13B)> {
let MethodProtos = [{
iterator allocation_order_begin(const MachineFunction &MF) const;
iterator allocation_order_end(const MachineFunction &MF) const;
@ -323,14 +323,14 @@ def GR8 : RegisterClass<"X86", [i8], 8,
}
def GR16 : RegisterClass<"X86", [i16], 16,
[AX, CX, DX, SI, DI, BX, BP, SP,
R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W]> {
(add AX, CX, DX, SI, DI, BX, BP, SP,
R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W)> {
let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi)];
}
def GR32 : RegisterClass<"X86", [i32], 32,
[EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP,
R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> {
(add EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP,
R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D)> {
let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit)];
}
@ -338,8 +338,8 @@ def GR32 : RegisterClass<"X86", [i32], 32,
// RIP isn't really a register and it can't be used anywhere except in an
// address, but it doesn't cause trouble.
def GR64 : RegisterClass<"X86", [i64], 64,
[RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
RBX, R14, R15, R12, R13, RBP, RSP, RIP]> {
(add RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
RBX, R14, R15, R12, R13, RBP, RSP, RIP)> {
let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi),
(GR16 sub_16bit),
(GR32 sub_32bit)];
@ -348,16 +348,13 @@ def GR64 : RegisterClass<"X86", [i64], 64,
// Segment registers for use by MOV instructions (and others) that have a
// segment register as one operand. Always contain a 16-bit segment
// descriptor.
def SEGMENT_REG : RegisterClass<"X86", [i16], 16, [CS, DS, SS, ES, FS, GS]>;
def SEGMENT_REG : RegisterClass<"X86", [i16], 16, (add CS, DS, SS, ES, FS, GS)>;
// Debug registers.
def DEBUG_REG : RegisterClass<"X86", [i32], 32,
[DR0, DR1, DR2, DR3, DR4, DR5, DR6, DR7]>;
def DEBUG_REG : RegisterClass<"X86", [i32], 32, (sequence "DR%u", 0, 7)>;
// Control registers.
def CONTROL_REG : RegisterClass<"X86", [i64], 64,
[CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7, CR8,
CR9, CR10, CR11, CR12, CR13, CR14, CR15]>;
def CONTROL_REG : RegisterClass<"X86", [i64], 64, (sequence "CR%u", 0, 15)>;
// GR8_ABCD_L, GR8_ABCD_H, GR16_ABCD, GR32_ABCD, GR64_ABCD - Subclasses of
// GR8, GR16, GR32, and GR64 which contain just the "a" "b", "c", and "d"
@ -365,38 +362,38 @@ def CONTROL_REG : RegisterClass<"X86", [i64], 64,
// that support 8-bit subreg operations. On x86-64, GR16_ABCD, GR32_ABCD,
// and GR64_ABCD are classes for registers that support 8-bit h-register
// operations.
def GR8_ABCD_L : RegisterClass<"X86", [i8], 8, [AL, CL, DL, BL]>;
def GR8_ABCD_H : RegisterClass<"X86", [i8], 8, [AH, CH, DH, BH]>;
def GR16_ABCD : RegisterClass<"X86", [i16], 16, [AX, CX, DX, BX]> {
def GR8_ABCD_L : RegisterClass<"X86", [i8], 8, (add AL, CL, DL, BL)>;
def GR8_ABCD_H : RegisterClass<"X86", [i8], 8, (add AH, CH, DH, BH)>;
def GR16_ABCD : RegisterClass<"X86", [i16], 16, (add AX, CX, DX, BX)> {
let SubRegClasses = [(GR8_ABCD_L sub_8bit), (GR8_ABCD_H sub_8bit_hi)];
}
def GR32_ABCD : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, EBX]> {
def GR32_ABCD : RegisterClass<"X86", [i32], 32, (add EAX, ECX, EDX, EBX)> {
let SubRegClasses = [(GR8_ABCD_L sub_8bit),
(GR8_ABCD_H sub_8bit_hi),
(GR16_ABCD sub_16bit)];
}
def GR64_ABCD : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RBX]> {
def GR64_ABCD : RegisterClass<"X86", [i64], 64, (add RAX, RCX, RDX, RBX)> {
let SubRegClasses = [(GR8_ABCD_L sub_8bit),
(GR8_ABCD_H sub_8bit_hi),
(GR16_ABCD sub_16bit),
(GR32_ABCD sub_32bit)];
}
def GR32_TC : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX]> {
def GR32_TC : RegisterClass<"X86", [i32], 32, (add EAX, ECX, EDX)> {
let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit)];
}
def GR64_TC : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI,
R8, R9, R11, RIP]> {
def GR64_TC : RegisterClass<"X86", [i64], 64, (add RAX, RCX, RDX, RSI, RDI,
R8, R9, R11, RIP)> {
let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi),
(GR16 sub_16bit),
(GR32_TC sub_32bit)];
}
def GR64_TCW64 : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX,
R8, R9, R11]>;
def GR64_TCW64 : RegisterClass<"X86", [i64], 64, (add RAX, RCX, RDX,
R8, R9, R11)>;
// GR8_NOREX - GR8 registers which do not require a REX prefix.
def GR8_NOREX : RegisterClass<"X86", [i8], 8,
[AL, CL, DL, AH, CH, DH, BL, BH]> {
(add AL, CL, DL, AH, CH, DH, BL, BH)> {
let MethodProtos = [{
iterator allocation_order_begin(const MachineFunction &MF) const;
iterator allocation_order_end(const MachineFunction &MF) const;
@ -430,34 +427,30 @@ def GR8_NOREX : RegisterClass<"X86", [i8], 8,
}
// GR16_NOREX - GR16 registers which do not require a REX prefix.
def GR16_NOREX : RegisterClass<"X86", [i16], 16,
[AX, CX, DX, SI, DI, BX, BP, SP]> {
(add AX, CX, DX, SI, DI, BX, BP, SP)> {
let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi)];
}
// GR32_NOREX - GR32 registers which do not require a REX prefix.
def GR32_NOREX : RegisterClass<"X86", [i32], 32,
[EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP]> {
(add EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP)> {
let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi),
(GR16_NOREX sub_16bit)];
}
// GR64_NOREX - GR64 registers which do not require a REX prefix.
def GR64_NOREX : RegisterClass<"X86", [i64], 64,
[RAX, RCX, RDX, RSI, RDI, RBX, RBP, RSP, RIP]> {
(add RAX, RCX, RDX, RSI, RDI, RBX, RBP, RSP, RIP)> {
let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi),
(GR16_NOREX sub_16bit),
(GR32_NOREX sub_32bit)];
}
// GR32_NOSP - GR32 registers except ESP.
def GR32_NOSP : RegisterClass<"X86", [i32], 32,
[EAX, ECX, EDX, ESI, EDI, EBX, EBP,
R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> {
def GR32_NOSP : RegisterClass<"X86", [i32], 32, (sub GR32, ESP)> {
let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit)];
}
// GR64_NOSP - GR64 registers except RSP (and RIP).
def GR64_NOSP : RegisterClass<"X86", [i64], 64,
[RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
RBX, R14, R15, R12, R13, RBP]> {
def GR64_NOSP : RegisterClass<"X86", [i64], 64, (sub GR64, RSP, RIP)> {
let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi),
(GR16 sub_16bit),
(GR32_NOSP sub_32bit)];
@ -466,36 +459,30 @@ def GR64_NOSP : RegisterClass<"X86", [i64], 64,
// GR32_NOREX_NOSP - GR32 registers which do not require a REX prefix except
// ESP.
def GR32_NOREX_NOSP : RegisterClass<"X86", [i32], 32,
[EAX, ECX, EDX, ESI, EDI, EBX, EBP]> {
(and GR32_NOREX, GR32_NOSP)> {
let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi),
(GR16_NOREX sub_16bit)];
}
// GR64_NOREX_NOSP - GR64_NOREX registers except RSP.
def GR64_NOREX_NOSP : RegisterClass<"X86", [i64], 64,
[RAX, RCX, RDX, RSI, RDI, RBX, RBP]> {
(and GR64_NOREX, GR64_NOSP)> {
let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi),
(GR16_NOREX sub_16bit),
(GR32_NOREX_NOSP sub_32bit)];
}
// A class to support the 'A' assembler constraint: EAX then EDX.
def GR32_AD : RegisterClass<"X86", [i32], 32, [EAX, EDX]> {
def GR32_AD : RegisterClass<"X86", [i32], 32, (add EAX, EDX)> {
let SubRegClasses = [(GR8_ABCD_L sub_8bit),
(GR8_ABCD_H sub_8bit_hi),
(GR16_ABCD sub_16bit)];
}
// Scalar SSE2 floating point registers.
def FR32 : RegisterClass<"X86", [f32], 32,
[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
XMM8, XMM9, XMM10, XMM11,
XMM12, XMM13, XMM14, XMM15]>;
def FR32 : RegisterClass<"X86", [f32], 32, (sequence "XMM%u", 0, 15)>;
def FR64 : RegisterClass<"X86", [f64], 64,
[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
XMM8, XMM9, XMM10, XMM11,
XMM12, XMM13, XMM14, XMM15]>;
def FR64 : RegisterClass<"X86", [f64], 64, (add FR32)>;
// FIXME: This sets up the floating point register files as though they are f64
@ -504,37 +491,31 @@ def FR64 : RegisterClass<"X86", [f64], 64,
// faster on common hardware. In reality, this should be controlled by a
// command line option or something.
def RFP32 : RegisterClass<"X86",[f32], 32, [FP0, FP1, FP2, FP3, FP4, FP5, FP6]>;
def RFP64 : RegisterClass<"X86",[f64], 32, [FP0, FP1, FP2, FP3, FP4, FP5, FP6]>;
def RFP80 : RegisterClass<"X86",[f80], 32, [FP0, FP1, FP2, FP3, FP4, FP5, FP6]>;
def RFP32 : RegisterClass<"X86",[f32], 32, (sequence "FP%u", 0, 6)>;
def RFP64 : RegisterClass<"X86",[f64], 32, (add RFP32)>;
def RFP80 : RegisterClass<"X86",[f80], 32, (add RFP32)>;
// Floating point stack registers (these are not allocatable by the
// register allocator - the floating point stackifier is responsible
// for transforming FPn allocations to STn registers)
def RST : RegisterClass<"X86", [f80, f64, f32], 32,
[ST0, ST1, ST2, ST3, ST4, ST5, ST6, ST7]> {
def RST : RegisterClass<"X86", [f80, f64, f32], 32, (sequence "ST%u", 0, 7)> {
let isAllocatable = 0;
}
// Generic vector registers: VR64 and VR128.
def VR64: RegisterClass<"X86", [x86mmx], 64,
[MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7]>;
def VR128 : RegisterClass<"X86", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],128,
[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
XMM8, XMM9, XMM10, XMM11,
XMM12, XMM13, XMM14, XMM15]> {
def VR64: RegisterClass<"X86", [x86mmx], 64, (sequence "MM%u", 0, 7)>;
def VR128 : RegisterClass<"X86", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
128, (add FR32)> {
let SubRegClasses = [(FR32 sub_ss), (FR64 sub_sd)];
}
def VR256 : RegisterClass<"X86", [v32i8, v8i32, v4i64, v8f32, v4f64], 256,
[YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7,
YMM8, YMM9, YMM10, YMM11,
YMM12, YMM13, YMM14, YMM15]> {
(sequence "YMM%u", 0, 15)> {
let SubRegClasses = [(FR32 sub_ss), (FR64 sub_sd), (VR128 sub_xmm)];
}
// Status flags registers.
def CCR : RegisterClass<"X86", [i32], 32, [EFLAGS]> {
def CCR : RegisterClass<"X86", [i32], 32, (add EFLAGS)> {
let CopyCost = -1; // Don't allow copying of status registers.
let isAllocatable = 0;
}

View File

@ -44,13 +44,13 @@ def LR : Ri<15, "lr">, DwarfRegNum<[15]>;
//
def GRRegs : RegisterClass<"XCore", [i32], 32,
// Return values and arguments
[R0, R1, R2, R3,
(add R0, R1, R2, R3,
// Not preserved across procedure calls
R11,
// Callee save
R4, R5, R6, R7, R8, R9, R10]>;
R4, R5, R6, R7, R8, R9, R10)>;
// Reserved
def RRegs : RegisterClass<"XCore", [i32], 32, [CP, DP, SP, LR]> {
def RRegs : RegisterClass<"XCore", [i32], 32, (add CP, DP, SP, LR)> {
let isAllocatable = 0;
}