home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / SVGALIB / SVGALIB1.TAR / svgalib / gl / inlstring.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-09  |  6.0 KB  |  268 lines

  1.  
  2. /* Based on functions in linux/string.h */
  3.  
  4. #include <linux/types.h>    /* for size_t */
  5.  
  6.  
  7. static inline void * __memcpy_conventional(void * to, const void * from, size_t n)
  8. {
  9. __asm__("cld\n\t"
  10.     "movl %%edi,%%ecx\n\t"
  11.     "andl $1,%%ecx\n\t"
  12.     "subl %%ecx,%%edx\n\t"
  13.     "rep ; movsb\n\t"        /* 16-bit align destination */
  14.     "movl %%edx,%%ecx\n\t"
  15.     "shrl $2,%%ecx\n\t"
  16.     "rep ; movsl\n\t"
  17.     "testb $1,%%dl\n\t"
  18.     "je 1f\n\t"
  19.     "movsb\n"
  20.     "1:\ttestb $2,%%dl\n\t"
  21.     "je 2f\n\t"
  22.     "movsw\n"
  23.     "2:\n"
  24.     ::"d" (n),"D" ((long) to),"S" ((long) from)
  25.     : "cx","dx","di","si");
  26. return (to);
  27. }
  28.  
  29.  
  30. static inline void * __memcpyb(void * to, const void * from, size_t n)
  31. {
  32. __asm__("cld\n\t"
  33.     "rep ; movsb\n\t"
  34.     ::"c" (n),"D" ((long) to),"S" ((long) from)
  35.     : "cx","di","si");
  36. return (to);
  37. }
  38.  
  39. static inline void * __memsetb(void * s,char c,size_t count)
  40. {
  41. __asm__("cld\n\t"
  42.     "rep\n\t"
  43.     "stosb"
  44.     ::"a" (c),"D" (s),"c" (count)
  45.     :"cx","di");
  46. return s;
  47. }
  48.  
  49. static inline void * __memsetlong(void * s,unsigned c,size_t count)
  50. {
  51. __asm__("cld\n\t"
  52.     "rep\n\t"
  53.     "stosl"
  54.     ::"a" (c),"D" (s),"c" (count)
  55.     :"cx","di");
  56. return s;
  57. }
  58.  
  59. static inline void * __memset(void * s,char c,size_t count)
  60. {
  61. __asm__(
  62.     "cld\n\t"
  63.     "cmpl $12,%%edx\n\t"
  64.     "jl 1f\n\t"            /* if (count >= 12) */
  65.  
  66.     "movzbl %%al,%%ax\n\t"
  67.     "movl %%eax,%%ecx\n\t"
  68.     "shll $8,%%ecx\n\t"        /* c |= c << 8 */
  69.     "orl %%ecx,%%eax\n\t"
  70.     "movl %%eax,%%ecx\n\t"
  71.     "shll $16,%%ecx\n\t"        /* c |= c << 16 */
  72.     "orl %%ecx,%%eax\n\t" 
  73.     
  74.     "movl %%edx,%%ecx\n\t"
  75.     "negl %%ecx\n\t"
  76.     "andl $3,%%ecx\n\t"        /* (-s % 4) */
  77.     "subl %%ecx,%%edx\n\t"        /* count -= (-s % 4) */
  78.     "rep ; stosb\n\t"        /* align to longword boundary */
  79.     
  80.     "movl %%edx,%%ecx\n\t"
  81.     "shrl $2,%%ecx\n\t"
  82.     "rep ; stosl\n\t"        /* fill longwords */
  83.     
  84.     "andl $3,%%edx\n"        /* fill last few bytes */
  85.     "1:\tmovl %%edx,%%ecx\n\t"    /* <= 12 entry point */
  86.     "rep ; stosb\n\t"
  87.     ::"a" (c),"D" (s),"d" (count)
  88.     :"ax","cx","dx","di");
  89. return s;
  90. }
  91.  
  92. static inline void * __memset2(void * s,short c,size_t count)
  93. /* count is in 16-bit pixels */
  94. /* s is assumed to be 16-bit aligned */
  95. {
  96. __asm__(
  97.     "cld\n\t"
  98.     "cmpl $12,%%edx\n\t"
  99.     "jl 1f\n\t"            /* if (count >= 12) */
  100.  
  101.     "movzwl %%ax,%%eax\n\t"
  102.     "movl %%eax,%%ecx\n\t"
  103.     "shll $16,%%ecx\n\t"        /* c |= c << 16 */
  104.     "orl %%ecx,%%eax\n\t" 
  105.     
  106.     "movl %%edi,%%ecx\n\t"
  107.     "andl $2,%%ecx\n\t"        /* s & 2 */
  108.     "jz 2f\n\t"
  109.     "decl %%edx\n\t"        /* count -= 1 */
  110.     "stosw\n\t"            /* align to longword boundary */
  111.     
  112.     "2:\n\t"
  113.     "movl %%edx,%%ecx\n\t"
  114.     "shrl $1,%%ecx\n\t"
  115.     "rep ; stosl\n\t"        /* fill longwords */
  116.     
  117.     "andl $1,%%edx\n"        /* one 16-bit word left? */
  118.     "jz 3f\n\t"            /* no, finished */
  119.     "1:\tmovl %%edx,%%ecx\n\t"    /* <= 12 entry point */
  120.     "rep ; stosw\n\t"
  121.     "3:\n\t"
  122.     : :"a" (c),"D" (s),"d" (count)
  123.     :"ax","cx","dx","di");
  124. return s;
  125. }
  126.  
  127. static inline void * __memset3(void * s,int c,size_t count)
  128. /* count is in 24-bit pixels (3 bytes per pixel) */
  129. {
  130. __asm__(
  131.     "cmpl $8,%%edx\n\t"
  132. /*    "jmp 2f\n\t" */            /* debug */
  133.     "jl 2f\n\t"
  134.  
  135.     "movl %%eax,%%ebx\n\t"        /* eax = (low) BGR0 (high) */
  136.     "shll $24,%%ebx\n\t"        /* ebx = 000B */
  137.     "orl %%ebx,%%eax\n\t"        /* eax = BGRB */
  138.  
  139.     "movl %%eax,%%ebx\n\t"
  140.     "shrl $8,%%ebx\n\t"        /* ebx = GRB0 */
  141.     "movl %%ebx,%%ecx\n\t"
  142.     "shll $24,%%ecx\n\t"        /* ecx = 000G */
  143.     "orl %%ecx,%%ebx\n\t"        /* ebx = GRBG */
  144.  
  145.     "movl %%eax,%%ecx\n\t"
  146.     "shll $8,%%ecx\n\t"        /* ecx = 0BGR */
  147.     "movb %%bh,%%cl\n\t"        /* ecx = RBGR */
  148.  
  149.     "cmpl $16,%%edx\n\t"
  150.     "jl 1f\n\t"
  151.     "jmp 5f\n\t"
  152.     ".align 4,0x90\n\t"
  153.  
  154.     "5:\n\t"            /* loop unrolling */
  155.     "movl %%eax,(%%edi)\n\t"    /* write BGRB */
  156.     "movl %%ebx,4(%%edi)\n\t"    /* write GRBG */
  157.     "movl %%ecx,8(%%edi)\n\t"    /* write RBGR */
  158.     "movl %%eax,12(%%edi)\n\t"
  159.     "movl %%ebx,16(%%edi)\n\t"
  160.     "movl %%ecx,20(%%edi)\n\t"
  161.     "movl %%eax,24(%%edi)\n\t"
  162.     "movl %%ebx,28(%%edi)\n\t"
  163.     "movl %%ecx,32(%%edi)\n\t"
  164.     "movl %%eax,36(%%edi)\n\t"
  165.     "subl $16,%%edx\n\t"        /* blend end-of-loop instr. */
  166.     "movl %%ebx,40(%%edi)\n\t"
  167.     "movl %%ecx,44(%%edi)\n\t"
  168.     "addl $48,%%edi\n\t"
  169.     "cmpl $16,%%edx\n\t"
  170.     "jge 5b\n\t"
  171.     "andl %%edx,%%edx\n\t"
  172.     "jz 4f\n\t"            /* finished */
  173.     "cmpl $4,%%edx\n\t"
  174.     "jl 2f\n\t"            /* less than 4 pixels left */
  175.     "jmp 1f\n\t"
  176.     ".align 4,0x90\n\t"
  177.  
  178.     "1:\n\t"
  179.     "movl %%eax,(%%edi)\n\t"    /* write BGRB */ 
  180.     "movl %%ebx,4(%%edi)\n\t"    /* write GRBG */
  181.     "movl %%ecx,8(%%edi)\n\t"    /* write RBGR */
  182.     "addl $12,%%edi\n\t"
  183.     "subl $4,%%edx\n\t"
  184.     "cmpl $4,%%edx\n\t"
  185.     "jge 1b\n\t"
  186.  
  187.     "2:\n\t"
  188.     "cmpl $0,%%edx\n\t"        /* none left? */
  189.     "jle 4f\n\t"            /* finished */
  190.  
  191.     "mov %%eax,%%ecx\n\t"
  192.     "shrl $16,%%ecx\n\t"        /* B in cl */
  193.  
  194.     "3:\n\t"            /* write last few pixels */
  195.     "movw %%ax,(%%edi)\n\t"        /* write RG */ 
  196.     "movb %%cl,2(%%edi)\n\t"    /* write B */
  197.     "addl $3,%%edi\n\t"
  198.     "decl %%edx\n\t"
  199.     "jnz 3b\n\t"
  200.  
  201.     "4:\n\t"
  202.     ::"a" (c),"D" (s),"d" (count)
  203.     :"ax","bx","cx","dx","di");
  204. return s;
  205. }
  206.  
  207. /* Functions defined in mem.S */
  208.  
  209. extern memcpy4to3( void *dest, void *src, int n );
  210. extern memcpy32shift8( void *dest, void *src, int n );
  211.  
  212. /* Functions for which arguments must be passed in %ebx, %edx, and %ecx. */
  213. extern __memcpyasm_regargs();        /* nu_bytes >= 3 */
  214. extern __memcpyasm_regargs_aligned();    /* nu_bytes >= 32 */
  215.  
  216.  
  217. /* Always 32-bit align destination, even for a small number of bytes. */
  218. static inline void * __memcpy_aligndest( void *dest, const void *src, int n )
  219. {
  220. __asm__ __volatile__("
  221.     cmpl $3,%%ecx
  222.     ja 1f
  223.     call *__memcpy_jumptable(,%%ecx,4)
  224.     jmp 2f
  225. 1:    call __memcpyasm_regargs
  226.     "
  227.     :
  228.     : "b" (dest), "d" (src), "c" (n)
  229.     : "ax", "0", "1", "2" );
  230. }
  231.  
  232.  
  233. /* Optimized version for 32-bit aligned destination. */
  234. static inline void * __memcpy_destaligned( void *dest, const void *src, int n )
  235. {
  236. __asm__ __volatile__("
  237.     cmpl $32,%%ecx
  238.     ja 1f
  239.     call *__memcpy_jumptable(,%%ecx,4)
  240.     jmp 2f
  241. 1:    call __memcpyasm_regargs_aligned
  242. 2:
  243.     "
  244.     :
  245.     : "b" (dest), "d" (src), "c" (n)
  246.     : "ax", "0", "1", "2" );
  247. }
  248.  
  249.  
  250. /* Balanced inline memcpy; 32-bit align destination if nu_bytes >= 20. */
  251. static inline void * __memcpy_balanced( void *dest, const void *src, int n )
  252. {
  253. __asm__ __volatile__("
  254.     cmpl $19,%%ecx
  255.     ja 1f
  256.     call *__memcpy_jumptable(,%%ecx,4)
  257.     jmp 2f
  258. 1:    call __memcpyasm_regargs
  259. 2:
  260.     "
  261.     :
  262.     : "b" ((long) dest), "d" ((long) src), "c" ((long) n)
  263.     : "ax", "bx", "cx", "dx" );
  264. }
  265.  
  266.  
  267. #define __memcpy __memcpy_conventional
  268.