Two new pieces of information are available for all encoding recipes:
- The size in bytes of an encoded instruction, and
- The range of a branch encoded with the recipe, if any.
In the meta language, EncRecipe takes two new constructor arguments. The
size is required for all encodings and branch_range is required for all
recipes used to encode branches.
The tables returned by recipe_names() and recipe_constraints() are now
collected into an EncInfo struct that is available from
TargetIsa::encoding_info(). This is equivalent to the register bank
tables available fro TargetIsa::register_info().
This cleans of the TargetIsa interface and makes it easier to add
encoding-related information.
Not all br_icmp opcodes are present in the ISA. The missing ones can be
reached by commuting operands.
Don't attempt to encode EBB offsets yet. For now just emit an EBB
relocation for the branch instruction.
The carry and borrow values are boolean, so we have to convert them to
an integer type with bint(c) before we can add them to the result.
Also tweak the default legalizer action for unsupported types: Only
attempt a narrowing pattern for lane types > 32 bits.
This was found by @angusholder's new type checks in the verifier.
Use the meta language encoding recipes to generate an emit_inst()
function for each ISA. The generated calls into recipe_*() functions
that must be implemented by hand.
Implement recipe_*() functions for the RISC-V recipes.
Add the TargetIsa::emit_inst() entry point which emits an instruction to
a CodeSink trait object.
Insert conversion code that reconstructs the original function argument
types from the legalized ABI signature.
Add abi::legalize_abi_value(). This function is used when adapting code
to a legalized function signature.
Add an abi module with code that is probably useful to all ISAs when
implementing this function.
Add a unit() method to RegClassData which can be used to index the
register units in a class.
This entry point will be used for controlling ABI conventions when
legalizing.
Provide an empty implementation for RISC-V and let the other ISAs crash
in legalization.
This is just the scaffolding. We still need to:
- Rewrite the entry block arguments to match the legalized signature.
- Rewrite call and return instructions.
- Implement the legalize_signature() function for all ISAs.
- Add shared generic types to help with the legalize_signature()
functions.
This is a bare-bones outline of the SSA coloring pass. Many features are
missing, including:
- Handling instruction operand constraints beyond simple register
classes.
- Handling ABI requirements for function arguments and return values.
- Generating shuffle code for EBB arguments.
Some polymorphic instructions don't return the controlling type
variable, so it has to be computed from the designated operand instead.
- Add a requires_typevar_operand() method to the operand constraints
which indicates that.
- Add a ctrl_typevar(dfg) method to InstructionData which computes the
controlling type variable correctly, and returns VOID for monomorphic
instructions.
- Use ctrl_typevar(dfg) to drive the level-1 encoding table lookups.
On ISAs with no instruction predicates, just emit an unimplemented!()
stub for the check_instp() function. It is unlikely that a finished ISA
will not have any instruction predicates.
An SSA value is usually biased towards a specific register class or a
stack slot, depending on the constraints of the instructions using it.
Represent this bias as an Affinity enum, and implement a merging
algorithm for updating an affinity to satisfy a new constraint.
Affinities will be computed as part of the liveness analysis. This is
not implemented yet.
Ensure that the set of register classes is closed under intersection.
Provide a RegClass::intersect() method which finds the register class
representing the intersection of two classes.
Generate a bit-mask of subclasses for each register class to be used by
the intersect() method.
Ensure that register classes are sorted topologically. This is also used
by the intersect() method.
Every encoding recipe must specify register constraints on input and
output values.
Generate recipe constraint tables along with the other encoding tables.
This set of available register units also manages register aliasing in
an efficient way.
Detect if the units in a register straddles mask words. The algorithm
for allocating multi-unit registers expect the whole register to be
inside a single mask word. We could handle this if necessary, but so far
no ISAs need it.
The intel, arm32, and arm32 targets were only defined in the meta
language previously. Add Rust implementations too.
This is mostly boilerplate, except for the unit tests in the
registers.rs files.
Give these crates each a more standard directory layout with sources in
a 'src' sub-sirectory and Cargo.toml in the top lib/foo directory.
Add license and description fields to each.
The build script for the cretonne crate now lives in
'lib/cretonne/build.rs' separating it from the normal library sources
under 'lib/cretonne/src'.