150acfb2bSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */ 25d8544e2SPalmer Dabbelt/* 35d8544e2SPalmer Dabbelt * Copyright (C) 2013 Regents of the University of California 45d8544e2SPalmer Dabbelt */ 55d8544e2SPalmer Dabbelt 65d8544e2SPalmer Dabbelt#include <linux/linkage.h> 75d8544e2SPalmer Dabbelt#include <asm/asm.h> 85d8544e2SPalmer Dabbelt 95d8544e2SPalmer Dabbelt/* void *memcpy(void *, const void *, size_t) */ 108ad8b727SNick HuENTRY(__memcpy) 118ad8b727SNick HuWEAK(memcpy) 125d8544e2SPalmer Dabbelt move t6, a0 /* Preserve return value */ 135d8544e2SPalmer Dabbelt 145d8544e2SPalmer Dabbelt /* Defer to byte-oriented copy for small sizes */ 155d8544e2SPalmer Dabbelt sltiu a3, a2, 128 165d8544e2SPalmer Dabbelt bnez a3, 4f 175d8544e2SPalmer Dabbelt /* Use word-oriented copy only if low-order bits match */ 185d8544e2SPalmer Dabbelt andi a3, t6, SZREG-1 195d8544e2SPalmer Dabbelt andi a4, a1, SZREG-1 205d8544e2SPalmer Dabbelt bne a3, a4, 4f 215d8544e2SPalmer Dabbelt 225d8544e2SPalmer Dabbelt beqz a3, 2f /* Skip if already aligned */ 235d8544e2SPalmer Dabbelt /* 245d8544e2SPalmer Dabbelt * Round to nearest double word-aligned address 255d8544e2SPalmer Dabbelt * greater than or equal to start address 265d8544e2SPalmer Dabbelt */ 275d8544e2SPalmer Dabbelt andi a3, a1, ~(SZREG-1) 285d8544e2SPalmer Dabbelt addi a3, a3, SZREG 295d8544e2SPalmer Dabbelt /* Handle initial misalignment */ 305d8544e2SPalmer Dabbelt sub a4, a3, a1 315d8544e2SPalmer Dabbelt1: 325d8544e2SPalmer Dabbelt lb a5, 0(a1) 335d8544e2SPalmer Dabbelt addi a1, a1, 1 345d8544e2SPalmer Dabbelt sb a5, 0(t6) 355d8544e2SPalmer Dabbelt addi t6, t6, 1 365d8544e2SPalmer Dabbelt bltu a1, a3, 1b 375d8544e2SPalmer Dabbelt sub a2, a2, a4 /* Update count */ 385d8544e2SPalmer Dabbelt 395d8544e2SPalmer Dabbelt2: 405d8544e2SPalmer Dabbelt andi a4, a2, ~((16*SZREG)-1) 415d8544e2SPalmer Dabbelt beqz a4, 4f 425d8544e2SPalmer Dabbelt add a3, a1, a4 435d8544e2SPalmer Dabbelt3: 445d8544e2SPalmer Dabbelt REG_L a4, 0(a1) 455d8544e2SPalmer Dabbelt REG_L a5, SZREG(a1) 465d8544e2SPalmer Dabbelt REG_L a6, 2*SZREG(a1) 475d8544e2SPalmer Dabbelt REG_L a7, 3*SZREG(a1) 485d8544e2SPalmer Dabbelt REG_L t0, 4*SZREG(a1) 495d8544e2SPalmer Dabbelt REG_L t1, 5*SZREG(a1) 505d8544e2SPalmer Dabbelt REG_L t2, 6*SZREG(a1) 515d8544e2SPalmer Dabbelt REG_L t3, 7*SZREG(a1) 525d8544e2SPalmer Dabbelt REG_L t4, 8*SZREG(a1) 535d8544e2SPalmer Dabbelt REG_L t5, 9*SZREG(a1) 545d8544e2SPalmer Dabbelt REG_S a4, 0(t6) 555d8544e2SPalmer Dabbelt REG_S a5, SZREG(t6) 565d8544e2SPalmer Dabbelt REG_S a6, 2*SZREG(t6) 575d8544e2SPalmer Dabbelt REG_S a7, 3*SZREG(t6) 585d8544e2SPalmer Dabbelt REG_S t0, 4*SZREG(t6) 595d8544e2SPalmer Dabbelt REG_S t1, 5*SZREG(t6) 605d8544e2SPalmer Dabbelt REG_S t2, 6*SZREG(t6) 615d8544e2SPalmer Dabbelt REG_S t3, 7*SZREG(t6) 625d8544e2SPalmer Dabbelt REG_S t4, 8*SZREG(t6) 635d8544e2SPalmer Dabbelt REG_S t5, 9*SZREG(t6) 645d8544e2SPalmer Dabbelt REG_L a4, 10*SZREG(a1) 655d8544e2SPalmer Dabbelt REG_L a5, 11*SZREG(a1) 665d8544e2SPalmer Dabbelt REG_L a6, 12*SZREG(a1) 675d8544e2SPalmer Dabbelt REG_L a7, 13*SZREG(a1) 685d8544e2SPalmer Dabbelt REG_L t0, 14*SZREG(a1) 695d8544e2SPalmer Dabbelt REG_L t1, 15*SZREG(a1) 705d8544e2SPalmer Dabbelt addi a1, a1, 16*SZREG 715d8544e2SPalmer Dabbelt REG_S a4, 10*SZREG(t6) 725d8544e2SPalmer Dabbelt REG_S a5, 11*SZREG(t6) 735d8544e2SPalmer Dabbelt REG_S a6, 12*SZREG(t6) 745d8544e2SPalmer Dabbelt REG_S a7, 13*SZREG(t6) 755d8544e2SPalmer Dabbelt REG_S t0, 14*SZREG(t6) 765d8544e2SPalmer Dabbelt REG_S t1, 15*SZREG(t6) 775d8544e2SPalmer Dabbelt addi t6, t6, 16*SZREG 785d8544e2SPalmer Dabbelt bltu a1, a3, 3b 795d8544e2SPalmer Dabbelt andi a2, a2, (16*SZREG)-1 /* Update count */ 805d8544e2SPalmer Dabbelt 815d8544e2SPalmer Dabbelt4: 825d8544e2SPalmer Dabbelt /* Handle trailing misalignment */ 835d8544e2SPalmer Dabbelt beqz a2, 6f 845d8544e2SPalmer Dabbelt add a3, a1, a2 855d8544e2SPalmer Dabbelt 865d8544e2SPalmer Dabbelt /* Use word-oriented copy if co-aligned to word boundary */ 875d8544e2SPalmer Dabbelt or a5, a1, t6 885d8544e2SPalmer Dabbelt or a5, a5, a3 895d8544e2SPalmer Dabbelt andi a5, a5, 3 905d8544e2SPalmer Dabbelt bnez a5, 5f 915d8544e2SPalmer Dabbelt7: 925d8544e2SPalmer Dabbelt lw a4, 0(a1) 935d8544e2SPalmer Dabbelt addi a1, a1, 4 945d8544e2SPalmer Dabbelt sw a4, 0(t6) 955d8544e2SPalmer Dabbelt addi t6, t6, 4 965d8544e2SPalmer Dabbelt bltu a1, a3, 7b 975d8544e2SPalmer Dabbelt 985d8544e2SPalmer Dabbelt ret 995d8544e2SPalmer Dabbelt 1005d8544e2SPalmer Dabbelt5: 1015d8544e2SPalmer Dabbelt lb a4, 0(a1) 1025d8544e2SPalmer Dabbelt addi a1, a1, 1 1035d8544e2SPalmer Dabbelt sb a4, 0(t6) 1045d8544e2SPalmer Dabbelt addi t6, t6, 1 1055d8544e2SPalmer Dabbelt bltu a1, a3, 5b 1065d8544e2SPalmer Dabbelt6: 1075d8544e2SPalmer Dabbelt ret 1088ad8b727SNick HuEND(__memcpy) 109*26e7aacbSAlexandre GhitiSYM_FUNC_ALIAS(__pi_memcpy, __memcpy) 110*26e7aacbSAlexandre GhitiSYM_FUNC_ALIAS(__pi___memcpy, __memcpy) 111