root/arch/arm/lib/io-writesb.S
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  linux/arch/arm/lib/io-writesb.S
 *
 *  Copyright (C) 1995-2000 Russell King
 */
#include <linux/linkage.h>
#include <asm/assembler.h>

                .macro  outword, rd
#ifndef __ARMEB__
                strb    \rd, [r0]
                mov     \rd, \rd, lsr #8
                strb    \rd, [r0]
                mov     \rd, \rd, lsr #8
                strb    \rd, [r0]
                mov     \rd, \rd, lsr #8
                strb    \rd, [r0]
#else
                mov     lr, \rd, lsr #24
                strb    lr, [r0]
                mov     lr, \rd, lsr #16
                strb    lr, [r0]
                mov     lr, \rd, lsr #8
                strb    lr, [r0]
                strb    \rd, [r0]
#endif
                .endm

.Loutsb_align:  rsb     ip, ip, #4
                cmp     ip, r2
                movgt   ip, r2
                cmp     ip, #2
                ldrb    r3, [r1], #1
                strb    r3, [r0]
                ldrbge  r3, [r1], #1
                strbge  r3, [r0]
                ldrbgt  r3, [r1], #1
                strbgt  r3, [r0]
                subs    r2, r2, ip
                bne     .Loutsb_aligned

ENTRY(__raw_writesb)
                teq     r2, #0          @ do we have to check for the zero len?
                reteq   lr
                ands    ip, r1, #3
                bne     .Loutsb_align

.Loutsb_aligned:
                stmfd   sp!, {r4, r5, lr}

                subs    r2, r2, #16
                bmi     .Loutsb_no_16

.Loutsb_16_lp:  ldmia   r1!, {r3, r4, r5, ip}
                outword r3
                outword r4
                outword r5
                outword ip
                subs    r2, r2, #16
                bpl     .Loutsb_16_lp

                tst     r2, #15
                ldmfdeq sp!, {r4, r5, pc}

.Loutsb_no_16:  tst     r2, #8
                beq     .Loutsb_no_8

                ldmia   r1!, {r3, r4}
                outword r3
                outword r4

.Loutsb_no_8:   tst     r2, #4
                beq     .Loutsb_no_4

                ldr     r3, [r1], #4
                outword r3

.Loutsb_no_4:   ands    r2, r2, #3
                ldmfdeq sp!, {r4, r5, pc}

                cmp     r2, #2
                ldrb    r3, [r1], #1
                strb    r3, [r0]
                ldrbge  r3, [r1], #1
                strbge  r3, [r0]
                ldrbgt  r3, [r1]
                strbgt  r3, [r0]

                ldmfd   sp!, {r4, r5, pc}
ENDPROC(__raw_writesb)