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