This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GCC 4.4.1 global register variables defect


Hello,

I'm just preparing to switch from GCC 4.3.2 towards GCC 4.4.1 for MIPS platform and found the following issue.
We're making use of global register variables, which work fine in GCC version 4.3.2. GCC 4.4.1 however produces slightly different code, which seems to be incorrect.

A brief example is:

//---------------test_register_call.c-------------------
register unsigned long long *g_reg_counter asm("$20");

void register_add (void)
{
  *g_reg_counter++;
}
//---------------test_register_call.c-------------------

Compiled with: 
mips-elf-gcc.exe -save-temps test_register_call.c
This produces the following assembler file using GCC 4.3.2

//---------------test_register_call_4.3.2.s-------------
	.file	1 "test_register_call.c"
	.section .mdebug.abi32
	.previous
	.gnu_attribute 4, 1
	.text
	.align	2
	.globl	register_add
	.set	nomips16
	.ent	register_add
register_add:
	.frame	$fp,8,$31		# vars= 0, regs= 1/0, args= 0, gp= 0
	.mask	0x40000000,-4
	.fmask	0x00000000,0
	.set	noreorder
	.set	nomacro
	
	addiu	$sp,$sp,-8
	sw	$fp,4($sp)
	move	$fp,$sp
	move	$2,$20
	addiu	$2,$2,8
	move	$20,$2
	move	$sp,$fp
	lw	$fp,4($sp)
	addiu	$sp,$sp,8
	j	$31
	nop

	.set	macro
	.set	reorder
	.end	register_add
	.size	register_add, .-register_add
	.ident	"GCC: 4.3.2"
//---------------test_register_call_4.3.2.s-------------

GCC 4.4.1 produces different assembly code (lines are marked):

//---------------test_register_call_4.4.1.s-------------
	.file	1 "test_register_call.c"
	.section .mdebug.abi32
	.previous
	.gnu_attribute 4, 1
	.text
	.align	2
	.globl	register_add
	.set	nomips16
	.ent	register_add
	.type	register_add, @function
register_add:
	.frame	$fp,8,$31		# vars= 0, regs= 2/0, args= 0, gp= 0
	.mask	0x40100000,-4
	.fmask	0x00000000,0
	.set	noreorder
	.set	nomacro
	
	addiu	$sp,$sp,-8
	sw	$fp,4($sp)
	sw	$20,0($sp)              # <== $20 is stored to stack
	move	$fp,$sp
	move	$2,$20
	addiu	$2,$2,8
	move	$20,$2
	move	$sp,$fp
	lw	$fp,4($sp)
	lw	$20,0($sp)              # <== $20 is restored from stack
	addiu	$sp,$sp,8
	j	$31
	nop

	.set	macro
	.set	reorder
	.end	register_add
	.size	register_add, .-register_add
	.ident	"GCC: 4.4.1"
//---------------test_register_call_4.4.1.s-------------

As can be seen in the example, MIPS register $20 is the global variable register. The variable is modified in the function and the register should therefore not be saved and restored. GCC 4.3.2 seems to be correct here. GCC 4.4.1, however, stores and restores the register $20 content. In my understanding this behaviour is incorrect.

Is this a known bug or am I missing something? Can someone reproduce this behaviour?

Thanks, Steffen


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]