Verifies that the number of blocks found matches what should generally
be expected from this particular executable.
The specific value checked for is not independently verified, it just
happens to be a reasonable-looking value that the discovery process
currently identifies, and encoding it here ensures that if discovery
ever changes that the change will be seen and explicitly accepted or
fixed as needed.
We now thread a snapshot of the register state from the beginning of the
instruction evaluation through each instruction's semantics instead of
re-fetching register values each time we need it and potentially seeing
incorrect, partially modified register values.
The field it contains is supposed to be the instruction offset in its basic
block; overflowing it can cause significant problems during symbolic simulation.
There is a new metadata statement that tracks the start address of each
instruction. This is used in the translation to Crucible to provide better
error messages. The x86 backend was already updated, this commit adds the
metadata to the ARM and PowerPC backends.
In macaw core, the type of the arch-specific 'disassemble' function changed to
no longer take a Memory, and to pass the maximum offset as an Int instead of a
MemWord. It also removed the jump table entry size (which is no longer
required).
The removal of the Memory parameter required a bit of a change in how the
instruction parsers are structured, but it isn't a huge change (the "memory
contents after an address" can be computed from a MemSegmentOff, too).
The goal with these flags was to improve compile times by reducing the number of
times that the simplifier runs. It seems like that sometimes causes compiler
errors (e.g., the register allocator crash we hit sometimes) - presumably the
register allocator makes some assumptions about how much the simplifier is run.
The previous generator put all of the code for each matcher in a single large
case expression. While there were individual functions broken out for each case
body, they were all still in the same let expression, which created a huge term.
This refactoring lifts all of the semantics definition bodies to the top
level (with NOINLINE pragmas) to give the code generator less to chew on at a
time.
This improves compile times a little, but, more importantly, works around a bug
in the register allocator in GHC 8.4 that caused a crash in the PowerPC
semantics functions.
The semantics for these instructions cannot be represented in our semantics
language, as they have side effects (i.e., they trap). This currently means
that we have to implement their semantics by hand in macaw-ppc.