gccにregparmというのがあるらしい。普通にやるとIA32での関数呼び出しは全部の引数がスタック渡しになる。その昔x86アセンブラでプログラムを書いた人なら、AXとかDXに引数を置いて戻り値をAXにして…なんてことをやっていたことを思い出すだろうが、それをgccがやってくれるのだ。オプション-mregparm=nで、nがレジスタ渡しをする引数の数ということになる。
無論、*.o毎に-mregparm=nの指定が異なる場合は引数が正しく渡ることはない。
まあでも小さな関数を呼び出すだけの場合は-mregparm=nなんていう、ある種の危険なことをしなくても、単にinline指定するか、そうでなくても-O9などをつけておけば勝手にインライン展開されてスタックどころかcallすら呼ばなかったりする。あと、Alphaとか、レジスタの本数が多いアーキテクチャの場合は最初からレジスタ渡しになってたはずだ(よく覚えていないけどそうに違いない)。
Linux Kernel 2.6.4-rc2-bk1をコンパイルしようとして、オプションにあったので気づいた。もしかしたら、ポピュラーになるのかもしれない。ヘッダのプロトタイプ宣言でregparmの指定を書ければ、ライブラリで使っても互換性をとれるよなぁ。