The TargetIsa::encode() function returns the first encoding of an instruction where both ISA and instruction predicates are satisfied. We also need a way of enumerating all of the possible encodings of an instruction, probably by creating an iterator that returns encodings.
Instruction encodings can have multiple constraints that are checked at different points in the compiler pipeline:
ISA predicates depend only on static settings like available CPU and instruction set features. For example, the imul.i32 instruction can only be encoded if the RISC-V "M" extension is supported by the CPU.
Instruction predicates check if the immediate operands can be encoded. For example, iadd_imm.i32 can only be encoded as a RISC-V addi instruction if the immediate is a 12-bit signed integer.
Register constraints. These are described by the RecipeConstraints available from EncInfo and satisfied by the register allocator.
Branch range constraints. These are described by the BranchRange constraints also available from EncInfo.
Only the first two types of constraints are checked by the iterator, just like TargetISa::encode() does it. This iterator would be used by:
The encoding verifier will permit any of the valid encodings instead of requiring a unique one as it does now.
The branch relaxation pass (#73) will use it to search for a different branch encoding with more relaxed range constraints. For example, x86 branches can be encoded with an 8-bit or a 32-bit displacement.
An instruction compression pass (which doesn't exist yet) can look for a smaller encoding of the same instruction that still satisfies register constraints. For example, 32-bit ARM instructions can be represented as 16-bit Thumb2 instructions if the registers are right.
The tables that are generated in files like encoding-riscv.rs should already be usable for this. The implementation of TargetIsa::encode() stops at the first match. The iterator would keep going until reaching a stop code.
The
TargetIsa::encode()
function returns the first encoding of an instruction where both ISA and instruction predicates are satisfied. We also need a way of enumerating all of the possible encodings of an instruction, probably by creating an iterator that returns encodings.Instruction encodings can have multiple constraints that are checked at different points in the compiler pipeline:
imul.i32
instruction can only be encoded if the RISC-V "M" extension is supported by the CPU.iadd_imm.i32
can only be encoded as a RISC-Vaddi
instruction if the immediate is a 12-bit signed integer.RecipeConstraints
available fromEncInfo
and satisfied by the register allocator.BranchRange
constraints also available fromEncInfo
.Only the first two types of constraints are checked by the iterator, just like
TargetISa::encode()
does it. This iterator would be used by:The tables that are generated in files like
encoding-riscv.rs
should already be usable for this. The implementation ofTargetIsa::encode()
stops at the first match. The iterator would keep going until reaching a stop code.cc @anholt