Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::codegen::options::CodegenOptions;
use crate::codegen::{GrammarWriter, OPERAND_ID_RESULT, OPERAND_ID_RESULT_TYPE};
use crate::parse::{Grammar, InstMeta, Operand, Quantifier};
use quote::{format_ident, quote};
use quote::quote;

pub fn write_inst(writer: &mut GrammarWriter, grammar: &Grammar<'_>) -> anyhow::Result<()> {
let insts = grammar.insts.iter().map(|inst| {
Expand Down Expand Up @@ -156,82 +155,3 @@ pub fn write_inst(writer: &mut GrammarWriter, grammar: &Grammar<'_>) -> anyhow::
},
)
}

pub fn write_inst_enum(
writer: &mut GrammarWriter,
grammar: &Grammar<'_>,
opt: &CodegenOptions<'_>,
) -> anyhow::Result<()> {
let name = format_ident!("{}InstSet", opt.name_suffix_type);
let insts = grammar
.insts
.iter()
.map(|inst| {
let type_ident = InstMeta::type_ident(&inst.opname);
let enum_ident = InstMeta::enum_ident(&inst.opname);
(inst, type_ident, enum_ident)
})
.collect::<Vec<_>>();
let enum_variants = insts
.iter()
.map(|(_, type_ident, enum_ident)| quote!(#enum_ident(#type_ident),));
let encode_match = insts.iter().map(
|(_, _, enum_ident)| quote!(Self::#enum_ident(inst) => InstEncoding::encode(inst, writer),),
);
let decode_match = insts.iter().map(|(inst, type_ident, enum_ident)| {
let opcode = inst.opcode;
quote!(#opcode => Self::#enum_ident(<#type_ident as InstEncoding>::decode(reader)?),)
});
let dis_match = insts.iter().map(
|(_, _, enum_ident)| quote!(Self::#enum_ident(inst) => InstEncoding::dis_fmt(inst, f, ctx),),
);
let from_impls = insts.iter().map(|(_, type_ident, enum_ident)| {
quote! {
impl From<#type_ident> for #name {
fn from(inst: #type_ident) -> Self {
Self::#enum_ident(inst)
}
}
}
});
writer.write_module(
"inst_set",
quote! {
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum #name {
#(#enum_variants)*
}

impl InstEncoding for #name {
fn name() -> &'static str {
stringify!(#name)
}

fn encode(&self, writer: &mut impl WordWriter) -> Result<(), EncodeError> {
profiling::function_scope!();
match self {
#(#encode_match)*
}
}

fn decode(reader: InstReader<'_>) -> Result<Self, DecodeError> {
profiling::function_scope!();
let opcode = reader.opcode();
Ok(match opcode {
#(#decode_match)*
_ => return Err(DecodeErrorKind::UnknownOpCode { opcode }.into()),
})
}

fn dis_fmt(&self, f: &mut Formatter<'_>, ctx: &DisContext) -> std::fmt::Result {
profiling::function_scope!();
match self {
#(#dis_match)*
}
}
}

#(#from_impls)*
},
)
}
82 changes: 82 additions & 0 deletions crates/grammar-parser/src/codegen/inst_set.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use crate::codegen::{CodegenOptions, GrammarWriter};
use crate::parse::{Grammar, InstMeta};
use quote::{format_ident, quote};

pub fn write_inst_enum(
writer: &mut GrammarWriter,
grammar: &Grammar<'_>,
opt: &CodegenOptions<'_>,
) -> anyhow::Result<()> {
let name = format_ident!("{}InstSet", opt.name_suffix_type);
let insts = grammar
.insts
.iter()
.map(|inst| {
let type_ident = InstMeta::type_ident(&inst.opname);
let enum_ident = InstMeta::enum_ident(&inst.opname);
(inst, type_ident, enum_ident)
})
.collect::<Vec<_>>();
let enum_variants = insts
.iter()
.map(|(_, type_ident, enum_ident)| quote!(#enum_ident(#type_ident),));
let encode_match = insts.iter().map(
|(_, _, enum_ident)| quote!(Self::#enum_ident(inst) => InstEncoding::encode(inst, writer),),
);
let decode_match = insts.iter().map(|(inst, type_ident, enum_ident)| {
let opcode = inst.opcode;
quote!(#opcode => Self::#enum_ident(<#type_ident as InstEncoding>::decode(reader)?),)
});
let dis_match = insts.iter().map(
|(_, _, enum_ident)| quote!(Self::#enum_ident(inst) => InstEncoding::dis_fmt(inst, f, ctx),),
);
let from_impls = insts.iter().map(|(_, type_ident, enum_ident)| {
quote! {
impl From<#type_ident> for #name {
fn from(inst: #type_ident) -> Self {
Self::#enum_ident(inst)
}
}
}
});
writer.write_module(
"inst_set",
quote! {
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum #name {
#(#enum_variants)*
}

impl InstEncoding for #name {
fn name() -> &'static str {
stringify!(#name)
}

fn encode(&self, writer: &mut impl WordWriter) -> Result<(), EncodeError> {
profiling::function_scope!();
match self {
#(#encode_match)*
}
}

fn decode(reader: InstReader<'_>) -> Result<Self, DecodeError> {
profiling::function_scope!();
let opcode = reader.opcode();
Ok(match opcode {
#(#decode_match)*
_ => return Err(DecodeErrorKind::UnknownOpCode { opcode }.into()),
})
}

fn dis_fmt(&self, f: &mut Formatter<'_>, ctx: &DisContext) -> std::fmt::Result {
profiling::function_scope!();
match self {
#(#dis_match)*
}
}
}

#(#from_impls)*
},
)
}
3 changes: 2 additions & 1 deletion crates/grammar-parser/src/codegen/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod emit;
mod instructions;
mod inst;
mod inst_set;
mod modules;
mod operands;
mod options;
Expand Down
3 changes: 2 additions & 1 deletion crates/grammar-parser/src/codegen/modules.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::codegen::instructions::{write_inst, write_inst_enum};
use crate::codegen::inst::write_inst;
use crate::codegen::inst_set::write_inst_enum;
use crate::codegen::operands::write_operands;
use crate::codegen::options::CodegenOptions;
use crate::codegen::{EmitRef, GrammarWriter};
Expand Down
7 changes: 6 additions & 1 deletion crates/rspirv2-types/src/operand/literal_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ pub const OPERAND_KIND_LITERAL_CONTEXT_DEPENDENT_NUMBER: OperandKind = OperandKi
/// [`Instruction`]: crate::meta::InstMeta
/// [`Quantifier::ZeroOrMore`]: `crate::meta::Quantifier`
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct LiteralConst(SmallVec<[Word; 2]>);
pub struct LiteralConst(SmallVec<[Word; 4]>);

const _: () = {
// usually 2 Words should be sufficient to represent 64bit values, but 4 words is free:
assert!(size_of::<LiteralConst>() == size_of::<SmallVec<[Word; 2]>>());
};

pub type LiteralContextDependentNumber = LiteralConst;

Expand Down
Loading