0N/A#
1472N/A# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
0N/A# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A#
0N/A# This code is free software; you can redistribute it and/or modify it
0N/A# under the terms of the GNU General Public License version 2 only, as
0N/A# published by the Free Software Foundation.
0N/A#
0N/A# This code is distributed in the hope that it will be useful, but WITHOUT
0N/A# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A# version 2 for more details (a copy is included in the LICENSE file that
0N/A# accompanied this code).
0N/A#
0N/A# You should have received a copy of the GNU General Public License version
0N/A# 2 along with this work; if not, write to the Free Software Foundation,
0N/A# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A#
1472N/A# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1472N/A# or visit www.oracle.com if you need additional information or have any
1472N/A# questions.
0N/A#
0N/A
0N/A
0N/A # NOTE WELL! The _Copy functions are called directly
0N/A # from server-compiler-generated code via CallLeafNoFP,
0N/A # which means that they *must* either not use floating
0N/A # point or use it in the same manner as does the server
0N/A # compiler.
0N/A
0N/A .globl _Copy_arrayof_conjoint_bytes
0N/A .globl _Copy_arrayof_conjoint_jshorts
0N/A .globl _Copy_conjoint_jshorts_atomic
0N/A .globl _Copy_arrayof_conjoint_jints
0N/A .globl _Copy_conjoint_jints_atomic
0N/A .globl _Copy_arrayof_conjoint_jlongs
0N/A .globl _Copy_conjoint_jlongs_atomic
0N/A
0N/A .text
0N/A
0N/A .globl SafeFetch32, Fetch32PFI, Fetch32Resume
0N/A .align 16
0N/A .type SafeFetch32,@function
0N/A // Prototype: int SafeFetch32 (int * Adr, int ErrValue)
0N/ASafeFetch32:
0N/A movl %esi, %eax
0N/AFetch32PFI:
0N/A movl (%rdi), %eax
0N/AFetch32Resume:
0N/A ret
0N/A
0N/A .globl SafeFetchN, FetchNPFI, FetchNResume
0N/A .align 16
0N/A .type SafeFetchN,@function
0N/A // Prototype: intptr_t SafeFetchN (intptr_t * Adr, intptr_t ErrValue)
0N/ASafeFetchN:
0N/A movq %rsi, %rax
0N/AFetchNPFI:
0N/A movq (%rdi), %rax
0N/AFetchNResume:
0N/A ret
0N/A
0N/A .globl SpinPause
0N/A .align 16
0N/A .type SpinPause,@function
0N/ASpinPause:
0N/A rep
0N/A nop
0N/A movq $1, %rax
0N/A ret
0N/A
0N/A # Support for void Copy::arrayof_conjoint_bytes(void* from,
0N/A # void* to,
0N/A # size_t count)
0N/A # rdi - from
0N/A # rsi - to
0N/A # rdx - count, treated as ssize_t
0N/A #
0N/A .p2align 4,,15
0N/A .type _Copy_arrayof_conjoint_bytes,@function
0N/A_Copy_arrayof_conjoint_bytes:
0N/A movq %rdx,%r8 # byte count
0N/A shrq $3,%rdx # qword count
0N/A cmpq %rdi,%rsi
0N/A leaq -1(%rdi,%r8,1),%rax # from + bcount*1 - 1
0N/A jbe acb_CopyRight
0N/A cmpq %rax,%rsi
0N/A jbe acb_CopyLeft
0N/Aacb_CopyRight:
0N/A leaq -8(%rdi,%rdx,8),%rax # from + qcount*8 - 8
0N/A leaq -8(%rsi,%rdx,8),%rcx # to + qcount*8 - 8
0N/A negq %rdx
0N/A jmp 7f
0N/A .p2align 4,,15
0N/A1: movq 8(%rax,%rdx,8),%rsi
0N/A movq %rsi,8(%rcx,%rdx,8)
0N/A addq $1,%rdx
0N/A jnz 1b
0N/A2: testq $4,%r8 # check for trailing dword
0N/A jz 3f
0N/A movl 8(%rax),%esi # copy trailing dword
0N/A movl %esi,8(%rcx)
0N/A addq $4,%rax
0N/A addq $4,%rcx # original %rsi is trashed, so we
0N/A # can't use it as a base register
0N/A3: testq $2,%r8 # check for trailing word
0N/A jz 4f
0N/A movw 8(%rax),%si # copy trailing word
0N/A movw %si,8(%rcx)
0N/A addq $2,%rcx
0N/A4: testq $1,%r8 # check for trailing byte
0N/A jz 5f
0N/A movb -1(%rdi,%r8,1),%al # copy trailing byte
0N/A movb %al,8(%rcx)
0N/A5: ret
0N/A .p2align 4,,15
0N/A6: movq -24(%rax,%rdx,8),%rsi
0N/A movq %rsi,-24(%rcx,%rdx,8)
0N/A movq -16(%rax,%rdx,8),%rsi
0N/A movq %rsi,-16(%rcx,%rdx,8)
0N/A movq -8(%rax,%rdx,8),%rsi
0N/A movq %rsi,-8(%rcx,%rdx,8)
0N/A movq (%rax,%rdx,8),%rsi
0N/A movq %rsi,(%rcx,%rdx,8)
0N/A7: addq $4,%rdx
0N/A jle 6b
0N/A subq $4,%rdx
0N/A jl 1b
0N/A jmp 2b
0N/Aacb_CopyLeft:
0N/A testq $1,%r8 # check for trailing byte
0N/A jz 1f
0N/A movb -1(%rdi,%r8,1),%cl # copy trailing byte
0N/A movb %cl,-1(%rsi,%r8,1)
0N/A subq $1,%r8 # adjust for possible trailing word
0N/A1: testq $2,%r8 # check for trailing word
0N/A jz 2f
0N/A movw -2(%rdi,%r8,1),%cx # copy trailing word
0N/A movw %cx,-2(%rsi,%r8,1)
0N/A2: testq $4,%r8 # check for trailing dword
0N/A jz 5f
0N/A movl (%rdi,%rdx,8),%ecx # copy trailing dword
0N/A movl %ecx,(%rsi,%rdx,8)
0N/A jmp 5f
0N/A .p2align 4,,15
0N/A3: movq -8(%rdi,%rdx,8),%rcx
0N/A movq %rcx,-8(%rsi,%rdx,8)
0N/A subq $1,%rdx
0N/A jnz 3b
0N/A ret
0N/A .p2align 4,,15
0N/A4: movq 24(%rdi,%rdx,8),%rcx
0N/A movq %rcx,24(%rsi,%rdx,8)
0N/A movq 16(%rdi,%rdx,8),%rcx
0N/A movq %rcx,16(%rsi,%rdx,8)
0N/A movq 8(%rdi,%rdx,8),%rcx
0N/A movq %rcx,8(%rsi,%rdx,8)
0N/A movq (%rdi,%rdx,8),%rcx
0N/A movq %rcx,(%rsi,%rdx,8)
0N/A5: subq $4,%rdx
0N/A jge 4b
0N/A addq $4,%rdx
0N/A jg 3b
0N/A ret
0N/A
0N/A # Support for void Copy::arrayof_conjoint_jshorts(void* from,
0N/A # void* to,
0N/A # size_t count)
0N/A # Equivalent to
0N/A # conjoint_jshorts_atomic
0N/A #
0N/A # If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we
0N/A # let the hardware handle it. The tow or four words within dwords
0N/A # or qwords that span cache line boundaries will still be loaded
0N/A # and stored atomically.
0N/A #
0N/A # rdi - from
0N/A # rsi - to
0N/A # rdx - count, treated as ssize_t
0N/A #
0N/A .p2align 4,,15
0N/A .type _Copy_arrayof_conjoint_jshorts,@function
0N/A .type _Copy_conjoint_jshorts_atomic,@function
0N/A_Copy_arrayof_conjoint_jshorts:
0N/A_Copy_conjoint_jshorts_atomic:
0N/A movq %rdx,%r8 # word count
0N/A shrq $2,%rdx # qword count
0N/A cmpq %rdi,%rsi
0N/A leaq -2(%rdi,%r8,2),%rax # from + wcount*2 - 2
0N/A jbe acs_CopyRight
0N/A cmpq %rax,%rsi
0N/A jbe acs_CopyLeft
0N/Aacs_CopyRight:
0N/A leaq -8(%rdi,%rdx,8),%rax # from + qcount*8 - 8
0N/A leaq -8(%rsi,%rdx,8),%rcx # to + qcount*8 - 8
0N/A negq %rdx
0N/A jmp 6f
0N/A1: movq 8(%rax,%rdx,8),%rsi
0N/A movq %rsi,8(%rcx,%rdx,8)
0N/A addq $1,%rdx
0N/A jnz 1b
0N/A2: testq $2,%r8 # check for trailing dword
0N/A jz 3f
0N/A movl 8(%rax),%esi # copy trailing dword
0N/A movl %esi,8(%rcx)
0N/A addq $4,%rcx # original %rsi is trashed, so we
0N/A # can't use it as a base register
0N/A3: testq $1,%r8 # check for trailing word
0N/A jz 4f
0N/A movw -2(%rdi,%r8,2),%si # copy trailing word
0N/A movw %si,8(%rcx)
0N/A4: ret
0N/A .p2align 4,,15
0N/A5: movq -24(%rax,%rdx,8),%rsi
0N/A movq %rsi,-24(%rcx,%rdx,8)
0N/A movq -16(%rax,%rdx,8),%rsi
0N/A movq %rsi,-16(%rcx,%rdx,8)
0N/A movq -8(%rax,%rdx,8),%rsi
0N/A movq %rsi,-8(%rcx,%rdx,8)
0N/A movq (%rax,%rdx,8),%rsi
0N/A movq %rsi,(%rcx,%rdx,8)
0N/A6: addq $4,%rdx
0N/A jle 5b
0N/A subq $4,%rdx
0N/A jl 1b
0N/A jmp 2b
0N/Aacs_CopyLeft:
0N/A testq $1,%r8 # check for trailing word
0N/A jz 1f
0N/A movw -2(%rdi,%r8,2),%cx # copy trailing word
0N/A movw %cx,-2(%rsi,%r8,2)
0N/A1: testq $2,%r8 # check for trailing dword
0N/A jz 4f
0N/A movl (%rdi,%rdx,8),%ecx # copy trailing dword
0N/A movl %ecx,(%rsi,%rdx,8)
0N/A jmp 4f
0N/A2: movq -8(%rdi,%rdx,8),%rcx
0N/A movq %rcx,-8(%rsi,%rdx,8)
0N/A subq $1,%rdx
0N/A jnz 2b
0N/A ret
0N/A .p2align 4,,15
0N/A3: movq 24(%rdi,%rdx,8),%rcx
0N/A movq %rcx,24(%rsi,%rdx,8)
0N/A movq 16(%rdi,%rdx,8),%rcx
0N/A movq %rcx,16(%rsi,%rdx,8)
0N/A movq 8(%rdi,%rdx,8),%rcx
0N/A movq %rcx,8(%rsi,%rdx,8)
0N/A movq (%rdi,%rdx,8),%rcx
0N/A movq %rcx,(%rsi,%rdx,8)
0N/A4: subq $4,%rdx
0N/A jge 3b
0N/A addq $4,%rdx
0N/A jg 2b
0N/A ret
0N/A
0N/A # Support for void Copy::arrayof_conjoint_jints(jint* from,
0N/A # jint* to,
0N/A # size_t count)
0N/A # Equivalent to
0N/A # conjoint_jints_atomic
0N/A #
0N/A # If 'from' and/or 'to' are aligned on 4-byte boundaries, we let
0N/A # the hardware handle it. The two dwords within qwords that span
0N/A # cache line boundaries will still be loaded and stored atomically.
0N/A #
0N/A # rdi - from
0N/A # rsi - to
0N/A # rdx - count, treated as ssize_t
0N/A #
0N/A .p2align 4,,15
0N/A .type _Copy_arrayof_conjoint_jints,@function
0N/A .type _Copy_conjoint_jints_atomic,@function
0N/A_Copy_arrayof_conjoint_jints:
0N/A_Copy_conjoint_jints_atomic:
0N/A movq %rdx,%r8 # dword count
0N/A shrq %rdx # qword count
0N/A cmpq %rdi,%rsi
0N/A leaq -4(%rdi,%r8,4),%rax # from + dcount*4 - 4
0N/A jbe aci_CopyRight
0N/A cmpq %rax,%rsi
0N/A jbe aci_CopyLeft
0N/Aaci_CopyRight:
0N/A leaq -8(%rdi,%rdx,8),%rax # from + qcount*8 - 8
0N/A leaq -8(%rsi,%rdx,8),%rcx # to + qcount*8 - 8
0N/A negq %rdx
0N/A jmp 5f
0N/A .p2align 4,,15
0N/A1: movq 8(%rax,%rdx,8),%rsi
0N/A movq %rsi,8(%rcx,%rdx,8)
0N/A addq $1,%rdx
0N/A jnz 1b
0N/A2: testq $1,%r8 # check for trailing dword
0N/A jz 3f
0N/A movl 8(%rax),%esi # copy trailing dword
0N/A movl %esi,8(%rcx)
0N/A3: ret
0N/A .p2align 4,,15
0N/A4: movq -24(%rax,%rdx,8),%rsi
0N/A movq %rsi,-24(%rcx,%rdx,8)
0N/A movq -16(%rax,%rdx,8),%rsi
0N/A movq %rsi,-16(%rcx,%rdx,8)
0N/A movq -8(%rax,%rdx,8),%rsi
0N/A movq %rsi,-8(%rcx,%rdx,8)
0N/A movq (%rax,%rdx,8),%rsi
0N/A movq %rsi,(%rcx,%rdx,8)
0N/A5: addq $4,%rdx
0N/A jle 4b
0N/A subq $4,%rdx
0N/A jl 1b
0N/A jmp 2b
0N/Aaci_CopyLeft:
0N/A testq $1,%r8 # check for trailing dword
0N/A jz 3f
0N/A movl -4(%rdi,%r8,4),%ecx # copy trailing dword
0N/A movl %ecx,-4(%rsi,%r8,4)
0N/A jmp 3f
0N/A1: movq -8(%rdi,%rdx,8),%rcx
0N/A movq %rcx,-8(%rsi,%rdx,8)
0N/A subq $1,%rdx
0N/A jnz 1b
0N/A ret
0N/A .p2align 4,,15
0N/A2: movq 24(%rdi,%rdx,8),%rcx
0N/A movq %rcx,24(%rsi,%rdx,8)
0N/A movq 16(%rdi,%rdx,8),%rcx
0N/A movq %rcx,16(%rsi,%rdx,8)
0N/A movq 8(%rdi,%rdx,8),%rcx
0N/A movq %rcx,8(%rsi,%rdx,8)
0N/A movq (%rdi,%rdx,8),%rcx
0N/A movq %rcx,(%rsi,%rdx,8)
0N/A3: subq $4,%rdx
0N/A jge 2b
0N/A addq $4,%rdx
0N/A jg 1b
0N/A ret
0N/A
0N/A # Support for void Copy::arrayof_conjoint_jlongs(jlong* from,
0N/A # jlong* to,
0N/A # size_t count)
0N/A # Equivalent to
0N/A # conjoint_jlongs_atomic
0N/A # arrayof_conjoint_oops
0N/A # conjoint_oops_atomic
0N/A #
0N/A # rdi - from
0N/A # rsi - to
0N/A # rdx - count, treated as ssize_t
0N/A #
0N/A .p2align 4,,15
0N/A .type _Copy_arrayof_conjoint_jlongs,@function
0N/A .type _Copy_conjoint_jlongs_atomic,@function
0N/A_Copy_arrayof_conjoint_jlongs:
0N/A_Copy_conjoint_jlongs_atomic:
0N/A cmpq %rdi,%rsi
0N/A leaq -8(%rdi,%rdx,8),%rax # from + count*8 - 8
0N/A jbe acl_CopyRight
0N/A cmpq %rax,%rsi
0N/A jbe acl_CopyLeft
0N/Aacl_CopyRight:
0N/A leaq -8(%rsi,%rdx,8),%rcx # to + count*8 - 8
0N/A negq %rdx
0N/A jmp 3f
0N/A1: movq 8(%rax,%rdx,8),%rsi
0N/A movq %rsi,8(%rcx,%rdx,8)
0N/A addq $1,%rdx
0N/A jnz 1b
0N/A ret
0N/A .p2align 4,,15
0N/A2: movq -24(%rax,%rdx,8),%rsi
0N/A movq %rsi,-24(%rcx,%rdx,8)
0N/A movq -16(%rax,%rdx,8),%rsi
0N/A movq %rsi,-16(%rcx,%rdx,8)
0N/A movq -8(%rax,%rdx,8),%rsi
0N/A movq %rsi,-8(%rcx,%rdx,8)
0N/A movq (%rax,%rdx,8),%rsi
0N/A movq %rsi,(%rcx,%rdx,8)
0N/A3: addq $4,%rdx
0N/A jle 2b
0N/A subq $4,%rdx
0N/A jl 1b
0N/A ret
0N/A4: movq -8(%rdi,%rdx,8),%rcx
0N/A movq %rcx,-8(%rsi,%rdx,8)
0N/A subq $1,%rdx
0N/A jnz 4b
0N/A ret
0N/A .p2align 4,,15
0N/A5: movq 24(%rdi,%rdx,8),%rcx
0N/A movq %rcx,24(%rsi,%rdx,8)
0N/A movq 16(%rdi,%rdx,8),%rcx
0N/A movq %rcx,16(%rsi,%rdx,8)
0N/A movq 8(%rdi,%rdx,8),%rcx
0N/A movq %rcx,8(%rsi,%rdx,8)
0N/A movq (%rdi,%rdx,8),%rcx
0N/A movq %rcx,(%rsi,%rdx,8)
0N/Aacl_CopyLeft:
0N/A subq $4,%rdx
0N/A jge 5b
0N/A addq $4,%rdx
0N/A jg 4b
0N/A ret