/* * ========== Copyright Header Begin ========================================== * * OpenSPARC T2 Processor File: SS_Memory.s * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. * * The above named program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License version 2 as published by the Free Software Foundation. * * The above named program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * ========== Copyright Header End ============================================ */ #if defined(ARCH_X64) /*============================================================================*\ * For AMD64 ABI documentation, visit http://www.x86-64.org \*============================================================================*/ .text /*============================================================================*\ * uint8_t ss_ldstub( void* base, uint64_t ofs ) \*============================================================================*/ .align 16 .globl ss_ldstub .type ss_ldstub, @function ss_ldstub: addq %rsi,%rdi movb $0xff,%al lock xchgb (%rdi),%al ret .size ss_ldstub, [.-ss_ldstub] /*============================================================================*\ * uint32_t ss_swap( uint32_t rd, void* base, uint64_t ofs ) \*============================================================================*/ .align 16 .globl ss_swap .type ss_swap, @function ss_swap: addq %rdx,%rsi bswapl %edi lock xchgl (%rsi),%edi bswapl %edi movl %edi,%eax ret .size ss_swap, [.-ss_swap] /*============================================================================*\ * uint32_t ss_cas( uint32_t rd, void* base, uint32_t rs2 ) \*============================================================================*/ .align 16 .globl ss_cas .type ss_cas, @function ss_cas: movl %edx,%eax bswapl %edi bswapl %eax lock cmpxchgl %edi,(%rsi) bswapl %eax ret .size ss_cas, [.-ss_cas] /*============================================================================*\ * uint64_t ss_casx( uint64_t rd, void* base, uint64_t rs2 ) \*============================================================================*/ .align 16 .globl ss_casx .type ss_casx, @function ss_casx: movq %rdx,%rax bswapq %rdi bswapq %rax lock cmpxchgq %rdi,(%rsi) bswapq %rax ret .size ss_casx, [.-ss_casx] /*============================================================================*\ * void ss_stp8( double rd, void* base, uint64_t mask ) * The mask register: * SPARC: * bits 76543210 * mask for byte 7 --------^^^^^^^^ * mask for byte 6 ---------+|||||| * mask for byte 5 ----------+||||| * mask for byte 4 -----------+|||| * mask for byte 3 ------------+||| * mask for byte 2 -------------+|| * mask for byte 1 --------------+| * mask for byte 0 ---------------+ * AMD64: * bits 65433210 * 35791357 * mask for byte 7 --------^^^^^^^^ * mask for byte 6 ---------+|||||| * mask for byte 5 ----------+||||| * mask for byte 4 -----------+|||| * mask for byte 3 ------------+||| * mask for byte 2 -------------+|| * mask for byte 1 --------------+| * mask for byte 0 ---------------+ \*============================================================================*/ .align 16 .globl ss_stp8 .type ss_stp8, @function ss_stp8: shlq $0x7,%rsi movq %rsi,%r8 shlq $0x7,%rsi orq %rsi,%r8 shlq $0x7,%rsi orq %rsi,%r8 shlq $0x7,%rsi orq %rsi,%r8 shlq $0x7,%rsi orq %rsi,%r8 shlq $0x7,%rsi orq %rsi,%r8 shlq $0x7,%rsi orq %rsi,%r8 shlq $0x7,%rsi orq %rsi,%r8 bswapq %r8 /* byte swap the mask */ movdq %r8,%mm1 movdq %xmm0,%r8 bswapq %r8 /* byte swap the data */ movdq %r8,%mm0 maskmovq %mm0,%mm1 ret .size ss_stp8, [.-ss_stp8] /*============================================================================*\ * uint16_t ss_byteswap16( uint16_t v ) \*============================================================================*/ .align 16 .globl ss_byteswap16 .type ss_byteswap16, @function ss_byteswap16: movw %di,%ax xchgb %ah,%al ret .size ss_byteswap16, [.-ss_byteswap16] /*============================================================================*\ * uint32_t ss_byteswap32( uint32_t v ) \*============================================================================*/ .align 16 .globl ss_byteswap32 .type ss_byteswap32, @function ss_byteswap32: movl %edi,%eax bswapl %eax ret .size ss_byteswap32, [.-ss_byteswap32] /*============================================================================*\ * uint64_t ss_byteswap64( uint64_t v ) \*============================================================================*/ .align 16 .globl ss_byteswap64 .type ss_byteswap64, @function ss_byteswap64: movq %rdi,%rax bswapq %rax ret .size ss_byteswap64, [.-ss_byteswap64] #else .register %g2,#scratch .register %g3,#scratch .section ".text" /*============================================================================*\ * uint8_t ss_ldstub( void* base, uint64_t ofs ) \*============================================================================*/ .align 8 .global ss_ldstub .type ss_ldstub, #function ss_ldstub: #if defined(ARCH_V9) #elif defined(ARCH_V8) sllx %o1,32,%o1 ! ofs is o1:o2 srl %o2,0,%o2 or %o1,%o2,%o1 #else #error "Need ARCH definition" #endif ldstub [%o0+%o1],%o0 retl nop /*============================================================================*\ * uint32_t ss_swap( uint32_t rd, void* base, uint64_t ofs ) \*============================================================================*/ .align 8 .global ss_swap .type ss_swap, #function ss_swap: #if defined(ARCH_V9) #elif defined(ARCH_V8) sllx %o2,32,%o2 ! ofs is o2:o3 srl %o3,0,%o3 or %o2,%o3,%o2 #else #error "Need ARCH definition" #endif swap [%o1+%o2],%o0 retl nop /*============================================================================*\ * uint32_t ss_cas( uint32_t rd, void* base, uint32_t rs2 ) \*============================================================================*/ .align 8 .global ss_cas .type ss_cas, #function ss_cas: casa [%o1]0x80,%o2,%o0 retl nop /*============================================================================*\ * uint64_t ss_casx( uint64_t rd, void* base, uint64_t rs2 ) \*============================================================================*/ .align 8 .global ss_casx .type ss_casx, #function ss_casx: #if defined(ARCH_V9) casxa [%o1]0x80,%o2,%o0 retl nop #elif defined(ARCH_V8) sllx %o0,32,%o0 ! rd is o0:o1 srl %o1,0,%o1 or %o0,%o1,%o1 sllx %o3,32,%o3 ! rs2 is r3:o4 srl %o4,0,%o4 or %o3,%o4,%o3 casxa [%o2]0x80,%o3,%o1 ! base is o2 retl srlx %o1,32,%o0 ! result is o0:o1 #else #error "Need ARCH definition" #endif /*============================================================================*\ * void ss_stp8( double rd, void* base, uint64_t mask ) * * Handle partial store, mask is a bytemask (ASI used intrhe stda is 0xc0) \*============================================================================*/ .align 8 .global ss_stp8 .type ss_stp8, #function ss_stp8: #if defined(ARCH_V9) retl stda %f0,[%o1 + %o2]0xc0 ! f0 is double !! (o0:o1) #elif defined(ARCH_V8) sllx %o3,32,%o3 ! mask is o3:o4 srl %o4,0,%o4 or %o3,%o4,%o3 retl stda %f0,[%o2 + %o3]0xc0 ! f0 is double !! (o0:o1) #else #error "Need ARCH definition" #endif #endif