#endif
.endm
-.insw_bad_alignment:
- adr r0, .insw_bad_align_msg
- mov r2, lr
- b panic
-.insw_bad_align_msg:
- .asciz "insw: bad buffer alignment (0x%p, lr=0x%08lX)\n"
- .align
-
-.insw_align: tst r1, #1
- bne .insw_bad_alignment
-
- ldrh r3, [r0]
- strh r3, [r1], #2
-
- subs r2, r2, #1
- RETINSTR(moveq, pc, lr)
+.insw_align: movs ip, r1, lsl #31
+ bne .insw_noalign
+ ldrh ip, [r0]
+ sub r2, r2, #1
+ strh ip, [r1], #2
ENTRY(__raw_readsw)
- teq r2, #0 @ do we have to check for the zero len?
+ teq r2, #0
moveq pc, lr
tst r1, #3
bne .insw_align
ldrh lr, [r0]
pack ip, ip, lr
- stmia r1!, {r3 - r5, ip}
-
subs r2, r2, #8
+ stmia r1!, {r3 - r5, ip}
bpl .insw_8_lp
- tst r2, #7
- LOADREGS(eqfd, sp!, {r4, r5, pc})
-
.no_insw_8: tst r2, #4
beq .no_insw_4
stmia r1!, {r3, r4}
-.no_insw_4: tst r2, #2
- beq .no_insw_2
+.no_insw_4: movs r2, r2, lsl #31
+ bcc .no_insw_2
ldrh r3, [r0]
ldrh ip, [r0]
pack r3, r3, ip
-
str r3, [r1], #4
-.no_insw_2: tst r2, #1
- ldrneh r3, [r0]
+.no_insw_2: ldrneh r3, [r0]
strneh r3, [r1]
- LOADREGS(fd, sp!, {r4, r5, pc})
+ ldmfd sp!, {r4, r5, pc}
+
+#ifdef __ARMEB__
+#define _BE_ONLY_(code...) code
+#define _LE_ONLY_(code...)
+#define push_hbyte0 lsr #8
+#define pull_hbyte1 lsl #24
+#else
+#define _BE_ONLY_(code...)
+#define _LE_ONLY_(code...) code
+#define push_hbyte0 lsl #24
+#define pull_hbyte1 lsr #8
+#endif
+
+.insw_noalign: stmfd sp!, {r4, lr}
+ ldrccb ip, [r1, #-1]!
+ bcc 1f
+
+ ldrh ip, [r0]
+ sub r2, r2, #1
+ _BE_ONLY_( mov ip, ip, ror #8 )
+ strb ip, [r1], #1
+ _LE_ONLY_( mov ip, ip, lsr #8 )
+ _BE_ONLY_( mov ip, ip, lsr #24 )
+
+1: subs r2, r2, #2
+ bmi 3f
+ _BE_ONLY_( mov ip, ip, lsl #24 )
+
+2: ldrh r3, [r0]
+ ldrh r4, [r0]
+ subs r2, r2, #2
+ orr ip, ip, r3, lsl #8
+ orr ip, ip, r4, push_hbyte0
+ str ip, [r1], #4
+ mov ip, r4, pull_hbyte1
+ bpl 2b
+
+ _BE_ONLY_( mov ip, ip, lsr #24 )
+
+3: tst r2, #1
+ strb ip, [r1], #1
+ ldrneh ip, [r0]
+ _BE_ONLY_( movne ip, ip, ror #8 )
+ strneb ip, [r1], #1
+ _LE_ONLY_( movne ip, ip, lsr #8 )
+ _BE_ONLY_( movne ip, ip, lsr #24 )
+ strneb ip, [r1]
+ ldmfd sp!, {r4, pc}