Path: blob/master/arch/alpha/lib/ev67-strlen_user.S
10817 views
/*1* arch/alpha/lib/ev67-strlen_user.S2* 21264 version contributed by Rick Gorton <[email protected]>3*4* Return the length of the string including the NULL terminator5* (strlen+1) or zero if an error occurred.6*7* In places where it is critical to limit the processing time,8* and the data is not trusted, strnlen_user() should be used.9* It will return a value greater than its second argument if10* that limit would be exceeded. This implementation is allowed11* to access memory beyond the limit, but will not cross a page12* boundary when doing so.13*14* Much of the information about 21264 scheduling/coding comes from:15* Compiler Writer's Guide for the Alpha 2126416* abbreviated as 'CWG' in other comments here17* ftp.digital.com/pub/Digital/info/semiconductor/literature/dsc-library.html18* Scheduling notation:19* E - either cluster20* U - upper subcluster; U0 - subcluster U0; U1 - subcluster U121* L - lower subcluster; L0 - subcluster L0; L1 - subcluster L122* Try not to change the actual algorithm if possible for consistency.23*/2425#include <asm/regdef.h>262728/* Allow an exception for an insn; exit if we get one. */29#define EX(x,y...) \3099: x,##y; \31.section __ex_table,"a"; \32.long 99b - .; \33lda v0, $exception-99b(zero); \34.previous353637.set noreorder38.set noat39.text4041.globl __strlen_user42.ent __strlen_user43.frame sp, 0, ra4445.align 446__strlen_user:47ldah a1, 32767(zero) # do not use plain strlen_user() for strings48# that might be almost 2 GB long; you should49# be using strnlen_user() instead50nop51nop52nop5354.globl __strnlen_user5556.align 457__strnlen_user:58.prologue 059EX( ldq_u t0, 0(a0) ) # L : load first quadword (a0 may be misaligned)60lda t1, -1(zero) # E :6162insqh t1, a0, t1 # U :63andnot a0, 7, v0 # E :64or t1, t0, t0 # E :65subq a0, 1, a0 # E : get our +1 for the return6667cmpbge zero, t0, t1 # E : t1 <- bitmask: bit i == 1 <==> i-th byte == 068subq a1, 7, t2 # E :69subq a0, v0, t0 # E :70bne t1, $found # U :7172addq t2, t0, t2 # E :73addq a1, 1, a1 # E :74nop # E :75nop # E :7677.align 478$loop: ble t2, $limit # U :79EX( ldq t0, 8(v0) ) # L :80nop # E :81nop # E :8283cmpbge zero, t0, t1 # E :84subq t2, 8, t2 # E :85addq v0, 8, v0 # E : addr += 886beq t1, $loop # U :8788$found: cttz t1, t2 # U0 :89addq v0, t2, v0 # E :90subq v0, a0, v0 # E :91ret # L0 :9293$exception:94nop95nop96nop97ret9899.align 4 # currently redundant100$limit:101nop102nop103subq a1, t2, v0104ret105106.end __strlen_user107108109