0001
0002
0003
0004
0005
0006
0007 #include <linux/linkage.h>
0008 #include <asm/assembler.h>
0009
0010 .macro pack, rd, hw1, hw2
0011 #ifndef __ARMEB__
0012 orr \rd, \hw1, \hw2, lsl #16
0013 #else
0014 orr \rd, \hw2, \hw1, lsl #16
0015 #endif
0016 .endm
0017
0018 .Linsw_align: movs ip, r1, lsl #31
0019 bne .Linsw_noalign
0020 ldrh ip, [r0]
0021 sub r2, r2, #1
0022 strh ip, [r1], #2
0023
0024 ENTRY(__raw_readsw)
0025 teq r2, #0
0026 reteq lr
0027 tst r1, #3
0028 bne .Linsw_align
0029
0030 stmfd sp!, {r4, r5, lr}
0031
0032 subs r2, r2, #8
0033 bmi .Lno_insw_8
0034
0035 .Linsw_8_lp: ldrh r3, [r0]
0036 ldrh r4, [r0]
0037 pack r3, r3, r4
0038
0039 ldrh r4, [r0]
0040 ldrh r5, [r0]
0041 pack r4, r4, r5
0042
0043 ldrh r5, [r0]
0044 ldrh ip, [r0]
0045 pack r5, r5, ip
0046
0047 ldrh ip, [r0]
0048 ldrh lr, [r0]
0049 pack ip, ip, lr
0050
0051 subs r2, r2, #8
0052 stmia r1!, {r3 - r5, ip}
0053 bpl .Linsw_8_lp
0054
0055 .Lno_insw_8: tst r2, #4
0056 beq .Lno_insw_4
0057
0058 ldrh r3, [r0]
0059 ldrh r4, [r0]
0060 pack r3, r3, r4
0061
0062 ldrh r4, [r0]
0063 ldrh ip, [r0]
0064 pack r4, r4, ip
0065
0066 stmia r1!, {r3, r4}
0067
0068 .Lno_insw_4: movs r2, r2, lsl #31
0069 bcc .Lno_insw_2
0070
0071 ldrh r3, [r0]
0072 ldrh ip, [r0]
0073 pack r3, r3, ip
0074 str r3, [r1], #4
0075
0076 .Lno_insw_2: ldrhne r3, [r0]
0077 strhne r3, [r1]
0078
0079 ldmfd sp!, {r4, r5, pc}
0080
0081 #ifdef __ARMEB__
0082 #define _BE_ONLY_(code...) code
0083 #define _LE_ONLY_(code...)
0084 #define push_hbyte0 lsr #8
0085 #define pull_hbyte1 lsl #24
0086 #else
0087 #define _BE_ONLY_(code...)
0088 #define _LE_ONLY_(code...) code
0089 #define push_hbyte0 lsl #24
0090 #define pull_hbyte1 lsr #8
0091 #endif
0092
0093 .Linsw_noalign: stmfd sp!, {r4, lr}
0094 ldrbcc ip, [r1, #-1]!
0095 bcc 1f
0096
0097 ldrh ip, [r0]
0098 sub r2, r2, #1
0099 _BE_ONLY_( mov ip, ip, ror #8 )
0100 strb ip, [r1], #1
0101 _LE_ONLY_( mov ip, ip, lsr #8 )
0102 _BE_ONLY_( mov ip, ip, lsr #24 )
0103
0104 1: subs r2, r2, #2
0105 bmi 3f
0106 _BE_ONLY_( mov ip, ip, lsl #24 )
0107
0108 2: ldrh r3, [r0]
0109 ldrh r4, [r0]
0110 subs r2, r2, #2
0111 orr ip, ip, r3, lsl #8
0112 orr ip, ip, r4, push_hbyte0
0113 str ip, [r1], #4
0114 mov ip, r4, pull_hbyte1
0115 bpl 2b
0116
0117 _BE_ONLY_( mov ip, ip, lsr #24 )
0118
0119 3: tst r2, #1
0120 strb ip, [r1], #1
0121 ldrhne ip, [r0]
0122 _BE_ONLY_( movne ip, ip, ror #8 )
0123 strbne ip, [r1], #1
0124 _LE_ONLY_( movne ip, ip, lsr #8 )
0125 _BE_ONLY_( movne ip, ip, lsr #24 )
0126 strbne ip, [r1]
0127 ldmfd sp!, {r4, pc}
0128 ENDPROC(__raw_readsw)