// Copyright 2016 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. | |
// +build mips mipsle | |
#include "textflag.h" | |
#ifdef GOARCH_mips | |
#define MOVWHI MOVWL | |
#define MOVWLO MOVWR | |
#else | |
#define MOVWHI MOVWR | |
#define MOVWLO MOVWL | |
#endif | |
// func memmove(to, from unsafe.Pointer, n uintptr) | |
TEXT runtime·memmove(SB),NOSPLIT,$-0-12 | |
MOVW n+8(FP), R3 | |
MOVW from+4(FP), R2 | |
MOVW to+0(FP), R1 | |
ADDU R3, R2, R4 // end pointer for source | |
ADDU R3, R1, R5 // end pointer for destination | |
// if destination is ahead of source, start at the end of the buffer and go backward. | |
SGTU R1, R2, R6 | |
BNE R6, backward | |
// if less than 4 bytes, use byte by byte copying | |
SGTU $4, R3, R6 | |
BNE R6, f_small_copy | |
// align destination to 4 bytes | |
AND $3, R1, R6 | |
BEQ R6, f_dest_aligned | |
SUBU R1, R0, R6 | |
AND $3, R6 | |
MOVWHI 0(R2), R7 | |
SUBU R6, R3 | |
MOVWLO 3(R2), R7 | |
ADDU R6, R2 | |
MOVWHI R7, 0(R1) | |
ADDU R6, R1 | |
f_dest_aligned: | |
AND $31, R3, R7 | |
AND $3, R3, R6 | |
SUBU R7, R5, R7 // end pointer for 32-byte chunks | |
SUBU R6, R5, R6 // end pointer for 4-byte chunks | |
// if source is not aligned, use unaligned reads | |
AND $3, R2, R8 | |
BNE R8, f_large_ua | |
f_large: | |
BEQ R1, R7, f_words | |
ADDU $32, R1 | |
MOVW 0(R2), R8 | |
MOVW 4(R2), R9 | |
MOVW 8(R2), R10 | |
MOVW 12(R2), R11 | |
MOVW 16(R2), R12 | |
MOVW 20(R2), R13 | |
MOVW 24(R2), R14 | |
MOVW 28(R2), R15 | |
ADDU $32, R2 | |
MOVW R8, -32(R1) | |
MOVW R9, -28(R1) | |
MOVW R10, -24(R1) | |
MOVW R11, -20(R1) | |
MOVW R12, -16(R1) | |
MOVW R13, -12(R1) | |
MOVW R14, -8(R1) | |
MOVW R15, -4(R1) | |
JMP f_large | |
f_words: | |
BEQ R1, R6, f_tail | |
ADDU $4, R1 | |
MOVW 0(R2), R8 | |
ADDU $4, R2 | |
MOVW R8, -4(R1) | |
JMP f_words | |
f_tail: | |
BEQ R1, R5, ret | |
MOVWLO -1(R4), R8 | |
MOVWLO R8, -1(R5) | |
ret: | |
RET | |
f_large_ua: | |
BEQ R1, R7, f_words_ua | |
ADDU $32, R1 | |
MOVWHI 0(R2), R8 | |
MOVWHI 4(R2), R9 | |
MOVWHI 8(R2), R10 | |
MOVWHI 12(R2), R11 | |
MOVWHI 16(R2), R12 | |
MOVWHI 20(R2), R13 | |
MOVWHI 24(R2), R14 | |
MOVWHI 28(R2), R15 | |
MOVWLO 3(R2), R8 | |
MOVWLO 7(R2), R9 | |
MOVWLO 11(R2), R10 | |
MOVWLO 15(R2), R11 | |
MOVWLO 19(R2), R12 | |
MOVWLO 23(R2), R13 | |
MOVWLO 27(R2), R14 | |
MOVWLO 31(R2), R15 | |
ADDU $32, R2 | |
MOVW R8, -32(R1) | |
MOVW R9, -28(R1) | |
MOVW R10, -24(R1) | |
MOVW R11, -20(R1) | |
MOVW R12, -16(R1) | |
MOVW R13, -12(R1) | |
MOVW R14, -8(R1) | |
MOVW R15, -4(R1) | |
JMP f_large_ua | |
f_words_ua: | |
BEQ R1, R6, f_tail_ua | |
MOVWHI 0(R2), R8 | |
ADDU $4, R1 | |
MOVWLO 3(R2), R8 | |
ADDU $4, R2 | |
MOVW R8, -4(R1) | |
JMP f_words_ua | |
f_tail_ua: | |
BEQ R1, R5, ret | |
MOVWHI -4(R4), R8 | |
MOVWLO -1(R4), R8 | |
MOVWLO R8, -1(R5) | |
JMP ret | |
f_small_copy: | |
BEQ R1, R5, ret | |
ADDU $1, R1 | |
MOVB 0(R2), R6 | |
ADDU $1, R2 | |
MOVB R6, -1(R1) | |
JMP f_small_copy | |
backward: | |
SGTU $4, R3, R6 | |
BNE R6, b_small_copy | |
AND $3, R5, R6 | |
BEQ R6, b_dest_aligned | |
MOVWHI -4(R4), R7 | |
SUBU R6, R3 | |
MOVWLO -1(R4), R7 | |
SUBU R6, R4 | |
MOVWLO R7, -1(R5) | |
SUBU R6, R5 | |
b_dest_aligned: | |
AND $31, R3, R7 | |
AND $3, R3, R6 | |
ADDU R7, R1, R7 | |
ADDU R6, R1, R6 | |
AND $3, R4, R8 | |
BNE R8, b_large_ua | |
b_large: | |
BEQ R5, R7, b_words | |
ADDU $-32, R5 | |
MOVW -4(R4), R8 | |
MOVW -8(R4), R9 | |
MOVW -12(R4), R10 | |
MOVW -16(R4), R11 | |
MOVW -20(R4), R12 | |
MOVW -24(R4), R13 | |
MOVW -28(R4), R14 | |
MOVW -32(R4), R15 | |
ADDU $-32, R4 | |
MOVW R8, 28(R5) | |
MOVW R9, 24(R5) | |
MOVW R10, 20(R5) | |
MOVW R11, 16(R5) | |
MOVW R12, 12(R5) | |
MOVW R13, 8(R5) | |
MOVW R14, 4(R5) | |
MOVW R15, 0(R5) | |
JMP b_large | |
b_words: | |
BEQ R5, R6, b_tail | |
ADDU $-4, R5 | |
MOVW -4(R4), R8 | |
ADDU $-4, R4 | |
MOVW R8, 0(R5) | |
JMP b_words | |
b_tail: | |
BEQ R5, R1, ret | |
MOVWHI 0(R2), R8 // R2 and R1 have the same alignment so we don't need to load a whole word | |
MOVWHI R8, 0(R1) | |
JMP ret | |
b_large_ua: | |
BEQ R5, R7, b_words_ua | |
ADDU $-32, R5 | |
MOVWHI -4(R4), R8 | |
MOVWHI -8(R4), R9 | |
MOVWHI -12(R4), R10 | |
MOVWHI -16(R4), R11 | |
MOVWHI -20(R4), R12 | |
MOVWHI -24(R4), R13 | |
MOVWHI -28(R4), R14 | |
MOVWHI -32(R4), R15 | |
MOVWLO -1(R4), R8 | |
MOVWLO -5(R4), R9 | |
MOVWLO -9(R4), R10 | |
MOVWLO -13(R4), R11 | |
MOVWLO -17(R4), R12 | |
MOVWLO -21(R4), R13 | |
MOVWLO -25(R4), R14 | |
MOVWLO -29(R4), R15 | |
ADDU $-32, R4 | |
MOVW R8, 28(R5) | |
MOVW R9, 24(R5) | |
MOVW R10, 20(R5) | |
MOVW R11, 16(R5) | |
MOVW R12, 12(R5) | |
MOVW R13, 8(R5) | |
MOVW R14, 4(R5) | |
MOVW R15, 0(R5) | |
JMP b_large_ua | |
b_words_ua: | |
BEQ R5, R6, b_tail_ua | |
MOVWHI -4(R4), R8 | |
ADDU $-4, R5 | |
MOVWLO -1(R4), R8 | |
ADDU $-4, R4 | |
MOVW R8, 0(R5) | |
JMP b_words_ua | |
b_tail_ua: | |
BEQ R5, R1, ret | |
MOVWHI (R2), R8 | |
MOVWLO 3(R2), R8 | |
MOVWHI R8, 0(R1) | |
JMP ret | |
b_small_copy: | |
BEQ R5, R1, ret | |
ADDU $-1, R5 | |
MOVB -1(R4), R6 | |
ADDU $-1, R4 | |
MOVB R6, 0(R5) | |
JMP b_small_copy |