1/* 2 * linux/arch/m32r/strlen.S -- strlen code. 3 * 4 * Copyright (C) 2001 Hirokazu Takata 5 * 6 * size_t strlen(const char *s); 7 * 8 */ 9 10#include <linux/linkage.h> 11#include <asm/assembler.h> 12 13#ifdef CONFIG_ISA_DUAL_ISSUE 14 15 .text 16ENTRY(strlen) 17 mv r6, r0 || ldi r2, #0 18 and3 r0, r0, #3 19 bnez r0, strlen_byte 20; 21strlen_word: 22 ld r0, @r6+ 23; 24 seth r5, #high(0x01010101) 25 or3 r5, r5, #low(0x01010101) 26 sll3 r7, r5, #7 27strlen_word_loop: 28 ld r1, @r6+ || not r4, r0 29 sub r0, r5 || and r4, r7 30 and r4, r0 31 bnez r4, strlen_last_bytes 32 ld r0, @r6+ || not r4, r1 33 sub r1, r5 || and r4, r7 34 and r4, r1 || addi r2, #4 35 bnez r4, strlen_last_bytes 36 addi r2, #4 || bra.s strlen_word_loop 37 38 ; NOTE: If a null char. exists, return 0. 39 ; if ((x - 0x01010101) & ~x & 0x80808080) 40 ; return 0; 41; 42strlen_byte: 43 ldb r1, @r6 || addi r6, #1 44 beqz r1, strlen_exit 45 addi r2, #1 || bra.s strlen_byte 46; 47strlen_last_bytes: 48 ldi r0, #4 || addi r6, #-8 49; 50strlen_byte_loop: 51 ldb r1, @r6 || addi r6, #1 52 addi r0, #-1 || cmpz r1 53 bc.s strlen_exit || cmpz r0 54 addi r2, #1 || bnc.s strlen_byte_loop 55; 56strlen_exit: 57 mv r0, r2 || jmp r14 58 59#else /* not CONFIG_ISA_DUAL_ISSUE */ 60 61 .text 62ENTRY(strlen) 63 mv r6, r0 64 ldi r2, #0 65 and3 r0, r0, #3 66 bnez r0, strlen_byte 67; 68strlen_word: 69 ld r0, @r6+ 70; 71 seth r5, #high(0x01010101) 72 or3 r5, r5, #low(0x01010101) 73 sll3 r7, r5, #7 74strlen_word_loop: 75 ld r1, @r6+ 76 not r4, r0 ; NOTE: If a null char. exists, return 0. 77 sub r0, r5 ; if ((x - 0x01010101) & ~x & 0x80808080) 78 and r4, r7 ; return 0; 79 and r4, r0 80 bnez r4, strlen_last_bytes 81 addi r2, #4 82; 83 ld r0, @r6+ 84 not r4, r1 ; NOTE: If a null char. exists, return 0. 85 sub r1, r5 ; if ((x - 0x01010101) & ~x & 0x80808080) 86 and r4, r7 ; return 0; 87 and r4, r1 88 bnez r4, strlen_last_bytes 89 addi r2, #4 90 bra strlen_word_loop 91; 92strlen_byte: 93 ldb r1, @r6 94 addi r6, #1 95 beqz r1, strlen_exit 96 addi r2, #1 97 bra strlen_byte 98; 99strlen_last_bytes: 100 ldi r0, #4 101 addi r6, #-8 102; 103strlen_byte_loop: 104 ldb r1, @r6 105 addi r6, #1 106 addi r0, #-1 107 beqz r1, strlen_exit 108 addi r2, #1 109 bnez r0, strlen_byte_loop 110; 111strlen_exit: 112 mv r0, r2 113 jmp r14 114 115#endif /* not CONFIG_ISA_DUAL_ISSUE */ 116 117 .end 118