This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils 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]

Re: [patch] MIPS gas problems with gcc's explicit relocs


On Mon, 14 Jun 2004, Richard Sandiford wrote:

> So far, folks have been using toy cut-down examples (usually the most
> helpful thing to do, of course).  But Thiemo's example was invalid, and
> Maciej's was too if you believe the current gas behaviour to be correct.
> And both of the asms could be done easily enough in C.

 My point was and still is, with "la", etc. gas rejects a legitimate
address, which is accepted for other macros/instructions expecting an
address.  I know C code can be rewritten to work this problem around, but
it is not an excuse for keeping the bug in gas.

> So I'm curious: what's the "real" asm that started off this whole thing?

 The exact code is of course irrelevant -- the provided test cases were
sufficient to describe the bug unambiguously, though I see no problem with
disclosing it.  The relevant part of C source as well as generated
assembly is provided below.  They are modified Linux 2.4.x sources.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

semaphore.h
static inline void up(struct semaphore * sem)
{
	unsigned long tmp, tmp2, ptr;
	int count;

#if WAITQUEUE_DEBUG
	CHECK_MAGIC(sem->__magic);
#endif
	/*
	 * We must manipulate count and waking simultaneously and atomically.
	 * Otherwise we have races between up and __down_failed_interruptible
	 * waking up on a signal.
	 */

	__asm__ __volatile__(
	"	.set	mips3		# up			\n"
	"	dla	%3, %4					\n"
	"	sync						\n"
	"1:	lld	%1, (%3)				\n"
	"	dsra32	%0, %1, 0	# extract count to %0	\n"
	"	daddiu	%0, 1		# count += 1		\n"
	"	slti	%2, %0, 1	# %3 = (%0 <= 0)	\n"
	"	daddu	%1, %2		# waking += %3		\n"
	"	dsll32 %1, %1, 0	# zero-extend %1	\n"
	"	dsrl32 %1, %1, 0				\n"
	"	dsll32	%2, %0, 0	# Reassemble union	\n"
	"	or	%1, %2		# from count and waking	\n"
	"	scd	%1, (%3)				\n"
	"	beqz	%1, 1b					\n"
	"	.set	mips0					\n"
	: "=&r"(count), "=&r"(tmp), "=&r"(tmp2), "=&r"(ptr), "+m"(*sem)
	:
	: "memory");

	if (unlikely(count <= 0))
		__up_wakeup(sem);
}

printk.s
	.align	3
.L67:
	lui	$2,%highest(console_may_schedule)
	.set	noat
	addiu	$1,$0,%higher(console_may_schedule)
	daddu	$2,$2,$1
	.set	at
	lui	$6,%highest(console_sem)
	dsll	$2,$2,16
	.set	noat
	addiu	$1,$0,%higher(console_sem)
	daddu	$6,$6,$1
	.set	at
	.set	noat
	addiu	$1,$0,%hi(console_may_schedule)
	daddu	$2,$2,$1
	.set	at
	dsll	$6,$6,16
	dsll	$2,$2,16
	.set	noat
	addiu	$1,$0,%hi(console_sem)
	daddu	$6,$6,$1
	.set	at
	sw	$0,%lo(console_may_schedule)($2)
	dsll	$6,$6,16
#APP
		.set	mips3		# up			
	dla	$3, %lo(console_sem)($6)					
	sync						
1:	lld	$5, ($3)				
	dsra32	$2, $5, 0	# extract count to $2	
	daddiu	$2, 1		# count += 1		
	slti	$4, $2, 1	# $3 = ($2 <= 0)	
	daddu	$5, $4		# waking += $3		
	dsll32 $5, $5, 0	# zero-extend $5	
	dsrl32 $5, $5, 0				
	dsll32	$4, $2, 0	# Reassemble union	
	or	$5, $4		# from count and waking	
	scd	$5, ($3)				
	beqz	$5, 1b					
	.set	mips0					

#NO_APP
	sll	$2,$2,0
	slt	$2,$2,1
	dsll	$2,$2,32
	dsrl	$2,$2,32
	bne	$2,$0,.L104


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