added Opcode flags methods

generate `is_branch`, `is_terminator`, `can_trap` methods for `enum
Opcode`.
This commit is contained in:
Dominik Inführ
2016-12-01 00:11:06 +01:00
committed by Jakob Stoklund Olesen
parent 19ac05577c
commit 93aa2b456e
3 changed files with 30 additions and 10 deletions

View File

@@ -83,7 +83,7 @@ trap = Instruction(
'trap', r""" 'trap', r"""
Terminate execution unconditionally. Terminate execution unconditionally.
""", """,
is_terminator=True) is_terminator=True, can_trap=True)
trapz = Instruction( trapz = Instruction(
'trapz', r""" 'trapz', r"""
@@ -91,7 +91,7 @@ trapz = Instruction(
if ``c`` is non-zero, execution continues at the following instruction. if ``c`` is non-zero, execution continues at the following instruction.
""", """,
ins=c) ins=c, can_trap=True)
trapnz = Instruction( trapnz = Instruction(
'trapnz', r""" 'trapnz', r"""
@@ -99,7 +99,7 @@ trapnz = Instruction(
if ``c`` is zero, execution continues at the following instruction. if ``c`` is zero, execution continues at the following instruction.
""", """,
ins=c) ins=c, can_trap=True)
rvals = Operand('rvals', VARIABLE_ARGS, doc='return values') rvals = Operand('rvals', VARIABLE_ARGS, doc='return values')
@@ -111,7 +111,7 @@ x_return = Instruction(
provided return values. The list of return values must match the provided return values. The list of return values must match the
function signature's return types. function signature's return types.
""", """,
ins=rvals) ins=rvals, is_terminator=True)
FN = Operand( FN = Operand(
'FN', 'FN',
@@ -366,7 +366,7 @@ udiv = Instruction(
This operation traps if the divisor is zero. This operation traps if the divisor is zero.
""", """,
ins=(x, y), outs=a) ins=(x, y), outs=a, can_trap=True)
sdiv = Instruction( sdiv = Instruction(
'sdiv', r""" 'sdiv', r"""
@@ -377,7 +377,7 @@ sdiv = Instruction(
representable in :math:`B` bits two's complement. This only happens representable in :math:`B` bits two's complement. This only happens
when :math:`x = -2^{B-1}, y = -1`. when :math:`x = -2^{B-1}, y = -1`.
""", """,
ins=(x, y), outs=a) ins=(x, y), outs=a, can_trap=True)
urem = Instruction( urem = Instruction(
'urem', """ 'urem', """
@@ -385,7 +385,7 @@ urem = Instruction(
This operation traps if the divisor is zero. This operation traps if the divisor is zero.
""", """,
ins=(x, y), outs=a) ins=(x, y), outs=a, can_trap=True)
srem = Instruction( srem = Instruction(
'srem', """ 'srem', """
@@ -399,7 +399,7 @@ srem = Instruction(
dividend. Should we add a ``smod`` instruction for the case where dividend. Should we add a ``smod`` instruction for the case where
the result has the same sign as the divisor? the result has the same sign as the divisor?
""", """,
ins=(x, y), outs=a) ins=(x, y), outs=a, can_trap=True)
a = Operand('a', iB) a = Operand('a', iB)
x = Operand('x', iB) x = Operand('x', iB)
@@ -1136,7 +1136,7 @@ fcvt_to_uint = Instruction(
The result type must have the same number of vector lanes as the input. The result type must have the same number of vector lanes as the input.
""", """,
ins=x, outs=a) ins=x, outs=a, can_trap=True)
fcvt_to_sint = Instruction( fcvt_to_sint = Instruction(
'fcvt_to_sint', r""" 'fcvt_to_sint', r"""
@@ -1148,7 +1148,7 @@ fcvt_to_sint = Instruction(
The result type must have the same number of vector lanes as the input. The result type must have the same number of vector lanes as the input.
""", """,
ins=x, outs=a) ins=x, outs=a, can_trap=True)
x = Operand('x', Int) x = Operand('x', Int)
a = Operand('a', FloatTo) a = Operand('a', FloatTo)

View File

@@ -80,6 +80,7 @@ class Instruction(object):
values or `variable_args`. values or `variable_args`.
:param is_terminator: This is a terminator instruction. :param is_terminator: This is a terminator instruction.
:param is_branch: This is a branch instruction. :param is_branch: This is a branch instruction.
:param can_trap: This instruction can trap.
""" """
def __init__(self, name, doc, ins=(), outs=(), **kwargs): def __init__(self, name, doc, ins=(), outs=(), **kwargs):
@@ -94,6 +95,9 @@ class Instruction(object):
self.value_results = tuple( self.value_results = tuple(
i for i, o in enumerate(self.outs) if o.is_value()) i for i, o in enumerate(self.outs) if o.is_value())
self._verify_polymorphic() self._verify_polymorphic()
self.is_branch = 'is_branch' in kwargs
self.is_terminator = 'is_terminator' in kwargs
self.can_trap = 'can_trap' in kwargs
InstructionGroup.append(self) InstructionGroup.append(self)
def __str__(self): def __str__(self):

View File

@@ -271,6 +271,22 @@ def gen_opcodes(groups, fmt):
fmt.line(i.camel_name + ',') fmt.line(i.camel_name + ',')
fmt.line() fmt.line()
with fmt.indented('impl Opcode {', '}'):
attrs = ['is_branch', 'is_terminator', 'can_trap']
for attr in attrs:
if attr != attrs[0]:
fmt.line()
with fmt.indented('fn {}(self) -> bool {{'
.format(attr), '}'):
with fmt.indented('match self {', '}'):
for i in instrs:
if getattr(i, attr):
fmt.format('Opcode::{} => true,', i.camel_name, i.name)
fmt.line('_ => false')
# Generate a private opcode_format table. # Generate a private opcode_format table.
with fmt.indented( with fmt.indented(
'const OPCODE_FORMAT: [InstructionFormat; {}] = [' 'const OPCODE_FORMAT: [InstructionFormat; {}] = ['