aboutsummaryrefslogtreecommitdiffstats
path: root/arch/frv/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/frv/lib')
-rw-r--r--arch/frv/lib/Makefile2
-rw-r--r--arch/frv/lib/__ucmpdi2.S45
-rw-r--r--arch/frv/lib/checksum.c31
3 files changed, 71 insertions, 7 deletions
diff --git a/arch/frv/lib/Makefile b/arch/frv/lib/Makefile
index 19be2626d5e6..08be305c9f44 100644
--- a/arch/frv/lib/Makefile
+++ b/arch/frv/lib/Makefile
@@ -3,6 +3,6 @@
3# 3#
4 4
5lib-y := \ 5lib-y := \
6 __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o \ 6 __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o __ucmpdi2.o \
7 checksum.o memcpy.o memset.o atomic-ops.o \ 7 checksum.o memcpy.o memset.o atomic-ops.o \
8 outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o 8 outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o
diff --git a/arch/frv/lib/__ucmpdi2.S b/arch/frv/lib/__ucmpdi2.S
new file mode 100644
index 000000000000..d892f16ffaa9
--- /dev/null
+++ b/arch/frv/lib/__ucmpdi2.S
@@ -0,0 +1,45 @@
1/* __ucmpdi2.S: 64-bit unsigned compare
2 *
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12
13 .text
14 .p2align 4
15
16###############################################################################
17#
18# int __ucmpdi2(unsigned long long a [GR8:GR9],
19# unsigned long long b [GR10:GR11])
20#
21# - returns 0, 1, or 2 as a <, =, > b respectively.
22#
23###############################################################################
24 .globl __ucmpdi2
25 .type __ucmpdi2,@function
26__ucmpdi2:
27 or.p gr8,gr0,gr4
28 subcc gr8,gr10,gr0,icc0
29 setlos.p #0,gr8
30 bclr icc0,#2 ; a.msw < b.msw
31
32 setlos.p #2,gr8
33 bhilr icc0,#0 ; a.msw > b.msw
34
35 subcc.p gr9,gr11,gr0,icc1
36 setlos #0,gr8
37 setlos.p #2,gr9
38 setlos #1,gr7
39 cknc icc1,cc6
40 cor.p gr9,gr0,gr8, cc6,#1
41 cckls icc1,cc4, cc6,#1
42 andcr cc6,cc4,cc4
43 cor gr7,gr0,gr8, cc4,#1
44 bralr
45 .size __ucmpdi2, .-__ucmpdi2
diff --git a/arch/frv/lib/checksum.c b/arch/frv/lib/checksum.c
index 7bf5bd6cac8a..20e7dfc474ef 100644
--- a/arch/frv/lib/checksum.c
+++ b/arch/frv/lib/checksum.c
@@ -33,6 +33,7 @@
33 33
34#include <net/checksum.h> 34#include <net/checksum.h>
35#include <asm/checksum.h> 35#include <asm/checksum.h>
36#include <linux/module.h>
36 37
37static inline unsigned short from32to16(unsigned long x) 38static inline unsigned short from32to16(unsigned long x)
38{ 39{
@@ -115,34 +116,52 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum)
115 return result; 116 return result;
116} 117}
117 118
119EXPORT_SYMBOL(csum_partial);
120
118/* 121/*
119 * this routine is used for miscellaneous IP-like checksums, mainly 122 * this routine is used for miscellaneous IP-like checksums, mainly
120 * in icmp.c 123 * in icmp.c
121 */ 124 */
122unsigned short ip_compute_csum(const unsigned char * buff, int len) 125unsigned short ip_compute_csum(const unsigned char * buff, int len)
123{ 126{
124 return ~do_csum(buff,len); 127 return ~do_csum(buff, len);
125} 128}
126 129
130EXPORT_SYMBOL(ip_compute_csum);
131
127/* 132/*
128 * copy from fs while checksumming, otherwise like csum_partial 133 * copy from fs while checksumming, otherwise like csum_partial
129 */ 134 */
130
131unsigned int 135unsigned int
132csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err) 136csum_partial_copy_from_user(const char __user *src, char *dst,
137 int len, int sum, int *csum_err)
133{ 138{
134 if (csum_err) *csum_err = 0; 139 int rem;
135 memcpy(dst, src, len); 140
141 if (csum_err)
142 *csum_err = 0;
143
144 rem = copy_from_user(dst, src, len);
145 if (rem != 0) {
146 if (csum_err)
147 *csum_err = -EFAULT;
148 memset(dst + len - rem, 0, rem);
149 len = rem;
150 }
151
136 return csum_partial(dst, len, sum); 152 return csum_partial(dst, len, sum);
137} 153}
138 154
155EXPORT_SYMBOL(csum_partial_copy_from_user);
156
139/* 157/*
140 * copy from ds while checksumming, otherwise like csum_partial 158 * copy from ds while checksumming, otherwise like csum_partial
141 */ 159 */
142
143unsigned int 160unsigned int
144csum_partial_copy(const char *src, char *dst, int len, int sum) 161csum_partial_copy(const char *src, char *dst, int len, int sum)
145{ 162{
146 memcpy(dst, src, len); 163 memcpy(dst, src, len);
147 return csum_partial(dst, len, sum); 164 return csum_partial(dst, len, sum);
148} 165}
166
167EXPORT_SYMBOL(csum_partial_copy);