0001
0002
0003
0004
0005
0006
0007 #include <linux/linkage.h>
0008 #include <asm/assembler.h>
0009
0010 .macro outword, rd
0011 #ifndef __ARMEB__
0012 strh \rd, [r0]
0013 mov \rd, \rd, lsr #16
0014 strh \rd, [r0]
0015 #else
0016 mov lr, \rd, lsr #16
0017 strh lr, [r0]
0018 strh \rd, [r0]
0019 #endif
0020 .endm
0021
0022 .Loutsw_align: movs ip, r1, lsl #31
0023 bne .Loutsw_noalign
0024
0025 ldrh r3, [r1], #2
0026 sub r2, r2, #1
0027 strh r3, [r0]
0028
0029 ENTRY(__raw_writesw)
0030 teq r2, #0
0031 reteq lr
0032 ands r3, r1, #3
0033 bne .Loutsw_align
0034
0035 stmfd sp!, {r4, r5, lr}
0036
0037 subs r2, r2, #8
0038 bmi .Lno_outsw_8
0039
0040 .Loutsw_8_lp: ldmia r1!, {r3, r4, r5, ip}
0041 subs r2, r2, #8
0042 outword r3
0043 outword r4
0044 outword r5
0045 outword ip
0046 bpl .Loutsw_8_lp
0047
0048 .Lno_outsw_8: tst r2, #4
0049 beq .Lno_outsw_4
0050
0051 ldmia r1!, {r3, ip}
0052 outword r3
0053 outword ip
0054
0055 .Lno_outsw_4: movs r2, r2, lsl #31
0056 bcc .Lno_outsw_2
0057
0058 ldr r3, [r1], #4
0059 outword r3
0060
0061 .Lno_outsw_2: ldrhne r3, [r1]
0062 strhne r3, [r0]
0063
0064 ldmfd sp!, {r4, r5, pc}
0065
0066 #ifdef __ARMEB__
0067 #define pull_hbyte0 lsl #8
0068 #define push_hbyte1 lsr #24
0069 #else
0070 #define pull_hbyte0 lsr #24
0071 #define push_hbyte1 lsl #8
0072 #endif
0073
0074 .Loutsw_noalign:
0075 ARM( ldr r3, [r1, -r3]! )
0076 THUMB( rsb r3, r3, #0 )
0077 THUMB( ldr r3, [r1, r3] )
0078 THUMB( sub r1, r3 )
0079 subcs r2, r2, #1
0080 bcs 2f
0081 subs r2, r2, #2
0082 bmi 3f
0083
0084 1: mov ip, r3, lsr #8
0085 strh ip, [r0]
0086 2: mov ip, r3, pull_hbyte0
0087 ldr r3, [r1, #4]!
0088 subs r2, r2, #2
0089 orr ip, ip, r3, push_hbyte1
0090 strh ip, [r0]
0091 bpl 1b
0092
0093 tst r2, #1
0094 3: movne ip, r3, lsr #8
0095 strhne ip, [r0]
0096 ret lr
0097 ENDPROC(__raw_writesw)