mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-03 21:48:15 +00:00 
			
		
		
		
	Using optimized versions of memset and memcpy from linux brings a quite
noticeable speed (x2 or better) improvement for these two functions.
Here are some numbers for test done with jadecpu
                           | HEAD(1)| HEAD(1)| HEAD(2)| HEAD(2)|
                           |        | +patch |        | +patch |
---------------------------+--------+--------+--------+--------+
Reset to prompt            |  438ms |  330ms |  228ms |  120ms |
                           |        |        |        |        |
TFTP a 3MB img             | 4782ms | 3428ms | 3245ms | 2820ms |
                           |        |        |        |        |
FATLOAD USB a 3MB img*     | 8515ms | 8510ms | ------ | ------ |
                           |        |        |        |        |
BOOTM LZO img in RAM       | 3473ms | 3168ms |  592ms |  592ms |
 where CRC is              |  615ms |  615ms |   54ms |   54ms |
 uncompress                | 2460ms | 2462ms |  450ms |  451ms |
 final boot_elf            |  376ms |   68ms |   65ms |   65ms |
                           |        |        |        |        |
BOOTM LZO img in FLASH     | 3207ms | 2902ms | 1050ms | 1050ms |
 where CRC is              |  600ms |  600ms |  135ms |  135ms |
 uncompress                | 2209ms | 2211ms |  828ms |  828ms |
                           |        |        |        |        |
Copy 1.4MB from NOR to RAM |  134ms |   72ms |  120ms |   70ms |
(1) No dcache
(2) dcache enabled in board_init
*Does not work when dcache is on
Size impact:
C version:
   text    data     bss     dec     hex filename
 202862   18912  266456  488230   77326 u-boot
ASM version:
   text    data     bss     dec     hex filename
 203798   18912  266288  488998   77626 u-boot
222712  u-boot.bin
Signed-off-by: Matthias Weisser <weisserm@arcor.de>
		
	
			
		
			
				
	
	
		
			127 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
/*
 | 
						|
 *  linux/arch/arm/lib/memset.S
 | 
						|
 *
 | 
						|
 *  Copyright (C) 1995-2000 Russell King
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or modify
 | 
						|
 * it under the terms of the GNU General Public License version 2 as
 | 
						|
 * published by the Free Software Foundation.
 | 
						|
 *
 | 
						|
 *  ASM optimised string functions
 | 
						|
 */
 | 
						|
#include <asm/assembler.h>
 | 
						|
 | 
						|
	.text
 | 
						|
	.align	5
 | 
						|
	.word	0
 | 
						|
 | 
						|
1:	subs	r2, r2, #4		@ 1 do we have enough
 | 
						|
	blt	5f			@ 1 bytes to align with?
 | 
						|
	cmp	r3, #2			@ 1
 | 
						|
	strltb	r1, [r0], #1		@ 1
 | 
						|
	strleb	r1, [r0], #1		@ 1
 | 
						|
	strb	r1, [r0], #1		@ 1
 | 
						|
	add	r2, r2, r3		@ 1 (r2 = r2 - (4 - r3))
 | 
						|
/*
 | 
						|
 * The pointer is now aligned and the length is adjusted.  Try doing the
 | 
						|
 * memset again.
 | 
						|
 */
 | 
						|
 | 
						|
.globl memset
 | 
						|
memset:
 | 
						|
	ands	r3, r0, #3		@ 1 unaligned?
 | 
						|
	bne	1b			@ 1
 | 
						|
/*
 | 
						|
 * we know that the pointer in r0 is aligned to a word boundary.
 | 
						|
 */
 | 
						|
	orr	r1, r1, r1, lsl #8
 | 
						|
	orr	r1, r1, r1, lsl #16
 | 
						|
	mov	r3, r1
 | 
						|
	cmp	r2, #16
 | 
						|
	blt	4f
 | 
						|
 | 
						|
#if ! CALGN(1)+0
 | 
						|
 | 
						|
