Mason wrote:
I'm having problems mixing MIPS 32-bit object files compiled with two different compilers. 1) gcc version 4.4.1 (Sourcery G++ Lite 4.4-305) 2) Green Hills Software (exact version unknown) Before describing my problem, I'd like to ask a few questions. GCC supports several MIPS ABIs. Where are they documented? http://gcc.gnu.org/onlinedocs/gcc/MIPS-Options.html -mabi=32 -mabi=o64 -mabi=n32 -mabi=64 -mabi=eabi ( Links for self reference ) http://gcc.gnu.org/gcc-3.4/mips-abi.html http://www.cygwin.com/ml/binutils/2003-06/msg00436.html http://math-atlas.sourceforge.net/devel/assembly/mipsabi32.pdf Next question, when a function starts, is the stack pointer (r29) supposed to point to A) the last live value in the previous frame OR B) the first free/available word in the current frame ??? Do different compilers have different conventions/ABIs? The reason I ask is because, in my default invocation, gcc seems to consider case B: $ cat foo.c extern void bar(void *p); void foo(void *p) { bar(p); } $ mips-sde-elf-gcc -S foo.c .file 1 "foo.c" .section .mdebug.abi32 .previous .gnu_attribute 4, 1 .text .align 2 .globl foo .set nomips16 .set nomicromips .ent foo .type foo, @function foo: .frame $fp,24,$31 # vars= 0, regs= 2/0, args= 16, gp= 0 .mask 0xc0000000,-4 .fmask 0x00000000,0 .set noreorder .set nomacro addiu $sp,$sp,-24 sw $31,20($sp) sw $fp,16($sp) move $fp,$sp sw $4,24($fp) lw $4,24($fp) jal bar nop move $sp,$fp lw $31,20($sp) lw $fp,16($sp) addiu $sp,$sp,24 j $31 nop .set macro .set reorder .end foo .size foo, .-foo .ident "GCC: (Sourcery G++ Lite 4.4-305) 4.4.1" gcc stores r4 at fp+24 (fp+24 being the initial value of sp)
I tried targeting every ABI documented by gcc. $ for abi in 32 o64 n32 64 eabi; do gcc -S -mabi=$abi -o foo-$abi.s foo.c; done I got errors for o64, n32, 64 foo.c:1: error: '-march=mips32r2' is not compatible with the selected ABI foo.c:1: error: '-march=mips32r2' is not compatible with the selected ABI foo.c:1: error: '-march=mips32r2' is not compatible with the selected ABI abi=32 was the default, abi=eabi looks "better" (i.e. compatible with the GHS compiler) foo: .frame $fp,16,$31 # vars= 8, regs= 2/0, args= 0, gp= 0 .mask 0xc0000000,-4 .fmask 0x00000000,0 .set noreorder .set nomacro addiu $sp,$sp,-16 sw $31,12($sp) sw $fp,8($sp) move $fp,$sp sw $4,0($fp) lw $4,0($fp) jal bar nop move $sp,$fp lw $31,12($sp) lw $fp,8($sp) addiu $sp,$sp,16 j $31 nop $ objdump -x foo-eabi.o foo-eabi.o: file format elf32-tradbigmips foo-eabi.o architecture: mips:isa32r2, flags 0x00000011: HAS_RELOC, HAS_SYMS start address 0x00000000 private flags = 70003001: [abi=EABI32] [mips32r2] [not 32bitmode] [noreorder] In this ABI, gcc does preserve the value pointed to by the inital value of sp. Does this mean all I need to do is compile everything with -mabi=eabi ? And it will all auto-magically work? :-) -- Regards.