diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/common/atomic/sparcv9/atomic.s | 20 | ||||
-rw-r--r-- | usr/src/uts/sun4v/Makefile.files | 2 | ||||
-rw-r--r-- | usr/src/uts/sun4v/cpu/rock.c | 18 | ||||
-rw-r--r-- | usr/src/uts/sun4v/cpu/rock_asm.s | 50 | ||||
-rw-r--r-- | usr/src/uts/sun4v/cpu/rock_atomic.s | 1367 | ||||
-rw-r--r-- | usr/src/uts/sun4v/rock/Makefile | 14 |
6 files changed, 96 insertions, 1375 deletions
diff --git a/usr/src/common/atomic/sparcv9/atomic.s b/usr/src/common/atomic/sparcv9/atomic.s index aed2f7db96..5cf3526e25 100644 --- a/usr/src/common/atomic/sparcv9/atomic.s +++ b/usr/src/common/atomic/sparcv9/atomic.s @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -82,6 +82,13 @@ label/**/0: ; \ mov tmp2, %o7 /* restore callee's return address */ ; \ label/**/1: +#ifdef ATOMIC_SIMPLE_BO_ENABLE +/* + * For some processors, simple limit has proved benefical + */ +#define ATOMIC_BACKOFF_CPU(val, limit, ncpu, cas_cnt, label) \ + set 1 << ATOMIC_BO_ENABLE_SHIFT, limit +#else /* * For the kernel, we take into consideration of cas failures * and also scale the backoff limit w.r.t. the number of cpus. @@ -104,6 +111,7 @@ label/**/0: ; \ mov %g0, cas_cnt ; \ mov 1, val ; \ label/**/1: +#endif /* ATOMIC_SIMPLE_BO_ENABLE */ #endif /* ATOMIC_BO_ENABLE_SHIFT */ #else /* _KERNEL */ @@ -129,11 +137,18 @@ label/**/0: * The cas_cnt counts the cas instruction failure and is * initialized to 0. */ +#ifdef ATOMIC_SIMPLE_BO_ENABLE +#define ATOMIC_BACKOFF_INIT(val, ncpu, cas_cnt) \ + mov 1, val + +#else /* If not defined ATOMIC_SIMPLE_BO_ENABLE */ #define ATOMIC_BACKOFF_INIT(val, ncpu, cas_cnt) \ mov 1, val ; \ mov %g0, ncpu ; \ mov %g0, cas_cnt +#endif /* ATOMIC_SIMPLE_BO_ENABLE */ + #define ATOMIC_BACKOFF_BRANCH(cr, backoff, loop) \ bne,a,pn cr, backoff @@ -152,7 +167,8 @@ label/**/_1: ; \ bgu,pn %xcc, label/**/_20 /* branch to middle of DELAY_SPIN */ ; \ nop ; \ ba retlabel ; \ - sllx val, 1, val + sllx val, 1, val + #else /* ATOMIC_BO_ENABLE_SHIFT */ #define ATOMIC_BACKOFF_INIT(val, ncpu, cas_cnt) diff --git a/usr/src/uts/sun4v/Makefile.files b/usr/src/uts/sun4v/Makefile.files index 19831917cc..53bd197bac 100644 --- a/usr/src/uts/sun4v/Makefile.files +++ b/usr/src/uts/sun4v/Makefile.files @@ -188,7 +188,7 @@ NIAGARACPU_OBJS = niagara.o niagara_copy.o common_asm.o niagara_perfctr.o NIAGARACPU_OBJS += niagara_asm.o atomic.o NIAGARA2CPU_OBJS = niagara2.o niagara_copy.o common_asm.o niagara_perfctr.o NIAGARA2CPU_OBJS += niagara2_asm.o atomic.o -ROCKCPU_OBJS = rock.o rock_copy.o common_asm.o rock_atomic.o rock_asm.o +ROCKCPU_OBJS = rock.o rock_copy.o common_asm.o rock_asm.o atomic.o # # platform module diff --git a/usr/src/uts/sun4v/cpu/rock.c b/usr/src/uts/sun4v/cpu/rock.c index 1838a2806e..b5192fab57 100644 --- a/usr/src/uts/sun4v/cpu/rock.c +++ b/usr/src/uts/sun4v/cpu/rock.c @@ -56,12 +56,13 @@ #include <sys/rock_hypervisor_api.h> #include <sys/hsvc.h> #include <vm/hat_sfmmu.h> +#include <sys/mutex_impl.h> uint_t root_phys_addr_lo_mask = 0xffffffffU; uint8_t enable_tm = 1; char cpu_module_name[] = "SUNW,UltraSPARC-AT10"; -static boolean_t hsvc_tm_available = B_TRUE; +boolean_t hsvc_tm_available = B_TRUE; static hsvc_info_t rock_tm_hsvc = { HSVC_REV_1, /* HSVC rev num */ @@ -87,6 +88,8 @@ static void encode_pgsz_order(uint64_t, int, int, uint16_t *, uchar_t *); static void set_pgsz_order(uchar_t, uchar_t, uint64_t *, int *, int *, sfmmu_t *); +extern void rock_mutex_delay(void); + /* * External /etc/system tunable, for controlling whether shared or private pages * come first in the pagesize order register. @@ -273,6 +276,7 @@ void cpu_init_private(struct cpu *cp) { cpu_map_exec_units(cp); + mutex_delay = rock_mutex_delay; } /*ARGSUSED*/ @@ -289,6 +293,18 @@ cpu_uninit_private(struct cpu *cp) void cpu_feature_init(void) { + static int set_mutex_backoff_tunables = 0; + /* + * Set constants for mutex_backoff only once. + * On Rock, setting this to 8 gives the best performance, + * even for multi-chip systems. + */ + if (! set_mutex_backoff_tunables) { + mutex_backoff_base = 1; + mutex_cap_factor = 8; + set_mutex_backoff_tunables = 1; + } + /* * Enable or disable for each cpu if hypervisor API is negotiated. */ diff --git a/usr/src/uts/sun4v/cpu/rock_asm.s b/usr/src/uts/sun4v/cpu/rock_asm.s index f9b1c94894..b6df570c77 100644 --- a/usr/src/uts/sun4v/cpu/rock_asm.s +++ b/usr/src/uts/sun4v/cpu/rock_asm.s @@ -114,6 +114,13 @@ void cpu_inv_tsb(caddr_t tsb_base, uint_t tsb_bytes) {} +void +cpu_atomic_delay(void) +{} + +void +rock_mutex_delay(void) +{} #else /* lint */ /* @@ -433,4 +440,47 @@ fp_zero_zero: restore SET_SIZE(cpu_inv_tsb) +/* + * This is CPU specific delay routine for atomic backoff. + * It is used in case of Rock CPU. The rd instruction uses + * less resources than casx on these CPUs. + */ + .align 32 + ENTRY(cpu_atomic_delay) + rd %ccr, %g0 + rd %ccr, %g0 + retl + rd %ccr, %g0 + SET_SIZE(cpu_atomic_delay) + +/* + * Delay to last ~100 nano seconds on a 2.1 GHz. Membars + * should be linear and not in a loop to avoid impact + * on the sibling strand (BR pipeline is shared by + * two sibling strands). + */ + .align 64 + ENTRY(rock_mutex_delay) + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + membar #Halt + retl + membar #Halt + SET_SIZE(rock_mutex_delay) #endif /* lint */ diff --git a/usr/src/uts/sun4v/cpu/rock_atomic.s b/usr/src/uts/sun4v/cpu/rock_atomic.s deleted file mode 100644 index 426c5e3b99..0000000000 --- a/usr/src/uts/sun4v/cpu/rock_atomic.s +++ /dev/null @@ -1,1367 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <sys/asm_linkage.h> - -#ifndef chkpt -#define chkpt(FAILADDR) btrans.FAILADDR: \ - .word 0x30500000|((FAILADDR-btrans.FAILADDR)>>2) -#endif - -#ifndef commit -#define commit .word 0xbdf00000 -#endif - -#if defined(lint) - -/* ARGSUSED */ -uint8_t -cas8(uint8_t *target, uint8_t value1, uint8_t value2) -{ return (0); } - -/* ARGSUSED */ -uint32_t -cas32(uint32_t *target, uint32_t value1, uint32_t value2) -{ return (0); } - -/* ARGSUSED */ -uint64_t -cas64(uint64_t *target, uint64_t value1, uint64_t value2) -{ return (0); } - -/* ARGSUSED */ -ulong_t -caslong(ulong_t *target, ulong_t value1, ulong_t value2) -{ return (0); } - -/* ARGSUSED */ -void * -casptr(void *ptr1, void *ptr2, void *ptr3) -{ return (0); } - -/* ARGSUSED */ -void -atomic_and_long(ulong_t *target, ulong_t value) -{} - -/* ARGSUSED */ -void -atomic_or_long(ulong_t *target, ulong_t value) -{} - -/* ARGSUSED */ -void -atomic_inc_8(volatile uint8_t *target) -{} - -/* ARGSUSED */ -void -atomic_inc_uchar(volatile uchar_t *target) -{} - -/* ARGSUSED */ -void -atomic_inc_16(volatile uint16_t *target) -{} - -/* ARGSUSED */ -void -atomic_inc_ushort(volatile ushort_t *target) -{} - -/* ARGSUSED */ -void -atomic_inc_32(volatile uint32_t *target) -{} - -/* ARGSUSED */ -void -atomic_inc_uint(volatile uint_t *target) -{} - -/* ARGSUSED */ -void -atomic_inc_ulong(volatile ulong_t *target) -{} - -/* ARGSUSED */ -void -atomic_inc_64(volatile uint64_t *target) -{} - -/* ARGSUSED */ -void -atomic_dec_8(volatile uint8_t *target) -{} - -/* ARGSUSED */ -void -atomic_dec_uchar(volatile uchar_t *target) -{} - -/* ARGSUSED */ -void -atomic_dec_16(volatile uint16_t *target) -{} - -/* ARGSUSED */ -void -atomic_dec_ushort(volatile ushort_t *target) -{} - -/* ARGSUSED */ -void -atomic_dec_32(volatile uint32_t *target) -{} - -/* ARGSUSED */ -void -atomic_dec_uint(volatile uint_t *target) -{} - -/* ARGSUSED */ -void -atomic_dec_ulong(volatile ulong_t *target) -{} - -/* ARGSUSED */ -void -atomic_dec_64(volatile uint64_t *target) -{} - -/* ARGSUSED */ -void -atomic_add_8(volatile uint8_t *target, int8_t value) -{} - -/* ARGSUSED */ -void -atomic_add_char(volatile uchar_t *target, signed char value) -{} - -/* ARGSUSED */ -void -atomic_add_16(volatile uint16_t *target, int16_t delta) -{} - -/* ARGSUSED */ -void -atomic_add_ushort(volatile ushort_t *target, short value) -{} - -/* ARGSUSED */ -void -atomic_add_32(volatile uint32_t *target, int32_t delta) -{} - -/* ARGSUSED */ -void -atomic_add_ptr(volatile void *target, ssize_t value) -{} - -/* ARGSUSED */ -void -atomic_add_long(volatile ulong_t *target, long delta) -{} - -/* ARGSUSED */ -void -atomic_add_64(volatile uint64_t *target, int64_t delta) -{} - -/* ARGSUSED */ -void -atomic_or_8(volatile uint8_t *target, uint8_t bits) -{} - -/* ARGSUSED */ -void -atomic_or_uchar(volatile uchar_t *target, uchar_t bits) -{} - -/* ARGSUSED */ -void -atomic_or_16(volatile uint16_t *target, uint16_t bits) -{} - -/* ARGSUSED */ -void -atomic_or_ushort(volatile ushort_t *target, ushort_t bits) -{} - -/* ARGSUSED */ -void -atomic_or_32(volatile uint32_t *target, uint32_t bits) -{} - -/* ARGSUSED */ -void -atomic_or_uint(volatile uint_t *target, uint_t bits) -{} - -/* ARGSUSED */ -void -atomic_or_ulong(volatile ulong_t *target, ulong_t bits) -{} - -/* ARGSUSED */ -void -atomic_or_64(volatile uint64_t *target, uint64_t bits) -{} - -/* ARGSUSED */ -void -atomic_and_8(volatile uint8_t *target, uint8_t bits) -{} - -/* ARGSUSED */ -void -atomic_and_uchar(volatile uchar_t *target, uchar_t bits) -{} - -/* ARGSUSED */ -void -atomic_and_16(volatile uint16_t *target, uint16_t bits) -{} - -/* ARGSUSED */ -void -atomic_and_ushort(volatile ushort_t *target, ushort_t bits) -{} - -/* ARGSUSED */ -void -atomic_and_32(volatile uint32_t *target, uint32_t bits) -{} - -/* ARGSUSED */ -void -atomic_and_uint(volatile uint_t *target, uint_t bits) -{} - -/* ARGSUSED */ -void -atomic_and_ulong(volatile ulong_t *target, ulong_t bits) -{} - -/* ARGSUSED */ -void -atomic_and_64(volatile uint64_t *target, uint64_t bits) -{} - -/* ARGSUSED */ -uint8_t -atomic_inc_8_nv(volatile uint8_t *target) -{ return (0); } - -/* ARGSUSED */ -uchar_t -atomic_inc_uchar_nv(volatile uchar_t *target) -{ return (0); } - -/* ARGSUSED */ -uint16_t -atomic_inc_16_nv(volatile uint16_t *target) -{ return (0); } - -/* ARGSUSED */ -ushort_t -atomic_inc_ushort_nv(volatile ushort_t *target) -{ return (0); } - -/* ARGSUSED */ -uint32_t -atomic_inc_32_nv(volatile uint32_t *target) -{ return (0); } - -/* ARGSUSED */ -uint_t -atomic_inc_uint_nv(volatile uint_t *target) -{ return (0); } - -/* ARGSUSED */ -ulong_t -atomic_inc_ulong_nv(volatile ulong_t *target) -{ return (0); } - -/* ARGSUSED */ -uint64_t -atomic_inc_64_nv(volatile uint64_t *target) -{ return (0); } - -/* ARGSUSED */ -uint8_t -atomic_dec_8_nv(volatile uint8_t *target) -{ return (0); } - -/* ARGSUSED */ -uchar_t -atomic_dec_uchar_nv(volatile uchar_t *target) -{ return (0); } - -/* ARGSUSED */ -uint16_t -atomic_dec_16_nv(volatile uint16_t *target) -{ return (0); } - -/* ARGSUSED */ -ushort_t -atomic_dec_ushort_nv(volatile ushort_t *target) -{ return (0); } - -/* ARGSUSED */ -uint32_t -atomic_dec_32_nv(volatile uint32_t *target) -{ return (0); } - -/* ARGSUSED */ -uint_t -atomic_dec_uint_nv(volatile uint_t *target) -{ return (0); } - -/* ARGSUSED */ -ulong_t -atomic_dec_ulong_nv(volatile ulong_t *target) -{ return (0); } - -/* ARGSUSED */ -uint64_t -atomic_dec_64_nv(volatile uint64_t *target) -{ return (0); } - -/* ARGSUSED */ -uint8_t -atomic_add_8_nv(volatile uint8_t *target, int8_t value) -{ return (0); } - -/* ARGSUSED */ -uchar_t -atomic_add_char_nv(volatile uchar_t *target, signed char value) -{ return (0); } - -/* ARGSUSED */ -uint16_t -atomic_add_16_nv(volatile uint16_t *target, int16_t delta) -{ return (0); } - -/* ARGSUSED */ -ushort_t -atomic_add_short_nv(volatile ushort_t *target, short value) -{ return (0); } - -/* ARGSUSED */ -uint32_t -atomic_add_32_nv(volatile uint32_t *target, int32_t delta) -{ return (0); } - -/* ARGSUSED */ -uint_t -atomic_add_int_nv(volatile uint_t *target, int delta) -{ return (0); } - -/* ARGSUSED */ -void * -atomic_add_ptr_nv(volatile void *target, ssize_t value) -{ return (0); } - -/* ARGSUSED */ -ulong_t -atomic_add_long_nv(volatile ulong_t *target, long delta) -{ return (0); } - -/* ARGSUSED */ -uint64_t -atomic_add_64_nv(volatile uint64_t *target, int64_t delta) -{ return (0); } - -/* ARGSUSED */ -uint8_t -atomic_or_8_nv(volatile uint8_t *target, uint8_t value) -{ return (0); } - -/* ARGSUSED */ -uchar_t -atomic_or_uchar_nv(volatile uchar_t *target, uchar_t value) -{ return (0); } - -/* ARGSUSED */ -uint16_t -atomic_or_16_nv(volatile uint16_t *target, uint16_t value) -{ return (0); } - -/* ARGSUSED */ -ushort_t -atomic_or_ushort_nv(volatile ushort_t *target, ushort_t value) -{ return (0); } - -/* ARGSUSED */ -uint32_t -atomic_or_32_nv(volatile uint32_t *target, uint32_t value) -{ return (0); } - -/* ARGSUSED */ -uint_t -atomic_or_uint_nv(volatile uint_t *target, uint_t value) -{ return (0); } - -/* ARGSUSED */ -ulong_t -atomic_or_ulong_nv(volatile ulong_t *target, ulong_t value) -{ return (0); } - -/* ARGSUSED */ -uint64_t -atomic_or_64_nv(volatile uint64_t *target, uint64_t value) -{ return (0); } - -/* ARGSUSED */ -uint8_t -atomic_and_8_nv(volatile uint8_t *target, uint8_t value) -{ return (0); } - -/* ARGSUSED */ -uchar_t -atomic_and_uchar_nv(volatile uchar_t *target, uchar_t value) -{ return (0); } - -/* ARGSUSED */ -uint16_t -atomic_and_16_nv(volatile uint16_t *target, uint16_t value) -{ return (0); } - -/* ARGSUSED */ -ushort_t -atomic_and_ushort_nv(volatile ushort_t *target, ushort_t value) -{ return (0); } - -/* ARGSUSED */ -uint32_t -atomic_and_32_nv(volatile uint32_t *target, uint32_t value) -{ return (0); } - -/* ARGSUSED */ -uint_t -atomic_and_uint_nv(volatile uint_t *target, uint_t value) -{ return (0); } - -/* ARGSUSED */ -ulong_t -atomic_and_ulong_nv(volatile ulong_t *target, ulong_t value) -{ return (0); } - -/* ARGSUSED */ -uint64_t -atomic_and_64_nv(volatile uint64_t *target, uint64_t value) -{ return (0); } - -/* ARGSUSED */ -uint8_t -atomic_cas_8(volatile uint8_t *target, uint8_t cmp, uint8_t new) -{ return (0); } - -/* ARGSUSED */ -uchar_t -atomic_cas_uchar(volatile uchar_t *target, uchar_t cmp, uchar_t new) -{ return (0); } - -/* ARGSUSED */ -uint16_t -atomic_cas_16(volatile uint16_t *target, uint16_t cmp, uint16_t new) -{ return (0); } - -/* ARGSUSED */ -ushort_t -atomic_cas_ushort(volatile ushort_t *target, ushort_t cmp, ushort_t new) -{ return (0); } - -/* ARGSUSED */ -uint32_t -atomic_cas_32(volatile uint32_t *target, uint32_t cmp, uint32_t new) -{ return (0); } - -/* ARGSUSED */ -uint_t -atomic_cas_uint(volatile uint_t *target, uint_t cmp, uint_t new) -{ return (0); } - -/* ARGSUSED */ -ulong_t -atomic_cas_ulong(volatile ulong_t *target, ulong_t cmp, ulong_t new) -{ return (0); } - -/* ARGSUSED */ -uint64_t -atomic_cas_uint64(volatile uint64_t *target, ulong_t cmp, uint64_t new) -{ return (0); } - -/* ARGSUSED */ -void * -atomic_cas_ptr(volatile void *target, void *cmp, void *new) -{ return (0); } - -/* ARGSUSED */ -uint8_t -atomic_swap_8(volatile uint8_t *target, uint8_t new) -{ return (0); } - -/* ARGSUSED */ -uchar_t -atomic_swap_char(volatile uchar_t *target, uchar_t new) -{ return (0); } - -/* ARGSUSED */ -uint16_t -atomic_swap_16(volatile uint16_t *target, uint16_t new) -{ return (0); } - -/* ARGSUSED */ -ushort_t -atomic_swap_ushort(volatile ushort_t *target, ushort_t new) -{ return (0); } - -/* ARGSUSED */ -uint32_t -atomic_swap_32(volatile uint32_t *target, uint32_t new) -{ return (0); } - -/* ARGSUSED */ -uint_t -atomic_swap_uint(volatile uint_t *target, uint_t new) -{ return (0); } - -/* ARGSUSED */ -uint64_t -atomic_swap_64(volatile uint64_t *target, uint64_t new) -{ return (0); } - -/* ARGSUSED */ -void * -atomic_swap_ptr(volatile void *target, void *new) -{ return (0); } - -/* ARGSUSED */ -ulong_t -atomic_swap_ulong(volatile ulong_t *target, ulong_t new) -{ return (0); } - -/* ARGSUSED */ -int -atomic_set_long_excl(volatile ulong_t *target, uint_t value) -{ return (0); } - -/* ARGSUSED */ -int -atomic_clear_long_excl(volatile ulong_t *target, uint_t value) -{ return (0); } - -#else /* lint */ - - /* - * Legacy kernel interfaces; they will go away (eventually). - */ - ANSI_PRAGMA_WEAK2(cas8,atomic_cas_8,function) - ANSI_PRAGMA_WEAK2(cas32,atomic_cas_32,function) - ANSI_PRAGMA_WEAK2(cas64,atomic_cas_64,function) - ANSI_PRAGMA_WEAK2(caslong,atomic_cas_ulong,function) - ANSI_PRAGMA_WEAK2(casptr,atomic_cas_ptr,function) - ANSI_PRAGMA_WEAK2(atomic_and_long,atomic_and_ulong,function) - ANSI_PRAGMA_WEAK2(atomic_or_long,atomic_or_ulong,function) - ANSI_PRAGMA_WEAK2(swapl,atomic_swap_32,function) - - ENTRY(atomic_inc_8) - ALTENTRY(atomic_inc_8_nv) - ALTENTRY(atomic_inc_uchar) - ALTENTRY(atomic_inc_uchar_nv) - ba add_8 - add %g0, 1, %o1 - SET_SIZE(atomic_inc_uchar_nv) - SET_SIZE(atomic_inc_uchar) - SET_SIZE(atomic_inc_8_nv) - SET_SIZE(atomic_inc_8) - - ENTRY(atomic_dec_8) - ALTENTRY(atomic_dec_8_nv) - ALTENTRY(atomic_dec_uchar) - ALTENTRY(atomic_dec_uchar_nv) - ba add_8 - sub %g0, 1, %o1 - SET_SIZE(atomic_dec_uchar_nv) - SET_SIZE(atomic_dec_uchar) - SET_SIZE(atomic_dec_8_nv) - SET_SIZE(atomic_dec_8) - - ENTRY(atomic_add_8) - ALTENTRY(atomic_add_8_nv) - ALTENTRY(atomic_add_char) - ALTENTRY(atomic_add_char_nv) -add_8: chkpt (add08_tmfail) ! Enter transaction - ldub [%o0], %o2 ! read old value - add %o2, %o1, %o3 ! add value to the old value - stub %o3, [%o0] ! Store back - commit ! Commit transaction - retl - mov %o3, %o0 ! Retrun result for free in delay slot -add08_tmfail: - and %o0, 0x3, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x3, %g1 ! %g1 = byte offset, right-to-left - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - set 0xff, %o3 ! %o3 = mask - sll %o3, %g1, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single byte value - andn %o0, 0x3, %o0 ! %o0 = word address - ld [%o0], %o2 ! read old value -1: - add %o2, %o1, %o5 ! add value to the old value - and %o5, %o3, %o5 ! clear other bits - andn %o2, %o3, %o4 ! clear target bits - or %o4, %o5, %o5 ! insert the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - add %o2, %o1, %o5 - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = new value - SET_SIZE(atomic_add_char_nv) - SET_SIZE(atomic_add_char) - SET_SIZE(atomic_add_8_nv) - SET_SIZE(atomic_add_8) - - - - ENTRY(atomic_inc_16) - ALTENTRY(atomic_inc_16_nv) - ALTENTRY(atomic_inc_ushort) - ALTENTRY(atomic_inc_ushort_nv) - ba add_16 - add %g0, 1, %o1 - SET_SIZE(atomic_inc_ushort_nv) - SET_SIZE(atomic_inc_ushort) - SET_SIZE(atomic_inc_16_nv) - SET_SIZE(atomic_inc_16) - - ENTRY(atomic_dec_16) - ALTENTRY(atomic_dec_16_nv) - ALTENTRY(atomic_dec_ushort) - ALTENTRY(atomic_dec_ushort_nv) - ba add_16 - sub %g0, 1, %o1 - SET_SIZE(atomic_dec_ushort_nv) - SET_SIZE(atomic_dec_ushort) - SET_SIZE(atomic_dec_16_nv) - SET_SIZE(atomic_dec_16) - - ENTRY(atomic_add_16) - ALTENTRY(atomic_add_16_nv) - ALTENTRY(atomic_add_short) - ALTENTRY(atomic_add_short_nv) -add_16: chkpt (add16_tmfail) ! Enter transaction - lduh [%o0], %o2 ! read old value - add %o2, %o1, %o3 ! add value to the old value - stuh %o3, [%o0] ! Store back - commit ! Commit transaction - retl - mov %o3, %o0 ! Retrun result for free in delay slot -add16_tmfail: - and %o0, 0x2, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x2, %g1 ! %g1 = byte offset, right-to-left - sll %o4, 3, %o4 ! %o4 = bit offset, left-to-right - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - sethi %hi(0xffff0000), %o3 ! %o3 = mask - srl %o3, %o4, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single short value - andn %o0, 0x2, %o0 ! %o0 = word address - ! if low-order bit is 1, we will properly get an alignment fault here - ld [%o0], %o2 ! read old value -1: - add %o1, %o2, %o5 ! add value to the old value - and %o5, %o3, %o5 ! clear other bits - andn %o2, %o3, %o4 ! clear target bits - or %o4, %o5, %o5 ! insert the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - add %o1, %o2, %o5 - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = new value - SET_SIZE(atomic_add_short_nv) - SET_SIZE(atomic_add_short) - SET_SIZE(atomic_add_16_nv) - SET_SIZE(atomic_add_16) - - - - ENTRY(atomic_inc_32) - ALTENTRY(atomic_inc_32_nv) - ALTENTRY(atomic_inc_uint) - ALTENTRY(atomic_inc_uint_nv) - ba add_32 - add %g0, 1, %o1 - SET_SIZE(atomic_inc_uint_nv) - SET_SIZE(atomic_inc_uint) - SET_SIZE(atomic_inc_32_nv) - SET_SIZE(atomic_inc_32) - - ENTRY(atomic_dec_32) - ALTENTRY(atomic_dec_32_nv) - ALTENTRY(atomic_dec_uint) - ALTENTRY(atomic_dec_uint_nv) - ba add_32 - sub %g0, 1, %o1 - SET_SIZE(atomic_dec_uint_nv) - SET_SIZE(atomic_dec_uint) - SET_SIZE(atomic_dec_32_nv) - SET_SIZE(atomic_dec_32) - - ENTRY(atomic_add_32) - ALTENTRY(atomic_add_32_nv) - ALTENTRY(atomic_add_int) - ALTENTRY(atomic_add_int_nv) -add_32: chkpt (add32_tmfail) ! Enter transaction - lduw [%o0], %o2 ! read old value - add %o2, %o1, %o3 ! add value to the old value - stuw %o3, [%o0] ! Store back - commit ! Commit transaction - retl - mov %o3, %o0 ! Retrun result for free in delay slot -add32_tmfail: - ld [%o0], %o2 -1: - add %o2, %o1, %o3 - cas [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %icc, 1b - mov %o3, %o2 - retl - add %o2, %o1, %o0 ! return new value - SET_SIZE(atomic_add_int_nv) - SET_SIZE(atomic_add_int) - SET_SIZE(atomic_add_32_nv) - SET_SIZE(atomic_add_32) - - - - ENTRY(atomic_inc_64) - ALTENTRY(atomic_inc_64_nv) - ALTENTRY(atomic_inc_ulong) - ALTENTRY(atomic_inc_ulong_nv) - ba add_64 - add %g0, 1, %o1 - SET_SIZE(atomic_inc_ulong_nv) - SET_SIZE(atomic_inc_ulong) - SET_SIZE(atomic_inc_64_nv) - SET_SIZE(atomic_inc_64) - - ENTRY(atomic_dec_64) - ALTENTRY(atomic_dec_64_nv) - ALTENTRY(atomic_dec_ulong) - ALTENTRY(atomic_dec_ulong_nv) - ba add_64 - sub %g0, 1, %o1 - SET_SIZE(atomic_dec_ulong_nv) - SET_SIZE(atomic_dec_ulong) - SET_SIZE(atomic_dec_64_nv) - SET_SIZE(atomic_dec_64) - - ENTRY(atomic_add_64) - ALTENTRY(atomic_add_64_nv) - ALTENTRY(atomic_add_ptr) - ALTENTRY(atomic_add_ptr_nv) - ALTENTRY(atomic_add_long) - ALTENTRY(atomic_add_long_nv) -add_64: chkpt (add64_tmfail) ! Enter transaction - ldx [%o0], %o2 ! read old value - add %o2, %o1, %o3 ! add value to the old value - stx %o3, [%o0] ! Store back - commit ! Commit transaction - retl - mov %o3, %o0 ! Retrun result for free in delay slot -add64_tmfail: - ldx [%o0], %o2 -1: - add %o2, %o1, %o3 - casx [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %xcc, 1b - mov %o3, %o2 - retl - add %o2, %o1, %o0 ! return new value - SET_SIZE(atomic_add_long_nv) - SET_SIZE(atomic_add_long) - SET_SIZE(atomic_add_ptr_nv) - SET_SIZE(atomic_add_ptr) - SET_SIZE(atomic_add_64_nv) - SET_SIZE(atomic_add_64) - - - - ENTRY(atomic_or_8) - ALTENTRY(atomic_or_8_nv) - ALTENTRY(atomic_or_uchar) - ALTENTRY(atomic_or_uchar_nv) - chkpt (or08_tmfail) - ldub [%o0], %o2 - or %o2, %o1, %o3 - stub %o3, [%o0] - commit - retl - mov %o3, %o0 -or08_tmfail: - and %o0, 0x3, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x3, %g1 ! %g1 = byte offset, right-to-left - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - set 0xff, %o3 ! %o3 = mask - sll %o3, %g1, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single byte value - andn %o0, 0x3, %o0 ! %o0 = word address - ld [%o0], %o2 ! read old value -1: - or %o2, %o1, %o5 ! or in the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - or %o2, %o1, %o5 - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = new value - SET_SIZE(atomic_or_uchar_nv) - SET_SIZE(atomic_or_uchar) - SET_SIZE(atomic_or_8_nv) - SET_SIZE(atomic_or_8) - - - - ENTRY(atomic_or_16) - ALTENTRY(atomic_or_16_nv) - ALTENTRY(atomic_or_ushort) - ALTENTRY(atomic_or_ushort_nv) - chkpt (or16_tmfail) - lduh [%o0], %o2 - or %o2, %o1, %o3 - stuh %o3, [%o0] - commit - retl - mov %o3, %o0 -or16_tmfail: - and %o0, 0x2, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x2, %g1 ! %g1 = byte offset, right-to-left - sll %o4, 3, %o4 ! %o4 = bit offset, left-to-right - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - sethi %hi(0xffff0000), %o3 ! %o3 = mask - srl %o3, %o4, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single short value - andn %o0, 0x2, %o0 ! %o0 = word address - ! if low-order bit is 1, we will properly get an alignment fault here - ld [%o0], %o2 ! read old value -1: - or %o2, %o1, %o5 ! or in the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - or %o2, %o1, %o5 ! or in the new value - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = new value - SET_SIZE(atomic_or_ushort_nv) - SET_SIZE(atomic_or_ushort) - SET_SIZE(atomic_or_16_nv) - SET_SIZE(atomic_or_16) - - - - ENTRY(atomic_or_32) - ALTENTRY(atomic_or_32_nv) - ALTENTRY(atomic_or_uint) - ALTENTRY(atomic_or_uint_nv) - chkpt (or32_tmfail) - lduw [%o0], %o2 - or %o2, %o1, %o3 - stuw %o3, [%o0] - commit - retl - mov %o3, %o0 -or32_tmfail: - ld [%o0], %o2 -1: - or %o2, %o1, %o3 - cas [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %icc, 1b - mov %o3, %o2 - retl - or %o2, %o1, %o0 ! return new value - SET_SIZE(atomic_or_uint_nv) - SET_SIZE(atomic_or_uint) - SET_SIZE(atomic_or_32_nv) - SET_SIZE(atomic_or_32) - - - - ENTRY(atomic_or_64) - ALTENTRY(atomic_or_64_nv) - ALTENTRY(atomic_or_ulong) - ALTENTRY(atomic_or_ulong_nv) - chkpt (or64_tmfail) - ldx [%o0], %o2 - or %o2, %o1, %o3 - stx %o3, [%o0] - commit - retl - mov %o3, %o0 -or64_tmfail: - ldx [%o0], %o2 -1: - or %o2, %o1, %o3 - casx [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %xcc, 1b - mov %o3, %o2 - retl - or %o2, %o1, %o0 ! return new value - SET_SIZE(atomic_or_ulong_nv) - SET_SIZE(atomic_or_ulong) - SET_SIZE(atomic_or_64_nv) - SET_SIZE(atomic_or_64) - - - - ENTRY(atomic_and_8) - ALTENTRY(atomic_and_8_nv) - ALTENTRY(atomic_and_uchar) - ALTENTRY(atomic_and_uchar_nv) - chkpt (and08_tmfail) - ldub [%o0], %o2 - and %o2, %o1, %o3 - stub %o3, [%o0] - commit - retl - mov %o3, %o0 -and08_tmfail: - and %o0, 0x3, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x3, %g1 ! %g1 = byte offset, right-to-left - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - set 0xff, %o3 ! %o3 = mask - sll %o3, %g1, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - orn %o1, %o3, %o1 ! all ones in other bytes - andn %o0, 0x3, %o0 ! %o0 = word address - ld [%o0], %o2 ! read old value -1: - and %o2, %o1, %o5 ! and in the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - and %o2, %o1, %o5 - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = new value - SET_SIZE(atomic_and_uchar_nv) - SET_SIZE(atomic_and_uchar) - SET_SIZE(atomic_and_8_nv) - SET_SIZE(atomic_and_8) - - - - ENTRY(atomic_and_16) - ALTENTRY(atomic_and_16_nv) - ALTENTRY(atomic_and_ushort) - ALTENTRY(atomic_and_ushort_nv) - chkpt (and16_tmfail) - lduh [%o0], %o2 - and %o2, %o1, %o3 - stuh %o3, [%o0] - commit - retl - mov %o3, %o0 -and16_tmfail: - and %o0, 0x2, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x2, %g1 ! %g1 = byte offset, right-to-left - sll %o4, 3, %o4 ! %o4 = bit offset, left-to-right - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - sethi %hi(0xffff0000), %o3 ! %o3 = mask - srl %o3, %o4, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - orn %o1, %o3, %o1 ! all ones in the other half - andn %o0, 0x2, %o0 ! %o0 = word address - ! if low-order bit is 1, we will properly get an alignment fault here - ld [%o0], %o2 ! read old value -1: - and %o2, %o1, %o5 ! and in the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - and %o2, %o1, %o5 - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = new value - SET_SIZE(atomic_and_ushort_nv) - SET_SIZE(atomic_and_ushort) - SET_SIZE(atomic_and_16_nv) - SET_SIZE(atomic_and_16) - - - - ENTRY(atomic_and_32) - ALTENTRY(atomic_and_32_nv) - ALTENTRY(atomic_and_uint) - ALTENTRY(atomic_and_uint_nv) - chkpt (and32_tmfail) - lduw [%o0], %o2 - and %o2, %o1, %o3 - stuw %o3, [%o0] - commit - retl - mov %o3, %o0 -and32_tmfail: - ld [%o0], %o2 -1: - and %o2, %o1, %o3 - cas [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %icc, 1b - mov %o3, %o2 - retl - and %o2, %o1, %o0 ! return new value - SET_SIZE(atomic_and_uint_nv) - SET_SIZE(atomic_and_uint) - SET_SIZE(atomic_and_32_nv) - SET_SIZE(atomic_and_32) - - - - ENTRY(atomic_and_64) - ALTENTRY(atomic_and_64_nv) - ALTENTRY(atomic_and_ulong) - ALTENTRY(atomic_and_ulong_nv) - chkpt (and64_tmfail) - ldx [%o0], %o2 - and %o2, %o1, %o3 - stx %o3, [%o0] - commit - retl - mov %o3, %o0 -and64_tmfail: - ldx [%o0], %o2 -1: - and %o2, %o1, %o3 - casx [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %xcc, 1b - mov %o3, %o2 - retl - and %o2, %o1, %o0 ! return new value - SET_SIZE(atomic_and_ulong_nv) - SET_SIZE(atomic_and_ulong) - SET_SIZE(atomic_and_64_nv) - SET_SIZE(atomic_and_64) - - - - ENTRY(atomic_cas_8) - ALTENTRY(atomic_cas_uchar) - chkpt (cas08_tmfail) - ldub [%o0], %o3 - cmp %o3, %o1 - bne,a,pn %icc, ret_cas8 - nop - stub %o2, [%o0] - commit -ret_cas8: retl - mov %o3, %o2 -cas08_tmfail: - and %o0, 0x3, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x3, %g1 ! %g1 = byte offset, right-to-left - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - set 0xff, %o3 ! %o3 = mask - sll %o3, %g1, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single byte value - sll %o2, %g1, %o2 ! %o2 = shifted to bit offset - and %o2, %o3, %o2 ! %o2 = single byte value - andn %o0, 0x3, %o0 ! %o0 = word address - ld [%o0], %o4 ! read old value -1: - andn %o4, %o3, %o4 ! clear target bits - or %o4, %o2, %o5 ! insert the new value - or %o4, %o1, %o4 ! insert the comparison value - cas [%o0], %o4, %o5 - cmp %o4, %o5 ! did we succeed? - be,pt %icc, 2f - and %o5, %o3, %o4 ! isolate the old value - cmp %o1, %o4 ! should we have succeeded? - be,a,pt %icc, 1b ! yes, try again - mov %o5, %o4 ! %o4 = old value -2: - retl - srl %o4, %g1, %o0 ! %o0 = old value - SET_SIZE(atomic_cas_uchar) - SET_SIZE(atomic_cas_8) - - - - ENTRY(atomic_cas_16) - ALTENTRY(atomic_cas_ushort) - chkpt (cas16_tmfail) - lduh [%o0], %o3 - cmp %o3, %o1 - bne,a,pn %icc, ret_cas16 - nop - stuh %o2, [%o0] - commit -ret_cas16: retl - mov %o3, %o2 -cas16_tmfail: - and %o0, 0x2, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x2, %g1 ! %g1 = byte offset, right-to-left - sll %o4, 3, %o4 ! %o4 = bit offset, left-to-right - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - sethi %hi(0xffff0000), %o3 ! %o3 = mask - srl %o3, %o4, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single short value - sll %o2, %g1, %o2 ! %o2 = shifted to bit offset - and %o2, %o3, %o2 ! %o2 = single short value - andn %o0, 0x2, %o0 ! %o0 = word address - ! if low-order bit is 1, we will properly get an alignment fault here - ld [%o0], %o4 ! read old value -1: - andn %o4, %o3, %o4 ! clear target bits - or %o4, %o2, %o5 ! insert the new value - or %o4, %o1, %o4 ! insert the comparison value - cas [%o0], %o4, %o5 - cmp %o4, %o5 ! did we succeed? - be,pt %icc, 2f - and %o5, %o3, %o4 ! isolate the old value - cmp %o1, %o4 ! should we have succeeded? - be,a,pt %icc, 1b ! yes, try again - mov %o5, %o4 ! %o4 = old value -2: - retl - srl %o4, %g1, %o0 ! %o0 = old value - SET_SIZE(atomic_cas_ushort) - SET_SIZE(atomic_cas_16) - - - ENTRY(atomic_cas_32) - ALTENTRY(atomic_cas_uint) - cas [%o0], %o1, %o2 - retl - mov %o2, %o0 - SET_SIZE(atomic_cas_uint) - SET_SIZE(atomic_cas_32) - - - ENTRY(atomic_cas_64) - ALTENTRY(atomic_cas_ptr) - ALTENTRY(atomic_cas_ulong) - casx [%o0], %o1, %o2 - retl - mov %o2, %o0 - SET_SIZE(atomic_cas_ulong) - SET_SIZE(atomic_cas_ptr) - SET_SIZE(atomic_cas_64) - - - ENTRY(atomic_swap_8) - ALTENTRY(atomic_swap_uchar) - chkpt (swp08_tmfail) - ldub [%o0], %o2 - stub %o1, [%o0] - commit - retl - mov %o2, %o1 -swp08_tmfail: - and %o0, 0x3, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x3, %g1 ! %g1 = byte offset, right-to-left - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - set 0xff, %o3 ! %o3 = mask - sll %o3, %g1, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single byte value - andn %o0, 0x3, %o0 ! %o0 = word address - ld [%o0], %o2 ! read old value -1: - andn %o2, %o3, %o5 ! clear target bits - or %o5, %o1, %o5 ! insert the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = old value - SET_SIZE(atomic_swap_uchar) - SET_SIZE(atomic_swap_8) - - - ENTRY(atomic_swap_16) - ALTENTRY(atomic_swap_ushort) - chkpt (swp16_tmfail) - lduh [%o0], %o2 - stuh %o1, [%o0] - commit - retl - mov %o2, %o1 -swp16_tmfail: - and %o0, 0x2, %o4 ! %o4 = byte offset, left-to-right - xor %o4, 0x2, %g1 ! %g1 = byte offset, right-to-left - sll %o4, 3, %o4 ! %o4 = bit offset, left-to-right - sll %g1, 3, %g1 ! %g1 = bit offset, right-to-left - sethi %hi(0xffff0000), %o3 ! %o3 = mask - srl %o3, %o4, %o3 ! %o3 = shifted to bit offset - sll %o1, %g1, %o1 ! %o1 = shifted to bit offset - and %o1, %o3, %o1 ! %o1 = single short value - andn %o0, 0x2, %o0 ! %o0 = word address - ! if low-order bit is 1, we will properly get an alignment fault here - ld [%o0], %o2 ! read old value -1: - andn %o2, %o3, %o5 ! clear target bits - or %o5, %o1, %o5 ! insert the new value - cas [%o0], %o2, %o5 - cmp %o2, %o5 - bne,a,pn %icc, 1b - mov %o5, %o2 ! %o2 = old value - and %o5, %o3, %o5 - retl - srl %o5, %g1, %o0 ! %o0 = old value - SET_SIZE(atomic_swap_ushort) - SET_SIZE(atomic_swap_16) - - - ENTRY(atomic_swap_32) - ALTENTRY(atomic_swap_uint) - chkpt (swp32_tmfail) - lduw [%o0], %o2 - stuw %o1, [%o0] - commit - retl - mov %o2, %o1 -swp32_tmfail: - ld [%o0], %o2 -1: - mov %o1, %o3 - cas [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %icc, 1b - mov %o3, %o2 - retl - mov %o3, %o0 - SET_SIZE(atomic_swap_uint) - SET_SIZE(atomic_swap_32) - - - ENTRY(atomic_swap_64) - ALTENTRY(atomic_swap_ptr) - ALTENTRY(atomic_swap_ulong) - - chkpt (swp64_tmfail) - ldx [%o0], %o2 - stx %o1, [%o0] - commit - retl - mov %o2, %o1 -swp64_tmfail: - ldx [%o0], %o2 -1: - mov %o1, %o3 - casx [%o0], %o2, %o3 - cmp %o2, %o3 - bne,a,pn %xcc, 1b - mov %o3, %o2 - retl - mov %o3, %o0 - SET_SIZE(atomic_swap_ulong) - SET_SIZE(atomic_swap_ptr) - SET_SIZE(atomic_swap_64) - - - ENTRY(atomic_set_long_excl) - mov 1, %o3 - slln %o3, %o1, %o3 - chkpt(slong_tmfail) - ldn [%o0], %o2 - or %o2, %o3, %o4 ! set the bit, and try to commit it - stn %o4, [%o0] - commit - retl - mov %o4, %o0 -slong_tmfail: - ldn [%o0], %o2 -1: - andcc %o2, %o3, %g0 ! test if the bit is set - bnz,a,pn %ncc, 2f ! if so, then fail out - mov -1, %o0 - or %o2, %o3, %o4 ! set the bit, and try to commit it - casn [%o0], %o2, %o4 - cmp %o2, %o4 - bne,a,pn %ncc, 1b ! failed to commit, try again - mov %o4, %o2 - mov %g0, %o0 -2: - retl - nop - SET_SIZE(atomic_set_long_excl) - - - ENTRY(atomic_clear_long_excl) - mov 1, %o3 - slln %o3, %o1, %o3 - chkpt(clong_tmfail) - ldn [%o0], %o2 - andn %o2, %o3, %o4 ! clear the bit, and try to commit it - stn %o4, [%o0] - commit - retl - mov %o4, %o0 -clong_tmfail: - ldn [%o0], %o2 -1: - andncc %o3, %o2, %g0 ! test if the bit is clear - bnz,a,pn %ncc, 2f ! if so, then fail out - mov -1, %o0 - andn %o2, %o3, %o4 ! clear the bit, and try to commit it - casn [%o0], %o2, %o4 - cmp %o2, %o4 - bne,a,pn %ncc, 1b ! failed to commit, try again - mov %o4, %o2 - mov %g0, %o0 -2: - retl - nop - SET_SIZE(atomic_clear_long_excl) - -#endif /* lint */ diff --git a/usr/src/uts/sun4v/rock/Makefile b/usr/src/uts/sun4v/rock/Makefile index fe86ee0108..9a361ed6f6 100644 --- a/usr/src/uts/sun4v/rock/Makefile +++ b/usr/src/uts/sun4v/rock/Makefile @@ -20,7 +20,7 @@ # # -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This makefile drives the production of the UltraSPARC-AT10 cpu module. @@ -62,15 +62,21 @@ LINT_TARGET = $(MODULE).lint INSTALL_TARGET = def $(BINARY) $(ROOTMODULE) # +# The ATOMIC_BO_ENABLE_SHIFT enables backoff in atomic routines. +# ATOMIC_SIMPLE_BO_ENABLE enables simple backoff required for rock +# +ATOMIC_BO_FLAG = -DATOMIC_BO_ENABLE_SHIFT=14 -DATOMIC_SIMPLE_BO_ENABLE + +# # lint pass one enforcement # -CFLAGS += $(CCVERBOSE) +CFLAGS += $(CCVERBOSE) $(ATOMIC_BO_FLAG) # # cpu-module-specific flags # -CPPFLAGS += -DCPU_MODULE -AS_CPPFLAGS += -DCPU_MODULE -DCUSTOM_FPZERO +CPPFLAGS += -DCPU_MODULE $(ATOMIC_BO_FLAG) +AS_CPPFLAGS += -DCPU_MODULE -DCUSTOM_FPZERO $(ATOMIC_BO_FLAG) LINTFLAGS += -DCUSTOM_FPZERO # |