I found that compiling for mips with -mabi=n32 produces such inefficient code. When -mabi=n32, mips_return_in_memory returns 0 if size is small regardless BLKmode or not.
.type foo, @function foo: .frame $sp,16,$31 # vars= 16, regs= 0/0, args= 0, gp= 0 addiu $sp,$sp,-16 li $2,-7 # 0xfffffffffffffff9 sh $2,0($sp) sh $2,2($sp) ld $3,0($sp) addiu $sp,$sp,16 dsrl $4,$3,32 andi $4,$4,0xffff dsrl $3,$3,48 dsll $4,$4,32 dsll $2,$3,48 j $31 or $2,$2,$4 .ent main .type main, @function main: addiu $sp,$sp,-48 sd $31,40($sp) jal foo nop dsra $3,$2,32 dsrl $2,$2,48 sh $3,18($sp) sh $2,16($sp) lw $2,16($sp) sll $3,$2,16 sw $2,0($sp) sra $3,$3,16 li $2,-7 # 0xfffffffffffffff9 bne $3,$2,$L8 ld $31,40($sp) j $31 addiu $sp,$sp,48 $L8: jal abort nop With old ABI, produced code is much simpler but the structure is returned through memory. mips_retrun_in_memory returns 1 because the structure type is BLKmode. foo: li $3,-7 # 0xfffffffffffffff9 move $2,$4 sh $3,0($4) j $31 sh $3,2($4) .ent main .type main, @function main: .frame $sp,32,$31 # vars= 8, regs= 1/0, args= 16, gp= 0 addiu $sp,$sp,-32 sw $31,28($sp) jal foo addiu $4,$sp,16 lh $3,18($sp) li $2,-7 # 0xfffffffffffffff9 bne $3,$2,$L8 nop lw $31,28($sp) nop j $31 addiu $sp,$sp,32 $L8: jal abort nop > -----Original Message----- > From: gcc-ow...@gcc.gnu.org [mailto:gcc-ow...@gcc.gnu.org] On > Behalf Of Bingfeng Mei > Sent: 13 March 2009 16:35 > To: gcc@gcc.gnu.org > Cc: Adrian Ashley > Subject: Understand BLKmode and returning structure in register. > > Hello, > I came across an issue regarding BLKmode and returning > structure in register. For following code, I try to return > the structure in register instead of memory. > > extern void abort(); > typedef struct { > short x; > short y; > } COMPLEX; > > COMPLEX foo (void) __attribute__ ((noinline)); > COMPLEX foo (void) > { > COMPLEX x; > > x.x = -7; > x.y = -7; > > return x; > } > > > int main(){ > COMPLEX x = foo(); > if(x.y != -7) > abort(); > } > > > In foo function, compute_record_mode function will set the > mode for struct COMPLEX as BLKmode partly because > STRICT_ALIGNMENT is 1 on my target. In > TARGET_RETURN_IN_MEMORY hook, I return 1 for BLKmode type and > 0 otherwise for small size (<8) (like MIPS). Thus, this > structure is still returned through memory, which is not very > efficient. More importantly, ABI is NOT FIXED under such > situation. If an assembly code programmer writes a function > returning a structure. How does he know the structure will be > treated as BLKmode or otherwise? So he doesn't know whether > to pass result through memory or register. Do I understand correctly? > > On the other hand, if I return 0 only according to struct > type's size regardless BLKmode or not, GCC will produces very > inefficient code. For example, stack setup code in foo is > still generated even it is totally unnecessary. > > Only when I set STRICT_ALIGNMENT to 0, the structure can be > passed through register in an efficient way. Unfortunately, > our machine is strictly aligned and I cannot really do that. > > Any suggestion? > > Thanks, > Bingfeng Mei > Broadcom UK > > >