Messages in this thread |  | | Date | Tue, 19 Sep 2000 16:39:21 +0200 | From | Andrea Arcangeli <> | Subject | Re: GCC proposal for "@" asm constraint |
| |
On Mon, Sep 18, 2000 at 09:37:43PM -0400, John Wehle wrote: > It's perhaps not optimal, however I'm not sure that it's wrong. In
It's not "wrong" in the sense that something breaks but it's definitely suboptimal. There's no reason to reload a value that can't change because it's embedded into the opcodes of the asm and set a static linking time.
> any case if you can supply a small standalone test case (i.e. preprocessed > source code) I'll take a quick look at things. I take it that you haven't > tried the current gcc sources?
The first testcase is the current spinlock implementation, the second testcase adds the "memory" clobber and it generates the _spurious_ reload of `p'. You should be able to compile with `gcc -O2 -S p-*.i`.
Andrea # 1 "p.c" # 1 "/home/andrea/kernel/devel/2.2.18pre9aa1/include/linux/spinlock.h" 1
# 1 "/usr/include/asm/spinlock.h" 1 3
# 134 "/usr/include/asm/spinlock.h" 3
typedef struct { volatile unsigned int lock; } spinlock_t;
typedef struct { unsigned long a[100]; } __dummy_lock_t;
# 169 "/usr/include/asm/spinlock.h" 3
typedef struct { volatile unsigned int lock; unsigned long previous; } rwlock_t;
# 231 "/usr/include/asm/spinlock.h" 3
# 249 "/usr/include/asm/spinlock.h" 3
# 3 "/home/andrea/kernel/devel/2.2.18pre9aa1/include/linux/spinlock.h" 2
# 1 "p.c" 2
int * p; spinlock_t lock = (spinlock_t) { 0 } ;
void dummy(int x , int y) {}
main() { int a, b; __asm__ __volatile__( "\n1:\t" "lock ; btsl $0,%0\n\t" "jc 2f\n" ".section .text.lock,\"ax\"\n" "2:\t" "testb $1,%0\n\t" "jne 2b\n\t" "jmp 1b\n" ".previous" :"=m" ((*(__dummy_lock_t *)( &lock )) )) ; a = *p; __asm__ __volatile__( "lock ; btrl $0,%0" :"=m" ((*(__dummy_lock_t *)( &lock )) )) ;
__asm__ __volatile__( "\n1:\t" "lock ; btsl $0,%0\n\t" "jc 2f\n" ".section .text.lock,\"ax\"\n" "2:\t" "testb $1,%0\n\t" "jne 2b\n\t" "jmp 1b\n" ".previous" :"=m" ((*(__dummy_lock_t *)( &lock )) )) ; b = *p; __asm__ __volatile__( "lock ; btrl $0,%0" :"=m" ((*(__dummy_lock_t *)( &lock )) )) ;
dummy(a,b); } # 1 "p.c" # 1 "/home/andrea/kernel/devel/2.2.18pre9aa1/include/linux/spinlock.h" 1
# 1 "/usr/include/asm/spinlock.h" 1 3
# 134 "/usr/include/asm/spinlock.h" 3
typedef struct { volatile unsigned int lock; } spinlock_t;
typedef struct { unsigned long a[100]; } __dummy_lock_t;
# 169 "/usr/include/asm/spinlock.h" 3
typedef struct { volatile unsigned int lock; unsigned long previous; } rwlock_t;
# 231 "/usr/include/asm/spinlock.h" 3
# 249 "/usr/include/asm/spinlock.h" 3
# 3 "/home/andrea/kernel/devel/2.2.18pre9aa1/include/linux/spinlock.h" 2
# 1 "p.c" 2
int * p; spinlock_t lock = (spinlock_t) { 0 } ;
void dummy(int x , int y) {}
main() { int a, b; __asm__ __volatile__( "\n1:\t" "lock ; btsl $0,%0\n\t" "jc 2f\n" ".section .text.lock,\"ax\"\n" "2:\t" "testb $1,%0\n\t" "jne 2b\n\t" "jmp 1b\n" ".previous" :"=m" ((*(__dummy_lock_t *)( &lock )) ) : : "memory") ; a = *p; __asm__ __volatile__( "lock ; btrl $0,%0" :"=m" ((*(__dummy_lock_t *)( &lock )) ) : : "memory") ;
__asm__ __volatile__( "\n1:\t" "lock ; btsl $0,%0\n\t" "jc 2f\n" ".section .text.lock,\"ax\"\n" "2:\t" "testb $1,%0\n\t" "jne 2b\n\t" "jmp 1b\n" ".previous" :"=m" ((*(__dummy_lock_t *)( &lock )) ) : : "memory") ; b = *p; __asm__ __volatile__( "lock ; btrl $0,%0" :"=m" ((*(__dummy_lock_t *)( &lock )) ) : : "memory") ;
dummy(a,b); }
|  |