1/* 2 * linux/arch/arm/lib/io-readsw-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 pack, rd, hw1, hw2 14#ifndef __ARMEB__ 15 orr \rd, \hw1, \hw2, lsl #16 16#else 17 orr \rd, \hw2, \hw1, lsl #16 18#endif 19 .endm 20 21.Linsw_align: movs ip, r1, lsl #31 22 bne .Linsw_noalign 23 ldrh ip, [r0] 24 sub r2, r2, #1 25 strh ip, [r1], #2 26 27ENTRY(__raw_readsw) 28 teq r2, #0 29 reteq lr 30 tst r1, #3 31 bne .Linsw_align 32 33 stmfd sp!, {r4, r5, lr} 34 35 subs r2, r2, #8 36 bmi .Lno_insw_8 37 38.Linsw_8_lp: ldrh r3, [r0] 39 ldrh r4, [r0] 40 pack r3, r3, r4 41 42 ldrh r4, [r0] 43 ldrh r5, [r0] 44 pack r4, r4, r5 45 46 ldrh r5, [r0] 47 ldrh ip, [r0] 48 pack r5, r5, ip 49 50 ldrh ip, [r0] 51 ldrh lr, [r0] 52 pack ip, ip, lr 53 54 subs r2, r2, #8 55 stmia r1!, {r3 - r5, ip} 56 bpl .Linsw_8_lp 57 58.Lno_insw_8: tst r2, #4 59 beq .Lno_insw_4 60 61 ldrh r3, [r0] 62 ldrh r4, [r0] 63 pack r3, r3, r4 64 65 ldrh r4, [r0] 66 ldrh ip, [r0] 67 pack r4, r4, ip 68 69 stmia r1!, {r3, r4} 70 71.Lno_insw_4: movs r2, r2, lsl #31 72 bcc .Lno_insw_2 73 74 ldrh r3, [r0] 75 ldrh ip, [r0] 76 pack r3, r3, ip 77 str r3, [r1], #4 78 79.Lno_insw_2: ldrneh r3, [r0] 80 strneh r3, [r1] 81 82 ldmfd sp!, {r4, r5, pc} 83 84#ifdef __ARMEB__ 85#define _BE_ONLY_(code...) code 86#define _LE_ONLY_(code...) 87#define push_hbyte0 lsr #8 88#define pull_hbyte1 lsl #24 89#else 90#define _BE_ONLY_(code...) 91#define _LE_ONLY_(code...) code 92#define push_hbyte0 lsl #24 93#define pull_hbyte1 lsr #8 94#endif 95 96.Linsw_noalign: stmfd sp!, {r4, lr} 97 ldrccb ip, [r1, #-1]! 98 bcc 1f 99 100 ldrh ip, [r0] 101 sub r2, r2, #1 102 _BE_ONLY_( mov ip, ip, ror #8 ) 103 strb ip, [r1], #1 104 _LE_ONLY_( mov ip, ip, lsr #8 ) 105 _BE_ONLY_( mov ip, ip, lsr #24 ) 106 1071: subs r2, r2, #2 108 bmi 3f 109 _BE_ONLY_( mov ip, ip, lsl #24 ) 110 1112: ldrh r3, [r0] 112 ldrh r4, [r0] 113 subs r2, r2, #2 114 orr ip, ip, r3, lsl #8 115 orr ip, ip, r4, push_hbyte0 116 str ip, [r1], #4 117 mov ip, r4, pull_hbyte1 118 bpl 2b 119 120 _BE_ONLY_( mov ip, ip, lsr #24 ) 121 1223: tst r2, #1 123 strb ip, [r1], #1 124 ldrneh ip, [r0] 125 _BE_ONLY_( movne ip, ip, ror #8 ) 126 strneb ip, [r1], #1 127 _LE_ONLY_( movne ip, ip, lsr #8 ) 128 _BE_ONLY_( movne ip, ip, lsr #24 ) 129 strneb ip, [r1] 130 ldmfd sp!, {r4, pc} 131ENDPROC(__raw_readsw) 132