LCOV - code coverage report
Current view: top level - arch/arm/include/asm - word-at-a-time.h (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_qemu_modules_combined.info Lines: 7 7 100.0 %
Date: 2020-09-30 20:25:01 Functions: 1 1 100.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: GPL-2.0 */
       2                 :            : #ifndef __ASM_ARM_WORD_AT_A_TIME_H
       3                 :            : #define __ASM_ARM_WORD_AT_A_TIME_H
       4                 :            : 
       5                 :            : #ifndef __ARMEB__
       6                 :            : 
       7                 :            : /*
       8                 :            :  * Little-endian word-at-a-time zero byte handling.
       9                 :            :  * Heavily based on the x86 algorithm.
      10                 :            :  */
      11                 :            : #include <linux/kernel.h>
      12                 :            : 
      13                 :            : struct word_at_a_time {
      14                 :            :         const unsigned long one_bits, high_bits;
      15                 :            : };
      16                 :            : 
      17                 :            : #define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) }
      18                 :            : 
      19                 :            : static inline unsigned long has_zero(unsigned long a, unsigned long *bits,
      20                 :            :                                      const struct word_at_a_time *c)
      21                 :            : {
      22                 : 1019094762 :         unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits;
      23                 :            :         *bits = mask;
      24                 :            :         return mask;
      25                 :            : }
      26                 :            : 
      27                 :            : #define prep_zero_mask(a, bits, c) (bits)
      28                 :            : 
      29                 :            : static inline unsigned long create_zero_mask(unsigned long bits)
      30                 :            : {
      31                 :  274873334 :         bits = (bits - 1) & ~bits;
      32                 :  274873334 :         return bits >> 7;
      33                 :            : }
      34                 :            : 
      35                 :            : static inline unsigned long find_zero(unsigned long mask)
      36                 :            : {
      37                 :            :         unsigned long ret;
      38                 :            : 
      39                 :            : #if __LINUX_ARM_ARCH__ >= 5
      40                 :            :         /* We have clz available. */
      41                 :  274873334 :         ret = fls(mask) >> 3;
      42                 :            : #else
      43                 :            :         /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */
      44                 :            :         ret = (0x0ff0001 + mask) >> 23;
      45                 :            :         /* Fix the 1 for 00 case */
      46                 :            :         ret &= mask;
      47                 :            : #endif
      48                 :            : 
      49                 :            :         return ret;
      50                 :            : }
      51                 :            : 
      52                 :            : #define zero_bytemask(mask) (mask)
      53                 :            : 
      54                 :            : #else   /* __ARMEB__ */
      55                 :            : #include <asm-generic/word-at-a-time.h>
      56                 :            : #endif
      57                 :            : 
      58                 :            : #ifdef CONFIG_DCACHE_WORD_ACCESS
      59                 :            : 
      60                 :            : /*
      61                 :            :  * Load an unaligned word from kernel space.
      62                 :            :  *
      63                 :            :  * In the (very unlikely) case of the word being a page-crosser
      64                 :            :  * and the next page not being mapped, take the exception and
      65                 :            :  * return zeroes in the non-existing part.
      66                 :            :  */
      67                 :  636500740 : static inline unsigned long load_unaligned_zeropad(const void *addr)
      68                 :            : {
      69                 :            :         unsigned long ret, offset;
      70                 :            : 
      71                 :            :         /* Load word from unaligned pointer addr */
      72                 :  636500740 :         asm(
      73                 :            :         "1:        ldr     %0, [%2]\n"
      74                 :            :         "2:\n"
      75                 :            :         "  .pushsection .text.fixup,\"ax\"\n"
      76                 :            :         "  .align 2\n"
      77                 :            :         "3:        and     %1, %2, #0x3\n"
      78                 :            :         "  bic     %2, %2, #0x3\n"
      79                 :            :         "  ldr     %0, [%2]\n"
      80                 :            :         "  lsl     %1, %1, #0x3\n"
      81                 :            : #ifndef __ARMEB__
      82                 :            :         "  lsr     %0, %0, %1\n"
      83                 :            : #else
      84                 :            :         "  lsl     %0, %0, %1\n"
      85                 :            : #endif
      86                 :            :         "  b       2b\n"
      87                 :            :         "  .popsection\n"
      88                 :            :         "  .pushsection __ex_table,\"a\"\n"
      89                 :            :         "  .align  3\n"
      90                 :            :         "  .long   1b, 3b\n"
      91                 :            :         "  .popsection"
      92                 :            :         : "=&r" (ret), "=&r" (offset)
      93                 :            :         : "r" (addr), "Qo" (*(unsigned long *)addr));
      94                 :            : 
      95                 :  636500740 :         return ret;
      96                 :            : }
      97                 :            : 
      98                 :            : #endif  /* DCACHE_WORD_ACCESS */
      99                 :            : #endif /* __ASM_ARM_WORD_AT_A_TIME_H */

Generated by: LCOV version 1.14