working on changing to use Rust's new asm! syntax since llvm_asm! is being deprecated...
authorJacob Lifshay <programmerjake@gmail.com>
Wed, 25 Aug 2021 01:57:38 +0000 (18:57 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Thu, 2 Sep 2021 21:14:01 +0000 (14:14 -0700)
power-instruction-analyzer-proc-macro/src/inline_assembly.rs
power-instruction-analyzer-proc-macro/src/instructions.rs
power-instruction-analyzer-proc-macro/src/lib.rs
src/lib.rs

index a0a8bf492fabbc6001ed997d7b92f6c1d56e8525..4dbb02fa02bddd27cbb24124c8bc17cccdf7b683 100644 (file)
@@ -2,7 +2,7 @@
 // See Notices.txt for copyright information
 
 use proc_macro2::{Span, TokenStream};
-use quote::{quote, ToTokens};
+use quote::{quote, quote_spanned, ToTokens};
 use std::{
     collections::HashMap,
     fmt::Write,
@@ -10,7 +10,7 @@ use std::{
     ops::{Deref, DerefMut},
     sync::atomic::{AtomicU64, Ordering},
 };
-use syn::LitStr;
+use syn::{punctuated::Punctuated, LitStr, Token};
 
 macro_rules! append_assembly {
     ($retval:ident;) => {};
@@ -467,9 +467,20 @@ impl ToTokens for AssemblyWithTextSpan {
                 },
             text_span,
         } = self;
-        let text = LitStr::new(&self.to_text(), text_span.clone());
+        let mut args: Punctuated<TokenStream, Token![,]> = self
+            .to_text()
+            .lines()
+            .map(|line| {
+                quote_spanned! {*text_span=>
+                    #line
+                }
+            })
+            .collect();
+        args.extend(outputs.iter().map(ToTokens::to_token_stream));
+        args.extend(inputs.iter().map(ToTokens::to_token_stream));
+        args.extend(clobbers.iter().map(ToTokens::to_token_stream));
         let value = quote! {
-            llvm_asm!(#text : #(#outputs),* : #(#inputs),* : #(#clobbers),*)
+            asm!(#args)
         };
         value.to_tokens(tokens);
     }
index 4146cb6af132497f3fc302fa3313a80742b65f2f..81dd20a1df74a4fe28ea57ac05c94286a9bc41fe 100644 (file)
@@ -294,21 +294,21 @@ type InstructionInput = InstructionArg<InstructionInputName>;
 type InstructionOutput = InstructionArg<InstructionOutputName>;
 
 impl InstructionInput {
-    fn constraint(&self) -> LitStr {
+    fn constraint(&self) -> TokenStream {
         if let Some(register) = &self.register {
-            LitStr::new(&format!("{{{}}}", register.value()), register.span())
+            register.to_token_stream()
         } else {
-            LitStr::new("b", Span::call_site())
+            quote! { reg_nonzero }
         }
     }
 }
 
 impl InstructionOutput {
-    fn constraint(&self) -> LitStr {
+    fn constraint(&self) -> TokenStream {
         if let Some(register) = &self.register {
-            LitStr::new(&format!("=&{{{}}}", register.value()), register.span())
+            register.to_token_stream()
         } else {
-            LitStr::new("=&b", Span::call_site())
+            quote! { reg_nonzero }
         }
     }
 }
@@ -448,7 +448,7 @@ impl Instruction {
                 InstructionOutputName::Rt(_) => {
                     before_asm.push(quote! {let rt: u64;});
                     let constraint = output.constraint();
-                    asm_instr_args.push(assembly! {"$" output{#constraint(rt)} });
+                    asm_instr_args.push(assembly! {"{" output{out(#constraint) rt} "}" });
                     after_asm.push(quote! {retval.rt = Some(rt);});
                 }
                 InstructionOutputName::Carry(_) => {
@@ -529,17 +529,17 @@ impl Instruction {
                 InstructionInputName::Ra(_) => {
                     before_asm.push(quote! {let ra: u64 = inputs.try_get_ra()?;});
                     let constraint = input.constraint();
-                    asm_instr_args.push(assembly! {"$" input{#constraint(ra)} });
+                    asm_instr_args.push(assembly! {"{" input{in(#constraint) ra} "}"});
                 }
                 InstructionInputName::Rb(_) => {
                     before_asm.push(quote! {let rb: u64 = inputs.try_get_rb()?;});
                     let constraint = input.constraint();
-                    asm_instr_args.push(assembly! {"$" input{#constraint(rb)} });
+                    asm_instr_args.push(assembly! {"{" input{in(#constraint) rb} "}"});
                 }
                 InstructionInputName::Rc(_) => {
                     before_asm.push(quote! {let rc: u64 = inputs.try_get_rc()?;});
                     let constraint = input.constraint();
-                    asm_instr_args.push(assembly! {"$" input{#constraint(rc)} });
+                    asm_instr_args.push(assembly! {"{" input{in(#constraint) rc} "}"});
                 }
                 InstructionInputName::ImmediateS16(_) | InstructionInputName::ImmediateU16(_) => {
                     input.error_if_register_is_specified()?;
@@ -597,13 +597,13 @@ impl Instruction {
             });
             let xer_out;
             before_instr_asm_lines.push(assembly! {
-                "mfxer $" output(xer_out = {"=&b"(xer_out)})
+                "mfxer {" output(xer_out = {out(reg_nonzero) xer_out}) "}"
             });
             before_instr_asm_lines.push(assembly! {
-                "and $" (xer_out) ", $" (xer_out) ", $" input{"b"(xer_mask_in)}
+                "and {" (xer_out) "}, {" (xer_out) "}, {" input{in(reg_nonzero) xer_mask_in} "}"
             });
             before_instr_asm_lines.push(assembly! {
-                "or $" (xer_out) ", $" (xer_out) ", $" input{"b"(xer_in)}
+                "or {" (xer_out) "}, {" (xer_out) "}, {" input{in(reg_nonzero) xer_in} "}"
             });
             before_instr_asm_lines.push(assembly! {
                 "mtxer $" (xer_out) clobber{"xer"}
index 8dcce4ff30bfef29f992cdc828aa83dadb1c0d75..2ad330940821db5295a29431c59afce5c38b92b0 100644 (file)
@@ -13,7 +13,10 @@ use syn::parse_macro_input;
 pub fn instructions(input: TokenStream) -> TokenStream {
     let input = parse_macro_input!(input as Instructions);
     match input.to_tokens() {
-        Ok(retval) => retval,
+        Ok(retval) => {
+            eprintln!("macro output:\n----------\n{}\n----------", retval);
+            retval
+        }
         Err(err) => err.to_compile_error(),
     }
     .into()
index 31d48a64ef1d09e2b5e7a2adc47e645525b043ac..28c5b35b81fed9bce01362b23dd10651c89039af 100644 (file)
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: LGPL-2.1-or-later
 // See Notices.txt for copyright information
 
-#![cfg_attr(feature = "native_instrs", feature(llvm_asm))]
+#![cfg_attr(feature = "native_instrs", feature(asm))]
 
 #[cfg(all(feature = "native_instrs", not(target_arch = "powerpc64")))]
 compile_error!("native_instrs feature requires target_arch to be powerpc64");