2017-06-05 13 views
2

私はRustの小さな言語を開発しています。パフォーマンスを向上させるために、私はx86用のfastcall呼び出し規約を使用したいと考えています。 "fastcall" ABIはARMではサポートされていません。 x86の場合マクロを使用するアーキテクチャによって、呼び出し規約が異なる関数を定義するにはどうすればよいですか?

:ARM用

fn add_primitive(&mut self, name: &str, action: extern "fastcall" fn(&mut Self)) { 
    ... 
} 

extern "fastcall" fn a_primitive(&mut self) {} 

fn add_primitive(&mut self, name: &str, action: fn(&mut Self)) { 
    ... 
} 

fn a_primitive(&mut self) {} 

CIを使用して、私は錆のマクロシステムを使用してこの問題を解決する方法がわからないマクロ

#ifdef x86 
#define PRIMITIVE extern "fastcall" fn 
#endif 
#ifdef arm 
#define PRIMITIVE fn 
#endif 

fn add_primitive(&mut self, name: &str, action: PRIMITIVE(&mut Self)) { 
    ... 
} 

PRIMITIVE a_primitive(&mut self) {} 

を定義することができます。

編集:

私は2つの異なるマクロが必要です。私はtarget_archを使って異なるバージョンの関数を定義する方法を知っていますが、マクロは定義していません。

+2

pub struct Word<Target> { symbol: Symbol, is_immediate: bool, is_compile_only: bool, hidden: bool, dfa: usize, cfa: usize, action: primitive!{ fn (&mut Target) }, pub(crate) compilation_semantics: fn(&mut Target, usize), } primitive!{fn dup(&mut self) { let slen = self.s_stack().len.wrapping_add(1); self.s_stack().len = slen; self.s_stack()[slen.wrapping_sub(1)] = self.s_stack()[slen.wrapping_sub(2)]; }} 
可能な重複(https://stackoverflow.com/questions/41896462/how-to- [アーキテクチャが32または64ビットである場合に錆に確認する方法?]アーキテクチャが32ビットまたは64ビットであるかどうかをチェックインしてください) - 質問は少し異なりますが、答えは同じです。 –

+1

[アーキテクチャが32ビットか64ビットかどうかをチェックする方法は?](https://stackoverflow.com/questions/41896462/how-to-check-in-rust-if-architecture-is-32-または64ビット)は私の問題では十分ではありません。私は2つの異なるバージョンのマクロが必要だからです。私はtarget_archを使って、マクロではなく関数の異なるバージョンを定義する方法を知っています。 –

+2

'#[cfg]'はマクロと同じように機能します。 –

答えて

1
#[cfg(target_arch = "arm")] 
#[macro_export] 
macro_rules! primitive { 
    (fn $args:tt) => { fn $args }; 
    (fn $f:ident $args:tt $body:tt) => { fn $f $args $body }; 
    (fn $f:ident $args:tt -> isize $body:tt) => { fn $f $args -> isize $body }; 
} 

#[cfg(target_arch = "x86")] 
#[macro_export] 
macro_rules! primitive { 
    (fn $args:tt) => { extern "fastcall" fn $args }; 
    (fn $f:ident $args:tt $body:tt) => { extern "fastcall" fn $f $args $body }; 
    (fn $f:ident $args:tt -> isize $body:tt) => { extern "fastcall" fn $f $args -> isize $body }; 
} 

例の

+0

使用方法の例を挙げることはできますか? – Boiethios

+0

@Boiethiosこれはwikiの回答です。改善するために自由に感じます。私はOPがその質問に答えてくれたからです。私はこの仕事がどういうものなのか、何が目的なのか分かりません。 – Stargateur

+1

私は自分自身で原始的な言葉を定義するためにそれを使用しました。 https://github.com/chengchangwu/rtforth/blob/master/src/core.rsをご覧ください。 –

関連する問題