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>
This commit is contained in:
Vineet Gupta 2013-10-07 18:10:08 +05:30
parent 1f7e3dc0ba
commit 8922bc3058
3 changed files with 41 additions and 15 deletions

View File

@ -22,11 +22,10 @@
static inline void __delay(unsigned long loops) static inline void __delay(unsigned long loops)
{ {
__asm__ __volatile__( __asm__ __volatile__(
"1: sub.f %0, %0, 1 \n" " lp 1f \n"
" jpnz 1b \n" " nop \n"
: "+r"(loops) "1: \n"
: : "+l"(loops));
: "cc");
} }
extern void __bad_udelay(void); extern void __bad_udelay(void);

View File

@ -659,31 +659,30 @@ static inline unsigned long __arc_clear_user(void __user *to, unsigned long n)
static inline long static inline long
__arc_strncpy_from_user(char *dst, const char __user *src, long count) __arc_strncpy_from_user(char *dst, const char __user *src, long count)
{ {
long res = count; long res = 0;
char val; char val;
unsigned int hw_count;
if (count == 0) if (count == 0)
return 0; return 0;
__asm__ __volatile__( __asm__ __volatile__(
" lp 2f \n" " lp 3f \n"
"1: ldb.ab %3, [%2, 1] \n" "1: ldb.ab %3, [%2, 1] \n"
" breq.d %3, 0, 2f \n" " breq.d %3, 0, 3f \n"
" stb.ab %3, [%1, 1] \n" " stb.ab %3, [%1, 1] \n"
"2: sub %0, %6, %4 \n" " add %0, %0, 1 # Num of NON NULL bytes copied \n"
"3: ;nop \n" "3: \n"
" .section .fixup, \"ax\" \n" " .section .fixup, \"ax\" \n"
" .align 4 \n" " .align 4 \n"
"4: mov %0, %5 \n" "4: mov %0, %4 # sets @res as -EFAULT \n"
" j 3b \n" " j 3b \n"
" .previous \n" " .previous \n"
" .section __ex_table, \"a\" \n" " .section __ex_table, \"a\" \n"
" .align 4 \n" " .align 4 \n"
" .word 1b, 4b \n" " .word 1b, 4b \n"
" .previous \n" " .previous \n"
: "=r"(res), "+r"(dst), "+r"(src), "=&r"(val), "=l"(hw_count) : "+r"(res), "+r"(dst), "+r"(src), "=r"(val)
: "g"(-EFAULT), "ir"(count), "4"(count) /* this "4" seeds lp_count */ : "g"(-EFAULT), "l"(count)
: "memory"); : "memory");
return res; return res;

View File

@ -24,14 +24,32 @@ ENTRY(memcmp)
ld r4,[r0,0] ld r4,[r0,0]
ld r5,[r1,0] ld r5,[r1,0]
lsr.f lp_count,r3,3 lsr.f lp_count,r3,3
#ifdef CONFIG_ISA_ARCV2
/* In ARCv2 a branch can't be the last instruction in a zero overhead
* loop.
* So we move the branch to the start of the loop, duplicate it
* after the end, and set up r12 so that the branch isn't taken
* initially.
*/
mov_s r12,WORD2
lpne .Loop_end
brne WORD2,r12,.Lodd
ld WORD2,[r0,4]
#else
lpne .Loop_end lpne .Loop_end
ld_s WORD2,[r0,4] ld_s WORD2,[r0,4]
#endif
ld_s r12,[r1,4] ld_s r12,[r1,4]
brne r4,r5,.Leven brne r4,r5,.Leven
ld.a r4,[r0,8] ld.a r4,[r0,8]
ld.a r5,[r1,8] ld.a r5,[r1,8]
#ifdef CONFIG_ISA_ARCV2
.Loop_end:
brne WORD2,r12,.Lodd
#else
brne WORD2,r12,.Lodd brne WORD2,r12,.Lodd
.Loop_end: .Loop_end:
#endif
asl_s SHIFT,SHIFT,3 asl_s SHIFT,SHIFT,3
bhs_s .Last_cmp bhs_s .Last_cmp
brne r4,r5,.Leven brne r4,r5,.Leven
@ -89,7 +107,6 @@ ENTRY(memcmp)
bset.cs r0,r0,31 bset.cs r0,r0,31
.Lodd: .Lodd:
cmp_s WORD2,r12 cmp_s WORD2,r12
mov_s r0,1 mov_s r0,1
j_s.d [blink] j_s.d [blink]
bset.cs r0,r0,31 bset.cs r0,r0,31
@ -100,14 +117,25 @@ ENTRY(memcmp)
ldb r4,[r0,0] ldb r4,[r0,0]
ldb r5,[r1,0] ldb r5,[r1,0]
lsr.f lp_count,r3 lsr.f lp_count,r3
#ifdef CONFIG_ISA_ARCV2
mov r12,r3
lpne .Lbyte_end lpne .Lbyte_end
brne r3,r12,.Lbyte_odd
#else
lpne .Lbyte_end
#endif
ldb_s r3,[r0,1] ldb_s r3,[r0,1]
ldb r12,[r1,1] ldb r12,[r1,1]
brne r4,r5,.Lbyte_even brne r4,r5,.Lbyte_even
ldb.a r4,[r0,2] ldb.a r4,[r0,2]
ldb.a r5,[r1,2] ldb.a r5,[r1,2]
#ifdef CONFIG_ISA_ARCV2
.Lbyte_end:
brne r3,r12,.Lbyte_odd
#else
brne r3,r12,.Lbyte_odd brne r3,r12,.Lbyte_odd
.Lbyte_end: .Lbyte_end:
#endif
bcc .Lbyte_even bcc .Lbyte_even
brne r4,r5,.Lbyte_even brne r4,r5,.Lbyte_even
ldb_s r3,[r0,1] ldb_s r3,[r0,1]