GCC 4.6 MIPS クロスコンパイラを作る
4.6でMIPSクロスコンパイラを作ってみたので、そのメモです。
Binutils
(追記) export PATHを追加
% cd binutils-2.21 % mkdir build_mips && cd build_mips % ../configure --target=mipsel-linux-elf \ --prefix=/home/syohei/local/mipsel_gcc46 --disable-nls % make 2>&1 | tee build_mips.log % make install % export PATH=/home/syohei/local/mipsel_gcc46/bin:$PATH
GCC
GCCをビルドする際は newlibも展開しておいてください。
そして newlibディレクトリと libglossディレクトリへの
シンボリックリンクを GCCのソースツリーのトップに作成します。
% cd gcc-4.6.0-RC % ln -s /home/syohei/gnu/newlib-1.18.0/newlib . % ln -s /home/syohei/gnu/newlib-1.18.0/libgloss . % mkdir build_mips && cd build_mips % ../configure --target=mipsel-linux-elf --enable-languages=c \ --with-gmp=/usr/local --with-mpfr=/usr/local --with-mpc=/usr/local \ --with-ppl=/usr/local --with-cloog=/usr/local \ --prefix=/home/syohei/local/mipsel_gcc46 --disable-nls \ --disable-multilib --disable-libssp --with-newlib \ --with-headers=/home/syohei/gnu/gcc-4.6.0-RC-20110314/newlib/libc/include % make % make install
newlib
% cd newlib-1.18.0 % ../configure --target=mipsel-linux-elf \ --prefix=/home/syohei/local/mipsel_tools --disable-nls % make 2>&1 | tee build_mips.log % make install
GDB
シミュレータ runのために GDBを作成します。
% cd gdb-7.2 % mkdir build_mips && cd build_mips % ../configure --target=mipsel-linux-elf \ --prefix=/home/syohei/local/mipsel_tools --disable-nls % make 2>&1 | tee build_mips.log % make install
テスト
#include <stdio.h> #include <stdlib.h> static int func(int a) { int array[1024]; int i, sum = 0; for (i = 0; i < a; i++) { sum += array[i]; } return sum; } int main (int argc, char *argv[]) { int a; if (argc >= 2) { a = atoi(argv[1]); } else { a = 1024; } return func(a); }
コンパイルします。バイナリは作れたんですが、実行できなかったので
アセンブリとスタック使用量だけ確認します。分かりやすいように最適化なしです。
% mipsel-linux-elf-gcc -S -O0 -fstack-usage stack_usage.c
スタック使用量は以下の通りです。
stack_usage.c:4:12:func 4112 static stack_usage.c:16:5:main 32 static
アセンブリで確認してみます。
すごく割愛していますが、スタックを伸ばしているサイズ(spレジスタの操作)
と同じであることがわかります。
func: .frame $fp,4112,$31 # vars= 4104, regs= 1/0, args= 0, gp= 0 .mask 0x40000000,-4 .fmask 0x00000000,0 .set noreorder .set nomacro addiu $sp,$sp,-4112 # ここでスタックを伸ばす sw $fp,4108($sp) move $fp,$sp .... main: .frame $fp,32,$31 # vars= 8, regs= 2/0, args= 16, gp= 0 .mask 0xc0000000,-4 .fmask 0x00000000,0 .set noreorder .set nomacro addiu $sp,$sp,-32 # ここでスタックを伸ばす sw $31,28($sp) sw $fp,24($sp) move $fp,$sp ......