diff --git a/lib/cretonne/meta/base/instructions.py b/lib/cretonne/meta/base/instructions.py index b5a2c784fa..eb98d175ef 100644 --- a/lib/cretonne/meta/base/instructions.py +++ b/lib/cretonne/meta/base/instructions.py @@ -83,7 +83,7 @@ trap = Instruction( 'trap', r""" Terminate execution unconditionally. """, - is_terminator=True) + is_terminator=True, can_trap=True) trapz = Instruction( 'trapz', r""" @@ -91,7 +91,7 @@ trapz = Instruction( if ``c`` is non-zero, execution continues at the following instruction. """, - ins=c) + ins=c, can_trap=True) trapnz = Instruction( 'trapnz', r""" @@ -99,7 +99,7 @@ trapnz = 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') @@ -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) + ins=rvals, is_terminator=True) FN = Operand( 'FN', @@ -366,7 +366,7 @@ udiv = Instruction( This operation traps if the divisor is zero. """, - ins=(x, y), outs=a) + ins=(x, y), outs=a, can_trap=True) sdiv = Instruction( 'sdiv', r""" @@ -377,7 +377,7 @@ sdiv = Instruction( representable in :math:`B` bits two's complement. This only happens when :math:`x = -2^{B-1}, y = -1`. """, - ins=(x, y), outs=a) + ins=(x, y), outs=a, can_trap=True) urem = Instruction( 'urem', """ @@ -385,7 +385,7 @@ urem = Instruction( This operation traps if the divisor is zero. """, - ins=(x, y), outs=a) + ins=(x, y), outs=a, can_trap=True) srem = Instruction( 'srem', """ @@ -399,7 +399,7 @@ srem = Instruction( dividend. Should we add a ``smod`` instruction for the case where 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) 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. """, - ins=x, outs=a) + ins=x, outs=a, can_trap=True) fcvt_to_sint = Instruction( '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. """, - ins=x, outs=a) + ins=x, outs=a, can_trap=True) x = Operand('x', Int) a = Operand('a', FloatTo) diff --git a/lib/cretonne/meta/cdsl/instructions.py b/lib/cretonne/meta/cdsl/instructions.py index ee6b9c4a59..84968c1b6b 100644 --- a/lib/cretonne/meta/cdsl/instructions.py +++ b/lib/cretonne/meta/cdsl/instructions.py @@ -80,6 +80,7 @@ class Instruction(object): values or `variable_args`. :param is_terminator: This is a terminator instruction. :param is_branch: This is a branch instruction. + :param can_trap: This instruction can trap. """ def __init__(self, name, doc, ins=(), outs=(), **kwargs): @@ -94,6 +95,9 @@ 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 InstructionGroup.append(self) def __str__(self): diff --git a/lib/cretonne/meta/gen_instr.py b/lib/cretonne/meta/gen_instr.py index 11aaa4fa0d..799c080473 100644 --- a/lib/cretonne/meta/gen_instr.py +++ b/lib/cretonne/meta/gen_instr.py @@ -271,6 +271,22 @@ def gen_opcodes(groups, fmt): fmt.line(i.camel_name + ',') 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. with fmt.indented( 'const OPCODE_FORMAT: [InstructionFormat; {}] = ['