ev67-strlen_user.S
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * arch/alpha/lib/ev67-strlen_user.S
  3.  * 21264 version contributed by Rick Gorton <rick.gorton@api-networks.com>
  4.  *
  5.  * Return the length of the string including the NULL terminator
  6.  * (strlen+1) or zero if an error occurred.
  7.  *
  8.  * In places where it is critical to limit the processing time,
  9.  * and the data is not trusted, strnlen_user() should be used.
  10.  * It will return a value greater than its second argument if
  11.  * that limit would be exceeded. This implementation is allowed
  12.  * to access memory beyond the limit, but will not cross a page
  13.  * boundary when doing so.
  14.  *
  15.  * Much of the information about 21264 scheduling/coding comes from:
  16.  *      Compiler Writer's Guide for the Alpha 21264
  17.  *      abbreviated as 'CWG' in other comments here
  18.  *      ftp.digital.com/pub/Digital/info/semiconductor/literature/dsc-library.html
  19.  * Scheduling notation:
  20.  *      E       - either cluster
  21.  *      U       - upper subcluster; U0 - subcluster U0; U1 - subcluster U1
  22.  *      L       - lower subcluster; L0 - subcluster L0; L1 - subcluster L1
  23.  * Try not to change the actual algorithm if possible for consistency.
  24.  */
  25. #include <alpha/regdef.h>
  26. /* Allow an exception for an insn; exit if we get one.  */
  27. #define EX(x,y...)
  28. 99: x,##y;
  29. .section __ex_table,"a";
  30. .gprel32 99b;
  31. lda v0, $exception-99b(zero);
  32. .previous
  33. .set noreorder
  34. .set noat
  35. .text
  36. .globl __strlen_user
  37. .ent __strlen_user
  38. .frame sp, 0, ra
  39. .align 4
  40. __strlen_user:
  41. ldah a1, 32767(zero) # do not use plain strlen_user() for strings
  42. # that might be almost 2 GB long; you should
  43. # be using strnlen_user() instead
  44. nop
  45. nop
  46. nop
  47. .globl __strnlen_user
  48. .align 4
  49. __strnlen_user:
  50. ldgp $29,0($27) # E E : we do exceptions -- we need the gp.
  51. /* Decomposes into lda/ldah */
  52. .prologue 1
  53. EX( ldq_u t0, 0(a0) ) # L : load first quadword (a0 may be misaligned)
  54. lda     t1, -1(zero) # E :
  55. insqh   t1, a0, t1 # U :
  56. andnot  a0, 7, v0 # E :
  57. or      t1, t0, t0 # E :
  58. subq a0, 1, a0 # E : get our +1 for the return 
  59. cmpbge  zero, t0, t1 # E : t1 <- bitmask: bit i == 1 <==> i-th byte == 0
  60. subq a1, 7, t2 # E :
  61. subq a0, v0, t0 # E :
  62. bne     t1, $found # U :
  63. addq t2, t0, t2 # E :
  64. addq a1, 1, a1 # E :
  65. nop # E :
  66. nop # E :
  67. .align 4
  68. $loop: ble t2, $limit # U :
  69. EX( ldq t0, 8(v0) ) # L :
  70. nop # E :
  71. nop # E :
  72. cmpbge  zero, t0, t1 # E :
  73. subq t2, 8, t2 # E :
  74. addq    v0, 8, v0 # E : addr += 8
  75. beq     t1, $loop # U :
  76. $found: cttz t1, t2 # U0 :
  77. addq v0, t2, v0 # E :
  78. subq    v0, a0, v0 # E :
  79. ret # L0 :
  80. $exception:
  81. nop
  82. nop
  83. nop
  84. ret
  85. .align 4 # currently redundant
  86. $limit:
  87. nop
  88. nop
  89. subq a1, t2, v0
  90. ret
  91. .end __strlen_user