GCC の調査(2)
double の sin
double sin_double_cpp(double x) { return sin(x); }
から作られるアセンブリ言語のコードは以下のようになります。
_Z14sin_double_cppd: link.w %fp,#0 move.l 12(%fp),-(%sp) move.l 8(%fp),-(%sp) jsr sin addq.l #8,%sp unlk %fp rts
x の上位32ビットを x0、下位32ビットを x1 とします。スタックが
| 0 | 4 | |
| スタックの入り口 | x0 | x1 |
の状態でこの関数が呼び出されると
| 0 | 4 | 8 | 12 | 16 | 20 | |
| スタックの入り口 | x0 | x1 | fp | pc | x0 | x1 |
float の sin
float sin_float_cpp(float x) { return sin(x); }
から作られるアセンブリ言語のコードは以下のようになります。
_Z13sin_float_cppf: link.w %fp,#0 move.l 8(%fp),-(%sp) jsr __extendsfdf2 addq.l #4,%sp move.l %d1,-(%sp) move.l %d0,-(%sp) jsr sin addq.l #8,%sp move.l %d1,-(%sp) move.l %d0,-(%sp) jsr __truncdfsf2 addq.l #8,%sp unlk %fp rts
スタックが
| 0 | |
| スタックの入り口 | x |
の状態でこの関数が呼び出されると
| 0 | 4 | 8 | 12 | |
| スタックの入り口 | x | fp | pc | x |
の状態で __extendsfdf2 が呼び出されます。d0 レジスタと d1 レジスタに x を倍精度浮動小数点数に変換したものを返します(x0 と x1 とします)。
| 0 | 4 | 8 | 12 | 16 | |
| スタックの入り口 | x0 | x1 | fp | pc | x |
の状態で sin が呼び出されます。sin は d0 レジスタと d1 レジスタに sin x を返します。これを y0 と y1 とすると
| 0 | 4 | 8 | 12 | 16 | |
| スタックの入り口 | y0 | y1 | fp | pc | x |
の状態で __truncdfsf2 が呼び出されます。(sin x を)単精度浮動小数点数に変換されたものが d0 レジスタに返されます。
整数から倍精度浮動小数点数への変換
double int_to_double_cpp(int x) { return double(x); }
から作られるアセンブリ言語のコードは以下のようになります。
_Z17int_to_double_cppi: link.w %fp,#0 move.l 8(%fp),-(%sp) jsr __floatsidf addq.l #4,%sp unlk %fp rts
スタックが
| 0 | |
| スタックの入り口 | x |
の状態でこの関数が呼び出されると
| 0 | 4 | 8 | 12 | |
| スタックの入り口 | x | fp | pc | x |
の状態で __floatsidf が呼び出されます。__floatsidf は d0 と d1 レジスタに x を倍精度浮動小数点数に変換したものを返します。
整数から単精度浮動小数点数への変換
float int_to_float_cpp(int x) { return float(x); }
から作られるアセンブリ言語のコードは以下のようになります。
_Z16int_to_float_cppi: link.w %fp,#0 move.l 8(%fp),-(%sp) jsr __floatsisf addq.l #4,%sp unlk %fp rts
スタックが
| 0 | |
| スタックの入り口 | x |
の状態でこの関数が呼び出されると
| 0 | 4 | 8 | 12 | |
| スタックの入り口 | x | fp | pc | x |
の状態で __floatsisf が呼び出されます。__floatsisf は d0 レジスタに x を単精度浮動小数点数に変換したものを返します。


