1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 // Copyright 2018 Jacob Lifshay
4 use proc_macro2::TokenStream;
6 use serde::de::{self, Deserialize, Deserializer};
10 use std::num::ParseIntError;
11 use util::NameFormat::*;
12 use util::WordIterator;
14 #[derive(Copy, Clone)]
15 pub struct QuotedInteger<T>(pub T);
17 pub trait QuotedIntegerProperties: Sized {
18 const DIGIT_COUNT: usize;
19 fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError>;
22 impl QuotedIntegerProperties for QuotedInteger<u16> {
23 const DIGIT_COUNT: usize = 4;
24 fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
25 Ok(QuotedInteger(u16::from_str_radix(src, radix)?))
29 impl QuotedIntegerProperties for QuotedInteger<u32> {
30 const DIGIT_COUNT: usize = 8;
31 fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
32 Ok(QuotedInteger(u32::from_str_radix(src, radix)?))
36 impl<T: ToTokens> ToTokens for QuotedInteger<T> {
37 fn to_tokens(&self, tokens: &mut TokenStream) {
38 self.0.to_tokens(tokens)
42 impl fmt::Display for QuotedInteger<u16> {
43 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44 write!(f, "{:#06X}", self.0)
48 impl fmt::Display for QuotedInteger<u32> {
49 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
50 write!(f, "{:#010X}", self.0)
54 impl<T> fmt::Debug for QuotedInteger<T>
56 Self: fmt::Display + Copy,
58 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
59 struct DisplayQuotedInteger<T>(QuotedInteger<T>);
60 impl<T> fmt::Debug for DisplayQuotedInteger<T>
62 QuotedInteger<T>: fmt::Display,
64 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65 fmt::Display::fmt(&self.0, f)
68 f.debug_tuple("QuotedInteger")
69 .field(&DisplayQuotedInteger(*self))
74 impl<'de, T> Deserialize<'de> for QuotedInteger<T>
76 Self: QuotedIntegerProperties,
78 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
79 let s = String::deserialize(deserializer)?;
81 if !s.starts_with(prefix) {
82 return Err(de::Error::custom(format!(
83 "invalid quoted integer -- must start with {:?}",
87 let digits = s.split_at(prefix.len()).1;
89 if digits.find(|c: char| !c.is_digit(radix)).is_some() {
90 return Err(de::Error::custom(
91 "invalid quoted integer -- not a hexadecimal digit",
94 if digits.len() != Self::DIGIT_COUNT {
95 return Err(de::Error::custom(
96 "invalid quoted integer -- wrong number of hex digits",
99 Ok(Self::from_str_radix(digits, radix).unwrap())
103 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
104 pub enum SPIRVVersion {
107 AtLeast { major: u32, minor: u32 },
110 impl Default for SPIRVVersion {
111 fn default() -> Self {
116 impl<'de> Deserialize<'de> for SPIRVVersion {
117 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
118 let s = String::deserialize(deserializer)?;
120 return Ok(SPIRVVersion::None);
124 .ok_or_else(|| de::Error::custom("invalid SPIR-V version -- no decimal place"))?;
125 let (major_digits, minor_digits) = s.split_at(dot_pos);
126 let minor_digits = minor_digits.split_at(1).1;
127 let parse_digits = |digits: &str| -> Result<u32, D::Error> {
129 return Err(de::Error::custom(
130 "invalid SPIR-V version -- expected a decimal digit",
133 if digits.find(|c: char| !c.is_ascii_digit()).is_some() {
134 return Err(de::Error::custom(
135 "invalid SPIR-V version -- expected a decimal digit",
138 if digits.len() > 5 {
139 return Err(de::Error::custom(
140 "invalid SPIR-V version -- too many digits",
143 Ok(digits.parse().unwrap())
145 let major = parse_digits(major_digits)?;
146 let minor = parse_digits(minor_digits)?;
147 Ok(SPIRVVersion::AtLeast { major, minor })
151 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
152 pub enum Quantifier {
153 #[serde(rename = "?")]
155 #[serde(rename = "*")]
159 #[derive(Clone, Deserialize, Debug)]
160 #[serde(deny_unknown_fields)]
161 pub struct InstructionOperand {
163 pub name: Option<String>,
164 pub quantifier: Option<Quantifier>,
167 impl InstructionOperand {
168 pub fn fixup(&mut self) -> Result<(), ::Error> {
169 if self.name.is_none() {
172 .name_from_words(WordIterator::new(self.kind.as_ref()))
173 .ok_or(::Error::DeducingNameForInstructionOperandFailed)?,
176 self.kind.set_bit_width(BitWidth::Bits32);
181 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
182 pub enum InstructionName {
220 OpInBoundsAccessChain,
221 OpInBoundsPtrAccessChain,
242 OpShiftRightArithmetic,
255 pub const OP_SPEC_CONSTANT_OP_SUPPORTED_INSTRUCTIONS: &[InstructionName] = &[
256 InstructionName::OpAccessChain,
257 InstructionName::OpBitcast,
258 InstructionName::OpBitwiseAnd,
259 InstructionName::OpBitwiseOr,
260 InstructionName::OpBitwiseXor,
261 InstructionName::OpCompositeExtract,
262 InstructionName::OpCompositeInsert,
263 InstructionName::OpConvertFToS,
264 InstructionName::OpConvertFToU,
265 InstructionName::OpConvertPtrToU,
266 InstructionName::OpConvertSToF,
267 InstructionName::OpConvertUToF,
268 InstructionName::OpConvertUToPtr,
269 InstructionName::OpFAdd,
270 InstructionName::OpFConvert,
271 InstructionName::OpFDiv,
272 InstructionName::OpFMod,
273 InstructionName::OpFMul,
274 InstructionName::OpFNegate,
275 InstructionName::OpFRem,
276 InstructionName::OpFSub,
277 InstructionName::OpGenericCastToPtr,
278 InstructionName::OpIAdd,
279 InstructionName::OpIEqual,
280 InstructionName::OpIMul,
281 InstructionName::OpINotEqual,
282 InstructionName::OpISub,
283 InstructionName::OpInBoundsAccessChain,
284 InstructionName::OpInBoundsPtrAccessChain,
285 InstructionName::OpLogicalAnd,
286 InstructionName::OpLogicalEqual,
287 InstructionName::OpLogicalNot,
288 InstructionName::OpLogicalNotEqual,
289 InstructionName::OpLogicalOr,
290 InstructionName::OpNot,
291 InstructionName::OpPtrAccessChain,
292 InstructionName::OpPtrCastToGeneric,
293 InstructionName::OpQuantizeToF16,
294 InstructionName::OpSConvert,
295 InstructionName::OpSDiv,
296 InstructionName::OpSGreaterThan,
297 InstructionName::OpSGreaterThanEqual,
298 InstructionName::OpSLessThan,
299 InstructionName::OpSLessThanEqual,
300 InstructionName::OpSMod,
301 InstructionName::OpSNegate,
302 InstructionName::OpSRem,
303 InstructionName::OpSelect,
304 InstructionName::OpShiftLeftLogical,
305 InstructionName::OpShiftRightArithmetic,
306 InstructionName::OpShiftRightLogical,
307 InstructionName::OpUConvert,
308 InstructionName::OpUDiv,
309 InstructionName::OpUGreaterThan,
310 InstructionName::OpUGreaterThanEqual,
311 InstructionName::OpULessThan,
312 InstructionName::OpULessThanEqual,
313 InstructionName::OpUMod,
314 InstructionName::OpVectorShuffle,
317 impl Default for InstructionName {
318 fn default() -> Self {
319 InstructionName::Other(String::new())
323 impl From<String> for InstructionName {
324 fn from(v: String) -> Self {
326 "OpSwitch" => return InstructionName::OpSwitch,
327 "OpConstant" => return InstructionName::OpConstant,
328 "OpSpecConstant" => return InstructionName::OpSpecConstant,
329 "OpSpecConstantOp" => return InstructionName::OpSpecConstantOp,
330 "OpAccessChain" => return InstructionName::OpAccessChain,
331 "OpBitcast" => return InstructionName::OpBitcast,
332 "OpBitwiseAnd" => return InstructionName::OpBitwiseAnd,
333 "OpBitwiseOr" => return InstructionName::OpBitwiseOr,
334 "OpBitwiseXor" => return InstructionName::OpBitwiseXor,
335 "OpCompositeExtract" => return InstructionName::OpCompositeExtract,
336 "OpCompositeInsert" => return InstructionName::OpCompositeInsert,
337 "OpConvertFToS" => return InstructionName::OpConvertFToS,
338 "OpConvertFToU" => return InstructionName::OpConvertFToU,
339 "OpConvertPtrToU" => return InstructionName::OpConvertPtrToU,
340 "OpConvertSToF" => return InstructionName::OpConvertSToF,
341 "OpConvertUToF" => return InstructionName::OpConvertUToF,
342 "OpConvertUToPtr" => return InstructionName::OpConvertUToPtr,
343 "OpFAdd" => return InstructionName::OpFAdd,
344 "OpFConvert" => return InstructionName::OpFConvert,
345 "OpFDiv" => return InstructionName::OpFDiv,
346 "OpFMod" => return InstructionName::OpFMod,
347 "OpFMul" => return InstructionName::OpFMul,
348 "OpFNegate" => return InstructionName::OpFNegate,
349 "OpFRem" => return InstructionName::OpFRem,
350 "OpFSub" => return InstructionName::OpFSub,
351 "OpGenericCastToPtr" => return InstructionName::OpGenericCastToPtr,
352 "OpIAdd" => return InstructionName::OpIAdd,
353 "OpIEqual" => return InstructionName::OpIEqual,
354 "OpIMul" => return InstructionName::OpIMul,
355 "OpINotEqual" => return InstructionName::OpINotEqual,
356 "OpISub" => return InstructionName::OpISub,
357 "OpInBoundsAccessChain" => return InstructionName::OpInBoundsAccessChain,
358 "OpInBoundsPtrAccessChain" => return InstructionName::OpInBoundsPtrAccessChain,
359 "OpLogicalAnd" => return InstructionName::OpLogicalAnd,
360 "OpLogicalEqual" => return InstructionName::OpLogicalEqual,
361 "OpLogicalNot" => return InstructionName::OpLogicalNot,
362 "OpLogicalNotEqual" => return InstructionName::OpLogicalNotEqual,
363 "OpLogicalOr" => return InstructionName::OpLogicalOr,
364 "OpNot" => return InstructionName::OpNot,
365 "OpPtrAccessChain" => return InstructionName::OpPtrAccessChain,
366 "OpPtrCastToGeneric" => return InstructionName::OpPtrCastToGeneric,
367 "OpQuantizeToF16" => return InstructionName::OpQuantizeToF16,
368 "OpSConvert" => return InstructionName::OpSConvert,
369 "OpSDiv" => return InstructionName::OpSDiv,
370 "OpSGreaterThan" => return InstructionName::OpSGreaterThan,
371 "OpSGreaterThanEqual" => return InstructionName::OpSGreaterThanEqual,
372 "OpSLessThan" => return InstructionName::OpSLessThan,
373 "OpSLessThanEqual" => return InstructionName::OpSLessThanEqual,
374 "OpSMod" => return InstructionName::OpSMod,
375 "OpSNegate" => return InstructionName::OpSNegate,
376 "OpSRem" => return InstructionName::OpSRem,
377 "OpSelect" => return InstructionName::OpSelect,
378 "OpShiftLeftLogical" => return InstructionName::OpShiftLeftLogical,
379 "OpShiftRightArithmetic" => return InstructionName::OpShiftRightArithmetic,
380 "OpShiftRightLogical" => return InstructionName::OpShiftRightLogical,
381 "OpUConvert" => return InstructionName::OpUConvert,
382 "OpUDiv" => return InstructionName::OpUDiv,
383 "OpUGreaterThan" => return InstructionName::OpUGreaterThan,
384 "OpUGreaterThanEqual" => return InstructionName::OpUGreaterThanEqual,
385 "OpULessThan" => return InstructionName::OpULessThan,
386 "OpULessThanEqual" => return InstructionName::OpULessThanEqual,
387 "OpUMod" => return InstructionName::OpUMod,
388 "OpVectorShuffle" => return InstructionName::OpVectorShuffle,
391 InstructionName::Other(v)
395 impl AsRef<str> for InstructionName {
396 fn as_ref(&self) -> &str {
398 InstructionName::OpSwitch => "OpSwitch",
399 InstructionName::OpSwitch32 => "OpSwitch32",
400 InstructionName::OpSwitch64 => "OpSwitch64",
401 InstructionName::OpConstant => "OpConstant",
402 InstructionName::OpConstant32 => "OpConstant32",
403 InstructionName::OpConstant64 => "OpConstant64",
404 InstructionName::OpSpecConstant => "OpSpecConstant",
405 InstructionName::OpSpecConstant32 => "OpSpecConstant32",
406 InstructionName::OpSpecConstant64 => "OpSpecConstant64",
407 InstructionName::OpSpecConstantOp => "OpSpecConstantOp",
408 InstructionName::OpAccessChain => "OpAccessChain",
409 InstructionName::OpBitcast => "OpBitcast",
410 InstructionName::OpBitwiseAnd => "OpBitwiseAnd",
411 InstructionName::OpBitwiseOr => "OpBitwiseOr",
412 InstructionName::OpBitwiseXor => "OpBitwiseXor",
413 InstructionName::OpCompositeExtract => "OpCompositeExtract",
414 InstructionName::OpCompositeInsert => "OpCompositeInsert",
415 InstructionName::OpConvertFToS => "OpConvertFToS",
416 InstructionName::OpConvertFToU => "OpConvertFToU",
417 InstructionName::OpConvertPtrToU => "OpConvertPtrToU",
418 InstructionName::OpConvertSToF => "OpConvertSToF",
419 InstructionName::OpConvertUToF => "OpConvertUToF",
420 InstructionName::OpConvertUToPtr => "OpConvertUToPtr",
421 InstructionName::OpFAdd => "OpFAdd",
422 InstructionName::OpFConvert => "OpFConvert",
423 InstructionName::OpFDiv => "OpFDiv",
424 InstructionName::OpFMod => "OpFMod",
425 InstructionName::OpFMul => "OpFMul",
426 InstructionName::OpFNegate => "OpFNegate",
427 InstructionName::OpFRem => "OpFRem",
428 InstructionName::OpFSub => "OpFSub",
429 InstructionName::OpGenericCastToPtr => "OpGenericCastToPtr",
430 InstructionName::OpIAdd => "OpIAdd",
431 InstructionName::OpIEqual => "OpIEqual",
432 InstructionName::OpIMul => "OpIMul",
433 InstructionName::OpINotEqual => "OpINotEqual",
434 InstructionName::OpISub => "OpISub",
435 InstructionName::OpInBoundsAccessChain => "OpInBoundsAccessChain",
436 InstructionName::OpInBoundsPtrAccessChain => "OpInBoundsPtrAccessChain",
437 InstructionName::OpLogicalAnd => "OpLogicalAnd",
438 InstructionName::OpLogicalEqual => "OpLogicalEqual",
439 InstructionName::OpLogicalNot => "OpLogicalNot",
440 InstructionName::OpLogicalNotEqual => "OpLogicalNotEqual",
441 InstructionName::OpLogicalOr => "OpLogicalOr",
442 InstructionName::OpNot => "OpNot",
443 InstructionName::OpPtrAccessChain => "OpPtrAccessChain",
444 InstructionName::OpPtrCastToGeneric => "OpPtrCastToGeneric",
445 InstructionName::OpQuantizeToF16 => "OpQuantizeToF16",
446 InstructionName::OpSConvert => "OpSConvert",
447 InstructionName::OpSDiv => "OpSDiv",
448 InstructionName::OpSGreaterThan => "OpSGreaterThan",
449 InstructionName::OpSGreaterThanEqual => "OpSGreaterThanEqual",
450 InstructionName::OpSLessThan => "OpSLessThan",
451 InstructionName::OpSLessThanEqual => "OpSLessThanEqual",
452 InstructionName::OpSMod => "OpSMod",
453 InstructionName::OpSNegate => "OpSNegate",
454 InstructionName::OpSRem => "OpSRem",
455 InstructionName::OpSelect => "OpSelect",
456 InstructionName::OpShiftLeftLogical => "OpShiftLeftLogical",
457 InstructionName::OpShiftRightArithmetic => "OpShiftRightArithmetic",
458 InstructionName::OpShiftRightLogical => "OpShiftRightLogical",
459 InstructionName::OpUConvert => "OpUConvert",
460 InstructionName::OpUDiv => "OpUDiv",
461 InstructionName::OpUGreaterThan => "OpUGreaterThan",
462 InstructionName::OpUGreaterThanEqual => "OpUGreaterThanEqual",
463 InstructionName::OpULessThan => "OpULessThan",
464 InstructionName::OpULessThanEqual => "OpULessThanEqual",
465 InstructionName::OpUMod => "OpUMod",
466 InstructionName::OpVectorShuffle => "OpVectorShuffle",
467 InstructionName::Other(v) => v,
472 impl<'de> Deserialize<'de> for InstructionName {
473 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
474 Ok(Self::from(String::deserialize(deserializer)?))
478 #[derive(Clone, Deserialize, Debug)]
479 #[serde(deny_unknown_fields)]
480 pub struct Instruction {
481 pub opname: InstructionName,
484 pub operands: Vec<InstructionOperand>,
486 pub capabilities: Vec<String>,
488 pub extensions: Vec<String>,
490 pub version: SPIRVVersion,
494 pub fn fixup(&mut self) -> Result<(), ::Error> {
495 for operand in self.operands.iter_mut() {
502 #[derive(Deserialize, Debug)]
503 #[serde(deny_unknown_fields)]
504 pub struct ExtensionInstruction {
508 pub operands: Vec<InstructionOperand>,
510 pub capabilities: Vec<String>,
513 impl ExtensionInstruction {
514 pub fn fixup(&mut self) -> Result<(), ::Error> {
515 for operand in self.operands.iter_mut() {
522 #[derive(Deserialize, Debug, Default)]
523 #[serde(deny_unknown_fields)]
524 pub struct BitwiseEnumerantParameter {
528 impl BitwiseEnumerantParameter {
529 pub fn fixup(&mut self) -> Result<(), ::Error> {
530 self.kind.set_bit_width(BitWidth::Bits32);
535 #[derive(Deserialize, Debug, Default)]
536 #[serde(deny_unknown_fields)]
537 pub struct ValueEnumerantParameter {
539 pub name: Option<String>,
542 impl ValueEnumerantParameter {
543 pub fn fixup(&mut self) -> Result<(), ::Error> {
544 if self.name.is_none() {
547 .name_from_words(WordIterator::new(self.kind.as_ref()))
548 .ok_or(::Error::DeducingNameForEnumerantParameterFailed)?,
551 self.kind.set_bit_width(BitWidth::Bits32);
556 #[derive(Deserialize, Debug)]
557 #[serde(deny_unknown_fields)]
558 pub struct Enumerant<Value, EnumerantParameter> {
559 pub enumerant: String,
562 pub capabilities: Vec<String>,
564 pub parameters: Vec<EnumerantParameter>,
566 pub extensions: Vec<String>,
568 pub version: SPIRVVersion,
571 impl Enumerant<u32, ValueEnumerantParameter> {
572 pub fn fixup(&mut self) -> Result<(), ::Error> {
573 for parameter in self.parameters.iter_mut() {
580 impl Enumerant<QuotedInteger<u16>, BitwiseEnumerantParameter> {
581 pub fn fixup(&mut self) -> Result<(), ::Error> {
582 for parameter in self.parameters.iter_mut() {
589 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
591 Literal(LiteralKind),
593 PairLiteralIntegerIdRef,
594 PairLiteralInteger32IdRef,
595 PairLiteralInteger64IdRef,
600 pub fn set_bit_width(&mut self, bit_width: BitWidth) {
601 match (self, bit_width) {
602 (Kind::Literal(literal), bit_width) => literal.set_bit_width(bit_width),
603 (this @ Kind::PairLiteralIntegerIdRef, BitWidth::Bits32) => {
604 *this = Kind::PairLiteralInteger32IdRef
606 (this @ Kind::PairLiteralIntegerIdRef, BitWidth::Bits64) => {
607 *this = Kind::PairLiteralInteger64IdRef
610 | (Kind::PairLiteralInteger32IdRef, _)
611 | (Kind::PairLiteralInteger64IdRef, _)
612 | (Kind::Other(_), _) => {}
617 impl Default for Kind {
618 fn default() -> Self {
619 Kind::Other(String::new())
623 impl<'a> From<Cow<'a, str>> for Kind {
624 fn from(v: Cow<'a, str>) -> Self {
625 if let Some(v) = LiteralKind::from_str(&v) {
627 } else if v == "IdRef" {
629 } else if v == "PairLiteralIntegerIdRef" {
630 Kind::PairLiteralIntegerIdRef
632 Kind::Other(v.into_owned())
637 impl<'a> From<&'a str> for Kind {
638 fn from(v: &'a str) -> Self {
639 Kind::from(Cow::Borrowed(v))
643 impl From<String> for Kind {
644 fn from(v: String) -> Self {
645 Kind::from(Cow::Owned(v))
649 impl AsRef<str> for Kind {
650 fn as_ref(&self) -> &str {
652 Kind::Literal(v) => v.as_ref(),
653 Kind::IdRef => "IdRef",
654 Kind::PairLiteralIntegerIdRef => "PairLiteralIntegerIdRef",
655 Kind::PairLiteralInteger32IdRef => "PairLiteralInteger32IdRef",
656 Kind::PairLiteralInteger64IdRef => "PairLiteralInteger64IdRef",
662 impl<'de> Deserialize<'de> for Kind {
663 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
664 Ok(Self::from(String::deserialize(deserializer)?))
668 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
669 pub enum LiteralKind {
671 #[serde(skip_deserializing)]
673 #[serde(skip_deserializing)]
676 LiteralContextDependentNumber,
677 #[serde(skip_deserializing)]
678 LiteralContextDependentNumber32,
679 #[serde(skip_deserializing)]
680 LiteralContextDependentNumber64,
681 LiteralExtInstInteger,
682 LiteralSpecConstantOpInteger,
685 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
692 pub fn from_str<T: AsRef<str>>(v: T) -> Option<Self> {
694 "LiteralInteger" => Some(LiteralKind::LiteralInteger),
695 "LiteralString" => Some(LiteralKind::LiteralString),
696 "LiteralContextDependentNumber" => Some(LiteralKind::LiteralContextDependentNumber),
697 "LiteralExtInstInteger" => Some(LiteralKind::LiteralExtInstInteger),
698 "LiteralSpecConstantOpInteger" => Some(LiteralKind::LiteralSpecConstantOpInteger),
702 pub fn set_bit_width(&mut self, bit_width: BitWidth) {
703 *self = match (*self, bit_width) {
704 (LiteralKind::LiteralInteger, BitWidth::Bits32) => LiteralKind::LiteralInteger32,
705 (LiteralKind::LiteralInteger, BitWidth::Bits64) => LiteralKind::LiteralInteger64,
706 (LiteralKind::LiteralContextDependentNumber, BitWidth::Bits32) => {
707 LiteralKind::LiteralContextDependentNumber32
709 (LiteralKind::LiteralContextDependentNumber, BitWidth::Bits64) => {
710 LiteralKind::LiteralContextDependentNumber64
712 (LiteralKind::LiteralInteger32, _)
713 | (LiteralKind::LiteralInteger64, _)
714 | (LiteralKind::LiteralString, _)
715 | (LiteralKind::LiteralContextDependentNumber32, _)
716 | (LiteralKind::LiteralContextDependentNumber64, _)
717 | (LiteralKind::LiteralExtInstInteger, _)
718 | (LiteralKind::LiteralSpecConstantOpInteger, _) => return,
723 impl AsRef<str> for LiteralKind {
724 fn as_ref(&self) -> &str {
726 LiteralKind::LiteralInteger => "LiteralInteger",
727 LiteralKind::LiteralInteger32 => "LiteralInteger32",
728 LiteralKind::LiteralInteger64 => "LiteralInteger64",
729 LiteralKind::LiteralString => "LiteralString",
730 LiteralKind::LiteralContextDependentNumber => "LiteralContextDependentNumber",
731 LiteralKind::LiteralContextDependentNumber32 => "LiteralContextDependentNumber32",
732 LiteralKind::LiteralContextDependentNumber64 => "LiteralContextDependentNumber64",
733 LiteralKind::LiteralExtInstInteger => "LiteralExtInstInteger",
734 LiteralKind::LiteralSpecConstantOpInteger => "LiteralSpecConstantOpInteger",
739 #[derive(Deserialize, Debug)]
740 #[serde(deny_unknown_fields)]
741 #[serde(tag = "category")]
742 pub enum OperandKind {
745 enumerants: Vec<Enumerant<QuotedInteger<u16>, BitwiseEnumerantParameter>>,
749 enumerants: Vec<Enumerant<u32, ValueEnumerantParameter>>,
765 #[derive(Deserialize, Debug)]
766 #[serde(deny_unknown_fields)]
767 pub struct CoreGrammar {
768 pub copyright: Vec<String>,
769 pub magic_number: QuotedInteger<u32>,
770 pub major_version: u32,
771 pub minor_version: u32,
773 pub instructions: Vec<Instruction>,
774 pub operand_kinds: Vec<OperandKind>,
778 pub fn fixup(&mut self) -> Result<(), ::Error> {
779 let instructions = mem::replace(&mut self.instructions, Vec::new());
780 for mut instruction in instructions {
781 if instruction.version == SPIRVVersion::None {
784 let (opname_32, opname_64) = match instruction.opname {
785 InstructionName::OpSwitch => {
786 (InstructionName::OpSwitch32, InstructionName::OpSwitch64)
788 InstructionName::OpConstant => {
789 (InstructionName::OpConstant32, InstructionName::OpConstant64)
791 InstructionName::OpSpecConstant => (
792 InstructionName::OpSpecConstant32,
793 InstructionName::OpSpecConstant64,
796 instruction.opname = opname;
797 instruction.fixup()?;
798 self.instructions.push(instruction);
802 instruction.opname = InstructionName::default();
803 let mut op_32 = Instruction {
805 ..instruction.clone()
807 for operand in op_32.operands.iter_mut() {
808 operand.kind.set_bit_width(BitWidth::Bits32);
811 self.instructions.push(op_32);
812 let mut op_64 = Instruction {
816 for operand in op_64.operands.iter_mut() {
817 operand.kind.set_bit_width(BitWidth::Bits64);
820 self.instructions.push(op_64);
822 let operand_kinds = mem::replace(&mut self.operand_kinds, Vec::new());
823 for operand_kind in operand_kinds {
825 OperandKind::BitEnum {
829 enumerants.retain(|enumerant| enumerant.version != SPIRVVersion::None);
830 for enumerant in enumerants.iter_mut() {
834 .push(OperandKind::BitEnum { kind, enumerants });
836 OperandKind::ValueEnum {
840 enumerants.retain(|enumerant| enumerant.version != SPIRVVersion::None);
841 for enumerant in enumerants.iter_mut() {
845 .push(OperandKind::ValueEnum { kind, enumerants });
847 OperandKind::Composite { kind, mut bases } => match kind {
848 Kind::PairLiteralIntegerIdRef => {
849 let mut bases_32 = bases.clone();
850 let mut bases_64 = bases;
851 for base in bases_32.iter_mut() {
852 base.set_bit_width(BitWidth::Bits32);
854 for base in bases_64.iter_mut() {
855 base.set_bit_width(BitWidth::Bits64);
857 self.operand_kinds.push(OperandKind::Composite {
858 kind: Kind::PairLiteralInteger32IdRef,
861 self.operand_kinds.push(OperandKind::Composite {
862 kind: Kind::PairLiteralInteger64IdRef,
867 for base in bases.iter_mut() {
868 base.set_bit_width(BitWidth::Bits32);
871 .push(OperandKind::Composite { kind, bases });
874 OperandKind::Literal { kind, doc } => match kind {
875 LiteralKind::LiteralInteger => {
876 self.operand_kinds.push(OperandKind::Literal {
877 kind: LiteralKind::LiteralInteger32,
880 self.operand_kinds.push(OperandKind::Literal {
881 kind: LiteralKind::LiteralInteger64,
885 LiteralKind::LiteralContextDependentNumber => {
886 self.operand_kinds.push(OperandKind::Literal {
887 kind: LiteralKind::LiteralContextDependentNumber32,
890 self.operand_kinds.push(OperandKind::Literal {
891 kind: LiteralKind::LiteralContextDependentNumber64,
895 kind => self.operand_kinds.push(OperandKind::Literal { kind, doc }),
897 OperandKind::Id { kind, doc } => {
898 self.operand_kinds.push(OperandKind::Id { kind, doc })
906 #[derive(Deserialize, Debug)]
907 #[serde(deny_unknown_fields)]
908 pub struct ExtensionInstructionSet {
909 pub copyright: Vec<String>,
912 pub instructions: Vec<ExtensionInstruction>,
915 impl ExtensionInstructionSet {
916 pub fn fixup(&mut self) -> Result<(), ::Error> {
917 for instruction in self.instructions.iter_mut() {
918 instruction.fixup()?;