1/* 2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include "pico/asm_helper.S" 8#include "pico/bootrom.h" 9#include "pico/runtime_init.h" 10 11pico_default_asm_setup 12 13.macro bits_section name 14#if PICO_BITS_IN_RAM 15.section RAM_SECTION_NAME(\name), "ax" 16#else 17.section SECTION_NAME(\name), "ax" 18#endif 19.endm 20 21#if PICO_RP2040 22PICO_RUNTIME_INIT_FUNC_RUNTIME(__aeabi_bits_init, PICO_RUNTIME_INIT_AEABI_BIT_OPS) 23 24.section .data.aeabi_bits_funcs 25.global aeabi_bits_funcs, aeabi_bits_funcs_end 26.equ BITS_FUNC_COUNT, 4 27.align 4 28aeabi_bits_funcs: 29 .word ROM_FUNC_POPCOUNT32 30 .word ROM_FUNC_CLZ32 31 .word ROM_FUNC_CTZ32 32 .word ROM_FUNC_REVERSE32 33aeabi_bits_funcs_end: 34 35.section .text 36.thumb_func 37__aeabi_bits_init: 38 ldr r0, =aeabi_bits_funcs 39 movs r1, #BITS_FUNC_COUNT 40 ldr r3, =rom_funcs_lookup 41 bx r3 42 43.equ POPCOUNT32, 0 44.equ CLZ32, 4 45.equ CTZ32, 8 46.equ REVERSE32, 12 47 48bits_section clzsi 49wrapper_func __clz 50wrapper_func __clzl 51wrapper_func __clzsi2 52 ldr r3, =aeabi_bits_funcs 53 ldr r3, [r3, #CLZ32] 54 bx r3 55 56bits_section ctzsi 57wrapper_func __ctzsi2 58 ldr r3, =aeabi_bits_funcs 59 ldr r3, [r3, #CTZ32] 60 bx r3 61 62bits_section popcountsi 63wrapper_func __popcountsi2 64 ldr r3, =aeabi_bits_funcs 65 ldr r3, [r3, #POPCOUNT32] 66 bx r3 67 68bits_section clzdi 69wrapper_func __clzll 70wrapper_func __clzdi2 71 ldr r3, =aeabi_bits_funcs 72 ldr r3, [r3, #CLZ32] 73 cmp r1, #0 74 bne 1f 75 push {lr} 76 blx r3 77 adds r0, #32 78 pop {pc} 791: 80 mov r0, r1 81 bx r3 82 83bits_section ctzdi 84wrapper_func __ctzdi2 85 ldr r3, =aeabi_bits_funcs 86 ldr r3, [r3, #CTZ32] 87 cmp r0, #0 88 beq 1f 89 bx r3 901: 91 push {lr} 92 mov r0, r1 93 blx r3 94 adds r0, #32 95 pop {pc} 96 97bits_section popcountdi 98wrapper_func __popcountdi2 99 ldr r3, =aeabi_bits_funcs 100 ldr r3, [r3, #POPCOUNT32] 101 push {r1, r3, lr} 102 blx r3 103 mov ip, r0 104 pop {r0, r3} 105 blx r3 106 mov r1, ip 107 add r0, r1 108 pop {pc} 109 110bits_section __rev 111regular_func __rev 112regular_func __revl 113regular_func reverse32 114 ldr r3, =aeabi_bits_funcs 115 ldr r3, [r3, #REVERSE32] 116 bx r3 117 118bits_section __revll 119regular_func __revll 120regular_func reverse64 121 push {lr} 122 ldr r3, =aeabi_bits_funcs 123 ldr r3, [r3, #REVERSE32] 124 push {r1, r3} 125 blx r3 126 mov ip, r0 // reverse32 preserves ip 127 pop {r0, r3} 128 blx r3 129 mov r1, ip 130 pop {pc} 131 132#else // RP2350 133 134bits_section __rev 135regular_func __rev 136regular_func __revl 137regular_func reverse32 138#ifdef __riscv 139 rev8 a0, a0 140 brev8 a0, a0 141 ret 142#else 143 rbit r0, r0 144 bx lr 145#endif 146 147bits_section __revll 148regular_func __revll 149regular_func reverse64 150#ifdef __riscv 151 rev8 a0, a0 152 brev8 a0, a0 153 rev8 a1, a1 154 brev8 a1, a1 155 mv a2, a0 156 mv a0, a1 157 mv a1, a2 158 ret 159#else 160 mov r2, r1 161 rbit r1, r0 162 rbit r0, r2 163 bx lr 164#endif 165 166// todo gcc riscv version is nuts; we'll provide both versions for simplicity in CMakeLists.txt 167// (also gcc arm version is a bit pants) 168bits_section ctzdi 169wrapper_func __ctzdi2 170#ifdef __riscv 171 beqz a0, 1f 172 ctz a0, a0 173 ret 1741: 175 ctz a0, a1 176 addi a0, a0, 32 177 ret 178#else 179 cbz r0, 1f 180 rbit r0, r0 181 clz r0, r0 182 bx lr 1831: 184 rbit r0, r1 185 clz r0, r0 186 adds r0, #32 187 bx lr 188#endif 189 190#endif