memcpy.S分析

/* 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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章