/*
 | 
						|
 * We need an extra register for this loop - save the return address and
 | 
						|
 * use the LR
 | 
						|
 */
 | 
						|
	str	lr, [sp, #-4]!
 | 
						|
	mov	ip, r1
 | 
						|
	mov	lr, r1
 | 
						|
 | 
						|
2:	subs	r2, r2, #64
 | 
						|
	stmgeia	r0!, {r1, r3, ip, lr}	@ 64 bytes at a time.
 | 
						|
	stmgeia	r0!, {r1, r3, ip, lr}
 | 
						|
	stmgeia	r0!, {r1, r3, ip, lr}
 | 
						|
	stmgeia	r0!, {r1, r3, ip, lr}
 | 
						|
	bgt	2b
 | 
						|
	ldmeqfd	sp!, {pc}		@ Now <64 bytes to go.
 | 
						|
/*
 | 
						|
 * No need to correct the count; we're only testing bits from now on
 | 
						|
 */
 | 
						|
	tst	r2, #32
 | 
						|
	stmneia	r0!, {r1, r3, ip, lr}
 | 
						|
	stmneia	r0!, {r1, r3, ip, lr}
 | 
						|
	tst	r2, #16
 | 
						|
	stmneia	r0!, {r1, r3, ip, lr}
 | 
						|
	ldr	lr, [sp], #4
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
/*
 | 
						|
 * This version aligns the destination pointer in order to write
 | 
						|
 * whole cache lines at once.
 | 
						|
 */
 | 
						|
 | 
						|
	stmfd	sp!, {r4-r7, lr}
 | 
						|
	mov	r4, r1
 | 
						|
	mov	r5, r1
 | 
						|
	mov	r6, r1
 | 
						|
	mov	r7, r1
 | 
						|
	mov	ip, r1
 | 
						|
	mov	lr, r1
 | 
						|
 | 
						|
	cmp	r2, #96
 | 
						|
	tstgt	r0, #31
 | 
						|
	ble	3f
 | 
						|
 | 
						|
	and	ip, r0, #31
 | 
						|
	rsb	ip, ip, #32
 | 
						|
	sub	r2, r2, ip
 | 
						|
	movs	ip, ip, lsl #(32 - 4)
 | 
						|
	stmcsia	r0!, {r4, r5, r6, r7}
 | 
						|
	stmmiia	r0!, {r4, r5}
 | 
						|
	tst	ip, #(1 << 30)
 | 
						|
	mov	ip, r1
 | 
						|
	strne	r1, [r0], #4
 | 
						|
 | 
						|
3:	subs	r2, r2, #64
 | 
						|
	stmgeia	r0!, {r1, r3-r7, ip, lr}
 | 
						|
	stmgeia	r0!, {r1, r3-r7, ip, lr}
 | 
						|
	bgt	3b
 | 
						|
	ldmeqfd	sp!, {r4-r7, pc}
 | 
						|
 | 
						|
	tst	r2, #32
 | 
						|
	stmneia	r0!, {r1, r3-r7, ip, lr}
 | 
						|
	tst	r2, #16
 | 
						|
	stmneia	r0!, {r4-r7}
 | 
						|
	ldmfd	sp!, {r4-r7, lr}
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
4:	tst	r2, #8
 | 
						|
	stmneia	r0!, {r1, r3}
 | 
						|
	tst	r2, #4
 | 
						|
	strne	r1, [r0], #4
 | 
						|
/*
 | 
						|
 * When we get here, we've got less than 4 bytes to zero.  We
 | 
						|
 * may have an unaligned pointer as well.
 | 
						|
 */
 | 
						|
5:	tst	r2, #2
 | 
						|
	strneb	r1, [r0], #1
 | 
						|
	strneb	r1, [r0], #1
 | 
						|
	tst	r2, #1
 | 
						|
	strneb	r1, [r0], #1
 | 
						|
	mov	pc, lr
 |