diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-10-07 08:40:08 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2015-06-22 04:36:56 -0400 |
commit | 8922bc3058abbe5deaf887147e26531750ce7513 (patch) | |
tree | 647f15f01077a23afd047e3d01b125a93e2ac9b1 | |
parent | 1f7e3dc0baaa41217dc06d3370e1efd1aecbc1f0 (diff) |
ARCv2: Adhere to Zero Delay loop restriction
Branch insn can't be scheduled as last insn of Zero Overhead loop
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r-- | arch/arc/include/asm/delay.h | 9 | ||||
-rw-r--r-- | arch/arc/include/asm/uaccess.h | 17 | ||||
-rw-r--r-- | arch/arc/lib/memcmp.S | 30 |
3 files changed, 41 insertions, 15 deletions
diff --git a/arch/arc/include/asm/delay.h b/arch/arc/include/asm/delay.h index 43de30256981..08e7e2a16ac1 100644 --- a/arch/arc/include/asm/delay.h +++ b/arch/arc/include/asm/delay.h | |||
@@ -22,11 +22,10 @@ | |||
22 | static inline void __delay(unsigned long loops) | 22 | static inline void __delay(unsigned long loops) |
23 | { | 23 | { |
24 | __asm__ __volatile__( | 24 | __asm__ __volatile__( |
25 | "1: sub.f %0, %0, 1 \n" | 25 | " lp 1f \n" |
26 | " jpnz 1b \n" | 26 | " nop \n" |
27 | : "+r"(loops) | 27 | "1: \n" |
28 | : | 28 | : "+l"(loops)); |
29 | : "cc"); | ||
30 | } | 29 | } |
31 | 30 | ||
32 | extern void __bad_udelay(void); | 31 | extern void __bad_udelay(void); |
diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h index 30c9baffa96f..d1da6032b715 100644 --- a/arch/arc/include/asm/uaccess.h +++ b/arch/arc/include/asm/uaccess.h | |||
@@ -659,31 +659,30 @@ static inline unsigned long __arc_clear_user(void __user *to, unsigned long n) | |||
659 | static inline long | 659 | static inline long |
660 | __arc_strncpy_from_user(char *dst, const char __user *src, long count) | 660 | __arc_strncpy_from_user(char *dst, const char __user *src, long count) |
661 | { | 661 | { |
662 | long res = count; | 662 | long res = 0; |
663 | char val; | 663 | char val; |
664 | unsigned int hw_count; | ||
665 | 664 | ||
666 | if (count == 0) | 665 | if (count == 0) |
667 | return 0; | 666 | return 0; |
668 | 667 | ||
669 | __asm__ __volatile__( | 668 | __asm__ __volatile__( |
670 | " lp 2f \n" | 669 | " lp 3f \n" |
671 | "1: ldb.ab %3, [%2, 1] \n" | 670 | "1: ldb.ab %3, [%2, 1] \n" |
672 | " breq.d %3, 0, 2f \n" | 671 | " breq.d %3, 0, 3f \n" |
673 | " stb.ab %3, [%1, 1] \n" | 672 | " stb.ab %3, [%1, 1] \n" |
674 | "2: sub %0, %6, %4 \n" | 673 | " add %0, %0, 1 # Num of NON NULL bytes copied \n" |
675 | "3: ;nop \n" | 674 | "3: \n" |
676 | " .section .fixup, \"ax\" \n" | 675 | " .section .fixup, \"ax\" \n" |
677 | " .align 4 \n" | 676 | " .align 4 \n" |
678 | "4: mov %0, %5 \n" | 677 | "4: mov %0, %4 # sets @res as -EFAULT \n" |
679 | " j 3b \n" | 678 | " j 3b \n" |
680 | " .previous \n" | 679 | " .previous \n" |
681 | " .section __ex_table, \"a\" \n" | 680 | " .section __ex_table, \"a\" \n" |
682 | " .align 4 \n" | 681 | " .align 4 \n" |
683 | " .word 1b, 4b \n" | 682 | " .word 1b, 4b \n" |
684 | " .previous \n" | 683 | " .previous \n" |
685 | : "=r"(res), "+r"(dst), "+r"(src), "=&r"(val), "=l"(hw_count) | 684 | : "+r"(res), "+r"(dst), "+r"(src), "=r"(val) |
686 | : "g"(-EFAULT), "ir"(count), "4"(count) /* this "4" seeds lp_count */ | 685 | : "g"(-EFAULT), "l"(count) |
687 | : "memory"); | 686 | : "memory"); |
688 | 687 | ||
689 | return res; | 688 | return res; |
diff --git a/arch/arc/lib/memcmp.S b/arch/arc/lib/memcmp.S index 978bf8314dfb..a4015e7d9ab7 100644 --- a/arch/arc/lib/memcmp.S +++ b/arch/arc/lib/memcmp.S | |||
@@ -24,14 +24,32 @@ ENTRY(memcmp) | |||
24 | ld r4,[r0,0] | 24 | ld r4,[r0,0] |
25 | ld r5,[r1,0] | 25 | ld r5,[r1,0] |
26 | lsr.f lp_count,r3,3 | 26 | lsr.f lp_count,r3,3 |
27 | #ifdef CONFIG_ISA_ARCV2 | ||
28 | /* In ARCv2 a branch can't be the last instruction in a zero overhead | ||
29 | * loop. | ||
30 | * So we move the branch to the start of the loop, duplicate it | ||
31 | * after the end, and set up r12 so that the branch isn't taken | ||
32 | * initially. | ||
33 | */ | ||
34 | mov_s r12,WORD2 | ||
35 | lpne .Loop_end | ||
36 | brne WORD2,r12,.Lodd | ||
37 | ld WORD2,[r0,4] | ||
38 | #else | ||
27 | lpne .Loop_end | 39 | lpne .Loop_end |
28 | ld_s WORD2,[r0,4] | 40 | ld_s WORD2,[r0,4] |
41 | #endif | ||
29 | ld_s r12,[r1,4] | 42 | ld_s r12,[r1,4] |
30 | brne r4,r5,.Leven | 43 | brne r4,r5,.Leven |
31 | ld.a r4,[r0,8] | 44 | ld.a r4,[r0,8] |
32 | ld.a r5,[r1,8] | 45 | ld.a r5,[r1,8] |
46 | #ifdef CONFIG_ISA_ARCV2 | ||
47 | .Loop_end: | ||
48 | brne WORD2,r12,.Lodd | ||
49 | #else | ||
33 | brne WORD2,r12,.Lodd | 50 | brne WORD2,r12,.Lodd |
34 | .Loop_end: | 51 | .Loop_end: |
52 | #endif | ||
35 | asl_s SHIFT,SHIFT,3 | 53 | asl_s SHIFT,SHIFT,3 |
36 | bhs_s .Last_cmp | 54 | bhs_s .Last_cmp |
37 | brne r4,r5,.Leven | 55 | brne r4,r5,.Leven |
@@ -89,7 +107,6 @@ ENTRY(memcmp) | |||
89 | bset.cs r0,r0,31 | 107 | bset.cs r0,r0,31 |
90 | .Lodd: | 108 | .Lodd: |
91 | cmp_s WORD2,r12 | 109 | cmp_s WORD2,r12 |
92 | |||
93 | mov_s r0,1 | 110 | mov_s r0,1 |
94 | j_s.d [blink] | 111 | j_s.d [blink] |
95 | bset.cs r0,r0,31 | 112 | bset.cs r0,r0,31 |
@@ -100,14 +117,25 @@ ENTRY(memcmp) | |||
100 | ldb r4,[r0,0] | 117 | ldb r4,[r0,0] |
101 | ldb r5,[r1,0] | 118 | ldb r5,[r1,0] |
102 | lsr.f lp_count,r3 | 119 | lsr.f lp_count,r3 |
120 | #ifdef CONFIG_ISA_ARCV2 | ||
121 | mov r12,r3 | ||
103 | lpne .Lbyte_end | 122 | lpne .Lbyte_end |
123 | brne r3,r12,.Lbyte_odd | ||
124 | #else | ||
125 | lpne .Lbyte_end | ||
126 | #endif | ||
104 | ldb_s r3,[r0,1] | 127 | ldb_s r3,[r0,1] |
105 | ldb r12,[r1,1] | 128 | ldb r12,[r1,1] |
106 | brne r4,r5,.Lbyte_even | 129 | brne r4,r5,.Lbyte_even |
107 | ldb.a r4,[r0,2] | 130 | ldb.a r4,[r0,2] |
108 | ldb.a r5,[r1,2] | 131 | ldb.a r5,[r1,2] |
132 | #ifdef CONFIG_ISA_ARCV2 | ||
133 | .Lbyte_end: | ||
134 | brne r3,r12,.Lbyte_odd | ||
135 | #else | ||
109 | brne r3,r12,.Lbyte_odd | 136 | brne r3,r12,.Lbyte_odd |
110 | .Lbyte_end: | 137 | .Lbyte_end: |
138 | #endif | ||
111 | bcc .Lbyte_even | 139 | bcc .Lbyte_even |
112 | brne r4,r5,.Lbyte_even | 140 | brne r4,r5,.Lbyte_even |
113 | ldb_s r3,[r0,1] | 141 | ldb_s r3,[r0,1] |