/* $NetBSD: bus_space_asm_generic.S,v 1.7 2024/02/07 04:20:26 msaitoh Exp $ */ /* * Copyright (c) 2017 Ryo Shimizu * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include "assym.h" RCSID("$NetBSD: bus_space_asm_generic.S,v 1.7 2024/02/07 04:20:26 msaitoh Exp $") .macro generate_bsfunc funcname, dsbop /* uint8_t {funcname}_bs_r_1(x0:tag, x1:addr, x2:offset) */ ENTRY_NP(\funcname\()_bs_r_1) \dsbop ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ ldrb w0, [x1, x8] ret END(\funcname\()_bs_r_1) /* uint16_t {funcname}_bs_r_2(x0:tag, x1:addr, x2:offset) */ ENTRY_NP(\funcname\()_bs_r_2) \dsbop ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ ldrh w0, [x1, x8] ret END(\funcname\()_bs_r_2) /* uint32_t {funcname}_bs_r_4(x0:tag, x1:addr, x2:offset) */ ENTRY_NP(\funcname\()_bs_r_4) \dsbop ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ ldr w0, [x1, x8] ret END(\funcname\()_bs_r_4) /* uint64_t {funcname}_bs_r_8(x0:tag, x1:addr, x2:offset) */ ENTRY_NP(\funcname\()_bs_r_8) \dsbop ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ ldr x0, [x1, x8] ret END(\funcname\()_bs_r_8) /* uint16_t {funcname}_bs_r_2_swap(x0:tag, x1:addr, x2:offset) */ ENTRY_NP(\funcname\()_bs_r_2_swap) \dsbop ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ ldrh w0, [x1, x8] rev16 w0, w0 ret END(\funcname\()_bs_r_2_swap) /* uint32_t {funcname}_bs_r_4_swap(x0:tag, x1:addr, x2:offset) */ ENTRY_NP(\funcname\()_bs_r_4_swap) \dsbop ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ ldr w0, [x1, x8] rev w0, w0 ret END(\funcname\()_bs_r_4_swap) /* uint64_t {funcname}_bs_r_8_swap(x0:tag, x1:addr, x2:offset) */ ENTRY_NP(\funcname\()_bs_r_8_swap) \dsbop ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ ldr x0, [x1, x8] rev x0, x0 ret END(\funcname\()_bs_r_8_swap) /* void {funcname}_bs_rm_1(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_rm_1) #ifdef DIAGNOSTIC cbz x4, 99f #endif \dsbop ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: ldrb w9, [x1, x8] subs x4, x4, #1 /* count-- */ strb w9, [x3], #1 b.ne 1b ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_rm_1: count == 0" #endif END(\funcname\()_bs_rm_1) /* void {funcname}_bs_rm_2(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_rm_2) #ifdef DIAGNOSTIC cbz x4, 99f #endif \dsbop ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: ldrh w9, [x1, x8] subs x4, x4, #1 /* count-- */ strh w9, [x3], #2 b.ne 1b ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_rm_2: count == 0" #endif END(\funcname\()_bs_rm_2) /* void {funcname}_bs_rm_4(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_rm_4) #ifdef DIAGNOSTIC cbz x4, 99f #endif \dsbop ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr w9, [x1, x8] subs x4, x4, #1 /* count-- */ str w9, [x3], #4 b.ne 1b ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_rm_4: count == 0" #endif END(\funcname\()_bs_rm_4) /* void {funcname}_bs_rm_8(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_rm_8) #ifdef DIAGNOSTIC cbz x4, 99f #endif \dsbop ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr x9, [x1, x8] subs x4, x4, #1 /* count-- */ str x9, [x3], #8 b.ne 1b ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_rm_8: count == 0" #endif END(\funcname\()_bs_rm_8) /* void {funcname}_bs_rm_2_swap(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_rm_2_swap) #ifdef DIAGNOSTIC cbz x4, 99f #endif \dsbop ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: ldrh w9, [x1, x8] subs x4, x4, #1 /* count-- */ rev16 w9, w9 strh w9, [x3], #2 b.ne 1b ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_rm_2_swap: count == 0" #endif END(\funcname\()_bs_rm_2_swap) /* void {funcname}_bs_rm_4_swap(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_rm_4_swap) #ifdef DIAGNOSTIC cbz x4, 99f #endif \dsbop ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr w9, [x1, x8] subs x4, x4, #1 /* count-- */ rev w9, w9 str w9, [x3], #4 b.ne 1b ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_rm_4_swap: count == 0" #endif END(\funcname\()_bs_rm_4_swap) /* void {funcname}_bs_rm_8_swap(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_rm_8_swap) #ifdef DIAGNOSTIC cbz x4, 99f #endif \dsbop ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr x9, [x1, x8] subs x4, x4, #1 /* count-- */ rev x9, x9 str x9, [x3], #8 b.ne 1b ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_rm_8_swap: count == 0" #endif END(\funcname\()_bs_rm_8_swap) /* void {funcname}_bs_rr_1(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_rr_1) #ifdef DIAGNOSTIC cbz x4, 99f #endif \dsbop ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: ldrb w8, [x1, x2] /* value = *src */ subs x4, x4, #1 /* count-- */ add x2, x2, x9 /* src += delta */ strb w8, [x3], #1 /* *dst++ = value */ b.ne 1b ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_rr_1: count == 0" #endif END(\funcname\()_bs_rr_1) /* void {funcname}_bs_rr_2(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_rr_2) #ifdef DIAGNOSTIC cbz x4, 99f #endif \dsbop ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #2 /* if (delta < 2) { */ bcs 0f /* delta = 2; */ mov x9, #2 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: ldrh w8, [x1, x2] /* value = *src */ subs x4, x4, #1 /* count-- */ add x2, x2, x9 /* src += delta */ strh w8, [x3], #2 /* *dst++ = value */ b.ne 1b ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_rr_2: count == 0" #endif END(\funcname\()_bs_rr_2) /* void {funcname}_bs_rr_4(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_rr_4) #ifdef DIAGNOSTIC cbz x4, 99f #endif \dsbop ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #4 /* if (delta < 4) { */ bcs 0f /* delta = 4; */ mov x9, #4 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr w8, [x1, x2] /* value = *src */ subs x4, x4, #1 /* count-- */ add x2, x2, x9 /* src += delta */ str w8, [x3], #4 /* *dst++ = value */ b.ne 1b ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_rr_4: count == 0" #endif END(\funcname\()_bs_rr_4) /* void {funcname}_bs_rr_8(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_rr_8) #ifdef DIAGNOSTIC cbz x4, 99f #endif \dsbop ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #8 /* if (delta < 8) { */ bcs 0f /* delta = 8; */ mov x9, #8 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr x8, [x1, x2] /* value = *src */ subs x4, x4, #1 /* count-- */ add x2, x2, x9 /* src += delta */ str x8, [x3], #8 /* *dst++ = value */ b.ne 1b ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_rr_8: count == 0" #endif END(\funcname\()_bs_rr_8) /* void {funcname}_bs_rr_2_swap(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_rr_2_swap) #ifdef DIAGNOSTIC cbz x4, 99f #endif \dsbop ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #2 /* if (delta < 2) { */ bcs 0f /* delta = 2; */ mov x9, #2 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: ldrh w8, [x1, x2] /* value = *src */ subs x4, x4, #1 /* count-- */ add x2, x2, x9 /* src += delta */ rev16 w8, w8 strh w8, [x3], #2 /* *dst++ = value */ b.ne 1b ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_rr_2_swap: count == 0" #endif END(\funcname\()_bs_rr_2_swap) /* void {funcname}_bs_rr_4_swap(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_rr_4_swap) #ifdef DIAGNOSTIC cbz x4, 99f #endif \dsbop ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #4 /* if (delta < 4) { */ bcs 0f /* delta = 4; */ mov x9, #4 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr w8, [x1, x2] /* value = *src */ subs x4, x4, #1 /* count-- */ add x2, x2, x9 /* src += delta */ rev w8, w8 str w8, [x3], #4 /* *dst++ = value */ b.ne 1b ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_rr_4_swap: count == 0" #endif END(\funcname\()_bs_rr_4_swap) /* void {funcname}_bs_rr_8_swap(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_rr_8_swap) #ifdef DIAGNOSTIC cbz x4, 99f #endif \dsbop ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #8 /* if (delta < 8) { */ bcs 0f /* delta = 8; */ mov x9, #8 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr x8, [x1, x2] /* value = *src */ subs x4, x4, #1 /* count-- */ add x2, x2, x9 /* src += delta */ rev x8, x8 str x8, [x3], #8 /* *dst++ = value */ b.ne 1b ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_rr_8_swap: count == 0" #endif END(\funcname\()_bs_rr_8_swap) /* void {funcname}_bs_sm_1(x0:tag, x1:addr, x2:offset, x3:data, x4:count) */ ENTRY_NP(\funcname\()_bs_sm_1) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: subs x4, x4, #1 /* count-- */ strb w3, [x1, x8] b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_sm_1: count == 0" #endif END(\funcname\()_bs_sm_1) /* void {funcname}_bs_sm_2(x0:tag, x1:addr, x2:offset, x3:data, x4:count) */ /* void {funcname}_bs_sm_2_swap(x0:tag, x1:addr, x2:offset, x3:data, x4:count) */ ENTRY_NP(\funcname\()_bs_sm_2_swap) rev16 w3, w3 ENTRY_NP(\funcname\()_bs_sm_2) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: subs x4, x4, #1 /* count-- */ strh w3, [x1, x8] b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_sm_2(_swap): count == 0" #endif END(\funcname\()_bs_sm_2) END(\funcname\()_bs_sm_2_swap) /* void {funcname}_bs_sm_4(x0:tag, x1:addr, x2:offset, x3:data, x4:count) */ /* void {funcname}_bs_sm_4_swap(x0:tag, x1:addr, x2:offset, x3:data, x4:count) */ ENTRY_NP(\funcname\()_bs_sm_4_swap) rev w3, w3 ENTRY_NP(\funcname\()_bs_sm_4) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: subs x4, x4, #1 /* count-- */ str w3, [x1, x8] b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_sm_4(_swap): count == 0" #endif END(\funcname\()_bs_sm_4) END(\funcname\()_bs_sm_4_swap) /* void {funcname}_bs_sm_8(x0:tag, x1:addr, x2:offset, x3:data, x4:count) */ /* void {funcname}_bs_sm_8_swap(x0:tag, x1:addr, x2:offset, x3:data, x4:count) */ ENTRY_NP(\funcname\()_bs_sm_8_swap) rev x3, x3 ENTRY_NP(\funcname\()_bs_sm_8) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: subs x4, x4, #1 /* count-- */ str x3, [x1, x8] b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_sm_8(_swap): count == 0" #endif END(\funcname\()_bs_sm_8) END(\funcname\()_bs_sm_8_swap) /* void {funcname}_bs_w_1(x0:tag, x1:addr, x2:offset, x3:data) */ ENTRY_NP(\funcname\()_bs_w_1) ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ strb w3, [x1, x8] \dsbop ret END(\funcname\()_bs_w_1) /* void {funcname}_bs_w_2(x0:tag, x1:addr, x2:offset, x3:data) */ /* void {funcname}_bs_w_2_swap(x0:tag, x1:addr, x2:offset, x3:data) */ ENTRY_NP(\funcname\()_bs_w_2_swap) rev16 w3, w3 ENTRY_NP(\funcname\()_bs_w_2) ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ strh w3, [x1, x8] \dsbop ret END(\funcname\()_bs_w_2) END(\funcname\()_bs_w_2_swap) /* void {funcname}_bs_w_4(x0:tag, x1:addr, x2:offset, x3:data) */ /* void {funcname}_bs_w_4_swap(x0:tag, x1:addr, x2:offset, x3:data) */ ENTRY_NP(\funcname\()_bs_w_4_swap) rev w3, w3 ENTRY_NP(\funcname\()_bs_w_4) ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ str w3, [x1, x8] \dsbop ret END(\funcname\()_bs_w_4) END(\funcname\()_bs_w_4_swap) /* void {funcname}_bs_w_8(x0:tag, x1:addr, x2:offset, x3:data) */ /* void {funcname}_bs_w_8_swap(x0:tag, x1:addr, x2:offset, x3:data) */ ENTRY_NP(\funcname\()_bs_w_8_swap) rev x3, x3 ENTRY_NP(\funcname\()_bs_w_8) ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ str x3, [x1, x8] \dsbop ret END(\funcname\()_bs_w_8) END(\funcname\()_bs_w_8_swap) /* void {funcname}_bs_wm_1(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_wm_1) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: ldrb w9, [x3], #1 subs x4, x4, #1 /* count-- */ strb w9, [x1, x8] b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_wm_1: count == 0" #endif END(\funcname\()_bs_wm_1) /* void {funcname}_bs_wm_2(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_wm_2) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: ldrh w9, [x3], #2 subs x4, x4, #1 /* count-- */ strh w9, [x1, x8] b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_wm_2: count == 0" #endif END(\funcname\()_bs_wm_2) /* void {funcname}_bs_wm_4(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_wm_4) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr w9, [x3], #4 subs x4, x4, #1 /* count-- */ str w9, [x1, x8] b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_wm_4: count == 0" #endif END(\funcname\()_bs_wm_4) /* void {funcname}_bs_wm_8(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_wm_8) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr x9, [x3], #8 subs x4, x4, #1 /* count-- */ str x9, [x1, x8] b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_wm_8: count == 0" #endif END(\funcname\()_bs_wm_8) /* void {funcname}_bs_wm_2_swap(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_wm_2_swap) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: ldrh w9, [x3], #2 subs x4, x4, #1 /* count-- */ rev16 w9, w9 strh w9, [x1, x8] b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_wm_2_swap: count == 0" #endif END(\funcname\()_bs_wm_2_swap) /* void {funcname}_bs_wm_4_swap(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_wm_4_swap) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr w9, [x3], #4 subs x4, x4, #1 /* count-- */ rev w9, w9 str w9, [x1, x8] b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_wm_4_swap: count == 0" #endif END(\funcname\()_bs_wm_4_swap) /* void {funcname}_bs_wm_8_swap(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_wm_8_swap) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x8, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr x9, [x3], #8 subs x4, x4, #1 /* count-- */ rev x9, x9 str x9, [x1, x8] b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_wm_8_swap: count == 0" #endif END(\funcname\()_bs_wm_8_swap) /* void {funcname}_bs_wr_1(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_wr_1) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: ldrb w8, [x3], #1 /* value = *src++ */ subs x4, x4, #1 /* count-- */ strb w8, [x1, x2] /* *dst = value */ add x2, x2, x9 /* dst += delta */ b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_wr_1: count == 0" #endif END(\funcname\()_bs_wr_1) /* void {funcname}_bs_wr_2(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_wr_2) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #2 /* if (delta < 2) { */ bcs 0f /* delta = 2; */ mov x9, #2 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: ldrh w8, [x3], #2 /* value = *src++ */ subs x4, x4, #1 /* count-- */ strh w8, [x1, x2] /* *dst = value */ add x2, x2, x9 /* dst += delta */ b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_wr_2: count == 0" #endif END(\funcname\()_bs_wr_2) /* void {funcname}_bs_wr_4(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_wr_4) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #4 /* if (delta < 4) { */ bcs 0f /* delta = 4; */ mov x9, #4 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr w8, [x3], #4 /* value = *src++ */ subs x4, x4, #1 /* count-- */ str w8, [x1, x2] /* *dst = value */ add x2, x2, x9 /* dst += delta */ b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_wr_4: count == 0" #endif END(\funcname\()_bs_wr_4) /* void {funcname}_bs_wr_8(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_wr_8) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #8 /* if (delta < 8) { */ bcs 0f /* delta = 8; */ mov x9, #8 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr x8, [x3], #8 /* value = *src++ */ subs x4, x4, #1 /* count-- */ str x8, [x1, x2] /* *dst = value */ add x2, x2, x9 /* dst += delta */ b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_wr_8: count == 0" #endif END(\funcname\()_bs_wr_8) /* void {funcname}_bs_wr_2_swap(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_wr_2_swap) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #2 /* if (delta < 2) { */ bcs 0f /* delta = 2; */ mov x9, #2 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: ldrh w8, [x3], #2 /* value = *src++ */ rev16 w8, w8 subs x4, x4, #1 /* count-- */ strh w8, [x1, x2] /* *dst = value */ add x2, x2, x9 /* dst += delta */ b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_wr_2_swap: count == 0" #endif END(\funcname\()_bs_wr_2_swap) /* void {funcname}_bs_wr_4_swap(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_wr_4_swap) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #4 /* if (delta < 4) { */ bcs 0f /* delta = 4; */ mov x9, #4 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr w8, [x3], #4 /* value = *src++ */ rev w8, w8 subs x4, x4, #1 /* count-- */ str w8, [x1, x2] /* *dst = value */ add x2, x2, x9 /* dst += delta */ b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_wr_4_swap: count == 0" #endif END(\funcname\()_bs_wr_4_swap) /* void {funcname}_bs_wr_8_swap(x0:tag, x1:addr, x2:offset, x3:datap, x4:count) */ ENTRY_NP(\funcname\()_bs_wr_8_swap) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #8 /* if (delta < 8) { */ bcs 0f /* delta = 8; */ mov x9, #8 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: ldr x8, [x3], #8 /* value = *src++ */ rev x8, x8 subs x4, x4, #1 /* count-- */ str x8, [x1, x2] /* *dst = value */ add x2, x2, x9 /* dst += delta */ b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_wr_8_swap: count == 0" #endif END(\funcname\()_bs_wr_8_swap) /* void {funcname}_bs_sr_1(x0:tag, x1:addr, x2:offset, x3:value, x4:count) */ ENTRY_NP(\funcname\()_bs_sr_1) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: strb w3, [x1, x2] /* *dst = value */ subs x4, x4, #1 /* count-- */ add x2, x2, x9 /* dst += delta */ b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_sr_1: count == 0" #endif END(\funcname\()_bs_sr_1) /* void {funcname}_bs_sr_2(x0:tag, x1:addr, x2:offset, x3:value, x4:count) */ /* void {funcname}_bs_sr_2_swap(x0:tag, x1:addr, x2:offset, x3:value, x4:count) */ ENTRY_NP(\funcname\()_bs_sr_2_swap) rev16 w3, w3 ENTRY_NP(\funcname\()_bs_sr_2) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #2 /* if (delta < 2) { */ bcs 0f /* delta = 2; */ mov x9, #2 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: strh w3, [x1, x2] /* *dst = value */ subs x4, x4, #1 /* count-- */ add x2, x2, x9 /* dst += delta */ b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_sr_2(_swap): count == 0" #endif END(\funcname\()_bs_sr_2) END(\funcname\()_bs_sr_2_swap) /* void {funcname}_bs_sr_4(x0:tag, x1:addr, x2:offset, x3:value, x4:count) */ /* void {funcname}_bs_sr_4_swap(x0:tag, x1:addr, x2:offset, x3:value, x4:count) */ ENTRY_NP(\funcname\()_bs_sr_4_swap) rev w3, w3 ENTRY_NP(\funcname\()_bs_sr_4) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #4 /* if (delta < 4) { */ bcs 0f /* delta = 4; */ mov x9, #4 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: str w3, [x1, x2] /* *dst = value */ subs x4, x4, #1 /* count-- */ add x2, x2, x9 /* dst += delta */ b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_sr_4(_swap): count == 0" #endif END(\funcname\()_bs_sr_4) END(\funcname\()_bs_sr_4_swap) /* void {funcname}_bs_sr_8(x0:tag, x1:addr, x2:offset, x3:value, x4:count) */ /* void {funcname}_bs_sr_8_swap(x0:tag, x1:addr, x2:offset, x3:value, x4:count) */ ENTRY_NP(\funcname\()_bs_sr_8_swap) rev x3, x3 ENTRY_NP(\funcname\()_bs_sr_8) #ifdef DIAGNOSTIC cbz x4, 99f #endif ldr w8, [x0, #BS_STRIDE] mov x9, #1 lsl x9, x9, x8 /* delta = 1 << tag->bs_stride */ cmp x9, #8 /* if (delta < 8) { */ bcs 0f /* delta = 8; */ mov x9, #8 /* } */ 0: lsl x2, x2, x8 /* offset <<= tag->bs_stride */ 1: str x3, [x1, x2] /* *dst = value */ subs x4, x4, #1 /* count-- */ add x2, x2, x9 /* dst += delta */ b.ne 1b \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_sr_8(_swap): count == 0" #endif END(\funcname\()_bs_sr_8) END(\funcname\()_bs_sr_8_swap) /* void {funcname}_bs_c_1(x0:tag, x1:addr1, x2:offset1, x3:addr2, x4:offset2, x5:count) */ ENTRY_NP(\funcname\()_bs_c_1) #ifdef DIAGNOSTIC cbz x5, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x2, x2, x8 /* offset1 <<= tag->bs_stride */ lsl x4, x4, x8 /* offset2 <<= tag->bs_stride */ add x1, x1, x2 /* addr1 += offset1 */ add x3, x3, x4 /* addr2 += offset2 */ mov x10, #1 lsl x10, x10, x8 /* delta = (1 << tag->bs_stride) */ cmp x1, x3 /* addr1 > addr2 ? */ b.cc 2f 1: /* in case of (addr1 > addr2) */ ldrb w9, [x1] subs x5, x5, #1 strb w9, [x3] add x1, x1, x10 /* addr1 += delta */ add x3, x3, x10 /* addr2 += delta */ b.ne 1b b 8f 2: lsl x8, x5, x8 /* (x8 = count * delta) */ add x1, x1, x8 /* addr1 += count * delta */ add x3, x3, x8 /* addr2 += count * delta */ 3: sub x1, x1, x10 /* addr1 -= delta */ sub x3, x3, x10 /* addr2 -= delta */ ldrb w9, [x1] subs x5, x5, #1 strb w9, [x3] b.ne 3b 8: \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_c_1: count == 0" #endif END(\funcname\()_bs_c_1) /* void {funcname}_bs_c_2(x0:tag, x1:addr1, x2:offset1, x3:addr2, x4:offset2, x5:count) */ ENTRY_NP(\funcname\()_bs_c_2) #ifdef DIAGNOSTIC cbz x5, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x2, x2, x8 /* offset1 <<= tag->bs_stride */ lsl x4, x4, x8 /* offset2 <<= tag->bs_stride */ add x1, x1, x2 /* addr1 += offset1 */ add x3, x3, x4 /* addr2 += offset2 */ mov x10, #1 lsl x10, x10, x8 /* delta = (1 << tag->bs_stride) */ cmp x10, #2 /* if (delta < 2) { */ bcs 0f /* delta = 2; */ mov x10, #2 /* } */ 0: cmp x1, x3 /* addr1 > addr2 ? */ b.cc 2f 1: /* in case of (addr1 > addr2) */ ldrh w9, [x1] subs x5, x5, #1 strh w9, [x3] add x1, x1, x10 /* addr1 += delta */ add x3, x3, x10 /* addr1 += delta */ b.ne 1b b 8f 2: mul x8, x5, x10 /* (x8 = count * delta) */ add x1, x1, x8 /* addr1 += count << tag->bs_stride */ add x3, x3, x8 /* addr2 += count << tag->bs_stride */ 3: sub x1, x1, x10 /* addr1 -= delta */ sub x3, x3, x10 /* addr1 -= delta */ ldrh w9, [x1] subs x5, x5, #1 strh w9, [x3] b.ne 3b 8: \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_c_2: count == 0" #endif END(\funcname\()_bs_c_2) /* void {funcname}_bs_c_4(x0:tag, x1:addr1, x2:offset1, x3:addr2, x4:offset2, x5:count) */ ENTRY_NP(\funcname\()_bs_c_4) #ifdef DIAGNOSTIC cbz x5, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x2, x2, x8 /* offset1 <<= tag->bs_stride */ lsl x4, x4, x8 /* offset2 <<= tag->bs_stride */ add x1, x1, x2 /* addr1 += offset1 */ add x3, x3, x4 /* addr2 += offset2 */ mov x10, #1 lsl x10, x10, x8 /* delta = (1 << tag->bs_stride) */ cmp x10, #4 /* if (delta < 4) { */ bcs 0f /* delta = 4; */ mov x10, #4 /* } */ 0: cmp x1, x3 /* addr1 > addr2 ? */ b.cc 2f 1: /* in case of (addr1 > addr2) */ ldr w9, [x1] subs x5, x5, #1 str w9, [x3] add x1, x1, x10 /* addr1 += delta */ add x3, x3, x10 /* addr2 += delta */ b.ne 1b b 8f 2: mul x8, x5, x10 /* (x8 = count * delta) */ add x1, x1, x5 /* addr1 += count << tag->bs_delta */ add x3, x3, x5 /* addr2 += count << tag->bs_delta */ 3: sub x1, x1, x10 /* addr1 -= delta */ sub x3, x3, x10 /* addr1 -= delta */ ldr w9, [x1] subs x5, x5, #1 str w9, [x3] b.ne 3b 8: \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_c_4: count == 0" #endif END(\funcname\()_bs_c_4) /* void {funcname}_bs_c_8(x0:tag, x1:addr1, x2:offset1, x3:addr2, x4:offset2, x5:count) */ ENTRY_NP(\funcname\()_bs_c_8) #ifdef DIAGNOSTIC cbz x5, 99f #endif ldr w8, [x0, #BS_STRIDE] lsl x2, x2, x8 /* offset1 <<= tag->bs_stride */ lsl x4, x4, x8 /* offset2 <<= tag->bs_stride */ add x1, x1, x2 /* addr1 += offset1 */ add x3, x3, x4 /* addr2 += offset2 */ mov x10, #1 lsl x10, x10, x8 /* delta = (1 << tag->bs_stride) */ cmp x10, #8 /* if (delta < 8) { */ bcs 0f /* delta = 8; */ mov x10, #8 /* } */ 0: cmp x1, x3 /* addr1 > addr2 ? */ b.cc 2f 1: /* in case of (addr1 > addr2) */ ldr x9, [x1] subs x5, x5, #1 str x9, [x3] add x1, x1, x10 /* addr1 += delta */ add x3, x3, x10 /* addr1 += delta */ b.ne 1b b 8f 2: mul x8, x5, x10 /* (x8 = count * delta) */ add x1, x1, x8 /* addr1 += count << tag->bs_stride */ add x3, x3, x8 /* addr2 += count << tag->bs_stride */ 3: sub x1, x1, x10 /* addr1 -= delta */ sub x3, x3, x10 /* addr1 -= delta */ ldr x9, [x1] subs x5, x5, #1 str x9, [x3] b.ne 3b 8: \dsbop ret #ifdef DIAGNOSTIC 99: adr x0, 100f b _C_LABEL(panic) 100: .asciz "\funcname\()_bs_c_8: count == 0" #endif END(\funcname\()_bs_c_8) .endm generate_bsfunc generic generate_bsfunc generic_dsb, "dsb sy"