Add is_call and is_return instruction attributes.

This commit is contained in:
Jakob Stoklund Olesen
2017-03-08 14:48:50 -08:00
parent 7a45aeebeb
commit 58756e5d34
3 changed files with 23 additions and 31 deletions

View File

@@ -111,7 +111,7 @@ x_return = Instruction(
provided return values. The list of return values must match the
function signature's return types.
""",
ins=rvals, is_terminator=True)
ins=rvals, is_return=True, is_terminator=True)
raddr = Operand('raddr', iAddr, doc='Return address')
@@ -130,7 +130,7 @@ return_reg = Instruction(
:inst:`return` will be legalized into this instruction on these
architectures.
""",
ins=(raddr, rvals), is_terminator=True)
ins=(raddr, rvals), is_return=True, is_terminator=True)
FN = Operand(
'FN',
@@ -145,8 +145,7 @@ call = Instruction(
Call a function which has been declared in the preamble. The argument
types must match the function's signature.
""",
ins=(FN, args),
outs=rvals)
ins=(FN, args), outs=rvals, is_call=True)
SIG = Operand('SIG', entities.sig_ref, doc='function signature')
callee = Operand('callee', iAddr, doc='address of function to call')
@@ -158,8 +157,7 @@ call_indirect = Instruction(
Call the function pointed to by `callee` with the given arguments. The
called function must match the specified signature.
""",
ins=(SIG, callee, args),
outs=rvals)
ins=(SIG, callee, args), outs=rvals, is_call=True)
#
# Materializing constants.

View File

@@ -80,9 +80,22 @@ class Instruction(object):
values or `variable_args`.
:param is_terminator: This is a terminator instruction.
:param is_branch: This is a branch instruction.
:param is_call: This is a call instruction.
:param is_return: This is a return instruction.
:param can_trap: This instruction can trap.
"""
# Boolean instruction attributes that can be passed as keyword arguments to
# the constructor. Map attribute name to doc comment for generated Rust
# code.
ATTRIBS = {
'is_terminator': 'True for instructions that terminate the EBB.',
'is_branch': 'True for all branch or jump instructions.',
'is_call': 'Is this a call instruction?',
'is_return': 'Is this a return instruction?',
'can_trap': 'Can this instruction cause a trap?',
}
def __init__(self, name, doc, ins=(), outs=(), **kwargs):
# type: (str, str, OpList, OpList, **Any) -> None # noqa
self.name = name
@@ -95,9 +108,8 @@ class Instruction(object):
self.value_results = tuple(
i for i, o in enumerate(self.outs) if o.is_value())
self._verify_polymorphic()
self.is_branch = 'is_branch' in kwargs
self.is_terminator = 'is_terminator' in kwargs
self.can_trap = 'can_trap' in kwargs
for attr in Instruction.ATTRIBS:
setattr(self, attr, not not kwargs.get(attr, False))
InstructionGroup.append(self)
def __str__(self):

View File

@@ -288,31 +288,13 @@ def gen_opcodes(groups, fmt):
fmt.line()
with fmt.indented('impl Opcode {', '}'):
attrs = [
{
'name': 'is_branch',
'comment': 'True for all branch instructions.'
},
{
'name': 'is_terminator',
'comment': 'True for instructions that terminate EBB.'
},
{
'name': 'can_trap',
'comment': 'True if instruction could trap.'
}
]
for attr in attrs:
if attr != attrs[0]:
fmt.line()
fmt.doc_comment(attr['comment'])
for attr in sorted(Instruction.ATTRIBS.keys()):
fmt.doc_comment(Instruction.ATTRIBS[attr])
with fmt.indented('pub fn {}(self) -> bool {{'
.format(attr['name']), '}'):
.format(attr), '}'):
with fmt.indented('match self {', '}'):
for i in instrs:
if getattr(i, attr['name']):
if getattr(i, attr):
fmt.format(
'Opcode::{} => true,',
i.camel_name, i.name)