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 util::NameFormat::*;
11 use util::WordIterator;
13 #[derive(Copy, Clone)]
14 pub struct QuotedInteger(pub u32);
16 impl ToTokens for QuotedInteger {
17 fn to_tokens(&self, tokens: &mut TokenStream) {
18 self.0.to_tokens(tokens)
22 impl fmt::Display for QuotedInteger {
23 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24 write!(f, "{:#06X}", self.0)
28 impl fmt::Debug for QuotedInteger {
29 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
30 struct DisplayQuotedInteger(QuotedInteger);
31 impl fmt::Debug for DisplayQuotedInteger {
32 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
33 fmt::Display::fmt(&self.0, f)
36 f.debug_tuple("QuotedInteger")
37 .field(&DisplayQuotedInteger(*self))
42 impl<'de> Deserialize<'de> for QuotedInteger {
43 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
44 let s = String::deserialize(deserializer)?;
46 if !s.starts_with(prefix) {
47 return Err(de::Error::custom(format!(
48 "invalid quoted integer -- must start with {:?}",
52 let digits = s.split_at(prefix.len()).1;
54 if digits.find(|c: char| !c.is_digit(radix)).is_some() {
55 return Err(de::Error::custom(
56 "invalid quoted integer -- not a hexadecimal digit",
60 return Err(de::Error::custom(
61 "invalid quoted integer -- too many hexadecimal digits",
64 Ok(QuotedInteger(u32::from_str_radix(digits, radix).unwrap()))
68 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
69 pub enum SPIRVVersion {
72 AtLeast { major: u32, minor: u32 },
75 impl Default for SPIRVVersion {
76 fn default() -> Self {
81 impl<'de> Deserialize<'de> for SPIRVVersion {
82 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
83 let s = String::deserialize(deserializer)?;
85 return Ok(SPIRVVersion::None);
89 .ok_or_else(|| de::Error::custom("invalid SPIR-V version -- no decimal place"))?;
90 let (major_digits, minor_digits) = s.split_at(dot_pos);
91 let minor_digits = minor_digits.split_at(1).1;
92 let parse_digits = |digits: &str| -> Result<u32, D::Error> {
94 return Err(de::Error::custom(
95 "invalid SPIR-V version -- expected a decimal digit",
98 if digits.find(|c: char| !c.is_ascii_digit()).is_some() {
99 return Err(de::Error::custom(
100 "invalid SPIR-V version -- expected a decimal digit",
103 if digits.len() > 5 {
104 return Err(de::Error::custom(
105 "invalid SPIR-V version -- too many digits",
108 Ok(digits.parse().unwrap())
110 let major = parse_digits(major_digits)?;
111 let minor = parse_digits(minor_digits)?;
112 Ok(SPIRVVersion::AtLeast { major, minor })
116 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
117 pub enum Quantifier {
118 #[serde(rename = "?")]
120 #[serde(rename = "*")]
124 #[derive(Clone, Deserialize, Debug)]
125 #[serde(deny_unknown_fields)]
126 pub struct InstructionOperand {
128 pub name: Option<String>,
129 pub quantifier: Option<Quantifier>,
132 impl InstructionOperand {
133 pub fn fixup(&mut self) -> Result<(), ::Error> {
134 if let Some(name) = self.name.take() {
135 let substitute_name = match &*name {
136 "'Member 0 type', +\n'member 1 type', +\n..." => Some("Member Types"),
137 "'Parameter 0 Type', +\n'Parameter 1 Type', +\n..." => Some("Parameter Types"),
138 "'Argument 0', +\n'Argument 1', +\n..." => Some("Arguments"),
139 "'Operand 1', +\n'Operand 2', +\n..." => Some("Operands"),
142 self.name = Some(substitute_name.map(String::from).unwrap_or(name));
146 .name_from_words(WordIterator::new(self.kind.as_ref()))
147 .ok_or(::Error::DeducingNameForInstructionOperandFailed)?,
150 self.kind.set_bit_width(BitWidth::Bits32);
155 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
156 pub enum InstructionName {
194 OpInBoundsAccessChain,
195 OpInBoundsPtrAccessChain,
216 OpShiftRightArithmetic,
231 pub const OP_SPEC_CONSTANT_OP_SUPPORTED_INSTRUCTIONS: &[InstructionName] = &[
232 InstructionName::OpAccessChain,
233 InstructionName::OpBitcast,
234 InstructionName::OpBitwiseAnd,
235 InstructionName::OpBitwiseOr,
236 InstructionName::OpBitwiseXor,
237 InstructionName::OpCompositeExtract,
238 InstructionName::OpCompositeInsert,
239 InstructionName::OpConvertFToS,
240 InstructionName::OpConvertFToU,
241 InstructionName::OpConvertPtrToU,
242 InstructionName::OpConvertSToF,
243 InstructionName::OpConvertUToF,
244 InstructionName::OpConvertUToPtr,
245 InstructionName::OpFAdd,
246 InstructionName::OpFConvert,
247 InstructionName::OpFDiv,
248 InstructionName::OpFMod,
249 InstructionName::OpFMul,
250 InstructionName::OpFNegate,
251 InstructionName::OpFRem,
252 InstructionName::OpFSub,
253 InstructionName::OpGenericCastToPtr,
254 InstructionName::OpIAdd,
255 InstructionName::OpIEqual,
256 InstructionName::OpIMul,
257 InstructionName::OpINotEqual,
258 InstructionName::OpISub,
259 InstructionName::OpInBoundsAccessChain,
260 InstructionName::OpInBoundsPtrAccessChain,
261 InstructionName::OpLogicalAnd,
262 InstructionName::OpLogicalEqual,
263 InstructionName::OpLogicalNot,
264 InstructionName::OpLogicalNotEqual,
265 InstructionName::OpLogicalOr,
266 InstructionName::OpNot,
267 InstructionName::OpPtrAccessChain,
268 InstructionName::OpPtrCastToGeneric,
269 InstructionName::OpQuantizeToF16,
270 InstructionName::OpSConvert,
271 InstructionName::OpSDiv,
272 InstructionName::OpSGreaterThan,
273 InstructionName::OpSGreaterThanEqual,
274 InstructionName::OpSLessThan,
275 InstructionName::OpSLessThanEqual,
276 InstructionName::OpSMod,
277 InstructionName::OpSNegate,
278 InstructionName::OpSRem,
279 InstructionName::OpSelect,
280 InstructionName::OpShiftLeftLogical,
281 InstructionName::OpShiftRightArithmetic,
282 InstructionName::OpShiftRightLogical,
283 InstructionName::OpUConvert,
284 InstructionName::OpUDiv,
285 InstructionName::OpUGreaterThan,
286 InstructionName::OpUGreaterThanEqual,
287 InstructionName::OpULessThan,
288 InstructionName::OpULessThanEqual,
289 InstructionName::OpUMod,
290 InstructionName::OpVectorShuffle,
293 impl Default for InstructionName {
294 fn default() -> Self {
295 InstructionName::Other(String::new())
299 impl From<String> for InstructionName {
300 fn from(v: String) -> Self {
302 "OpSwitch" => return InstructionName::OpSwitch,
303 "OpConstant" => return InstructionName::OpConstant,
304 "OpSpecConstant" => return InstructionName::OpSpecConstant,
305 "OpSpecConstantOp" => return InstructionName::OpSpecConstantOp,
306 "OpAccessChain" => return InstructionName::OpAccessChain,
307 "OpBitcast" => return InstructionName::OpBitcast,
308 "OpBitwiseAnd" => return InstructionName::OpBitwiseAnd,
309 "OpBitwiseOr" => return InstructionName::OpBitwiseOr,
310 "OpBitwiseXor" => return InstructionName::OpBitwiseXor,
311 "OpCompositeExtract" => return InstructionName::OpCompositeExtract,
312 "OpCompositeInsert" => return InstructionName::OpCompositeInsert,
313 "OpConvertFToS" => return InstructionName::OpConvertFToS,
314 "OpConvertFToU" => return InstructionName::OpConvertFToU,
315 "OpConvertPtrToU" => return InstructionName::OpConvertPtrToU,
316 "OpConvertSToF" => return InstructionName::OpConvertSToF,
317 "OpConvertUToF" => return InstructionName::OpConvertUToF,
318 "OpConvertUToPtr" => return InstructionName::OpConvertUToPtr,
319 "OpFAdd" => return InstructionName::OpFAdd,
320 "OpFConvert" => return InstructionName::OpFConvert,
321 "OpFDiv" => return InstructionName::OpFDiv,
322 "OpFMod" => return InstructionName::OpFMod,
323 "OpFMul" => return InstructionName::OpFMul,
324 "OpFNegate" => return InstructionName::OpFNegate,
325 "OpFRem" => return InstructionName::OpFRem,
326 "OpFSub" => return InstructionName::OpFSub,
327 "OpGenericCastToPtr" => return InstructionName::OpGenericCastToPtr,
328 "OpIAdd" => return InstructionName::OpIAdd,
329 "OpIEqual" => return InstructionName::OpIEqual,
330 "OpIMul" => return InstructionName::OpIMul,
331 "OpINotEqual" => return InstructionName::OpINotEqual,
332 "OpISub" => return InstructionName::OpISub,
333 "OpInBoundsAccessChain" => return InstructionName::OpInBoundsAccessChain,
334 "OpInBoundsPtrAccessChain" => return InstructionName::OpInBoundsPtrAccessChain,
335 "OpLogicalAnd" => return InstructionName::OpLogicalAnd,
336 "OpLogicalEqual" => return InstructionName::OpLogicalEqual,
337 "OpLogicalNot" => return InstructionName::OpLogicalNot,
338 "OpLogicalNotEqual" => return InstructionName::OpLogicalNotEqual,
339 "OpLogicalOr" => return InstructionName::OpLogicalOr,
340 "OpNot" => return InstructionName::OpNot,
341 "OpPtrAccessChain" => return InstructionName::OpPtrAccessChain,
342 "OpPtrCastToGeneric" => return InstructionName::OpPtrCastToGeneric,
343 "OpQuantizeToF16" => return InstructionName::OpQuantizeToF16,
344 "OpSConvert" => return InstructionName::OpSConvert,
345 "OpSDiv" => return InstructionName::OpSDiv,
346 "OpSGreaterThan" => return InstructionName::OpSGreaterThan,
347 "OpSGreaterThanEqual" => return InstructionName::OpSGreaterThanEqual,
348 "OpSLessThan" => return InstructionName::OpSLessThan,
349 "OpSLessThanEqual" => return InstructionName::OpSLessThanEqual,
350 "OpSMod" => return InstructionName::OpSMod,
351 "OpSNegate" => return InstructionName::OpSNegate,
352 "OpSRem" => return InstructionName::OpSRem,
353 "OpSelect" => return InstructionName::OpSelect,
354 "OpShiftLeftLogical" => return InstructionName::OpShiftLeftLogical,
355 "OpShiftRightArithmetic" => return InstructionName::OpShiftRightArithmetic,
356 "OpShiftRightLogical" => return InstructionName::OpShiftRightLogical,
357 "OpUConvert" => return InstructionName::OpUConvert,
358 "OpUDiv" => return InstructionName::OpUDiv,
359 "OpUGreaterThan" => return InstructionName::OpUGreaterThan,
360 "OpUGreaterThanEqual" => return InstructionName::OpUGreaterThanEqual,
361 "OpULessThan" => return InstructionName::OpULessThan,
362 "OpULessThanEqual" => return InstructionName::OpULessThanEqual,
363 "OpUMod" => return InstructionName::OpUMod,
364 "OpVectorShuffle" => return InstructionName::OpVectorShuffle,
365 "OpTypeInt" => return InstructionName::OpTypeInt,
366 "OpTypeFloat" => return InstructionName::OpTypeFloat,
369 InstructionName::Other(v)
373 impl AsRef<str> for InstructionName {
374 fn as_ref(&self) -> &str {
376 InstructionName::OpSwitch => "OpSwitch",
377 InstructionName::OpSwitch32 => "OpSwitch32",
378 InstructionName::OpSwitch64 => "OpSwitch64",
379 InstructionName::OpConstant => "OpConstant",
380 InstructionName::OpConstant32 => "OpConstant32",
381 InstructionName::OpConstant64 => "OpConstant64",
382 InstructionName::OpSpecConstant => "OpSpecConstant",
383 InstructionName::OpSpecConstant32 => "OpSpecConstant32",
384 InstructionName::OpSpecConstant64 => "OpSpecConstant64",
385 InstructionName::OpSpecConstantOp => "OpSpecConstantOp",
386 InstructionName::OpAccessChain => "OpAccessChain",
387 InstructionName::OpBitcast => "OpBitcast",
388 InstructionName::OpBitwiseAnd => "OpBitwiseAnd",
389 InstructionName::OpBitwiseOr => "OpBitwiseOr",
390 InstructionName::OpBitwiseXor => "OpBitwiseXor",
391 InstructionName::OpCompositeExtract => "OpCompositeExtract",
392 InstructionName::OpCompositeInsert => "OpCompositeInsert",
393 InstructionName::OpConvertFToS => "OpConvertFToS",
394 InstructionName::OpConvertFToU => "OpConvertFToU",
395 InstructionName::OpConvertPtrToU => "OpConvertPtrToU",
396 InstructionName::OpConvertSToF => "OpConvertSToF",
397 InstructionName::OpConvertUToF => "OpConvertUToF",
398 InstructionName::OpConvertUToPtr => "OpConvertUToPtr",
399 InstructionName::OpFAdd => "OpFAdd",
400 InstructionName::OpFConvert => "OpFConvert",
401 InstructionName::OpFDiv => "OpFDiv",
402 InstructionName::OpFMod => "OpFMod",
403 InstructionName::OpFMul => "OpFMul",
404 InstructionName::OpFNegate => "OpFNegate",
405 InstructionName::OpFRem => "OpFRem",
406 InstructionName::OpFSub => "OpFSub",
407 InstructionName::OpGenericCastToPtr => "OpGenericCastToPtr",
408 InstructionName::OpIAdd => "OpIAdd",
409 InstructionName::OpIEqual => "OpIEqual",
410 InstructionName::OpIMul => "OpIMul",
411 InstructionName::OpINotEqual => "OpINotEqual",
412 InstructionName::OpISub => "OpISub",
413 InstructionName::OpInBoundsAccessChain => "OpInBoundsAccessChain",
414 InstructionName::OpInBoundsPtrAccessChain => "OpInBoundsPtrAccessChain",
415 InstructionName::OpLogicalAnd => "OpLogicalAnd",
416 InstructionName::OpLogicalEqual => "OpLogicalEqual",
417 InstructionName::OpLogicalNot => "OpLogicalNot",
418 InstructionName::OpLogicalNotEqual => "OpLogicalNotEqual",
419 InstructionName::OpLogicalOr => "OpLogicalOr",
420 InstructionName::OpNot => "OpNot",
421 InstructionName::OpPtrAccessChain => "OpPtrAccessChain",
422 InstructionName::OpPtrCastToGeneric => "OpPtrCastToGeneric",
423 InstructionName::OpQuantizeToF16 => "OpQuantizeToF16",
424 InstructionName::OpSConvert => "OpSConvert",
425 InstructionName::OpSDiv => "OpSDiv",
426 InstructionName::OpSGreaterThan => "OpSGreaterThan",
427 InstructionName::OpSGreaterThanEqual => "OpSGreaterThanEqual",
428 InstructionName::OpSLessThan => "OpSLessThan",
429 InstructionName::OpSLessThanEqual => "OpSLessThanEqual",
430 InstructionName::OpSMod => "OpSMod",
431 InstructionName::OpSNegate => "OpSNegate",
432 InstructionName::OpSRem => "OpSRem",
433 InstructionName::OpSelect => "OpSelect",
434 InstructionName::OpShiftLeftLogical => "OpShiftLeftLogical",
435 InstructionName::OpShiftRightArithmetic => "OpShiftRightArithmetic",
436 InstructionName::OpShiftRightLogical => "OpShiftRightLogical",
437 InstructionName::OpUConvert => "OpUConvert",
438 InstructionName::OpUDiv => "OpUDiv",
439 InstructionName::OpUGreaterThan => "OpUGreaterThan",
440 InstructionName::OpUGreaterThanEqual => "OpUGreaterThanEqual",
441 InstructionName::OpULessThan => "OpULessThan",
442 InstructionName::OpULessThanEqual => "OpULessThanEqual",
443 InstructionName::OpUMod => "OpUMod",
444 InstructionName::OpVectorShuffle => "OpVectorShuffle",
445 InstructionName::OpTypeInt => "OpTypeInt",
446 InstructionName::OpTypeFloat => "OpTypeFloat",
447 InstructionName::Other(v) => v,
452 impl<'de> Deserialize<'de> for InstructionName {
453 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
454 Ok(Self::from(String::deserialize(deserializer)?))
458 #[derive(Clone, Deserialize, Debug)]
459 #[serde(deny_unknown_fields)]
460 pub struct Instruction {
461 pub opname: InstructionName,
464 pub operands: Vec<InstructionOperand>,
466 pub capabilities: Vec<String>,
468 pub extensions: Vec<String>,
470 pub version: SPIRVVersion,
474 pub fn fixup(&mut self) -> Result<(), ::Error> {
475 for operand in self.operands.iter_mut() {
482 #[derive(Deserialize, Debug)]
483 #[serde(deny_unknown_fields)]
484 pub struct ExtensionInstruction {
488 pub operands: Vec<InstructionOperand>,
490 pub capabilities: Vec<String>,
493 impl ExtensionInstruction {
494 pub fn fixup(&mut self) -> Result<(), ::Error> {
495 for operand in self.operands.iter_mut() {
502 #[derive(Deserialize, Debug, Default)]
503 #[serde(deny_unknown_fields)]
504 pub struct BitwiseEnumerantParameter {
508 impl BitwiseEnumerantParameter {
509 pub fn fixup(&mut self) -> Result<(), ::Error> {
510 self.kind.set_bit_width(BitWidth::Bits32);
515 #[derive(Deserialize, Debug, Default)]
516 #[serde(deny_unknown_fields)]
517 pub struct ValueEnumerantParameter {
519 pub name: Option<String>,
522 impl ValueEnumerantParameter {
523 pub fn fixup(&mut self) -> Result<(), ::Error> {
524 if self.name.is_none() {
527 .name_from_words(WordIterator::new(self.kind.as_ref()))
528 .ok_or(::Error::DeducingNameForEnumerantParameterFailed)?,
531 self.kind.set_bit_width(BitWidth::Bits32);
536 #[derive(Deserialize, Debug)]
537 #[serde(deny_unknown_fields)]
538 pub struct Enumerant<Value, EnumerantParameter> {
539 pub enumerant: String,
542 pub capabilities: Vec<String>,
544 pub parameters: Vec<EnumerantParameter>,
546 pub extensions: Vec<String>,
548 pub version: SPIRVVersion,
551 impl Enumerant<u32, ValueEnumerantParameter> {
552 pub fn fixup(&mut self) -> Result<(), ::Error> {
553 for parameter in self.parameters.iter_mut() {
560 impl Enumerant<QuotedInteger, BitwiseEnumerantParameter> {
561 pub fn fixup(&mut self) -> Result<(), ::Error> {
562 for parameter in self.parameters.iter_mut() {
569 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
571 Literal(LiteralKind),
575 PairLiteralIntegerIdRef,
576 PairLiteralInteger32IdRef,
577 PairLiteralInteger64IdRef,
582 pub fn set_bit_width(&mut self, bit_width: BitWidth) {
583 match (self, bit_width) {
584 (Kind::Literal(literal), bit_width) => literal.set_bit_width(bit_width),
585 (this @ Kind::PairLiteralIntegerIdRef, BitWidth::Bits32) => {
586 *this = Kind::PairLiteralInteger32IdRef
588 (this @ Kind::PairLiteralIntegerIdRef, BitWidth::Bits64) => {
589 *this = Kind::PairLiteralInteger64IdRef
592 | (Kind::IdResult, _)
593 | (Kind::IdResultType, _)
594 | (Kind::PairLiteralInteger32IdRef, _)
595 | (Kind::PairLiteralInteger64IdRef, _)
596 | (Kind::Other(_), _) => {}
601 impl Default for Kind {
602 fn default() -> Self {
603 Kind::Other(String::new())
607 impl<'a> From<Cow<'a, str>> for Kind {
608 fn from(v: Cow<'a, str>) -> Self {
609 if let Some(v) = LiteralKind::from_str(&v) {
611 } else if v == "IdRef" {
613 } else if v == "IdResult" {
615 } else if v == "IdResultType" {
617 } else if v == "PairLiteralIntegerIdRef" {
618 Kind::PairLiteralIntegerIdRef
620 Kind::Other(v.into_owned())
625 impl<'a> From<&'a str> for Kind {
626 fn from(v: &'a str) -> Self {
627 Kind::from(Cow::Borrowed(v))
631 impl From<String> for Kind {
632 fn from(v: String) -> Self {
633 Kind::from(Cow::Owned(v))
637 impl AsRef<str> for Kind {
638 fn as_ref(&self) -> &str {
640 Kind::Literal(v) => v.as_ref(),
641 Kind::IdRef => "IdRef",
642 Kind::IdResult => "IdResult",
643 Kind::IdResultType => "IdResultType",
644 Kind::PairLiteralIntegerIdRef => "PairLiteralIntegerIdRef",
645 Kind::PairLiteralInteger32IdRef => "PairLiteralInteger32IdRef",
646 Kind::PairLiteralInteger64IdRef => "PairLiteralInteger64IdRef",
652 impl<'de> Deserialize<'de> for Kind {
653 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
654 Ok(Self::from(String::deserialize(deserializer)?))
658 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
659 pub enum LiteralKind {
661 #[serde(skip_deserializing)]
663 #[serde(skip_deserializing)]
666 LiteralContextDependentNumber,
667 #[serde(skip_deserializing)]
668 LiteralContextDependentNumber32,
669 #[serde(skip_deserializing)]
670 LiteralContextDependentNumber64,
671 LiteralExtInstInteger,
672 LiteralSpecConstantOpInteger,
675 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
682 pub fn from_str<T: AsRef<str>>(v: T) -> Option<Self> {
684 "LiteralInteger" => Some(LiteralKind::LiteralInteger),
685 "LiteralString" => Some(LiteralKind::LiteralString),
686 "LiteralContextDependentNumber" => Some(LiteralKind::LiteralContextDependentNumber),
687 "LiteralExtInstInteger" => Some(LiteralKind::LiteralExtInstInteger),
688 "LiteralSpecConstantOpInteger" => Some(LiteralKind::LiteralSpecConstantOpInteger),
692 pub fn set_bit_width(&mut self, bit_width: BitWidth) {
693 *self = match (*self, bit_width) {
694 (LiteralKind::LiteralInteger, BitWidth::Bits32) => LiteralKind::LiteralInteger32,
695 (LiteralKind::LiteralInteger, BitWidth::Bits64) => LiteralKind::LiteralInteger64,
696 (LiteralKind::LiteralContextDependentNumber, BitWidth::Bits32) => {
697 LiteralKind::LiteralContextDependentNumber32
699 (LiteralKind::LiteralContextDependentNumber, BitWidth::Bits64) => {
700 LiteralKind::LiteralContextDependentNumber64
702 (LiteralKind::LiteralInteger32, _)
703 | (LiteralKind::LiteralInteger64, _)
704 | (LiteralKind::LiteralString, _)
705 | (LiteralKind::LiteralContextDependentNumber32, _)
706 | (LiteralKind::LiteralContextDependentNumber64, _)
707 | (LiteralKind::LiteralExtInstInteger, _)
708 | (LiteralKind::LiteralSpecConstantOpInteger, _) => return,
713 impl AsRef<str> for LiteralKind {
714 fn as_ref(&self) -> &str {
716 LiteralKind::LiteralInteger => "LiteralInteger",
717 LiteralKind::LiteralInteger32 => "LiteralInteger32",
718 LiteralKind::LiteralInteger64 => "LiteralInteger64",
719 LiteralKind::LiteralString => "LiteralString",
720 LiteralKind::LiteralContextDependentNumber => "LiteralContextDependentNumber",
721 LiteralKind::LiteralContextDependentNumber32 => "LiteralContextDependentNumber32",
722 LiteralKind::LiteralContextDependentNumber64 => "LiteralContextDependentNumber64",
723 LiteralKind::LiteralExtInstInteger => "LiteralExtInstInteger",
724 LiteralKind::LiteralSpecConstantOpInteger => "LiteralSpecConstantOpInteger",
729 #[derive(Deserialize, Debug)]
730 #[serde(deny_unknown_fields)]
731 #[serde(tag = "category")]
732 pub enum OperandKind {
735 enumerants: Vec<Enumerant<QuotedInteger, BitwiseEnumerantParameter>>,
739 enumerants: Vec<Enumerant<u32, ValueEnumerantParameter>>,
755 #[derive(Deserialize, Debug)]
756 #[serde(deny_unknown_fields)]
757 pub struct CoreGrammar {
758 pub copyright: Vec<String>,
759 pub magic_number: QuotedInteger,
760 pub major_version: u32,
761 pub minor_version: u32,
763 pub instructions: Vec<Instruction>,
764 pub operand_kinds: Vec<OperandKind>,
768 pub fn fixup(&mut self) -> Result<(), ::Error> {
769 let instructions = mem::replace(&mut self.instructions, Vec::new());
770 for mut instruction in instructions {
771 if instruction.version == SPIRVVersion::None {
774 let (opname_32, opname_64) = match instruction.opname {
775 InstructionName::OpSwitch => {
776 (InstructionName::OpSwitch32, InstructionName::OpSwitch64)
778 InstructionName::OpConstant => {
779 (InstructionName::OpConstant32, InstructionName::OpConstant64)
781 InstructionName::OpSpecConstant => (
782 InstructionName::OpSpecConstant32,
783 InstructionName::OpSpecConstant64,
786 instruction.opname = opname;
787 instruction.fixup()?;
788 self.instructions.push(instruction);
792 instruction.opname = InstructionName::default();
793 let mut op_32 = Instruction {
795 ..instruction.clone()
797 for operand in op_32.operands.iter_mut() {
798 operand.kind.set_bit_width(BitWidth::Bits32);
801 self.instructions.push(op_32);
802 let mut op_64 = Instruction {
806 for operand in op_64.operands.iter_mut() {
807 operand.kind.set_bit_width(BitWidth::Bits64);
810 self.instructions.push(op_64);
812 let operand_kinds = mem::replace(&mut self.operand_kinds, Vec::new());
813 for operand_kind in operand_kinds {
815 OperandKind::BitEnum {
819 enumerants.retain(|enumerant| enumerant.version != SPIRVVersion::None);
820 for enumerant in enumerants.iter_mut() {
824 .push(OperandKind::BitEnum { kind, enumerants });
826 OperandKind::ValueEnum {
830 enumerants.retain(|enumerant| enumerant.version != SPIRVVersion::None);
831 for enumerant in enumerants.iter_mut() {
834 enumerants.sort_by_key(|enumerant| enumerant.value);
835 enumerants.dedup_by_key(|enumerant| enumerant.value);
837 .push(OperandKind::ValueEnum { kind, enumerants });
839 OperandKind::Composite { kind, mut bases } => match kind {
840 Kind::PairLiteralIntegerIdRef => {
841 let mut bases_32 = bases.clone();
842 let mut bases_64 = bases;
843 for base in bases_32.iter_mut() {
844 base.set_bit_width(BitWidth::Bits32);
846 for base in bases_64.iter_mut() {
847 base.set_bit_width(BitWidth::Bits64);
849 self.operand_kinds.push(OperandKind::Composite {
850 kind: Kind::PairLiteralInteger32IdRef,
853 self.operand_kinds.push(OperandKind::Composite {
854 kind: Kind::PairLiteralInteger64IdRef,
859 for base in bases.iter_mut() {
860 base.set_bit_width(BitWidth::Bits32);
863 .push(OperandKind::Composite { kind, bases });
866 OperandKind::Literal { kind, doc } => match kind {
867 LiteralKind::LiteralInteger => {
868 self.operand_kinds.push(OperandKind::Literal {
869 kind: LiteralKind::LiteralInteger32,
872 self.operand_kinds.push(OperandKind::Literal {
873 kind: LiteralKind::LiteralInteger64,
877 LiteralKind::LiteralContextDependentNumber => {
878 self.operand_kinds.push(OperandKind::Literal {
879 kind: LiteralKind::LiteralContextDependentNumber32,
882 self.operand_kinds.push(OperandKind::Literal {
883 kind: LiteralKind::LiteralContextDependentNumber64,
887 kind => self.operand_kinds.push(OperandKind::Literal { kind, doc }),
889 OperandKind::Id { kind, doc } => {
890 self.operand_kinds.push(OperandKind::Id { kind, doc })
898 #[derive(Deserialize, Debug)]
899 #[serde(deny_unknown_fields)]
900 pub struct ExtensionInstructionSet {
901 pub copyright: Vec<String>,
904 pub instructions: Vec<ExtensionInstruction>,
907 impl ExtensionInstructionSet {
908 pub fn fixup(&mut self) -> Result<(), ::Error> {
909 for instruction in self.instructions.iter_mut() {
910 instruction.fixup()?;