The encoding list compression algorithm is not the sharpest knife in the
drawer. It can reuse subsets of I64 encoding lists for I32 instructions,
but only when the I64 lists are defined first.
With this change and the previous change to the encoding list format, we
get the following table sizes for the Intel ISA:
ENCLISTS: 1478 B -> 662 B
LEVEL2: 1072 B (unchanged)
LEVEL1: 32 B -> 48 B
Total: 2582 B -> 1782 B (-31%)
The encoding list compression algorithm is not the sharpest knife in the
drawer. It can reuse subsets of I64 encoding lists for I32 instructions,
but only when the I64 lists are defined first.
With this change and the previous change to the encoding list format, we
get the following table sizes for the Intel ISA:
ENCLISTS: 1478 B -> 662 B
LEVEL2: 1072 B (unchanged)
LEVEL1: 32 B -> 48 B
Total: 2582 B -> 1782 B (-31%)
Encodings has a 16-bit "recipe" field, but even Intel only has 57
recipes currently, so it is unlikely that we will ever need to full
range. Use this to represent encoding lists more compactly.
Change the encoding list to a format that:
- Doesn't need a predicate entry before every encoding entry.
- Doesn't need a terminator after the list for each instruction.
- Supports multiple "stop codes" for configurable guidance of the
legalizer.
The encoding scheme has these limits:
- 2*NR + NS <= 0x1000
- INSTP + ISAP <= 0x1000
Where:
- NR is the number of recipes in an ISA,
- NS is the number of stop codes (legalization actions).
- INSTP is the number of instruction predicates.
- ISAP is the number of discrete ISA predicates.
Encodings has a 16-bit "recipe" field, but even Intel only has 57
recipes currently, so it is unlikely that we will ever need to full
range. Use this to represent encoding lists more compactly.
Change the encoding list to a format that:
- Doesn't need a predicate entry before every encoding entry.
- Doesn't need a terminator after the list for each instruction.
- Supports multiple "stop codes" for configurable guidance of the
legalizer.
The encoding scheme has these limits:
- 2*NR + NS <= 0x1000
- INSTP + ISAP <= 0x1000
Where:
- NR is the number of recipes in an ISA,
- NS is the number of stop codes (legalization actions).
- INSTP is the number of instruction predicates.
- ISAP is the number of discrete ISA predicates.
Instead of generating a single `check_instp()` function, create an array
of individual function pointers for checking instruction predicates.
This makes explicit the jump table in the old check_instp() method and
it gives us a way of determining the number of instruction predicates
that exists.
Instead of generating a single `check_instp()` function, create an array
of individual function pointers for checking instruction predicates.
This makes explicit the jump table in the old check_instp() method and
it gives us a way of determining the number of instruction predicates
that exists.
It turns out that most encoding predicates are expressed as recipe
predicates. This means that the encoding tables can be more compact
since we can check the recipe predicate separately from individual
instruction predicates, and the recipe number is already present in the
table.
- Don't combine recipe and encoding-specific predicates when creating an
Encoding. Keep them separate.
- Generate a table of recipe predicates with function pointers. Many of
these are null.
- Check any recipe predicate before accepting a recipe+bits pair.
This has the effect of making almost all instruction predicates
CODE_ALWAYS.
It turns out that most encoding predicates are expressed as recipe
predicates. This means that the encoding tables can be more compact
since we can check the recipe predicate separately from individual
instruction predicates, and the recipe number is already present in the
table.
- Don't combine recipe and encoding-specific predicates when creating an
Encoding. Keep them separate.
- Generate a table of recipe predicates with function pointers. Many of
these are null.
- Check any recipe predicate before accepting a recipe+bits pair.
This has the effect of making almost all instruction predicates
CODE_ALWAYS.
When an instruction doesn't have a valid encoding for the target ISA, it
needs to be legalized. Different legalization strategies can be
expressed as separate XFormGroup objects.
Make the choice of XFormGroup configurable per CPU mode, rather than
depending on a hard-coded default.
Add a CPUMode.legalize_type() method which assigns an XFormGroup to
controlling type variables and lets you set a default.
Add a `legalize` field to Level1Entry so the first-level hash table
lookup gives us the configured default legalization action for the
instruction's controlling type variable.
When an instruction doesn't have a valid encoding for the target ISA, it
needs to be legalized. Different legalization strategies can be
expressed as separate XFormGroup objects.
Make the choice of XFormGroup configurable per CPU mode, rather than
depending on a hard-coded default.
Add a CPUMode.legalize_type() method which assigns an XFormGroup to
controlling type variables and lets you set a default.
Add a `legalize` field to Level1Entry so the first-level hash table
lookup gives us the configured default legalization action for the
instruction's controlling type variable.
The encoding tables contain references to numbered ISA predicates.
- Give the ISA Flags types a predicate_view() method which returns a
PredicateView.
- Delete the old predicate_bytes() method which returned a raw &[u8].
- Use a 'static lifetime for the encoding list slice in the Encodings
iterator, and a single 'a lifetime for everything else.
The encoding tables contain references to numbered ISA predicates.
- Give the ISA Flags types a predicate_view() method which returns a
PredicateView.
- Delete the old predicate_bytes() method which returned a raw &[u8].
- Use a 'static lifetime for the encoding list slice in the Encodings
iterator, and a single 'a lifetime for everything else.
ARM has all of these as scalar integer instructions. Intel has band_not
in SSE and as a scalar in BMI1.
Add the trivial legalization patterns that use a bnot instruction.
ARM has all of these as scalar integer instructions. Intel has band_not
in SSE and as a scalar in BMI1.
Add the trivial legalization patterns that use a bnot instruction.
These map to single Intel instructions.
The i64 to float conversions are not tested yet. The encoding tables
can't yet differentiate instructions on a secondary type variable alone.
These map to single Intel instructions.
The i64 to float conversions are not tested yet. The encoding tables
can't yet differentiate instructions on a secondary type variable alone.