Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / system / mem / SS_Memory.s
/*
* ========== 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