Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

unicore32 additional architecture files: low-level lib: misc

This patch implements the rest low-level libraries.

Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
Acked-by: Arnd Bergmann <arnd@arndb.de>

+662
+131
arch/unicore32/include/asm/assembler.h
··· 1 + /* 2 + * linux/arch/unicore32/include/asm/assembler.h 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * Do not include any C declarations in this file - it is included by 13 + * assembler source. 14 + */ 15 + #ifndef __ASSEMBLY__ 16 + #error "Only include this from assembly code" 17 + #endif 18 + 19 + #include <asm/ptrace.h> 20 + 21 + /* 22 + * Little Endian independent macros for shifting bytes within registers. 23 + */ 24 + #define pull >> 25 + #define push << 26 + #define get_byte_0 << #0 27 + #define get_byte_1 >> #8 28 + #define get_byte_2 >> #16 29 + #define get_byte_3 >> #24 30 + #define put_byte_0 << #0 31 + #define put_byte_1 << #8 32 + #define put_byte_2 << #16 33 + #define put_byte_3 << #24 34 + 35 + #define cadd cmpadd 36 + #define cand cmpand 37 + #define csub cmpsub 38 + #define cxor cmpxor 39 + 40 + /* 41 + * Enable and disable interrupts 42 + */ 43 + .macro disable_irq, temp 44 + mov \temp, asr 45 + andn \temp, \temp, #0xFF 46 + or \temp, \temp, #PSR_I_BIT | PRIV_MODE 47 + mov.a asr, \temp 48 + .endm 49 + 50 + .macro enable_irq, temp 51 + mov \temp, asr 52 + andn \temp, \temp, #0xFF 53 + or \temp, \temp, #PRIV_MODE 54 + mov.a asr, \temp 55 + .endm 56 + 57 + #define USER(x...) \ 58 + 9999: x; \ 59 + .pushsection __ex_table, "a"; \ 60 + .align 3; \ 61 + .long 9999b, 9001f; \ 62 + .popsection 63 + 64 + .macro notcond, cond, nexti = .+8 65 + .ifc \cond, eq 66 + bne \nexti 67 + .else; .ifc \cond, ne 68 + beq \nexti 69 + .else; .ifc \cond, ea 70 + bub \nexti 71 + .else; .ifc \cond, ub 72 + bea \nexti 73 + .else; .ifc \cond, fs 74 + bns \nexti 75 + .else; .ifc \cond, ns 76 + bfs \nexti 77 + .else; .ifc \cond, fv 78 + bnv \nexti 79 + .else; .ifc \cond, nv 80 + bfv \nexti 81 + .else; .ifc \cond, ua 82 + beb \nexti 83 + .else; .ifc \cond, eb 84 + bua \nexti 85 + .else; .ifc \cond, eg 86 + bsl \nexti 87 + .else; .ifc \cond, sl 88 + beg \nexti 89 + .else; .ifc \cond, sg 90 + bel \nexti 91 + .else; .ifc \cond, el 92 + bsg \nexti 93 + .else; .ifnc \cond, al 94 + .error "Unknown cond in notcond macro argument" 95 + .endif; .endif; .endif; .endif; .endif; .endif; .endif 96 + .endif; .endif; .endif; .endif; .endif; .endif; .endif 97 + .endif 98 + .endm 99 + 100 + .macro usracc, instr, reg, ptr, inc, cond, rept, abort 101 + .rept \rept 102 + notcond \cond, .+8 103 + 9999 : 104 + .if \inc == 1 105 + \instr\()b.u \reg, [\ptr], #\inc 106 + .elseif \inc == 4 107 + \instr\()w.u \reg, [\ptr], #\inc 108 + .else 109 + .error "Unsupported inc macro argument" 110 + .endif 111 + 112 + .pushsection __ex_table, "a" 113 + .align 3 114 + .long 9999b, \abort 115 + .popsection 116 + .endr 117 + .endm 118 + 119 + .macro strusr, reg, ptr, inc, cond = al, rept = 1, abort = 9001f 120 + usracc st, \reg, \ptr, \inc, \cond, \rept, \abort 121 + .endm 122 + 123 + .macro ldrusr, reg, ptr, inc, cond = al, rept = 1, abort = 9001f 124 + usracc ld, \reg, \ptr, \inc, \cond, \rept, \abort 125 + .endm 126 + 127 + .macro nop8 128 + .rept 8 129 + nop 130 + .endr 131 + .endm
+47
arch/unicore32/include/asm/bitops.h
··· 1 + /* 2 + * linux/arch/unicore32/include/asm/bitops.h 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #ifndef __UNICORE_BITOPS_H__ 14 + #define __UNICORE_BITOPS_H__ 15 + 16 + #define find_next_bit __uc32_find_next_bit 17 + #define find_next_zero_bit __uc32_find_next_zero_bit 18 + 19 + #define find_first_bit __uc32_find_first_bit 20 + #define find_first_zero_bit __uc32_find_first_zero_bit 21 + 22 + #define _ASM_GENERIC_BITOPS_FLS_H_ 23 + #define _ASM_GENERIC_BITOPS___FLS_H_ 24 + #define _ASM_GENERIC_BITOPS_FFS_H_ 25 + #define _ASM_GENERIC_BITOPS___FFS_H_ 26 + /* 27 + * On UNICORE, those functions can be implemented around 28 + * the cntlz instruction for much better code efficiency. 29 + */ 30 + 31 + static inline int fls(int x) 32 + { 33 + int ret; 34 + 35 + asm("cntlz\t%0, %1" : "=r" (ret) : "r" (x) : "cc"); 36 + ret = 32 - ret; 37 + 38 + return ret; 39 + } 40 + 41 + #define __fls(x) (fls(x) - 1) 42 + #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) 43 + #define __ffs(x) (ffs(x) - 1) 44 + 45 + #include <asm-generic/bitops.h> 46 + 47 + #endif /* __UNICORE_BITOPS_H__ */
+41
arch/unicore32/include/asm/checksum.h
··· 1 + /* 2 + * linux/arch/unicore32/include/asm/checksum.h 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * IP checksum routines 13 + */ 14 + #ifndef __UNICORE_CHECKSUM_H__ 15 + #define __UNICORE_CHECKSUM_H__ 16 + 17 + /* 18 + * computes the checksum of the TCP/UDP pseudo-header 19 + * returns a 16-bit checksum, already complemented 20 + */ 21 + 22 + static inline __wsum 23 + csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, 24 + unsigned short proto, __wsum sum) 25 + { 26 + __asm__( 27 + "add.a %0, %1, %2\n" 28 + "addc.a %0, %0, %3\n" 29 + "addc.a %0, %0, %4 << #8\n" 30 + "addc.a %0, %0, %5\n" 31 + "addc %0, %0, #0\n" 32 + : "=&r"(sum) 33 + : "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (htons(proto)) 34 + : "cc"); 35 + return sum; 36 + } 37 + #define csum_tcpudp_nofold csum_tcpudp_nofold 38 + 39 + #include <asm-generic/checksum.h> 40 + 41 + #endif
+52
arch/unicore32/include/asm/delay.h
··· 1 + /* 2 + * linux/arch/unicore32/include/asm/delay.h 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * Delay routines, using a pre-computed "loops_per_second" value. 13 + */ 14 + #ifndef __UNICORE_DELAY_H__ 15 + #define __UNICORE_DELAY_H__ 16 + 17 + #include <asm/param.h> /* HZ */ 18 + 19 + extern void __delay(int loops); 20 + 21 + /* 22 + * This function intentionally does not exist; if you see references to 23 + * it, it means that you're calling udelay() with an out of range value. 24 + * 25 + * With currently imposed limits, this means that we support a max delay 26 + * of 2000us. Further limits: HZ<=1000 and bogomips<=3355 27 + */ 28 + extern void __bad_udelay(void); 29 + 30 + /* 31 + * division by multiplication: you don't have to worry about 32 + * loss of precision. 33 + * 34 + * Use only for very small delays ( < 1 msec). Should probably use a 35 + * lookup table, really, as the multiplications take much too long with 36 + * short delays. This is a "reasonable" implementation, though (and the 37 + * first constant multiplications gets optimized away if the delay is 38 + * a constant) 39 + */ 40 + extern void __udelay(unsigned long usecs); 41 + extern void __const_udelay(unsigned long); 42 + 43 + #define MAX_UDELAY_MS 2 44 + 45 + #define udelay(n) \ 46 + (__builtin_constant_p(n) ? \ 47 + ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() : \ 48 + __const_udelay((n) * ((2199023U*HZ)>>11))) : \ 49 + __udelay(n)) 50 + 51 + #endif /* __UNICORE_DELAY_H__ */ 52 +
+143
arch/unicore32/include/asm/futex.h
··· 1 + /* 2 + * linux/arch/unicore32/include/asm/futex.h 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #ifndef __UNICORE_FUTEX_H__ 14 + #define __UNICORE_FUTEX_H__ 15 + 16 + #ifdef __KERNEL__ 17 + 18 + #include <linux/futex.h> 19 + #include <linux/preempt.h> 20 + #include <linux/uaccess.h> 21 + #include <linux/errno.h> 22 + 23 + #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ 24 + __asm__ __volatile__( \ 25 + "1: ldw.u %1, [%2]\n" \ 26 + " " insn "\n" \ 27 + "2: stw.u %0, [%2]\n" \ 28 + " mov %0, #0\n" \ 29 + "3:\n" \ 30 + " .pushsection __ex_table,\"a\"\n" \ 31 + " .align 3\n" \ 32 + " .long 1b, 4f, 2b, 4f\n" \ 33 + " .popsection\n" \ 34 + " .pushsection .fixup,\"ax\"\n" \ 35 + "4: mov %0, %4\n" \ 36 + " b 3b\n" \ 37 + " .popsection" \ 38 + : "=&r" (ret), "=&r" (oldval) \ 39 + : "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \ 40 + : "cc", "memory") 41 + 42 + static inline int 43 + futex_atomic_op_inuser(int encoded_op, int __user *uaddr) 44 + { 45 + int op = (encoded_op >> 28) & 7; 46 + int cmp = (encoded_op >> 24) & 15; 47 + int oparg = (encoded_op << 8) >> 20; 48 + int cmparg = (encoded_op << 20) >> 20; 49 + int oldval = 0, ret; 50 + 51 + if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) 52 + oparg = 1 << oparg; 53 + 54 + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) 55 + return -EFAULT; 56 + 57 + pagefault_disable(); /* implies preempt_disable() */ 58 + 59 + switch (op) { 60 + case FUTEX_OP_SET: 61 + __futex_atomic_op("mov %0, %3", ret, oldval, uaddr, oparg); 62 + break; 63 + case FUTEX_OP_ADD: 64 + __futex_atomic_op("add %0, %1, %3", ret, oldval, uaddr, oparg); 65 + break; 66 + case FUTEX_OP_OR: 67 + __futex_atomic_op("or %0, %1, %3", ret, oldval, uaddr, oparg); 68 + break; 69 + case FUTEX_OP_ANDN: 70 + __futex_atomic_op("and %0, %1, %3", 71 + ret, oldval, uaddr, ~oparg); 72 + break; 73 + case FUTEX_OP_XOR: 74 + __futex_atomic_op("xor %0, %1, %3", ret, oldval, uaddr, oparg); 75 + break; 76 + default: 77 + ret = -ENOSYS; 78 + } 79 + 80 + pagefault_enable(); /* subsumes preempt_enable() */ 81 + 82 + if (!ret) { 83 + switch (cmp) { 84 + case FUTEX_OP_CMP_EQ: 85 + ret = (oldval == cmparg); 86 + break; 87 + case FUTEX_OP_CMP_NE: 88 + ret = (oldval != cmparg); 89 + break; 90 + case FUTEX_OP_CMP_LT: 91 + ret = (oldval < cmparg); 92 + break; 93 + case FUTEX_OP_CMP_GE: 94 + ret = (oldval >= cmparg); 95 + break; 96 + case FUTEX_OP_CMP_LE: 97 + ret = (oldval <= cmparg); 98 + break; 99 + case FUTEX_OP_CMP_GT: 100 + ret = (oldval > cmparg); 101 + break; 102 + default: 103 + ret = -ENOSYS; 104 + } 105 + } 106 + return ret; 107 + } 108 + 109 + static inline int 110 + futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) 111 + { 112 + int val; 113 + 114 + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) 115 + return -EFAULT; 116 + 117 + pagefault_disable(); /* implies preempt_disable() */ 118 + 119 + __asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n" 120 + "1: ldw.u %0, [%3]\n" 121 + " cmpxor.a %0, %1\n" 122 + " bne 3f\n" 123 + "2: stw.u %2, [%3]\n" 124 + "3:\n" 125 + " .pushsection __ex_table,\"a\"\n" 126 + " .align 3\n" 127 + " .long 1b, 4f, 2b, 4f\n" 128 + " .popsection\n" 129 + " .pushsection .fixup,\"ax\"\n" 130 + "4: mov %0, %4\n" 131 + " b 3b\n" 132 + " .popsection" 133 + : "=&r" (val) 134 + : "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT) 135 + : "cc", "memory"); 136 + 137 + pagefault_enable(); /* subsumes preempt_enable() */ 138 + 139 + return val; 140 + } 141 + 142 + #endif /* __KERNEL__ */ 143 + #endif /* __UNICORE_FUTEX_H__ */
+52
arch/unicore32/include/asm/io.h
··· 1 + /* 2 + * linux/arch/unicore32/include/asm/io.h 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + #ifndef __UNICORE_IO_H__ 13 + #define __UNICORE_IO_H__ 14 + 15 + #ifdef __KERNEL__ 16 + 17 + #include <asm/byteorder.h> 18 + #include <asm/memory.h> 19 + #include <asm/system.h> 20 + 21 + #include <asm-generic/io.h> 22 + 23 + /* 24 + * __uc32_ioremap and __uc32_ioremap_cached takes CPU physical address. 25 + */ 26 + extern void __iomem *__uc32_ioremap(unsigned long, size_t); 27 + extern void __iomem *__uc32_ioremap_cached(unsigned long, size_t); 28 + extern void __uc32_iounmap(volatile void __iomem *addr); 29 + 30 + /* 31 + * ioremap and friends. 32 + * 33 + * ioremap takes a PCI memory address, as specified in 34 + * Documentation/IO-mapping.txt. 35 + * 36 + */ 37 + #define ioremap(cookie, size) __uc32_ioremap(cookie, size) 38 + #define ioremap_cached(cookie, size) __uc32_ioremap_cached(cookie, size) 39 + #define iounmap(cookie) __uc32_iounmap(cookie) 40 + 41 + extern void __iomem *ioport_map(unsigned long port, unsigned int nr); 42 + extern void ioport_unmap(void __iomem *addr); 43 + 44 + /* 45 + * Convert a physical pointer to a virtual kernel pointer for /dev/mem 46 + * access 47 + */ 48 + #undef xlate_dev_mem_ptr 49 + #define xlate_dev_mem_ptr(p) __va(p) 50 + 51 + #endif /* __KERNEL__ */ 52 + #endif /* __UNICORE_IO_H__ */
+20
arch/unicore32/include/asm/mutex.h
··· 1 + /* 2 + * linux/arch/unicore32/include/asm/mutex.h 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * UniCore optimized mutex locking primitives 13 + * 14 + * Please look into asm-generic/mutex-xchg.h for a formal definition. 15 + */ 16 + #ifndef __UNICORE_MUTEX_H__ 17 + #define __UNICORE_MUTEX_H__ 18 + 19 + # include <asm-generic/mutex-xchg.h> 20 + #endif
+27
arch/unicore32/lib/Makefile
··· 1 + # 2 + # linux/arch/unicore32/lib/Makefile 3 + # 4 + # Copyright (C) 2001-2010 GUAN Xue-tao 5 + # 6 + 7 + lib-y := backtrace.o delay.o findbit.o 8 + lib-y += strncpy_from_user.o strnlen_user.o 9 + lib-y += clear_user.o copy_page.o 10 + lib-y += copy_from_user.o copy_to_user.o 11 + 12 + GNU_LIBC_A := $(shell $(CC) $(KBUILD_CFLAGS) -print-file-name=libc.a) 13 + GNU_LIBC_A_OBJS := memchr.o memcpy.o memmove.o memset.o 14 + GNU_LIBC_A_OBJS += strchr.o strrchr.o 15 + GNU_LIBC_A_OBJS += rawmemchr.o # needed by strrchr.o 16 + 17 + GNU_LIBGCC_A := $(shell $(CC) $(KBUILD_CFLAGS) -print-file-name=libgcc.a) 18 + GNU_LIBGCC_A_OBJS := _ashldi3.o _ashrdi3.o _lshrdi3.o 19 + GNU_LIBGCC_A_OBJS += _divsi3.o _modsi3.o _ucmpdi2.o _umodsi3.o _udivsi3.o 20 + 21 + lib-y += $(GNU_LIBC_A_OBJS) $(GNU_LIBGCC_A_OBJS) 22 + 23 + $(addprefix $(obj)/, $(GNU_LIBC_A_OBJS)): 24 + $(Q)$(AR) p $(GNU_LIBC_A) $(notdir $@) > $@ 25 + 26 + $(addprefix $(obj)/, $(GNU_LIBGCC_A_OBJS)): 27 + $(Q)$(AR) p $(GNU_LIBGCC_A) $(notdir $@) > $@
+51
arch/unicore32/lib/delay.S
··· 1 + /* 2 + * linux/arch/unicore32/lib/delay.S 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + #include <linux/linkage.h> 13 + #include <asm/assembler.h> 14 + #include <asm/param.h> 15 + .text 16 + 17 + .LC0: .word loops_per_jiffy 18 + .LC1: .word (2199023*HZ)>>11 19 + 20 + /* 21 + * r0 <= 2000 22 + * lpj <= 0x01ffffff (max. 3355 bogomips) 23 + * HZ <= 1000 24 + */ 25 + 26 + ENTRY(__udelay) 27 + ldw r2, .LC1 28 + mul r0, r2, r0 29 + ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff06 30 + ldw r2, .LC0 31 + ldw r2, [r2] @ max = 0x01ffffff 32 + mov r0, r0 >> #14 @ max = 0x0001ffff 33 + mov r2, r2 >> #10 @ max = 0x00007fff 34 + mul r0, r2, r0 @ max = 2^32-1 35 + mov.a r0, r0 >> #6 36 + cmoveq pc, lr 37 + 38 + /* 39 + * loops = r0 * HZ * loops_per_jiffy / 1000000 40 + * 41 + * Oh, if only we had a cycle counter... 42 + */ 43 + 44 + @ Delay routine 45 + ENTRY(__delay) 46 + sub.a r0, r0, #2 47 + bua __delay 48 + mov pc, lr 49 + ENDPROC(__udelay) 50 + ENDPROC(__const_udelay) 51 + ENDPROC(__delay)
+98
arch/unicore32/lib/findbit.S
··· 1 + /* 2 + * linux/arch/unicore32/lib/findbit.S 3 + * 4 + * Code specific to PKUnity SoC and UniCore ISA 5 + * 6 + * Copyright (C) 2001-2010 GUAN Xue-tao 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + #include <linux/linkage.h> 13 + #include <asm/assembler.h> 14 + .text 15 + 16 + /* 17 + * Purpose : Find a 'zero' bit 18 + * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit); 19 + */ 20 + __uc32_find_first_zero_bit: 21 + cxor.a r1, #0 22 + beq 3f 23 + mov r2, #0 24 + 1: ldb r3, [r0+], r2 >> #3 25 + xor.a r3, r3, #0xff @ invert bits 26 + bne .L_found @ any now set - found zero bit 27 + add r2, r2, #8 @ next bit pointer 28 + 2: csub.a r2, r1 @ any more? 29 + bub 1b 30 + 3: mov r0, r1 @ no free bits 31 + mov pc, lr 32 + 33 + /* 34 + * Purpose : Find next 'zero' bit 35 + * Prototype: int find_next_zero_bit 36 + * (void *addr, unsigned int maxbit, int offset) 37 + */ 38 + ENTRY(__uc32_find_next_zero_bit) 39 + cxor.a r1, #0 40 + beq 3b 41 + and.a ip, r2, #7 42 + beq 1b @ If new byte, goto old routine 43 + ldb r3, [r0+], r2 >> #3 44 + xor r3, r3, #0xff @ now looking for a 1 bit 45 + mov.a r3, r3 >> ip @ shift off unused bits 46 + bne .L_found 47 + or r2, r2, #7 @ if zero, then no bits here 48 + add r2, r2, #1 @ align bit pointer 49 + b 2b @ loop for next bit 50 + ENDPROC(__uc32_find_next_zero_bit) 51 + 52 + /* 53 + * Purpose : Find a 'one' bit 54 + * Prototype: int find_first_bit 55 + * (const unsigned long *addr, unsigned int maxbit); 56 + */ 57 + __uc32_find_first_bit: 58 + cxor.a r1, #0 59 + beq 3f 60 + mov r2, #0 61 + 1: ldb r3, [r0+], r2 >> #3 62 + mov.a r3, r3 63 + bne .L_found @ any now set - found zero bit 64 + add r2, r2, #8 @ next bit pointer 65 + 2: csub.a r2, r1 @ any more? 66 + bub 1b 67 + 3: mov r0, r1 @ no free bits 68 + mov pc, lr 69 + 70 + /* 71 + * Purpose : Find next 'one' bit 72 + * Prototype: int find_next_zero_bit 73 + * (void *addr, unsigned int maxbit, int offset) 74 + */ 75 + ENTRY(__uc32_find_next_bit) 76 + cxor.a r1, #0 77 + beq 3b 78 + and.a ip, r2, #7 79 + beq 1b @ If new byte, goto old routine 80 + ldb r3, [r0+], r2 >> #3 81 + mov.a r3, r3 >> ip @ shift off unused bits 82 + bne .L_found 83 + or r2, r2, #7 @ if zero, then no bits here 84 + add r2, r2, #1 @ align bit pointer 85 + b 2b @ loop for next bit 86 + ENDPROC(__uc32_find_next_bit) 87 + 88 + /* 89 + * One or more bits in the LSB of r3 are assumed to be set. 90 + */ 91 + .L_found: 92 + rsub r1, r3, #0 93 + and r3, r3, r1 94 + cntlz r3, r3 95 + rsub r3, r3, #31 96 + add r0, r2, r3 97 + mov pc, lr 98 +