summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/arm/arm/in_cksum.c12
-rw-r--r--sys/arm/include/in_cksum.h82
2 files changed, 80 insertions, 14 deletions
diff --git a/sys/arm/arm/in_cksum.c b/sys/arm/arm/in_cksum.c
index 98b9670..2850ea7 100644
--- a/sys/arm/arm/in_cksum.c
+++ b/sys/arm/arm/in_cksum.c
@@ -90,18 +90,6 @@ in_addword(u_short a, u_short b)
}
u_short
-in_pseudo(u_int32_t a, u_int32_t b, u_int32_t c)
-{
- u_int64_t sum;
- union q_util q_util;
- union l_util l_util;
-
- sum = (u_int64_t) a + b + c;
- REDUCE16;
- return (sum);
-}
-
-u_short
in_cksum_skip(struct mbuf *m, int len, int skip)
{
u_int64_t sum = 0;
diff --git a/sys/arm/include/in_cksum.h b/sys/arm/include/in_cksum.h
index 2086842..4bdbdbb 100644
--- a/sys/arm/include/in_cksum.h
+++ b/sys/arm/include/in_cksum.h
@@ -44,18 +44,96 @@
#ifdef _KERNEL
u_short in_cksum(struct mbuf *m, int len);
u_short in_addword(u_short sum, u_short b);
-u_short in_pseudo(u_int sum, u_int b, u_int c);
u_short in_cksum_skip(struct mbuf *m, int len, int skip);
u_int do_cksum(const void *, int);
static __inline u_int
in_cksum_hdr(const struct ip *ip)
{
- u_int sum = do_cksum(ip, sizeof(struct ip));
+ u_int sum = 0;
+ u_int tmp1, tmp2, tmp3, tmp4;
+ if (((vm_offset_t)ip & 0x03) == 0)
+ __asm __volatile (
+ "adds %0, %0, %1\n"
+ "adcs %0, %0, %2\n"
+ "adcs %0, %0, %3\n"
+ "adcs %0, %0, %4\n"
+ "adcs %0, %0, %5\n"
+ "adc %0, %0, #0\n"
+ : "+r" (sum)
+ : "r" (((const u_int32_t *)ip)[0]),
+ "r" (((const u_int32_t *)ip)[1]),
+ "r" (((const u_int32_t *)ip)[2]),
+ "r" (((const u_int32_t *)ip)[3]),
+ "r" (((const u_int32_t *)ip)[4])
+ );
+ else
+ __asm __volatile (
+ "and %1, %5, #3\n"
+ "cmp %1, #0x02\n"
+ "ldrb %2, [%5], #0x01\n"
+ "ldrgeb %3, [%5], #0x01\n"
+ "movlt %3, #0\n"
+ "ldrgtb %4, [%5], #0x01\n"
+ "movle %4, #0x00\n"
+#ifdef __ARMEB__
+ "orreq %0, %3, %2, lsl #8\n"
+ "orreq %0, %0, %4, lsl #24\n"
+ "orrne %0, %0, %3, lsl #8\n"
+ "orrne %0, %0, %4, lsl #16\n"
+#else
+ "orreq %0, %2, %3, lsl #8\n"
+ "orreq %0, %0, %4, lsl #16\n"
+ "orrne %0, %3, %2, lsl #8\n"
+ "orrne %0, %0, %4, lsl #24\n"
+#endif
+ "ldmia %5, {%2, %3, %4}\n"
+ "adcs %0, %0, %2\n"
+ "adcs %0, %0, %3\n"
+ "adcs %0, %0, %4\n"
+ "ldrb %2, [%5]\n"
+ "cmp %1, #0x02\n"
+ "ldrgeb %3, [%5, #0x01]\n"
+ "movlt %3, #0x00\n"
+ "ldrgtb %4, [%5, #0x02]\n"
+ "movle %4, #0x00\n"
+ "tst %5, #0x01\n"
+#ifdef __ARMEB__
+ "orreq %2, %3, %2, lsl #8\n"
+ "orreq %2, %2, %4, lsl #24\n"
+ "orrne %2, %2, %3, lsl #8\n"
+ "orrne %2, %2, %4, lsl #16\n"
+#else
+ "orreq %2, %2, %3, lsl #8\n"
+ "orreq %2, %2, %4, lsl #16\n"
+ "orrne %2, %3, %2, lsl #8\n"
+ "orrne %2, %2, %4, lsl #24\n"
+#endif
+ "adds %0, %0, %2\n"
+ "adc %0, %0, #0\n"
+ : "+r" (sum), "=r" (tmp1), "=r" (tmp2), "=r" (tmp3),
+ "=r" (tmp4)
+ : "r" (ip));
+
sum = (sum & 0xffff) + (sum >> 16);
if (sum > 0xffff)
sum -= 0xffff;
return (~sum & 0xffff);
}
+
+static __inline u_short
+in_pseudo(u_int sum, u_int b, u_int c)
+{
+ __asm __volatile("adds %0, %0, %1\n"
+ "adcs %0, %0, %2\n"
+ "adc %0, %0, #0\n"
+ : "+r" (sum)
+ : "r" (b), "r" (c));
+ sum = (sum & 0xffff) + (sum >> 16);
+ if (sum > 0xffff)
+ sum -= 0xffff;
+ return (sum);
+}
+
#endif /* _KERNEL */
#endif /* _MACHINE_IN_CKSUM_H_ */
OpenPOWER on IntegriCloud