This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: MIPS 32-bit ABI stack pointer
- From: Mason <mpeg dot blue at free dot fr>
- To: gcc-help at gcc dot gnu dot org
- Date: Wed, 10 Nov 2010 11:30:03 +0100
- Subject: Re: MIPS 32-bit ABI stack pointer
- References: <4CDA6E00.5020307@free.fr>
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.