Add is_call and is_return instruction attributes.
This commit is contained in:
@@ -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, is_terminator=True)
|
ins=rvals, is_return=True, is_terminator=True)
|
||||||
|
|
||||||
raddr = Operand('raddr', iAddr, doc='Return address')
|
raddr = Operand('raddr', iAddr, doc='Return address')
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ return_reg = Instruction(
|
|||||||
:inst:`return` will be legalized into this instruction on these
|
:inst:`return` will be legalized into this instruction on these
|
||||||
architectures.
|
architectures.
|
||||||
""",
|
""",
|
||||||
ins=(raddr, rvals), is_terminator=True)
|
ins=(raddr, rvals), is_return=True, is_terminator=True)
|
||||||
|
|
||||||
FN = Operand(
|
FN = Operand(
|
||||||
'FN',
|
'FN',
|
||||||
@@ -145,8 +145,7 @@ call = Instruction(
|
|||||||
Call a function which has been declared in the preamble. The argument
|
Call a function which has been declared in the preamble. The argument
|
||||||
types must match the function's signature.
|
types must match the function's signature.
|
||||||
""",
|
""",
|
||||||
ins=(FN, args),
|
ins=(FN, args), outs=rvals, is_call=True)
|
||||||
outs=rvals)
|
|
||||||
|
|
||||||
SIG = Operand('SIG', entities.sig_ref, doc='function signature')
|
SIG = Operand('SIG', entities.sig_ref, doc='function signature')
|
||||||
callee = Operand('callee', iAddr, doc='address of function to call')
|
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
|
Call the function pointed to by `callee` with the given arguments. The
|
||||||
called function must match the specified signature.
|
called function must match the specified signature.
|
||||||
""",
|
""",
|
||||||
ins=(SIG, callee, args),
|
ins=(SIG, callee, args), outs=rvals, is_call=True)
|
||||||
outs=rvals)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Materializing constants.
|
# Materializing constants.
|
||||||
|
|||||||
@@ -80,9 +80,22 @@ 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 is_call: This is a call instruction.
|
||||||
|
:param is_return: This is a return instruction.
|
||||||
:param can_trap: This instruction can trap.
|
: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):
|
def __init__(self, name, doc, ins=(), outs=(), **kwargs):
|
||||||
# type: (str, str, OpList, OpList, **Any) -> None # noqa
|
# type: (str, str, OpList, OpList, **Any) -> None # noqa
|
||||||
self.name = name
|
self.name = name
|
||||||
@@ -95,9 +108,8 @@ 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
|
for attr in Instruction.ATTRIBS:
|
||||||
self.is_terminator = 'is_terminator' in kwargs
|
setattr(self, attr, not not kwargs.get(attr, False))
|
||||||
self.can_trap = 'can_trap' in kwargs
|
|
||||||
InstructionGroup.append(self)
|
InstructionGroup.append(self)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|||||||
@@ -288,31 +288,13 @@ def gen_opcodes(groups, fmt):
|
|||||||
fmt.line()
|
fmt.line()
|
||||||
|
|
||||||
with fmt.indented('impl Opcode {', '}'):
|
with fmt.indented('impl Opcode {', '}'):
|
||||||
attrs = [
|
for attr in sorted(Instruction.ATTRIBS.keys()):
|
||||||
{
|
fmt.doc_comment(Instruction.ATTRIBS[attr])
|
||||||
'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'])
|
|
||||||
with fmt.indented('pub fn {}(self) -> bool {{'
|
with fmt.indented('pub fn {}(self) -> bool {{'
|
||||||
.format(attr['name']), '}'):
|
.format(attr), '}'):
|
||||||
with fmt.indented('match self {', '}'):
|
with fmt.indented('match self {', '}'):
|
||||||
for i in instrs:
|
for i in instrs:
|
||||||
if getattr(i, attr['name']):
|
if getattr(i, attr):
|
||||||
fmt.format(
|
fmt.format(
|
||||||
'Opcode::{} => true,',
|
'Opcode::{} => true,',
|
||||||
i.camel_name, i.name)
|
i.camel_name, i.name)
|
||||||
|
|||||||
Reference in New Issue
Block a user