_sgnu_add.c
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:2k
开发平台:

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _sgnu_add.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. #define MAX_WORD     0xFFFFFFFF
  12. typedef unsigned long  word;
  13. typedef unsigned int sz_t;
  14. extern sz_t School_Add(word *a, sz_t a_used, word *b, sz_t b_used, word* sum)
  15. {
  16.   /* compute sum = a + b   (a_used >= b_used) */
  17.   int n = b_used / 16;
  18.   word* a_stop = a + a_used;
  19.   word* s_last = sum + a_used;
  20.   word aa;
  21.   word bb;  /* is used for b and to save carry (asm) */
  22. #define ADD_LOOP_BODY {
  23. aa = *a++; bb = *b++;
  24. asm volatile ("addxcc  %2, %1,  %0" : "=r"(aa)    : "0"(aa), "r"(bb) );
  25. *sum++ = aa; }
  26. asm volatile ("addcc  %%g0,%%g0,%0" : "=r"(bb) :  ); 
  27.   switch (b_used%16) {
  28.       case 15: ADD_LOOP_BODY;
  29.       case 14: ADD_LOOP_BODY;
  30.       case 13: ADD_LOOP_BODY;
  31.       case 12: ADD_LOOP_BODY;
  32.       case 11: ADD_LOOP_BODY;
  33.       case 10: ADD_LOOP_BODY;
  34.       case  9: ADD_LOOP_BODY;
  35.       case  8: ADD_LOOP_BODY;
  36.       case  7: ADD_LOOP_BODY;
  37.       case  6: ADD_LOOP_BODY;
  38.       case  5: ADD_LOOP_BODY;
  39.       case  4: ADD_LOOP_BODY;
  40.       case  3: ADD_LOOP_BODY;
  41.       case  2: ADD_LOOP_BODY;
  42.       case  1: ADD_LOOP_BODY;
  43.       case  0: asm volatile ("addx  %%g0,%%g0,%0" : "=r"(bb) :  ); 
  44.      }
  45.   while (n--)
  46.   { asm volatile ("addcc 0xffffffff,%1,%0" : "=r"(bb) : "0"(bb) );
  47.     ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY; 
  48.     ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY; 
  49.     ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY; 
  50.     ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY; ADD_LOOP_BODY;
  51.     asm volatile ("addx  %%g0,%%g0,%0" : "=r"(bb) : );
  52.    }
  53.   if (sum != a) 
  54.   { /* Copy_Vector(sum,a,a_used-b_used); */
  55.     for(b =sum; b < s_last; b++) *b = *a++;
  56.     *s_last = 0;
  57.    }
  58.   if (bb) /* propagate carry */
  59.   { while (++*sum == 0) sum++;
  60.     if (sum == s_last) a_used++;
  61.    }
  62.   return a_used;
  63. }