Add trap codes to the Cretonne IL.

The trap and trapz/trapnz instructions now take a trap code immediate
operand which indicates the reason for trapping.
This commit is contained in:
Jakob Stoklund Olesen
2017-09-20 13:58:57 -07:00
parent 0f21fd342a
commit e8723be33f
28 changed files with 199 additions and 62 deletions

View File

@@ -9,7 +9,7 @@ from __future__ import absolute_import
from cdsl.formats import InstructionFormat
from cdsl.operands import VALUE, VARIABLE_ARGS
from .immediates import imm64, uimm8, uimm32, ieee32, ieee64, offset32
from .immediates import boolean, intcc, floatcc, memflags, regunit
from .immediates import boolean, intcc, floatcc, memflags, regunit, trapcode
from . import entities
from .entities import ebb, sig_ref, func_ref, stack_slot, heap
@@ -61,5 +61,8 @@ HeapAddr = InstructionFormat(heap, VALUE, uimm32)
RegMove = InstructionFormat(VALUE, ('src', regunit), ('dst', regunit))
Trap = InstructionFormat(trapcode)
CondTrap = InstructionFormat(VALUE, trapcode)
# Finally extract the names of global variables in this module.
InstructionFormat.extract_names(globals())

View File

@@ -105,3 +105,19 @@ regunit = ImmediateKind(
'regunit',
'A register unit in the target ISA',
rust_type='isa::RegUnit')
#: A trap code indicating the reason for trapping.
#:
#: The Rust enum type also has a `User(u16)` variant for user-provided trap
#: codes.
trapcode = ImmediateKind(
'trapcode',
'A trap reason code.',
default_member='code',
rust_type='ir::TrapCode',
values={
"stk_ovf": 'StackOverflow',
"heap_oob": 'HeapOutOfBounds',
"int_ovf": 'IntegerOverflow',
"int_divz": 'IntegerDivisionByZero',
})

View File

@@ -11,6 +11,7 @@ from cdsl.instructions import Instruction, InstructionGroup
from base.types import f32, f64, b1
from base.immediates import imm64, uimm8, uimm32, ieee32, ieee64, offset32
from base.immediates import boolean, intcc, floatcc, memflags, regunit
from base.immediates import trapcode
from base import entities
from cdsl.ti import WiderOrEq
import base.formats # noqa
@@ -126,11 +127,12 @@ br_table = Instruction(
""",
ins=(x, JT), is_branch=True)
code = Operand('code', trapcode)
trap = Instruction(
'trap', r"""
Terminate execution unconditionally.
""",
is_terminator=True, can_trap=True)
ins=code, is_terminator=True, can_trap=True)
trapz = Instruction(
'trapz', r"""
@@ -138,7 +140,7 @@ trapz = Instruction(
if ``c`` is non-zero, execution continues at the following instruction.
""",
ins=c, can_trap=True)
ins=(c, code), can_trap=True)
trapnz = Instruction(
'trapnz', r"""
@@ -146,7 +148,7 @@ trapnz = Instruction(
if ``c`` is zero, execution continues at the following instruction.
""",
ins=c, can_trap=True)
ins=(c, code), can_trap=True)
rvals = Operand('rvals', VARIABLE_ARGS, doc='return values')

View File

@@ -287,8 +287,8 @@ I64.enc(base.brnz.b1, *r.t8jccb_abcd(0x75))
#
# Trap as ud2
#
I32.enc(base.trap, *r.noop(0x0f, 0x0b))
I64.enc(base.trap, *r.noop(0x0f, 0x0b))
I32.enc(base.trap, *r.trap(0x0f, 0x0b))
I64.enc(base.trap, *r.trap(0x0f, 0x0b))
#
# Comparisons

View File

@@ -5,7 +5,7 @@ from __future__ import absolute_import
from cdsl.isa import EncRecipe
from cdsl.predicates import IsSignedInt, IsEqual
from base.formats import Unary, UnaryImm, Binary, BinaryImm, MultiAry
from base.formats import Nullary, Call, IndirectCall, Store, Load
from base.formats import Trap, Call, IndirectCall, Store, Load
from base.formats import IntCompare
from base.formats import RegMove, Ternary, Jump, Branch, FuncAddr
from .registers import GPR, ABCD, FPR
@@ -195,8 +195,8 @@ class TailRecipe:
null = EncRecipe('null', Unary, size=0, ins=GPR, outs=0, emit='')
# XX opcode, no ModR/M.
noop = TailRecipe(
'noop', Nullary, size=0, ins=(), outs=(),
trap = TailRecipe(
'trap', Trap, size=0, ins=(), outs=(),
emit='PUT_OP(bits, BASE_REX, sink);')
# XX /r