summary refs log tree commit diff stats
path: root/rust/qemu-api-macros/src/lib.rs
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2025-06-04 11:43:30 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2025-06-04 11:43:31 -0400
commitf8a113701dd2d28f3bedb216e59125ddcb77fd05 (patch)
tree55ce05f7943dc3bbb1fbb36f28b22f2608b0f831 /rust/qemu-api-macros/src/lib.rs
parent09be8a511a2e278b45729d7b065d30c68dd699d0 (diff)
parent214518614c1ce7eb7a002452cd43a7597f90d543 (diff)
downloadfocaccia-qemu-f8a113701dd2d28f3bedb216e59125ddcb77fd05.tar.gz
focaccia-qemu-f8a113701dd2d28f3bedb216e59125ddcb77fd05.zip
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging
* rust: use native Meson support for clippy and rustdoc
* rust: add "bits", a custom bitflags implementation
* target/i386: Remove FRED dependency on WRMSRNS
* target/i386: Add the immediate form MSR access instruction support
* TDX fixes

# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCgAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmg/XrsUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroOPIwf/VXh98Wd+7BJLkNJVFpczSF7YhJ5J
# a5BcWLOdVrzEJoqvfc9lkubgpShgzYDYJH99F/FloHddkPvZ1NRB2JXtDB1O3sSC
# NGaI4YM8uA/k21pt1jQtDJkk3Az7GNIBIcvi4HR5GjTOvOKGOXLpYErK52lM4GNG
# Aa17/Rb9Ug+QzyuS1M+mDPFdY2X6Hore2jXsp3ZH+U8hs+khecHEPsZUZ/Nlr1Z7
# UoiYks4U29wtVJ/BCjNkgXoMJC6uqL/nOP5dLJBgboOodrtwdwpDMIUcyPLrOnjf
# ugJx0zYHIVdqpdft72EvLD92bzB8WoUiPsUA/dG45gGmhzuYWDmOqSdaKg==
# =l0gm
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 03 Jun 2025 16:44:43 EDT
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* tag 'for-upstream' of https://gitlab.com/bonzini/qemu:
  rust: qemu-api-macros: add from_bits and into_bits to #[derive(TryInto)]
  rust: pl011: use the bits macro
  rust: add "bits", a custom bitflags implementation
  i386/tdvf: Fix build on 32-bit host
  i386/tdx: Fix build on 32-bit host
  meson: use config_base_arch for target libraries
  target/i386: Add the immediate form MSR access instruction support
  target/i386: Add a new CPU feature word for CPUID.7.1.ECX
  target/i386: Remove FRED dependency on WRMSRNS
  rust: use native Meson support for clippy and rustdoc
  rust: cell: remove support for running doctests with "cargo test --doc"
  rust: add qemu-api doctests to "meson test"
  build, dockerfiles: add support for detecting rustdoc
  rust: use "objects" for Rust executables as well
  meson: update to version 1.8.1
  rust: bindings: allow ptr_offset_with_cast

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'rust/qemu-api-macros/src/lib.rs')
-rw-r--r--rust/qemu-api-macros/src/lib.rs56
1 files changed, 48 insertions, 8 deletions
diff --git a/rust/qemu-api-macros/src/lib.rs b/rust/qemu-api-macros/src/lib.rs
index f97449bb30..103470785e 100644
--- a/rust/qemu-api-macros/src/lib.rs
+++ b/rust/qemu-api-macros/src/lib.rs
@@ -12,6 +12,9 @@ use syn::{
 mod utils;
 use utils::MacroError;
 
+mod bits;
+use bits::BitsConstInternal;
+
 fn get_fields<'a>(
     input: &'a DeriveInput,
     msg: &str,
@@ -190,23 +193,51 @@ fn get_variants(input: &DeriveInput) -> Result<&Punctuated<Variant, Comma>, Macr
 }
 
 #[rustfmt::skip::macros(quote)]
+fn derive_tryinto_body(
+    name: &Ident,
+    variants: &Punctuated<Variant, Comma>,
+    repr: &Path,
+) -> Result<proc_macro2::TokenStream, MacroError> {
+    let discriminants: Vec<&Ident> = variants.iter().map(|f| &f.ident).collect();
+
+    Ok(quote! {
+        #(const #discriminants: #repr = #name::#discriminants as #repr;)*;
+        match value {
+            #(#discriminants => Ok(#name::#discriminants),)*
+            _ => Err(value),
+        }
+    })
+}
+
+#[rustfmt::skip::macros(quote)]
 fn derive_tryinto_or_error(input: DeriveInput) -> Result<proc_macro2::TokenStream, MacroError> {
     let repr = get_repr_uN(&input, "#[derive(TryInto)]")?;
-
     let name = &input.ident;
-    let variants = get_variants(&input)?;
-    let discriminants: Vec<&Ident> = variants.iter().map(|f| &f.ident).collect();
+    let body = derive_tryinto_body(name, get_variants(&input)?, &repr)?;
+    let errmsg = format!("invalid value for {name}");
 
     Ok(quote! {
+        impl #name {
+            #[allow(dead_code)]
+            pub const fn into_bits(self) -> #repr {
+                self as #repr
+            }
+
+            #[allow(dead_code)]
+            pub const fn from_bits(value: #repr) -> Self {
+                match ({
+                    #body
+                }) {
+                    Ok(x) => x,
+                    Err(_) => panic!(#errmsg)
+                }
+            }
+        }
         impl core::convert::TryFrom<#repr> for #name {
             type Error = #repr;
 
             fn try_from(value: #repr) -> Result<Self, Self::Error> {
-                #(const #discriminants: #repr = #name::#discriminants as #repr;)*;
-                match value {
-                    #(#discriminants => Ok(Self::#discriminants),)*
-                    _ => Err(value),
-                }
+                #body
             }
         }
     })
@@ -219,3 +250,12 @@ pub fn derive_tryinto(input: TokenStream) -> TokenStream {
 
     TokenStream::from(expanded)
 }
+
+#[proc_macro]
+pub fn bits_const_internal(ts: TokenStream) -> TokenStream {
+    let ts = proc_macro2::TokenStream::from(ts);
+    let mut it = ts.into_iter();
+
+    let expanded = BitsConstInternal::parse(&mut it).unwrap_or_else(Into::into);
+    TokenStream::from(expanded)
+}