Give RegClassData a reference to its parent RegInfo.

This makes it possible to materialize new RegClass references without
requiring a RegInfo reference to be passed around.

- Move the RegInfo::toprc() method to RegClassData.
- Rename RegClassData::intersect() to intersect_index() and provide a
  new intersect() which returns a register class.
- Remove some &RegInfo parameters that are no longer needed.
This commit is contained in:
Jakob Stoklund Olesen
2017-10-04 10:10:07 -07:00
parent 7410ddfe08
commit ce4d723a73
8 changed files with 69 additions and 68 deletions

View File

@@ -790,22 +790,22 @@ def emit_operand_constraints(
fmt.format('kind: ConstraintKind::Tied({}),', tied[n])
else:
fmt.line('kind: ConstraintKind::Reg,')
fmt.format('regclass: {},', cons)
fmt.format('regclass: &{}_DATA,', cons)
elif isinstance(cons, Register):
assert n not in tied, "Can't tie fixed register operand"
fmt.format(
'kind: ConstraintKind::FixedReg({}),', cons.unit)
fmt.format('regclass: {},', cons.regclass)
fmt.format('regclass: &{}_DATA,', cons.regclass)
elif isinstance(cons, int):
# This is a tied output constraint. It should never happen
# for input constraints.
assert cons == tied[n], "Invalid tied constraint"
fmt.format('kind: ConstraintKind::Tied({}),', cons)
fmt.format('regclass: {},', recipe.ins[cons])
fmt.format('regclass: &{}_DATA,', recipe.ins[cons])
elif isinstance(cons, Stack):
assert n not in tied, "Can't tie stack operand"
fmt.line('kind: ConstraintKind::Stack,')
fmt.format('regclass: {},', cons.regclass)
fmt.format('regclass: &{}_DATA,', cons.regclass)
else:
raise AssertionError(
'Unsupported constraint {}'.format(cons))

View File

@@ -48,7 +48,9 @@ def gen_regclass(rc, fmt):
"""
Emit a static data definition for a register class.
"""
with fmt.indented('RegClassData {', '},'):
with fmt.indented(
'pub static {}_DATA: RegClassData = RegClassData {{'
.format(rc.name), '};'):
fmt.format('name: "{}",', rc.name)
fmt.format('index: {},', rc.index)
fmt.format('width: {},', rc.width)
@@ -58,6 +60,10 @@ def gen_regclass(rc, fmt):
fmt.format('subclasses: 0x{:x},', rc.subclass_mask())
mask = ', '.join('0x{:08x}'.format(x) for x in rc.mask())
fmt.format('mask: [{}],', mask)
fmt.line('info: &INFO,')
# Also emit a convenient reference for use by hand-written code.
fmt.line('#[allow(dead_code)]')
fmt.format('pub static {0}: RegClass = &{0}_DATA;', rc.name)
def gen_isa(isa, fmt):
@@ -73,22 +79,13 @@ def gen_isa(isa, fmt):
with fmt.indented('banks: &[', '],'):
for regbank in isa.regbanks:
gen_regbank(regbank, fmt)
fmt.line('classes: &CLASSES,')
with fmt.indented('classes: &[', '],'):
for rc in isa.regclasses:
fmt.format('&{}_DATA,', rc.name)
# Register class descriptors.
with fmt.indented(
'const CLASSES: [RegClassData; {}] = ['
.format(len(isa.regclasses)), '];'):
for idx, rc in enumerate(isa.regclasses):
assert idx == rc.index
gen_regclass(rc, fmt)
# Emit constants referencing the register classes.
for rc in isa.regclasses:
fmt.line('#[allow(dead_code)]')
fmt.line(
'pub const {}: RegClass = &CLASSES[{}];'
.format(rc.name, rc.index))
gen_regclass(rc, fmt)
# Emit constants for all the register units.
fmt.line('#[allow(dead_code, non_camel_case_types)]')