Replace the isa::Legalize enumeration with a function pointer. This
allows an ISA to define its own specific legalization actions instead of
relying on the default two.
Generate a LEGALIZE_ACTIONS table for each ISA which contains
legalization function pointers indexed by the legalization codes that
are already in the encoding tables. Include this table in
isa/*/enc_tables.rs.
Give the `Encodings` iterator a reference to the action table and change
its `legalize()` method to return a function pointer instead of an
ISA-specific code.
The Result<> returned from TargetIsa::encode() no longer implements
Debug, so eliminate uses of unwrap and expect on that type.
Replace the isa::Legalize enumeration with a function pointer. This
allows an ISA to define its own specific legalization actions instead of
relying on the default two.
Generate a LEGALIZE_ACTIONS table for each ISA which contains
legalization function pointers indexed by the legalization codes that
are already in the encoding tables. Include this table in
isa/*/enc_tables.rs.
Give the `Encodings` iterator a reference to the action table and change
its `legalize()` method to return a function pointer instead of an
ISA-specific code.
The Result<> returned from TargetIsa::encode() no longer implements
Debug, so eliminate uses of unwrap and expect on that type.
The following instructions have simple encodings:
- bitcast.f32.i32
- bitcast.i32.f32
- bitcast.f64.i64
- bitcast.i64.f64
- fpromote.f64.f32
- fdemote.f32.f64
Also add helper functions enc_flt() and enc_i32_i64 to
intel.encodings.py for generating the common set of encodings for an
instruction: I32, I64 w/REX, I64 w/o REX.
The following instructions have simple encodings:
- bitcast.f32.i32
- bitcast.i32.f32
- bitcast.f64.i64
- bitcast.i64.f64
- fpromote.f64.f32
- fdemote.f32.f64
Also add helper functions enc_flt() and enc_i32_i64 to
intel.encodings.py for generating the common set of encodings for an
instruction: I32, I64 w/REX, I64 w/o REX.
Instructions will multiple type variables can now use `any` to indicate
encodings that don't care about the value of a secondary type variable:
ishl.i32.any instead of ishl.i32.i32
This is only allowed for secondary type variables (which are converted
to instruction predicates). The controlling type variable must still be
fully specified because it is used to key the encoding tables.
Instructions will multiple type variables can now use `any` to indicate
encodings that don't care about the value of a secondary type variable:
ishl.i32.any instead of ishl.i32.i32
This is only allowed for secondary type variables (which are converted
to instruction predicates). The controlling type variable must still be
fully specified because it is used to key the encoding tables.
Predicate numbers are available in the maps
isa.settings.predicate_number and isa.instp_number instead.
Like the name field, predicate numbers don't interact well with
unique_pred().
Predicate numbers are available in the maps
isa.settings.predicate_number and isa.instp_number instead.
Like the name field, predicate numbers don't interact well with
unique_pred().
The name of a predicate was only ever used for named settings that are
computed as a boolean expression of other settings.
- Record the names of these settings in named_predicates instead.
- Remove the name field from all predicates.
Named predicates does not interact well with the interning of predicates
through isa.unique_pred().
The name of a predicate was only ever used for named settings that are
computed as a boolean expression of other settings.
- Record the names of these settings in named_predicates instead.
- Remove the name field from all predicates.
Named predicates does not interact well with the interning of predicates
through isa.unique_pred().
The encoding tables are keyed by the controlling type variable only. We
need to distinguish different encodings for instructions with multiple
type variables.
Add a TypePredicate instruction predicate which can check the type of an
instruction value operand. Combine type checks into the instruction
predicate for instructions with more than one type variable.
Add Intel encodings for fcvt_from_sint.f32.i64 which can now be
distinguished from fcvt_from_sint.f32.i32.
The encoding tables are keyed by the controlling type variable only. We
need to distinguish different encodings for instructions with multiple
type variables.
Add a TypePredicate instruction predicate which can check the type of an
instruction value operand. Combine type checks into the instruction
predicate for instructions with more than one type variable.
Add Intel encodings for fcvt_from_sint.f32.i64 which can now be
distinguished from fcvt_from_sint.f32.i32.
The new encoding format allows entries that mean "stop with this
legalization code" which makes it possible to configure legalization
actions per instruction, instead of only per controlling type variable.
This patch adds the Rust side of the legalization codes:
- Add an `Encodings::legalize()` method on the encoding iterator which
can be called after the iterator has returned `None`. The returned
code is either the default legalization action for the type, or a
specific code encountered in the encoding list.
- Change `lookup_enclist` to return a full iterator instead of just an
offset. The two-phase lookup can bail at multiple points, each time
with a default legalization code from the level 1 table. This default
legalization code is stored in the returned iterator.
- Change all the implementations of legal_encodings() in the ISA
implementations.
This change means that we don't need to return a Result any longer. The
`Encodings` iterator can be empty with an associated legalization code.
The new encoding format allows entries that mean "stop with this
legalization code" which makes it possible to configure legalization
actions per instruction, instead of only per controlling type variable.
This patch adds the Rust side of the legalization codes:
- Add an `Encodings::legalize()` method on the encoding iterator which
can be called after the iterator has returned `None`. The returned
code is either the default legalization action for the type, or a
specific code encountered in the encoding list.
- Change `lookup_enclist` to return a full iterator instead of just an
offset. The two-phase lookup can bail at multiple points, each time
with a default legalization code from the level 1 table. This default
legalization code is stored in the returned iterator.
- Change all the implementations of legal_encodings() in the ISA
implementations.
This change means that we don't need to return a Result any longer. The
`Encodings` iterator can be empty with an associated legalization code.
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.