2015-03-08 07:20:20 -06:00
|
|
|
// Copyright 2014 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
#include "textflag.h"
|
|
|
|
|
|
|
|
// void runtime·memmove(void*, void*, uintptr)
|
|
|
|
TEXT runtime·memmove(SB), NOSPLIT, $-8-24
|
|
|
|
MOVD to+0(FP), R3
|
|
|
|
MOVD from+8(FP), R4
|
|
|
|
MOVD n+16(FP), R5
|
|
|
|
CMP $0, R5
|
|
|
|
BNE check
|
|
|
|
RET
|
|
|
|
|
|
|
|
check:
|
2015-09-21 20:34:39 -06:00
|
|
|
AND $~7, R5, R7 // R7 is N&~7
|
|
|
|
// TODO(mwhudson): this is written this way to avoid tickling
|
|
|
|
// warnings from addpool when written as AND $7, R5, R6 (see
|
|
|
|
// https://golang.org/issue/12708)
|
|
|
|
SUB R7, R5, R6 // R6 is N&7
|
|
|
|
|
2015-03-08 07:20:20 -06:00
|
|
|
CMP R3, R4
|
|
|
|
BLT backward
|
|
|
|
|
2015-09-21 20:34:39 -06:00
|
|
|
// Copying forward proceeds by copying R7/8 words then copying R6 bytes.
|
|
|
|
// R3 and R4 are advanced as we copy.
|
|
|
|
|
|
|
|
// (There may be implementations of armv8 where copying by bytes until
|
|
|
|
// at least one of source or dest is word aligned is a worthwhile
|
|
|
|
// optimization, but the on the one tested so far (xgene) it did not
|
|
|
|
// make a significance difference.)
|
|
|
|
|
|
|
|
CMP $0, R7 // Do we need to do any word-by-word copying?
|
|
|
|
BEQ noforwardlarge
|
|
|
|
|
|
|
|
ADD R3, R7, R9 // R9 points just past where we copy by word
|
|
|
|
|
|
|
|
forwardlargeloop:
|
|
|
|
MOVD.P 8(R4), R8 // R8 is just a scratch register
|
|
|
|
MOVD.P R8, 8(R3)
|
|
|
|
CMP R3, R9
|
|
|
|
BNE forwardlargeloop
|
|
|
|
|
|
|
|
noforwardlarge:
|
|
|
|
CMP $0, R6 // Do we need to do any byte-by-byte copying?
|
|
|
|
BNE forwardtail
|
|
|
|
RET
|
|
|
|
|
|
|
|
forwardtail:
|
|
|
|
ADD R3, R6, R9 // R9 points just past the destination memory
|
|
|
|
|
|
|
|
forwardtailloop:
|
|
|
|
MOVBU.P 1(R4), R8
|
|
|
|
MOVBU.P R8, 1(R3)
|
|
|
|
CMP R3, R9
|
|
|
|
BNE forwardtailloop
|
2015-03-08 07:20:20 -06:00
|
|
|
RET
|
|
|
|
|
|
|
|
backward:
|
2015-09-21 20:34:39 -06:00
|
|
|
// Copying backwards proceeds by copying R6 bytes then copying R7/8 words.
|
|
|
|
// R3 and R4 are advanced to the end of the destination/source buffers
|
|
|
|
// respectively and moved back as we copy.
|
|
|
|
|
|
|
|
ADD R4, R5, R4 // R4 points just past the last source byte
|
|
|
|
ADD R3, R5, R3 // R3 points just past the last destination byte
|
|
|
|
|
|
|
|
CMP $0, R6 // Do we need to do any byte-by-byte copying?
|
|
|
|
BEQ nobackwardtail
|
|
|
|
|
|
|
|
SUB R6, R3, R9 // R9 points at the lowest destination byte that should be copied by byte.
|
|
|
|
backwardtailloop:
|
|
|
|
MOVBU.W -1(R4), R8
|
|
|
|
MOVBU.W R8, -1(R3)
|
|
|
|
CMP R9, R3
|
|
|
|
BNE backwardtailloop
|
|
|
|
|
|
|
|
nobackwardtail:
|
|
|
|
CMP $0, R7 // Do we need to do any word-by-word copying?
|
|
|
|
BNE backwardlarge
|
|
|
|
RET
|
|
|
|
|
|
|
|
backwardlarge:
|
|
|
|
SUB R7, R3, R9 // R9 points at the lowest destination byte
|
|
|
|
|
|
|
|
backwardlargeloop:
|
|
|
|
MOVD.W -8(R4), R8
|
|
|
|
MOVD.W R8, -8(R3)
|
|
|
|
CMP R9, R3
|
|
|
|
BNE backwardlargeloop
|
2015-03-08 07:20:20 -06:00
|
|
|
RET
|