Coalesce some formats into MultiAry.

Allow some flexibility in the signature matching for instruction
formats. In particular, look for a value list format as a second chance
option.

The Return, ReturnReg, and TernaryOverflow formats all fit the single
MultiAry catch-all format for instructions without immediate operands.
This commit is contained in:
Jakob Stoklund Olesen
2017-03-10 12:17:12 -08:00
parent 6021da8e1c
commit 519eb1934b
8 changed files with 50 additions and 99 deletions

View File

@@ -30,9 +30,10 @@ BinaryOverflow = InstructionFormat(VALUE, VALUE, multiple_results=True)
# The fma instruction has the same constraint on all inputs.
Ternary = InstructionFormat(VALUE, VALUE, VALUE, typevar_operand=1)
# Carry in *and* carry out for `iadd_carry` and friends.
TernaryOverflow = InstructionFormat(
VALUE, VALUE, VALUE, multiple_results=True, boxed_storage=True)
# Catch-all for instructions with many outputs and inputs and no immediate
# operands.
MultiAry = InstructionFormat(
VARIABLE_ARGS, multiple_results=True, value_list=True)
InsertLane = InstructionFormat(VALUE, ('lane', uimm8), VALUE)
ExtractLane = InstructionFormat(VALUE, ('lane', uimm8))
@@ -49,8 +50,6 @@ Call = InstructionFormat(
IndirectCall = InstructionFormat(
sig_ref, VALUE, VARIABLE_ARGS,
multiple_results=True, value_list=True)
Return = InstructionFormat(VARIABLE_ARGS, value_list=True)
ReturnReg = InstructionFormat(VALUE, VARIABLE_ARGS, value_list=True)
# Finally extract the names of global variables in this module.
InstructionFormat.extract_names(globals())

View File

@@ -82,7 +82,7 @@ class InstructionFormat(object):
if not self.has_value_list:
assert self.typevar_operand < self.num_value_operands, \
"typevar_operand must indicate a 'value' operand"
elif self.num_value_operands != 0:
elif self.has_value_list or self.num_value_operands > 0:
# Default to the first 'value' operand, if there is one.
self.typevar_operand = 0
@@ -176,12 +176,26 @@ class InstructionFormat(object):
has_varargs = (VARIABLE_ARGS in tuple(op.kind for op in ins))
sig = (multiple_results, imm_kinds, num_values, has_varargs)
if sig not in InstructionFormat._registry:
raise RuntimeError(
"No instruction format matches ins = ({}){}".format(
", ".join(map(str, sig[1])),
"[multiple results]" if multiple_results else ""))
return InstructionFormat._registry[sig]
if sig in InstructionFormat._registry:
return InstructionFormat._registry[sig]
# Try another value list format as an alternative.
sig = (True, imm_kinds, num_values, has_varargs)
if sig in InstructionFormat._registry:
return InstructionFormat._registry[sig]
sig = (multiple_results, imm_kinds, 0, True)
if sig in InstructionFormat._registry:
return InstructionFormat._registry[sig]
sig = (True, imm_kinds, 0, True)
if sig in InstructionFormat._registry:
return InstructionFormat._registry[sig]
raise RuntimeError(
'No instruction format matches multiple_results={},'
'imms={}, vals={}, varargs={}'.format(
multiple_results, imm_kinds, num_values, has_varargs))
@staticmethod
def extract_names(globs):

View File

@@ -50,10 +50,12 @@ def unwrap_inst(iref, node, fmt):
fmt.line('{},'.format(m))
if nvops == 1:
fmt.line('arg,')
elif nvops != 0:
fmt.line('args,')
elif iform.has_value_list or nvops > 1:
fmt.line('ref args,')
fmt.line('..')
fmt.outdented_line('} = dfg[inst] {')
if iform.has_value_list:
fmt.line('let args = args.as_slice(&dfg.value_lists);')
# Generate the values for the tuple.
outs = list()
prefix = 'data.' if iform.boxed_storage else ''

View File

@@ -11,7 +11,7 @@ instruction formats described in the reference:
from __future__ import absolute_import
from cdsl.isa import EncRecipe
from cdsl.predicates import IsSignedInt
from base.formats import Binary, BinaryImm, ReturnReg
from base.formats import Binary, BinaryImm, MultiAry
from .registers import GPR
# The low 7 bits of a RISC-V instruction is the base opcode. All 32-bit
@@ -86,4 +86,4 @@ I = EncRecipe(
# I-type encoding for `jalr` as a return instruction. We won't use the
# immediate offset.
# The variable return values are not encoded.
Iret = EncRecipe('Iret', ReturnReg, ins=GPR, outs=())
Iret = EncRecipe('Iret', MultiAry, ins=GPR, outs=())