root/arch/openrisc/lib/string.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0-or-later */
   2 /*
   3  * OpenRISC string.S
   4  *
   5  * Linux architectural port borrowing liberally from similar works of
   6  * others.  All original copyrights apply as per the original source
   7  * declaration.
   8  *
   9  * Modifications for the OpenRISC architecture:
  10  * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
  11  * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
  12  */
  13 
  14 #include <linux/linkage.h>
  15 #include <asm/errno.h>
  16 
  17         /*
  18          * this can be optimized by doing gcc inline assemlby with
  19          * proper constraints (no need to save args registers...)
  20          *
  21          */
  22 
  23 
  24 /*
  25  *
  26  * int __copy_tofrom_user(void *to, const void *from, unsigned long size);
  27  *
  28  * NOTE: it returns number of bytes NOT copied !!!
  29  *
  30  */
  31         .global __copy_tofrom_user
  32 __copy_tofrom_user:
  33         l.addi  r1,r1,-12
  34         l.sw    0(r1),r6
  35         l.sw    4(r1),r4
  36         l.sw    8(r1),r3
  37 
  38         l.addi  r11,r5,0
  39 2:      l.sfeq  r11,r0
  40         l.bf    1f
  41         l.addi  r11,r11,-1
  42 8:      l.lbz   r6,0(r4)
  43 9:      l.sb    0(r3),r6
  44         l.addi  r3,r3,1
  45         l.j     2b
  46         l.addi  r4,r4,1
  47 1:
  48         l.addi  r11,r11,1               // r11 holds the return value
  49 
  50         l.lwz   r6,0(r1)
  51         l.lwz   r4,4(r1)
  52         l.lwz   r3,8(r1)
  53         l.jr    r9
  54         l.addi  r1,r1,12
  55 
  56         .section .fixup, "ax"
  57 99:
  58                 l.j     1b
  59                 l.nop
  60         .previous
  61 
  62         .section __ex_table, "a"
  63                 .long 8b, 99b           // read fault
  64                 .long 9b, 99b           // write fault
  65         .previous
  66 
  67 /*
  68  * unsigned long clear_user(void *addr, unsigned long size) ;
  69  *
  70  * NOTE: it returns number of bytes NOT cleared !!!
  71  */
  72         .global __clear_user
  73 __clear_user:
  74         l.addi  r1,r1,-8
  75         l.sw    0(r1),r4
  76         l.sw    4(r1),r3
  77 
  78 2:      l.sfeq  r4,r0
  79         l.bf    1f
  80         l.addi  r4,r4,-1
  81 9:      l.sb    0(r3),r0
  82         l.j     2b
  83         l.addi  r3,r3,1
  84 
  85 1:
  86         l.addi  r11,r4,1
  87 
  88         l.lwz   r4,0(r1)
  89         l.lwz   r3,4(r1)
  90         l.jr    r9
  91         l.addi  r1,r1,8
  92 
  93         .section .fixup, "ax"
  94 99:
  95                 l.j     1b
  96                 l.nop
  97         .previous
  98 
  99         .section __ex_table, "a"
 100                 .long 9b, 99b           // write fault
 101         .previous

/* [<][>][^][v][top][bottom][index][help] */