summaryrefslogtreecommitdiff
path: root/arch/m32r/lib/memset.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m32r/lib/memset.S')
-rw-r--r--arch/m32r/lib/memset.S178
1 files changed, 178 insertions, 0 deletions
diff --git a/arch/m32r/lib/memset.S b/arch/m32r/lib/memset.S
new file mode 100644
index 000000000..2b2831a37
--- /dev/null
+++ b/arch/m32r/lib/memset.S
@@ -0,0 +1,178 @@
+/*
+ * linux/arch/m32r/lib/memset.S
+ *
+ * Copyright (C) 2001,2002 Hiroyuki Kondo, and Hirokazu Takata
+ * Copyright (C) 2004 Hirokazu Takata
+ *
+ * void *memset(void *dst, int val, int len);
+ *
+ * dst: r0
+ * val: r1
+ * len: r2
+ * ret: r0
+ *
+ */
+
+ .text
+ .global memset
+
+#ifdef CONFIG_ISA_DUAL_ISSUE
+
+ .align 4
+memset:
+ mv r4, r0 || cmpz r2
+ jc r14
+ cmpui r2, #16
+ bnc qword_align_check
+ cmpui r2, #4
+ bc byte_set
+word_align_check: /* len >= 4 */
+ and3 r3, r4, #3
+ beqz r3, word_set
+ addi r3, #-4
+ neg r3, r3 /* r3 = -(r3 - 4) */
+align_word:
+ stb r1, @r4 || addi r4, #1
+ addi r2, #-1 || addi r3, #-1
+ bnez r3, align_word
+ cmpui r2, #4
+ bc byte_set
+word_set:
+ and3 r1, r1, #0x00ff /* r1: abababab <-- ??????ab */
+ sll3 r3, r1, #8
+ or r1, r3 || addi r4, #-4
+ sll3 r3, r1, #16
+ or r1, r3 || addi r2, #-4
+word_set_loop:
+ st r1, @+r4 || addi r2, #-4
+ bgtz r2, word_set_loop
+ bnez r2, byte_set_wrap
+ st r1, @+r4
+ jmp r14
+
+qword_align_check: /* len >= 16 */
+ and3 r3, r4, #15
+ bnez r3, word_align_check
+qword_set:
+ and3 r1, r1, #0x00ff /* r1: abababab <-- ??????ab */
+ sll3 r3, r1, #8
+ or r1, r3 || addi r4, #-4
+ sll3 r3, r1, #16
+ or r1, r3 || ldi r5, #16
+qword_set_loop:
+ ld r3, @(4,r4) /* cache line allocate */
+ st r1, @+r4 || addi r2, #-16
+ st r1, @+r4 || cmpu r2, r5
+ st r1, @+r4
+ st r1, @+r4
+ bnc qword_set_loop || cmpz r2
+ jc r14
+set_remainder:
+ cmpui r2, #4
+ bc byte_set_wrap1
+ addi r2, #-4
+ bra word_set_loop
+
+byte_set_wrap:
+ addi r2, #4
+ cmpz r2
+ jc r14
+byte_set_wrap1:
+ addi r4, #4
+#if defined(CONFIG_ISA_M32R2)
+byte_set:
+ addi r2, #-1 || stb r1, @r4+
+ bnez r2, byte_set
+#elif defined(CONFIG_ISA_M32R)
+byte_set:
+ addi r2, #-1 || stb r1, @r4
+ addi r4, #1
+ bnez r2, byte_set
+#else
+#error unknown isa configuration
+#endif
+end_memset:
+ jmp r14
+
+#else /* not CONFIG_ISA_DUAL_ISSUE */
+
+ .align 4
+memset:
+ mv r4, r0
+ beqz r2, end_memset
+ cmpui r2, #16
+ bnc qword_align_check
+ cmpui r2, #4
+ bc byte_set
+word_align_check: /* len >= 4 */
+ and3 r3, r4, #3
+ beqz r3, word_set
+ addi r3, #-4
+ neg r3, r3 /* r3 = -(r3 - 4) */
+align_word:
+ stb r1, @r4
+ addi r4, #1
+ addi r2, #-1
+ addi r3, #-1
+ bnez r3, align_word
+ cmpui r2, #4
+ bc byte_set
+word_set:
+ and3 r1, r1, #0x00ff /* r1: abababab <-- ??????ab */
+ sll3 r3, r1, #8
+ or r1, r3
+ sll3 r3, r1, #16
+ or r1, r3
+ addi r2, #-4
+ addi r4, #-4
+word_set_loop:
+ st r1, @+r4
+ addi r2, #-4
+ bgtz r2, word_set_loop
+ bnez r2, byte_set_wrap
+ st r1, @+r4
+ jmp r14
+
+qword_align_check: /* len >= 16 */
+ and3 r3, r4, #15
+ bnez r3, word_align_check
+qword_set:
+ and3 r1, r1, #0x00ff /* r1: abababab <-- ??????ab */
+ sll3 r3, r1, #8
+ or r1, r3
+ sll3 r3, r1, #16
+ or r1, r3
+ addi r4, #-4
+qword_set_loop:
+ ld r3, @(4,r4) /* cache line allocate */
+ addi r2, #-16
+ st r1, @+r4
+ st r1, @+r4
+ cmpui r2, #16
+ st r1, @+r4
+ st r1, @+r4
+ bnc qword_set_loop
+ bnez r2, set_remainder
+ jmp r14
+set_remainder:
+ cmpui r2, #4
+ bc byte_set_wrap1
+ addi r2, #-4
+ bra word_set_loop
+
+byte_set_wrap:
+ addi r2, #4
+ beqz r2, end_memset
+byte_set_wrap1:
+ addi r4, #4
+byte_set:
+ addi r2, #-1
+ stb r1, @r4
+ addi r4, #1
+ bnez r2, byte_set
+end_memset:
+ jmp r14
+
+#endif /* not CONFIG_ISA_DUAL_ISSUE */
+
+ .end