loongarch64.rs 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. use proc_macro2::TokenStream;
  2. use quote::quote;
  3. use syn::{Ident, Type};
  4. /// Get the base address for percpu variables of the current thread.
  5. pub fn get_percpu_pointer(percpu: &Ident, ty: &Type) -> TokenStream {
  6. quote! {
  7. {
  8. let base: *mut #ty;
  9. unsafe extern "C" {
  10. fn PERCPU_DATA_START();
  11. }
  12. ::core::arch::asm!(
  13. "sub.d {base}, {base}, {start}",
  14. "add.d {base}, {base}, $tp",
  15. base = inout(reg) &raw const #percpu => base,
  16. start = in(reg) PERCPU_DATA_START as usize,
  17. options(nostack, preserves_flags)
  18. );
  19. base
  20. }
  21. }
  22. }
  23. pub fn get_percpu_offset(percpu: &Ident) -> TokenStream {
  24. quote! {
  25. unsafe {
  26. let offset: usize;
  27. unsafe extern "C" {
  28. fn PERCPU_DATA_START();
  29. }
  30. ::core::arch::asm!(
  31. "la.global {tmp}, {start}",
  32. "la.global {output}, {var}",
  33. "sub.d {output}, {output}, {tmp}",
  34. start = sym PERCPU_DATA_START,
  35. var = sym #percpu,
  36. tmp = out(reg) _,
  37. output = out(reg) offset,
  38. options(nostack, preserves_flags)
  39. );
  40. offset
  41. }
  42. }
  43. }