[ARM] 2974/1: fix ARM710 swi bug workaround
[linux-2.6] / arch / arm / lib / io-writesw-armv4.S
1 /*
2  *  linux/arch/arm/lib/io-writesw-armv4.S
3  *
4  *  Copyright (C) 1995-2000 Russell King
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10 #include <linux/linkage.h>
11 #include <asm/assembler.h>
12
13                 .macro  outword, rd
14 #ifndef __ARMEB__
15                 strh    \rd, [r0]
16                 mov     \rd, \rd, lsr #16
17                 strh    \rd, [r0]
18 #else
19                 mov     lr, \rd, lsr #16
20                 strh    lr, [r0]
21                 strh    \rd, [r0]
22 #endif
23                 .endm
24
25 .outsw_align:   movs    ip, r1, lsl #31
26                 bne     .outsw_noalign
27
28                 ldrh    r3, [r1], #2
29                 sub     r2, r2, #1
30                 strh    r3, [r0]
31
32 ENTRY(__raw_writesw)
33                 teq     r2, #0
34                 moveq   pc, lr
35                 ands    r3, r1, #3
36                 bne     .outsw_align
37
38                 stmfd   sp!, {r4, r5, lr}
39
40                 subs    r2, r2, #8
41                 bmi     .no_outsw_8
42
43 .outsw_8_lp:    ldmia   r1!, {r3, r4, r5, ip}
44                 subs    r2, r2, #8
45                 outword r3
46                 outword r4
47                 outword r5
48                 outword ip
49                 bpl     .outsw_8_lp
50
51 .no_outsw_8:    tst     r2, #4
52                 beq     .no_outsw_4
53
54                 ldmia   r1!, {r3, ip}
55                 outword r3
56                 outword ip
57
58 .no_outsw_4:    movs    r2, r2, lsl #31
59                 bcc     .no_outsw_2
60
61                 ldr     r3, [r1], #4
62                 outword r3
63
64 .no_outsw_2:    ldrneh  r3, [r1]
65                 strneh  r3, [r0]
66
67                 ldmfd   sp!, {r4, r5, pc}
68
69 #ifdef __ARMEB__
70 #define pull_hbyte0     lsl #8
71 #define push_hbyte1     lsr #24
72 #else
73 #define pull_hbyte0     lsr #24
74 #define push_hbyte1     lsl #8
75 #endif
76
77 .outsw_noalign: ldr     r3, [r1, -r3]!
78                 subcs   r2, r2, #1
79                 bcs     2f
80                 subs    r2, r2, #2
81                 bmi     3f
82
83 1:              mov     ip, r3, lsr #8
84                 strh    ip, [r0]
85 2:              mov     ip, r3, pull_hbyte0
86                 ldr     r3, [r1, #4]!
87                 subs    r2, r2, #2
88                 orr     ip, ip, r3, push_hbyte1
89                 strh    ip, [r0]
90                 bpl     1b
91
92                 tst     r2, #1
93 3:              movne   ip, r3, lsr #8
94                 strneh  ip, [r0]
95                 mov     pc, lr