diff --git a/lib/cretonne/meta/cdsl/registers.py b/lib/cretonne/meta/cdsl/registers.py index 6c1d379dac..243a72e669 100644 --- a/lib/cretonne/meta/cdsl/registers.py +++ b/lib/cretonne/meta/cdsl/registers.py @@ -19,7 +19,8 @@ The register allocator works with *register classes* which can allocate one or more register units at a time. A register class allocates more than one register unit at a time when its registers are composed of smaller alocatable units. For example, the ARM double precision floating point registers are -composed of two single precision registers. """ +composed of two single precision registers. +""" from __future__ import absolute_import from . import is_power_of_two, next_power_of_two @@ -78,3 +79,53 @@ class RegBank(object): # type: () -> str return ('RegBank({}, units={}, first_unit={})' .format(self.name, self.units, self.first_unit)) + + +class RegClass(object): + """ + A register class is a subset of register units in a RegBank along with a + strategy for allocating registers. + + The *width* parameter determines how many register units are allocated at a + time. Usually it that is one, but for example the ARM D registers are + allocated two units at a time. When multiple units are allocated, it is + always a contiguous set of unit numbers. + + :param name: Name of this register class. + :param bank: The register bank we're allocating from. + :param count: The maximum number of allocations in this register class. By + default, the whole register bank can be allocated. + :param width: How many units to allocate at a time. + :param start: The first unit to allocate, relative to `bank.first.unit`. + :param stride: How many units to skip to get to the next allocation. + Default is `width`. + """ + + def __init__(self, name, bank, count=None, width=1, start=0, stride=None): + # type: (str, RegBank, int, int, int, int) -> None + self.name = name + self.bank = bank + self.start = start + self.width = width + + assert width > 0 + assert start >= 0 and start < bank.units + + if stride is None: + stride = width + assert stride > 0 + self.stride = stride + + if count is None: + count = bank.units / stride + self.count = count + + # When the stride is 1, we can wrap around to the beginning of the + # register bank, but with a larger stride, we wouldn't cover all the + # possible allocations with a simple modulo stride. For example, + # attempting to allocate the even registers before the odd ones + # wouldn't work. Only if stride is coprime to bank.units would it work, + # but that is unlikely since the bank size is almost always a power of + # two. + if start + count*stride > bank.units: + assert stride == 1, 'Wrapping with stride not supported' diff --git a/lib/cretonne/meta/isa/arm32/registers.py b/lib/cretonne/meta/isa/arm32/registers.py index 8d2b0480ae..3084c2bf98 100644 --- a/lib/cretonne/meta/isa/arm32/registers.py +++ b/lib/cretonne/meta/isa/arm32/registers.py @@ -2,7 +2,7 @@ ARM32 register banks. """ from __future__ import absolute_import -from cdsl.registers import RegBank +from cdsl.registers import RegBank, RegClass from .defs import ISA @@ -27,3 +27,8 @@ FloatRegs = RegBank( - Q registers are 4 units each. """, units=64, prefix='s') + +GPR = RegClass('GPR', IntRegs) +S = RegClass('S', FloatRegs, count=32) +D = RegClass('D', FloatRegs, width=2) +Q = RegClass('Q', FloatRegs, width=4) diff --git a/lib/cretonne/meta/isa/arm64/registers.py b/lib/cretonne/meta/isa/arm64/registers.py index fa1c87120b..fec3601367 100644 --- a/lib/cretonne/meta/isa/arm64/registers.py +++ b/lib/cretonne/meta/isa/arm64/registers.py @@ -2,7 +2,7 @@ Aarch64 register banks. """ from __future__ import absolute_import -from cdsl.registers import RegBank +from cdsl.registers import RegBank, RegClass from .defs import ISA @@ -17,3 +17,6 @@ FloatRegs = RegBank( 'FloatRegs', ISA, 'Floating point registers', units=32, prefix='v') + +GPR = RegClass('GPR', IntRegs) +FPR = RegClass('FPR', FloatRegs) diff --git a/lib/cretonne/meta/isa/intel/registers.py b/lib/cretonne/meta/isa/intel/registers.py index abd6353eb1..6a4c59403e 100644 --- a/lib/cretonne/meta/isa/intel/registers.py +++ b/lib/cretonne/meta/isa/intel/registers.py @@ -23,7 +23,7 @@ data types, and the H-registers even less so. Rather than trying to model the H-registers accurately, we'll avoid using them in both I32 and I64 modes. """ from __future__ import absolute_import -from cdsl.registers import RegBank +from cdsl.registers import RegBank, RegClass from .defs import ISA @@ -37,3 +37,6 @@ FloatRegs = RegBank( 'FloatRegs', ISA, 'SSE floating point registers', units=16, prefix='xmm') + +GPR = RegClass('GPR', IntRegs) +FPR = RegClass('FPR', FloatRegs) diff --git a/lib/cretonne/meta/isa/riscv/registers.py b/lib/cretonne/meta/isa/riscv/registers.py index 9d1d0eaadb..f00c9a0f0d 100644 --- a/lib/cretonne/meta/isa/riscv/registers.py +++ b/lib/cretonne/meta/isa/riscv/registers.py @@ -2,7 +2,7 @@ RISC-V register banks. """ from __future__ import absolute_import -from cdsl.registers import RegBank +from cdsl.registers import RegBank, RegClass from .defs import ISA @@ -16,3 +16,6 @@ FloatRegs = RegBank( 'FloatRegs', ISA, 'Floating point registers', units=32, prefix='f') + +GPR = RegClass('GPR', IntRegs) +FPR = RegClass('FPR', FloatRegs)