isle: expand enums in ISLE (#3586)
* x64: expand FloatCC enum in ISLE * isle: regenerate manifests * isle: generate all enum fields in `clif.isle` This expands the `gen_isle` function to write all of the immediate `enum`s out explicitly in `clif.isle`. Non-`enum` immediates are still `extern primitive`. * Only compile `enum_values` with `rebuild-isle` feature * Only compile `gen_enum_isle` with `rebuild-isle` feature
This commit is contained in:
@@ -111,6 +111,17 @@ pub(crate) enum OperandKindFields {
|
||||
TypeVar(TypeVar),
|
||||
}
|
||||
|
||||
impl OperandKindFields {
|
||||
/// Return the [EnumValues] for this field if it is an `enum`.
|
||||
#[cfg(feature = "rebuild-isle")]
|
||||
pub(crate) fn enum_values(&self) -> Option<&EnumValues> {
|
||||
match self {
|
||||
OperandKindFields::ImmEnum(map) => Some(map),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct OperandKind {
|
||||
/// String representation of the Rust type mapping to this OperandKind.
|
||||
|
||||
@@ -1087,9 +1087,11 @@ fn gen_inst_builder(inst: &Instruction, format: &InstructionFormat, fmt: &mut Fo
|
||||
|
||||
#[cfg(feature = "rebuild-isle")]
|
||||
fn gen_isle(formats: &[&InstructionFormat], instructions: &AllInstructions, fmt: &mut Formatter) {
|
||||
use std::collections::BTreeSet;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::fmt::Write;
|
||||
|
||||
use crate::cdsl::formats::FormatField;
|
||||
|
||||
fmt.multi_line(
|
||||
r#"
|
||||
;; GENERATED BY `gen_isle`. DO NOT EDIT!!!
|
||||
@@ -1101,23 +1103,42 @@ fn gen_isle(formats: &[&InstructionFormat], instructions: &AllInstructions, fmt:
|
||||
);
|
||||
fmt.empty_line();
|
||||
|
||||
// Generate all the extern type declarations we need for various immediates.
|
||||
fmt.line(";;;; Extern type declarations for immediates ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");
|
||||
fmt.empty_line();
|
||||
let imm_tys: BTreeSet<_> = formats
|
||||
// Collect and deduplicate the immediate types from the instruction fields.
|
||||
let rust_name = |f: &FormatField| f.kind.rust_type.rsplit("::").next().unwrap();
|
||||
let fields = |f: &FormatField| f.kind.fields.clone();
|
||||
let immediate_types: BTreeMap<_, _> = formats
|
||||
.iter()
|
||||
.flat_map(|f| {
|
||||
f.imm_fields
|
||||
.iter()
|
||||
.map(|i| i.kind.rust_type.rsplit("::").next().unwrap())
|
||||
.map(|i| (rust_name(i), fields(i)))
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect();
|
||||
for ty in imm_tys {
|
||||
|
||||
// Separate the `enum` immediates (e.g., `FloatCC`) from other kinds of
|
||||
// immediates.
|
||||
let (enums, others): (BTreeMap<_, _>, BTreeMap<_, _>) = immediate_types
|
||||
.iter()
|
||||
.partition(|(_, field)| field.enum_values().is_some());
|
||||
|
||||
// Generate all the extern type declarations we need for the non-`enum`
|
||||
// immediates.
|
||||
fmt.line(";;;; Extern type declarations for immediates ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");
|
||||
fmt.empty_line();
|
||||
for ty in others.keys() {
|
||||
fmtln!(fmt, "(type {} (primitive {}))", ty, ty);
|
||||
}
|
||||
fmt.empty_line();
|
||||
|
||||
// Generate the `enum` immediates, expanding all of the available variants
|
||||
// into ISLE.
|
||||
for (name, field) in enums {
|
||||
let field = field.enum_values().expect("only enums considered here");
|
||||
let variants = field.values().cloned().collect();
|
||||
gen_isle_enum(name, variants, fmt)
|
||||
}
|
||||
|
||||
// Generate all of the value arrays we need for `InstructionData` as well as
|
||||
// the constructors and extractors for them.
|
||||
fmt.line(";;;; Value Arrays ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");
|
||||
@@ -1323,6 +1344,27 @@ fn gen_isle(formats: &[&InstructionFormat], instructions: &AllInstructions, fmt:
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate an `enum` immediate in ISLE.
|
||||
#[cfg(feature = "rebuild-isle")]
|
||||
fn gen_isle_enum(name: &str, mut variants: Vec<&str>, fmt: &mut Formatter) {
|
||||
variants.sort();
|
||||
let prefix = format!(";;;; Enumerated Immediate: {} ", name);
|
||||
fmtln!(fmt, "{:;<80}", prefix);
|
||||
fmt.empty_line();
|
||||
fmtln!(fmt, "(type {} extern", name);
|
||||
fmt.indent(|fmt| {
|
||||
fmt.line("(enum");
|
||||
fmt.indent(|fmt| {
|
||||
for variant in variants {
|
||||
fmtln!(fmt, "{}", variant);
|
||||
}
|
||||
});
|
||||
fmt.line(")");
|
||||
});
|
||||
fmt.line(")");
|
||||
fmt.empty_line();
|
||||
}
|
||||
|
||||
/// Generate a Builder trait with methods for all instructions.
|
||||
fn gen_builder(
|
||||
instructions: &AllInstructions,
|
||||
|
||||
@@ -6,10 +6,8 @@
|
||||
|
||||
;;;; Extern type declarations for immediates ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(type AtomicRmwOp (primitive AtomicRmwOp))
|
||||
(type Block (primitive Block))
|
||||
(type Constant (primitive Constant))
|
||||
(type FloatCC (primitive FloatCC))
|
||||
(type FuncRef (primitive FuncRef))
|
||||
(type GlobalValue (primitive GlobalValue))
|
||||
(type Heap (primitive Heap))
|
||||
@@ -17,18 +15,85 @@
|
||||
(type Ieee64 (primitive Ieee64))
|
||||
(type Imm64 (primitive Imm64))
|
||||
(type Immediate (primitive Immediate))
|
||||
(type IntCC (primitive IntCC))
|
||||
(type JumpTable (primitive JumpTable))
|
||||
(type MemFlags (primitive MemFlags))
|
||||
(type Offset32 (primitive Offset32))
|
||||
(type SigRef (primitive SigRef))
|
||||
(type StackSlot (primitive StackSlot))
|
||||
(type Table (primitive Table))
|
||||
(type TrapCode (primitive TrapCode))
|
||||
(type Uimm32 (primitive Uimm32))
|
||||
(type Uimm8 (primitive Uimm8))
|
||||
(type bool (primitive bool))
|
||||
|
||||
;;;; Enumerated Immediate: AtomicRmwOp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(type AtomicRmwOp extern
|
||||
(enum
|
||||
Add
|
||||
And
|
||||
Nand
|
||||
Or
|
||||
Smax
|
||||
Smin
|
||||
Sub
|
||||
Umax
|
||||
Umin
|
||||
Xchg
|
||||
Xor
|
||||
)
|
||||
)
|
||||
|
||||
;;;; Enumerated Immediate: FloatCC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(type FloatCC extern
|
||||
(enum
|
||||
Equal
|
||||
GreaterThan
|
||||
GreaterThanOrEqual
|
||||
LessThan
|
||||
LessThanOrEqual
|
||||
NotEqual
|
||||
Ordered
|
||||
OrderedNotEqual
|
||||
Unordered
|
||||
UnorderedOrEqual
|
||||
UnorderedOrGreaterThan
|
||||
UnorderedOrGreaterThanOrEqual
|
||||
UnorderedOrLessThan
|
||||
UnorderedOrLessThanOrEqual
|
||||
)
|
||||
)
|
||||
|
||||
;;;; Enumerated Immediate: IntCC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(type IntCC extern
|
||||
(enum
|
||||
Equal
|
||||
NotEqual
|
||||
NotOverflow
|
||||
Overflow
|
||||
SignedGreaterThan
|
||||
SignedGreaterThanOrEqual
|
||||
SignedLessThan
|
||||
SignedLessThanOrEqual
|
||||
UnsignedGreaterThan
|
||||
UnsignedGreaterThanOrEqual
|
||||
UnsignedLessThan
|
||||
UnsignedLessThanOrEqual
|
||||
)
|
||||
)
|
||||
|
||||
;;;; Enumerated Immediate: TrapCode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(type TrapCode extern
|
||||
(enum
|
||||
HeapOutOfBounds
|
||||
IntegerDivisionByZero
|
||||
IntegerOverflow
|
||||
StackOverflow
|
||||
)
|
||||
)
|
||||
|
||||
;;;; Value Arrays ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; ISLE representation of `[Value; 2]`.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
src/clif.isle 9c0563583e5500de00ec5e226edc0547ac3ea789c8d76f1da0401c80ec619320fdc9a6f17fd76bbcac74a5894f85385c1f51c900c2b83bc9906d03d0f29bf5cb
|
||||
src/clif.isle be1359b4b6b153f378517c1dd95cd80f4a6bed0c7b86eaba11c088fd71b7bfe80a3c868ace245b2da0bfbbd6ded262ea9576c8e0eeacbf89d03c34a17a709602
|
||||
src/prelude.isle 9bd1fcb6a3604a24cf2e05e6b7eb04dcb3b9dc8fa9a2f1c8f29c25b6e3bf7f679b3b1b72dff87501497b72bc30fc92fd755b898db7e03f380235fae931b6a74b
|
||||
src/isa/aarch64/inst.isle 6e042ec14166fceae4b7133f681fdf604e20a2997e1d60f797e40acd683ccb34e33376189f6b7ed2f5eb441dc61d592cad2592256dfea51296330752181b9403
|
||||
src/isa/aarch64/lower.isle 64a725771537f69c445f44c728e04bffd8a715d6a4d87a5a2bf2e89714ee290b7497c5ca8b335bdddd775f6734be03318ff9aa67e2e4068949ebae06b0902b3f
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
src/clif.isle 9c0563583e5500de00ec5e226edc0547ac3ea789c8d76f1da0401c80ec619320fdc9a6f17fd76bbcac74a5894f85385c1f51c900c2b83bc9906d03d0f29bf5cb
|
||||
src/clif.isle be1359b4b6b153f378517c1dd95cd80f4a6bed0c7b86eaba11c088fd71b7bfe80a3c868ace245b2da0bfbbd6ded262ea9576c8e0eeacbf89d03c34a17a709602
|
||||
src/prelude.isle 9bd1fcb6a3604a24cf2e05e6b7eb04dcb3b9dc8fa9a2f1c8f29c25b6e3bf7f679b3b1b72dff87501497b72bc30fc92fd755b898db7e03f380235fae931b6a74b
|
||||
src/isa/x64/inst.isle b151120df3c356ac697122a8557becd8857eb725851506e844edeb85d831d461322a96d280ad84f9a23518e1e4efb607aebc0e249004148675e4cc19e89f0655
|
||||
src/isa/x64/lower.isle c9b408df0a089fb4f207838973ac775b0f9b56c86f056867c28e6bae317873d3844f74f713f9acd6fed98d3d11a2f9d19d392fe5049169dad33b1fc703b9b766
|
||||
|
||||
Reference in New Issue
Block a user