/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2013 Regents of the University of California
*/
#include <linux/linkage.h>
#include <asm/asm.h>
/* void *memcpy(void *, const void *, size_t) */ //a0 = des, a1 = src, a2 = size
ENTRY(memcpy)
move t6, a0 /* Preserve return value */ //t6 = a0
/* Defer to byte-oriented copy for small sizes */
sltiu a3, a2, 128 //if a2 < 128 a3 = 1 else a3 = 0
bnez a3, 4f //if a3!= 0 go 4;
/* Use word-oriented copy only if low-order bits match */ //判断源地址和目的地址对齐关系
andi a3, t6, SZREG-1 //a3 = t6 & 7;
andi a4, a1, SZREG-1 //a4 = a1 & 7;
bne a3, a4, 4f //if a3 != a4 go 4;
beqz a3, 2f /* Skip if already aligned */ // if a3 == 0 go 2;
/*
* Round to nearest double word-aligned address
* greater than or equal to start address //向上对齐到8字节
*/
andi a3, a1, ~(SZREG-1) //a3 = a1 & (~7)
addi a3, a3, SZREG //a3 = a3 + 8
/* Handle initial misalignment */ //处理开始 不对齐的
sub a4, a3, a1 //a4 = a3 - a1
1: 1:copy开头不对齐8byte的部分
lb a5, 0(a1) //a5 = a1;
addi a1, a1, 1 //a1 = a1 + 1;
sb a5, 0(t6) //t6 = a5
addi t6, t6, 1 // t6 = t6 + 1;
bltu a1, a3, 1b // if a1 < a3 continue
sub a2, a2, a4 /* Update count */ // a2 = a2 -a4;
2: 2://剩余size 128字节的对齐关系判断
andi a4, a2, ~((16*SZREG)-1) //a4 = a2 & (~(16 * SZREG) -1)
beqz a4, 4f //if a4 == 0 go 4
add a3, a1, a4 //a3 = a1 + a4
3: 3://一次copy 128字节
REG_L a4, 0(a1) //a4 = a1;(copy第一个8字节)
REG_L a5, SZREG(a1) //a5 = a1 + 8; (copy第二个8字节)
REG_L a6, 2*SZREG(a1) //....
REG_L a7, 3*SZREG(a1)
REG_L t0, 4*SZREG(a1)
REG_L t1, 5*SZREG(a1)
REG_L t2, 6*SZREG(a1)
REG_L t3, 7*SZREG(a1)
REG_L t4, 8*SZREG(a1)
REG_L t5, 9*SZREG(a1)
REG_S a4, 0(t6) //t6 = a4;
REG_S a5, SZREG(t6) //t6 + 8 = a5;
REG_S a6, 2*SZREG(t6)
REG_S a7, 3*SZREG(t6)
REG_S t0, 4*SZREG(t6)
REG_S t1, 5*SZREG(t6)
REG_S t2, 6*SZREG(t6)
REG_S t3, 7*SZREG(t6)
REG_S t4, 8*SZREG(t6)
REG_S t5, 9*SZREG(t6)
REG_L a4, 10*SZREG(a1)
REG_L a5, 11*SZREG(a1)
REG_L a6, 12*SZREG(a1)
REG_L a7, 13*SZREG(a1)
REG_L t0, 14*SZREG(a1)
REG_L t1, 15*SZREG(a1)
addi a1, a1, 16*SZREG //a1 = a1 + 16 * 8
REG_S a4, 10*SZREG(t6)
REG_S a5, 11*SZREG(t6)
REG_S a6, 12*SZREG(t6)
REG_S a7, 13*SZREG(t6)
REG_S t0, 14*SZREG(t6)
REG_S t1, 15*SZREG(t6)
addi t6, t6, 16*SZREG //t6 = t6 + 16 * 8
bltu a1, a3, 3b //if a1 < a3 go 3
andi a2, a2, (16*SZREG)-1 /* Update count */ //a2 = a2 & (16 * 8 -1)
4:
/* Handle trailing misalignment */ //处理末尾未128字节对齐的部分
beqz a2, 6f //a2 == 0 go 6;
add a3, a1, a2 //a3 = a1 + a2
/* Use word-oriented copy if co-aligned to word boundary */ 判断四字节对齐
or a5, a1, t6 //a5 = a1 | t6;
or a5, a5, a3 //a5 = a5 | a3;
andi a5, a5, 3 //a5 = a5 & 3;
bnez a5, 5f //a5 != 0 go 5
7: //一次四字节的copy
lw a4, 0(a1) //a4 = a1;
addi a1, a1, 4 //a1 = a1 + 4;
sw a4, 0(t6) //t6 = a4;
addi t6, t6, 4 //t6= t6 + 4;
bltu a1, a3, 7b //if a1 < a3 go 7
ret
5: //一次一字节的copy
lb a4, 0(a1) //a4 = a1;
addi a1, a1, 1 //a1 = a1 + 1;
sb a4, 0(t6) //t6 = a4;
addi t6, t6, 1 //t6= t6 + 1;
bltu a1, a3, 5b //if a1 < a3 go 5
6:
ret
END(memcpy)
memcpy.S分析
最新推荐文章于 2024-03-27 18:34:26 发布