memset.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:2k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *
  3.  * Optimized version of the standard memset() function
  4.  *
  5.  * Return: none
  6.  *
  7.  * Inputs:
  8.  * in0: address of buffer
  9.  *  in1: byte value to use for storing
  10.  * in2: length of the buffer
  11.  *
  12.  * Copyright (C) 1999, 2001 Hewlett-Packard Co
  13.  * Copyright (C) 1999 Stephane Eranian <eranian@hpl.hp.com>
  14.  */
  15. #include <asm/asmmacro.h>
  16. // arguments
  17. //
  18. #define buf r32
  19. #define val r33
  20. #define len r34
  21. //
  22. // local registers
  23. //
  24. #define saved_pfs r14
  25. #define cnt r18
  26. #define buf2 r19
  27. #define saved_lc r20
  28. #define tmp r21
  29. GLOBAL_ENTRY(memset)
  30. .prologue
  31. .save ar.pfs, saved_pfs
  32.   alloc saved_pfs=ar.pfs,3,0,0,0 // cnt is sink here
  33. cmp.eq p8,p0=r0,len // check for zero length
  34. .save ar.lc, saved_lc
  35. mov saved_lc=ar.lc // preserve ar.lc (slow)
  36. ;;
  37. .body
  38. adds tmp=-1,len // br.ctop is repeat/until
  39. tbit.nz p6,p0=buf,0 // odd alignment
  40. (p8) br.ret.spnt.many rp
  41. cmp.lt p7,p0=16,len // if len > 16 then long memset
  42. mux1 val=val,@brcst // prepare value
  43. (p7) br.cond.dptk .long_memset
  44. ;;
  45. mov ar.lc=tmp // initialize lc for small count
  46. ;; // avoid RAW and WAW on ar.lc
  47. 1: // worst case 15 cyles, avg 8 cycles
  48. st1 [buf]=val,1
  49. br.cloop.dptk.few 1b
  50. ;; // avoid RAW on ar.lc
  51. mov ar.lc=saved_lc
  52. mov ar.pfs=saved_pfs
  53. br.ret.sptk.many rp // end of short memset
  54. // at this point we know we have more than 16 bytes to copy
  55. // so we focus on alignment
  56. .long_memset:
  57. (p6) st1 [buf]=val,1 // 1-byte aligned
  58. (p6) adds len=-1,len;; // sync because buf is modified
  59. tbit.nz p6,p0=buf,1
  60. ;;
  61. (p6) st2 [buf]=val,2 // 2-byte aligned
  62. (p6) adds len=-2,len;;
  63. tbit.nz p6,p0=buf,2
  64. ;;
  65. (p6) st4 [buf]=val,4 // 4-byte aligned
  66. (p6) adds len=-4,len;;
  67. tbit.nz p6,p0=buf,3
  68. ;;
  69. (p6) st8 [buf]=val,8 // 8-byte aligned
  70. (p6) adds len=-8,len;;
  71. shr.u cnt=len,4 // number of 128-bit (2x64bit) words
  72. ;;
  73. cmp.eq p6,p0=r0,cnt
  74. adds tmp=-1,cnt
  75. (p6) br.cond.dpnt .dotail // we have less than 16 bytes left
  76. ;;
  77. adds buf2=8,buf // setup second base pointer
  78. mov ar.lc=tmp
  79. ;;
  80. 2: // 16bytes/iteration
  81. st8 [buf]=val,16
  82. st8 [buf2]=val,16
  83. br.cloop.dptk.few 2b
  84. ;;
  85. .dotail: // tail correction based on len only
  86. tbit.nz p6,p0=len,3
  87. ;;
  88. (p6) st8 [buf]=val,8 // at least 8 bytes
  89. tbit.nz p6,p0=len,2
  90. ;;
  91. (p6) st4 [buf]=val,4 // at least 4 bytes
  92. tbit.nz p6,p0=len,1
  93. ;;
  94. (p6) st2 [buf]=val,2 // at least 2 bytes
  95. tbit.nz p6,p0=len,0
  96. mov ar.lc=saved_lc
  97. ;;
  98. (p6) st1 [buf]=val // only 1 byte left
  99. br.ret.sptk.many rp
  100. END(memset)