// 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. //go:build mips || mipsle #include "textflag.h" #ifdef GOARCH_mips #define MOVWHI MOVWL #define MOVWLO MOVWR #else #define MOVWHI MOVWR #define MOVWLO MOVWL #endif // See memmove Go doc for important implementation constraints. // 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