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: [email protected] [mailto:[email protected]] On
> Behalf Of Bingfeng Mei
> Sent: 13 March 2009 16:35
> To: [email protected]
> 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
>
>
>