Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

m68k: Unroll raw_outsb() loop

Unroll the raw_outsb() loop using the optimized assembler code from
raw_outsw(). That code is copied and pasted, with movew changed to moveb.

This improves the performance of sequential write transfers using mac_esp
in PIO mode by 5% or 10%. (The DMA controller on the 840av/660av models is
still unsupported so PIO transfers are used.)

Tested-by: Stan Johnson <userm57@yahoo.com>
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>

authored by

Finn Thain and committed by
Geert Uytterhoeven
b6cf523c 65102238

+35 -4
+35 -4
arch/m68k/include/asm/raw_io.h
··· 107 107 } 108 108 109 109 static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf, 110 - unsigned int len) 110 + unsigned int nr) 111 111 { 112 - unsigned int i; 112 + unsigned int tmp; 113 113 114 - for (i = 0; i < len; i++) 115 - out_8(port, *buf++); 114 + if (nr & 15) { 115 + tmp = (nr & 15) - 1; 116 + asm volatile ( 117 + "1: moveb %0@+,%2@; dbra %1,1b" 118 + : "=a" (buf), "=d" (tmp) 119 + : "a" (port), "0" (buf), 120 + "1" (tmp)); 121 + } 122 + if (nr >> 4) { 123 + tmp = (nr >> 4) - 1; 124 + asm volatile ( 125 + "1: " 126 + "moveb %0@+,%2@; " 127 + "moveb %0@+,%2@; " 128 + "moveb %0@+,%2@; " 129 + "moveb %0@+,%2@; " 130 + "moveb %0@+,%2@; " 131 + "moveb %0@+,%2@; " 132 + "moveb %0@+,%2@; " 133 + "moveb %0@+,%2@; " 134 + "moveb %0@+,%2@; " 135 + "moveb %0@+,%2@; " 136 + "moveb %0@+,%2@; " 137 + "moveb %0@+,%2@; " 138 + "moveb %0@+,%2@; " 139 + "moveb %0@+,%2@; " 140 + "moveb %0@+,%2@; " 141 + "moveb %0@+,%2@; " 142 + "dbra %1,1b" 143 + : "=a" (buf), "=d" (tmp) 144 + : "a" (port), "0" (buf), 145 + "1" (tmp)); 146 + } 116 147 } 117 148 118 149 static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr)