Sophie

Sophie

distrib > Fedora > 15 > i386 > by-pkgid > ff8e7344076b5fbaa54d805766a057bd > files > 5

libscs-devel-1.4.1-4.fc15.i686.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>addition_scs.c Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.2.15 -->
<center>
<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="annotated.html">Data Structures</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Data Fields</a> &nbsp; <a class="qindex" href="globals.html">Globals</a> &nbsp; </center>
<hr><h1>addition_scs.c</h1><a href="addition__scs_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001 <font class="comment">/** Functions for SCS addition and subtraction </font>
00002 <font class="comment"></font>
00003 <font class="comment">@file addition_scs.c</font>
00004 <font class="comment"></font>
00005 <font class="comment">@author Defour David David.Defour@ens-lyon.fr</font>
00006 <font class="comment">@author Florent de Dinechin Florent.de.Dinechin@ens-lyon.fr </font>
00007 <font class="comment"> </font>
00008 <font class="comment">This file is part of the SCS library.</font>
00009 <font class="comment"></font>
00010 <font class="comment">Many functions come in two versions, selected by a @#if.</font>
00011 <font class="comment"></font>
00012 <font class="comment">The reason is that we designed scslib library for internal use with</font>
00013 <font class="comment">SCS_NB_WORDS==8, so we provide a version with manual optimizations for</font>
00014 <font class="comment">this case.</font>
00015 <font class="comment"></font>
00016 <font class="comment">These optimisations include loop unrolling, and sometimes replacing</font>
00017 <font class="comment">temporary arrays of size 8 with 8 variables, which is more efficient</font>
00018 <font class="comment">on all modern processors with many (renaming) registers.</font>
00019 <font class="comment"></font>
00020 <font class="comment">Using gcc3.2 with the most aggressive optimization options for this</font>
00021 <font class="comment">purpose (-funroll-loops -foptimize-register-move -frerun-loop-opt</font>
00022 <font class="comment">-frerun-cse-after-loop) is still much slower. At some point in the</font>
00023 <font class="comment">future, gcc should catch up with unrolling since our loops are so</font>
00024 <font class="comment">simple, however the replacement of small arrays with variables is</font>
00025 <font class="comment">not something we are aware of in the literature about compiler</font>
00026 <font class="comment">optimization.</font>
00027 <font class="comment">*/</font>
00028 
00029 <font class="comment">/*</font>
00030 <font class="comment">Copyright (C) 2002  David Defour and Florent de Dinechin</font>
00031 <font class="comment"></font>
00032 <font class="comment">    This library is free software; you can redistribute it and/or</font>
00033 <font class="comment">    modify it under the terms of the GNU Lesser General Public</font>
00034 <font class="comment">    License as published by the Free Software Foundation; either</font>
00035 <font class="comment">    version 2.1 of the License, or (at your option) any later version.</font>
00036 <font class="comment"></font>
00037 <font class="comment">    This library is distributed in the hope that it will be useful,</font>
00038 <font class="comment">    but WITHOUT ANY WARRANTY; without even the implied warranty of</font>
00039 <font class="comment">    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU</font>
00040 <font class="comment">    Lesser General Public License for more details.</font>
00041 <font class="comment"></font>
00042 <font class="comment">    You should have received a copy of the GNU Lesser General Public</font>
00043 <font class="comment">    License along with this library; if not, write to the Free Software</font>
00044 <font class="comment">    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</font>
00045 <font class="comment"></font>
00046 <font class="comment"> */</font>
00047 
00048 <font class="preprocessor">#include "<a class="code" href="scs_8h.html">scs.h</a>"</font>
00049 <font class="preprocessor">#include "<a class="code" href="scs__private_8h.html">scs_private.h</a>"</font>
00050 <font class="comment"></font>
00051 <font class="comment">/**</font>
00052 <font class="comment">This function copies a result into another. There is an unrolled</font>
00053 <font class="comment">version for the case SCS_NB_WORDS==8.</font>
00054 <font class="comment">*/</font>
<a name="l00055"></a><a class="code" href="addition__scs_8c.html#a0">00055</a> <font class="keywordtype">void</font> <font class="keyword">inline</font> <a class="code" href="addition__scs_8c.html#a0">scs_set</a>(<a class="code" href="structscs.html">scs_ptr</a> result, <a class="code" href="structscs.html">scs_ptr</a> x){
00056  <font class="comment">/* unsigned int i;*/</font>
00057   
00058 <font class="preprocessor">#if (SCS_NB_WORDS==8)</font>
00059 <font class="preprocessor"></font>    R_HW[0] = X_HW[0]; R_HW[1] = X_HW[1]; 
00060     R_HW[2] = X_HW[2]; R_HW[3] = X_HW[3]; 
00061     R_HW[4] = X_HW[4]; R_HW[5] = X_HW[5]; 
00062     R_HW[6] = X_HW[6]; R_HW[7] = X_HW[7]; 
00063 <font class="preprocessor">#else</font>
00064 <font class="preprocessor"></font>  <font class="keywordflow">for</font>(i=0; i&lt;SCS_NB_WORDS; i++)
00065     R_HW[i] = X_HW[i];
00066 <font class="preprocessor">#endif</font>
00067 <font class="preprocessor"></font>  R_EXP = X_EXP;  
00068   R_IND = X_IND; 
00069   R_SGN = X_SGN;
00070 }
00071 
00072 <font class="comment"></font>
00073 <font class="comment">/** renormalize a SCS number.  </font>
00074 <font class="comment"></font>
00075 <font class="comment">This function removes the carry from each digit, and also shifts the</font>
00076 <font class="comment">digits in case of a cancellation (so that if result != 0 then its</font>
00077 <font class="comment">first digit is non-zero)</font>
00078 <font class="comment"> </font>
00079 <font class="comment"> @warning THIS FUNCTION HAS NEVER BEEN PROPERLY TESTED and is</font>
00080 <font class="comment"> currently unused in the library: instead, specific renormalisation</font>
00081 <font class="comment"> steps are fused within the code of the operations which require it.</font>
00082 <font class="comment"> */</font>
00083 
<a name="l00084"></a><a class="code" href="addition__scs_8c.html#a1">00084</a> <font class="keywordtype">void</font> <font class="keyword">inline</font> <a class="code" href="addition__scs_8c.html#a1">scs_renorm</a>(<a class="code" href="structscs.html">scs_ptr</a> result){
00085   <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> c;
00086   <font class="keywordtype">int</font> i, j, k;
00087 
00088   <font class="comment">/*</font>
00089 <font class="comment">   * Carry propagate</font>
00090 <font class="comment">   */</font>
00091   <font class="keywordflow">for</font>(i=SCS_NB_WORDS-1; i&gt;0; i--){
00092     c = R_HW[i] &amp; ~SCS_MASK_RADIX;
00093     R_HW[i-1] += c &gt;&gt; SCS_NB_BITS;
00094     R_HW[i]    = R_HW[i] &amp;  SCS_MASK_RADIX; 
00095   }
00096 
00097   <font class="keywordflow">if</font> (R_HW[0] &gt;= SCS_RADIX){
00098     <font class="comment">/*  Carry out! Need to shift digits  */</font>
00099     c = R_HW[0] &amp; ~SCS_MASK_RADIX;
00100     c = c &gt;&gt; SCS_NB_BITS;
00101     <font class="keywordflow">for</font>(i=SCS_NB_WORDS-1; i&gt;1; i--)
00102       R_HW[i] = R_HW[i-1];
00103 
00104     R_HW[1] = R_HW[0] &amp; SCS_MASK_RADIX;
00105     R_HW[0] = c;
00106     R_IND  += 1;
00107 
00108   }<font class="keywordflow">else</font>{
00109     <font class="comment">/* Was there a cancellation ? */</font>
00110     <font class="keywordflow">if</font> (R_HW[0] == 0){
00111 
00112       k = 1;
00113       <font class="keywordflow">while</font> ((R_HW[k] == 0) &amp;&amp; (k &lt;= SCS_NB_WORDS))
00114         k++;
00115       
00116       R_IND -= k;
00117 
00118       <font class="keywordflow">for</font>(j=k, i=0; j&lt;SCS_NB_WORDS; j++, i++)
00119         R_HW[i] = R_HW[j];
00120 
00121       <font class="keywordflow">for</font>(        ; i&lt;SCS_NB_WORDS; i++)
00122         R_HW[i] = 0;     
00123 
00124     }
00125   }
00126 }
00127 
00128 
00129 <font class="comment"></font>
00130 <font class="comment">/** Renormalization without cancellation check.</font>
00131 <font class="comment"></font>
00132 <font class="comment"> This renormalization step is especially designed for the addition of</font>
00133 <font class="comment"> several numbers with the same sign.  In this case, you know that there</font>
00134 <font class="comment"> has been no cancellation, which allows simpler renormalisation.</font>
00135 <font class="comment">*/</font>
00136 
<a name="l00137"></a><a class="code" href="addition__scs_8c.html#a2">00137</a> <font class="keywordtype">void</font> <font class="keyword">inline</font> <a class="code" href="addition__scs_8c.html#a2">scs_renorm_no_cancel_check</a>(<a class="code" href="structscs.html">scs_ptr</a> result){ 
00138   <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> carry, c0;
00139  <font class="comment">/* int i;*/</font>
00140 
00141   <font class="comment">/* Carry propagate  */</font>      
00142 <font class="preprocessor">#if (SCS_NB_WORDS==8)</font>
00143 <font class="preprocessor"></font>  carry = R_HW[7] &gt;&gt; SCS_NB_BITS;
00144   R_HW[6] += carry;  R_HW[7] = R_HW[7] &amp; SCS_MASK_RADIX;
00145   carry = R_HW[6] &gt;&gt; SCS_NB_BITS;
00146   R_HW[5] += carry;  R_HW[6] = R_HW[6] &amp; SCS_MASK_RADIX;
00147   carry = R_HW[5] &gt;&gt; SCS_NB_BITS;
00148   R_HW[4] += carry;  R_HW[5] = R_HW[5] &amp; SCS_MASK_RADIX;
00149   carry = R_HW[4] &gt;&gt; SCS_NB_BITS;
00150   R_HW[3] += carry;  R_HW[4] = R_HW[4] &amp; SCS_MASK_RADIX;
00151   carry = R_HW[3] &gt;&gt; SCS_NB_BITS;
00152   R_HW[2] += carry;  R_HW[3] = R_HW[3] &amp; SCS_MASK_RADIX;
00153   carry = R_HW[2] &gt;&gt; SCS_NB_BITS;
00154   R_HW[1] += carry;  R_HW[2] = R_HW[2] &amp; SCS_MASK_RADIX;
00155   carry = R_HW[1] &gt;&gt; SCS_NB_BITS;
00156   R_HW[0] += carry;  R_HW[1] = R_HW[1] &amp; SCS_MASK_RADIX;
00157 <font class="preprocessor">#else</font>
00158 <font class="preprocessor"></font>  <font class="keywordflow">for</font>(i=(SCS_NB_WORDS-1);i&gt;0;i--){
00159       carry      = R_HW[i] &gt;&gt; SCS_NB_BITS;
00160       R_HW[i-1] += carry;
00161       R_HW[i]    = R_HW[i] &amp; SCS_MASK_RADIX;
00162   }
00163 <font class="preprocessor">#endif</font>
00164 <font class="preprocessor"></font>    
00165   <font class="keywordflow">if</font> (R_HW[0] &gt;= SCS_RADIX){
00166     <font class="comment">/* Carry out ! Need to shift digits */</font>
00167     c0 = R_HW[0] &gt;&gt; SCS_NB_BITS;
00168     
00169 <font class="preprocessor">#if (SCS_NB_WORDS==8)</font>
00170 <font class="preprocessor"></font>    R_HW[7] = R_HW[6]; R_HW[6] = R_HW[5]; 
00171     R_HW[5] = R_HW[4]; R_HW[4] = R_HW[3]; 
00172     R_HW[3] = R_HW[2]; R_HW[2] = R_HW[1]; 
00173 <font class="preprocessor">#else</font>
00174 <font class="preprocessor"></font>    <font class="keywordflow">for</font>(i=(SCS_NB_WORDS-1); i&gt;1; i--)
00175       R_HW[i] =  R_HW[i-1];
00176 <font class="preprocessor">#endif    </font>
00177 <font class="preprocessor"></font>    R_HW[1] =  R_HW[0] &amp; SCS_MASK_RADIX;
00178     R_HW[0] =  c0;
00179     R_IND  += 1;
00180   }
00181   <font class="keywordflow">return</font>;
00182 }
00183 
00184 
00185 
00186 
00187 <font class="comment">/* addition without renormalisation.</font>
00188 <font class="comment"></font>
00189 <font class="comment"></font>
00190 <font class="comment">  Add two scs number x and y, the result is put into "result".</font>
00191 <font class="comment">  Assumes x.sign == y.sign    x.index &gt; y.index.  </font>
00192 <font class="comment"></font>
00193 <font class="comment">   The result is not normalized.</font>
00194 <font class="comment"> */</font>
00195 
00196 <font class="keywordtype">void</font> do_add_no_renorm(<a class="code" href="structscs.html">scs_ptr</a> result, <a class="code" href="structscs.html">scs_ptr</a> x, <a class="code" href="structscs.html">scs_ptr</a> y){
00197   <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> RES[SCS_NB_WORDS];
00198   <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> i, j, Diff;
00199   
00200   <font class="keywordflow">if</font> (x-&gt;<a class="code" href="structscs.html#m1">exception</a>.i[HI_ENDIAN]==0){<a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, y); <font class="keywordflow">return</font>; }
00201   <font class="keywordflow">if</font> (y-&gt;<a class="code" href="structscs.html#m1">exception</a>.i[HI_ENDIAN]==0){<a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, x); <font class="keywordflow">return</font>; }  
00202   
00203   <font class="keywordflow">for</font> (i=0; i&lt;SCS_NB_WORDS; i++)
00204     RES[i] = X_HW[i];
00205 
00206   Diff  = X_IND - Y_IND;
00207   R_EXP = X_EXP + Y_EXP - 1; 
00208   R_IND = X_IND;
00209   R_SGN = X_SGN;
00210 
00211   <font class="keywordflow">for</font> (i=Diff, j=0; i&lt;SCS_NB_WORDS; i++, j++)
00212     RES[i] += Y_HW[j];
00213 
00214   <font class="keywordflow">for</font> (i=0; i&lt;SCS_NB_WORDS; i++)
00215     R_HW[i] = RES[i];
00216 
00217   <font class="keywordflow">return</font>;
00218 }
00219 
00220 
00221 <font class="comment">/*</font>
00222 <font class="comment"> * Addition without renormalization. Assumes that x.sign == y.sign.</font>
00223 <font class="comment"> */</font>
<a name="l00224"></a><a class="code" href="addition__scs_8c.html#a4">00224</a> <font class="keywordtype">void</font> <font class="keyword">inline</font> <a class="code" href="addition__scs_8c.html#a4">scs_add_no_renorm</a>(<a class="code" href="structscs.html">scs_ptr</a> result, <a class="code" href="structscs.html">scs_ptr</a> x, <a class="code" href="structscs.html">scs_ptr</a> y)
00225 {
00226   <font class="keywordflow">if</font> (X_IND &gt;= Y_IND)
00227     do_add_no_renorm(result,x,y);
00228   <font class="keywordflow">else</font>
00229     do_add_no_renorm(result,y,x);
00230   <font class="keywordflow">return</font>;
00231 }
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 <font class="comment">/* The function that does the work in case of an addition</font>
00249 <font class="comment"></font>
00250 <font class="comment"> do_add is the function that does the addition of two SCS numbers,</font>
00251 <font class="comment">   assuming that x.sign == y.sign, X_IND &gt; Y_IND, x and y both</font>
00252 <font class="comment">   non-zero. </font>
00253 <font class="comment"> */</font>
00254 
00255 <font class="keywordtype">void</font> <font class="keyword">inline</font> do_add(<a class="code" href="structscs.html">scs_ptr</a> result, <a class="code" href="structscs.html">scs_ptr</a> x, <a class="code" href="structscs.html">scs_ptr</a> y)
00256 {
00257 <font class="preprocessor">#if (SCS_NB_WORDS==8)  </font><font class="comment">/* in this case we unroll all the loops */</font>
00258   <font class="keywordtype">int</font> carry, Diff;
00259   <font class="keywordtype">int</font> r0,r1,r2,r3,r4,r5,r6,r7;
00260   
00261   Diff  = X_IND - Y_IND;
00262   R_EXP = X_EXP + Y_EXP - 1; 
00263   R_IND = X_IND;
00264   R_SGN = X_SGN;
00265 
00266   <font class="keywordflow">switch</font> (Diff){
00267   <font class="keywordflow">case</font> 0:
00268     r0 = X_HW[0] + Y_HW[0]; r1 = X_HW[1] + Y_HW[1]; 
00269     r2 = X_HW[2] + Y_HW[2]; r3 = X_HW[3] + Y_HW[3];
00270     r4 = X_HW[4] + Y_HW[4]; r5 = X_HW[5] + Y_HW[5];
00271     r6 = X_HW[6] + Y_HW[6]; r7 = X_HW[7] + Y_HW[7]; <font class="keywordflow">break</font>;
00272   <font class="keywordflow">case</font> 1:
00273     r0 = X_HW[0];           r1 = X_HW[1] + Y_HW[0];
00274     r2 = X_HW[2] + Y_HW[1]; r3 = X_HW[3] + Y_HW[2];
00275     r4 = X_HW[4] + Y_HW[3]; r5 = X_HW[5] + Y_HW[4];
00276     r6 = X_HW[6] + Y_HW[5]; r7 = X_HW[7] + Y_HW[6]; <font class="keywordflow">break</font>;
00277   <font class="keywordflow">case</font> 2:
00278     r0 = X_HW[0];           r1 = X_HW[1];      
00279     r2 = X_HW[2] + Y_HW[0]; r3 = X_HW[3] + Y_HW[1];
00280     r4 = X_HW[4] + Y_HW[2]; r5 = X_HW[5] + Y_HW[3];
00281     r6 = X_HW[6] + Y_HW[4]; r7 = X_HW[7] + Y_HW[5]; <font class="keywordflow">break</font>;
00282   <font class="keywordflow">case</font> 3:
00283     r0 = X_HW[0];           r1 = X_HW[1];     
00284     r2 = X_HW[2];           r3 = X_HW[3] + Y_HW[0];
00285     r4 = X_HW[4] + Y_HW[1]; r5 = X_HW[5] + Y_HW[2];
00286     r6 = X_HW[6] + Y_HW[3]; r7 = X_HW[7] + Y_HW[4]; <font class="keywordflow">break</font>;
00287   <font class="keywordflow">case</font> 4:
00288     r0 = X_HW[0];           r1 = X_HW[1];
00289     r2 = X_HW[2];           r3 = X_HW[3];
00290     r4 = X_HW[4] + Y_HW[0]; r5 = X_HW[5] + Y_HW[1]; 
00291     r6 = X_HW[6] + Y_HW[2]; r7 = X_HW[7] + Y_HW[3]; <font class="keywordflow">break</font>;
00292   <font class="keywordflow">case</font> 5:
00293     r0 = X_HW[0];           r1 = X_HW[1];
00294     r2 = X_HW[2];           r3 = X_HW[3];
00295     r4 = X_HW[4];           r5 = X_HW[5] + Y_HW[0];
00296     r6 = X_HW[6] + Y_HW[1]; r7 = X_HW[7] + Y_HW[2]; <font class="keywordflow">break</font>;
00297   <font class="keywordflow">case</font> 6:
00298     r0 = X_HW[0];           r1 = X_HW[1];
00299     r2 = X_HW[2];           r3 = X_HW[3];
00300     r4 = X_HW[4];           r5 = X_HW[5];
00301     r6 = X_HW[6] + Y_HW[0]; r7 = X_HW[7] + Y_HW[1]; <font class="keywordflow">break</font>;
00302   <font class="keywordflow">case</font> 7:
00303     r0 = X_HW[0];           r1 = X_HW[1];
00304     r2 = X_HW[2];           r3 = X_HW[3];
00305     r4 = X_HW[4];           r5 = X_HW[5];
00306     r6 = X_HW[6];           r7 = X_HW[7] + Y_HW[0]; <font class="keywordflow">break</font>;
00307   <font class="keywordflow">default</font>:
00308     <font class="comment">/* Diff &gt;= 8*/</font>
00309     R_HW[0] = X_HW[0]; R_HW[1] = X_HW[1];
00310     R_HW[2] = X_HW[2]; R_HW[3] = X_HW[3];
00311     R_HW[4] = X_HW[4]; R_HW[5] = X_HW[5];
00312     R_HW[6] = X_HW[6]; R_HW[7] = X_HW[7];    <font class="keywordflow">return</font>;
00313   }
00314 
00315 
00316   <font class="comment">/* Carry propagation */</font>
00317   
00318   carry = r7 &gt;&gt; SCS_NB_BITS; r6 += carry;  r7 = r7 &amp; SCS_MASK_RADIX;
00319   carry = r6 &gt;&gt; SCS_NB_BITS; r5 += carry;  r6 = r6 &amp; SCS_MASK_RADIX;
00320   carry = r5 &gt;&gt; SCS_NB_BITS; r4 += carry;  r5 = r5 &amp; SCS_MASK_RADIX;
00321   carry = r4 &gt;&gt; SCS_NB_BITS; r3 += carry;  r4 = r4 &amp; SCS_MASK_RADIX;
00322   carry = r3 &gt;&gt; SCS_NB_BITS; r2 += carry;  r3 = r3 &amp; SCS_MASK_RADIX;
00323   carry = r2 &gt;&gt; SCS_NB_BITS; r1 += carry;  r2 = r2 &amp; SCS_MASK_RADIX;
00324   carry = r1 &gt;&gt; SCS_NB_BITS; r0 += carry;  r1 = r1 &amp; SCS_MASK_RADIX;
00325   carry = r0 &gt;&gt; SCS_NB_BITS;
00326    
00327   <font class="keywordflow">if</font> (carry){
00328     R_HW[7] = r6; R_HW[6] = r5;  R_HW[5] = r4; R_HW[4] = r3; 
00329     R_HW[3] = r2; R_HW[2] = r1;  R_HW[1] = r0 &amp; SCS_MASK_RADIX;
00330     R_HW[0] = 1 ;  
00331     R_IND  += 1;
00332   }
00333   <font class="keywordflow">else</font> {
00334     R_HW[0] = r0; R_HW[1] = r1; R_HW[2] = r2; R_HW[3] = r3; 
00335     R_HW[4] = r4; R_HW[5] = r5; R_HW[6] = r6; R_HW[7] = r7; 
00336   }
00337   <font class="keywordflow">return</font>;
00338 
00339 <font class="preprocessor">#else </font><font class="comment">/* #if SCS_NB_WORDS==8*/</font>
00340 
00341 <font class="comment">/* This generic version is still written in such a way that</font>
00342 <font class="comment"> it is unrollable at compile time</font>
00343 <font class="comment">*/</font>
00344   <font class="keywordtype">int</font> i,j, s, carry, Diff;
00345   <font class="keywordtype">int</font> res[SCS_NB_WORDS];
00346   
00347   Diff  = X_IND - Y_IND;
00348   R_EXP = X_EXP + Y_EXP - 1; 
00349   R_IND = X_IND;
00350   R_SGN = X_SGN;
00351 
00352   <font class="comment">/* The easy case */</font>
00353   <font class="keywordflow">if</font>(Diff &gt;= SCS_NB_WORDS){  
00354     <a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, x); <font class="keywordflow">return</font>;
00355   }
00356 
00357   <font class="comment">/* 0 &lt;= Diff &lt;= (SCS_NB_WORDS-1) */</font>
00358 
00359   carry=0;
00360   <font class="keywordflow">for</font>(i=(SCS_NB_WORDS-1), j=((SCS_NB_WORDS-1)-Diff); i&gt;=0 ; i--,j--){
00361     <font class="keywordflow">if</font> (j&gt;=0)
00362       s = X_HW[i] + Y_HW[j] + carry;
00363     <font class="keywordflow">else</font>
00364       s = X_HW[i] + carry;
00365     carry = s &gt;&gt; SCS_NB_BITS;
00366     res[i] = s &amp; SCS_MASK_RADIX;
00367   }
00368 
00369   <font class="keywordflow">if</font> (carry){
00370     <font class="comment">/* Carry out ! Need to shift digits */</font>    
00371     <font class="keywordflow">for</font>(i=(SCS_NB_WORDS-1); i&gt;=1; i--)
00372       R_HW[i] =  res[i-1];
00373     
00374     R_HW[0] = 1 ;  
00375     R_IND  += 1;
00376   }
00377   <font class="keywordflow">else</font> {
00378     <font class="keywordflow">for</font>(i=0; i&lt;SCS_NB_WORDS; i++)
00379       R_HW[i] =  res[i];
00380   }
00381 
00382   <font class="keywordflow">return</font>;
00383 <font class="preprocessor">#endif  </font><font class="comment">/* #if SCS_NB_WORDS==8*/</font>
00384 
00385 } <font class="comment">/* do_add*/</font>
00386 
00387 
00388 
00389 
00390 
00391 
00392 
00393 
00394 <font class="comment">/*</font>
00395 <font class="comment"> * Compare only the mantissa of x and y without the index or sign field</font>
00396 <font class="comment"> * Return : </font>
00397 <font class="comment"> * - 1    if x &gt; y</font>
00398 <font class="comment"> * - (-1) if x &lt; y</font>
00399 <font class="comment"> * - (0)  if x = y</font>
00400 <font class="comment"> */</font>
00401 
00402 <font class="keywordtype">int</font> <font class="keyword">inline</font> scs_cmp_mant(<a class="code" href="structscs.html">scs_ptr</a> x, <a class="code" href="structscs.html">scs_ptr</a> y){
00403   <font class="keywordtype">int</font> i;
00404   <font class="comment">/* Tried to unroll this loop, it doesn't work  */</font>
00405   <font class="keywordflow">for</font>(i=0; i&lt; SCS_NB_WORDS; i++){
00406     <font class="keywordflow">if</font> (X_HW[i] == Y_HW[i]) <font class="keywordflow">continue</font>;
00407     <font class="keywordflow">else</font> <font class="keywordflow">if</font> (X_HW[i] &gt; Y_HW[i]) <font class="keywordflow">return</font> 1;
00408     <font class="keywordflow">else</font> <font class="keywordflow">return</font> -1;}
00409   <font class="keywordflow">return</font> 0;
00410 }
00411 
00412 
00413 
00414 <font class="comment">/*</font><font class="comment">/////////////////////////////////////////////////////////////////</font>
00415 <font class="comment"></font><font class="comment">/////////////////////// SUBTRACTION //////////////////////////////</font>
00416 <font class="comment"></font><font class="comment">//////////////////////////////////////////////////////////////////</font>
00417 <font class="comment"></font>// This procedure assumes :
00418 // -    X_IND &gt;= Y_IND
00419 // -   X_SIGN != Y_SIGN
00420 //    neither x or y is zero
00421 //  and result = x - y  
00422 */
00423 
00424 
00425 <font class="keywordtype">void</font> <font class="keyword">inline</font> do_sub(<a class="code" href="structscs.html">scs_ptr</a> result, <a class="code" href="structscs.html">scs_ptr</a> x, <a class="code" href="structscs.html">scs_ptr</a> y){
00426   <font class="keywordtype">int</font> s, carry;
00427   <font class="keywordtype">int</font> Diff, i, j, cp;
00428   <font class="keywordtype">int</font> res[SCS_NB_WORDS];
00429 
00430   R_EXP = X_EXP + Y_EXP - 1;
00431   Diff  = X_IND - Y_IND;
00432   R_IND = X_IND;
00433   
00434     <font class="comment">/* The easy case */</font>
00435   <font class="keywordflow">if</font>(Diff &gt;= SCS_NB_WORDS){  
00436     <a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, x); <font class="keywordflow">return</font>;
00437   }
00438 
00439   <font class="keywordflow">else</font> { 
00440     <font class="comment">/* 0 &lt;= Diff &lt;= (SCS_NB_WORDS-1) */</font>
00441     carry = 0;
00442     <font class="keywordflow">if</font>(Diff==0) { 
00443       cp = scs_cmp_mant(x, y);
00444       
00445       <font class="keywordflow">if</font> (cp == 0) {
00446         <font class="comment">/* Yet another easy case: result = 0 */</font>
00447         <a class="code" href="zero__scs_8c.html#a0">scs_zero</a>(result);
00448         <font class="keywordflow">return</font>;
00449       }
00450       <font class="keywordflow">else</font> { <font class="comment">/* cp &lt;&gt; 0 */</font>
00451         <font class="keywordflow">if</font> (cp &gt; 0){
00452           <font class="comment">/* x &gt; y */</font>
00453 
00454           R_SGN = X_SGN; 
00455           <font class="keywordflow">for</font>(i=(SCS_NB_WORDS-1); i&gt;=0 ;i--){
00456             s = X_HW[i] - Y_HW[i] - carry;
00457             carry = (s&amp;SCS_RADIX)&gt;&gt;SCS_NB_BITS;
00458             res[i] = (s&amp;SCS_RADIX) + s;
00459           }       
00460         }
00461         <font class="keywordflow">else</font> { <font class="comment">/* cp &lt; 0  */</font>
00462           <font class="comment">/* x &lt; y (change of sign) */</font>
00463 
00464           R_SGN = - X_SGN;
00465           <font class="keywordflow">for</font>(i=(SCS_NB_WORDS-1); i&gt;=0 ;i--){
00466             s = - X_HW[i] + Y_HW[i] - carry;
00467             carry = (s&amp;SCS_RADIX)&gt;&gt;SCS_NB_BITS;
00468             res[i] = (s&amp;SCS_RADIX) + s;
00469           }
00470         }
00471       }
00472     }
00473     <font class="keywordflow">else</font> {
00474       <font class="comment">/* 1&lt;=Diff&lt;(SCS_NB_WORDS-1) Digits of x and y overlap but the</font>
00475 <font class="comment">       * sign will be that of x */</font>
00476       
00477       R_SGN = X_SGN; 
00478       <font class="keywordflow">for</font>(i=(SCS_NB_WORDS-1), j=((SCS_NB_WORDS-1)-Diff); i&gt;=0 ;i--,j--){
00479         <font class="keywordflow">if</font>(j&gt;=0)
00480           s = X_HW[i] - Y_HW[j] - carry;
00481         <font class="keywordflow">else</font>
00482           s = X_HW[i] - carry;
00483         carry = (s&amp;SCS_RADIX)&gt;&gt;SCS_NB_BITS;
00484         res[i] = (s&amp;SCS_RADIX) + s;
00485       }
00486     }
00487     <font class="comment">/* check for cancellations */</font>
00488     i=0;
00489     <font class="keywordflow">while</font> ((res[i]==0) &amp;&amp; (i &lt; SCS_NB_WORDS))  i++;
00490 
00491     <font class="keywordflow">if</font>(i&gt;0) { <font class="comment">/* cancellation, shift result*/</font>
00492       R_IND -= i;
00493       <font class="keywordflow">for</font>(j=0; i&lt;SCS_NB_WORDS; i++,j++)    R_HW[j] = res[i];
00494       <font class="keywordflow">for</font>(   ; j&lt;SCS_NB_WORDS; j++)        R_HW[j] = 0;
00495     }
00496     <font class="keywordflow">else</font> {
00497       <font class="keywordflow">for</font>(i=0; i&lt;SCS_NB_WORDS; i++)
00498         R_HW[i] =  res[i];
00499     }
00500   }
00501   <font class="keywordflow">return</font>;
00502 }
00503 
00504 
00505 
00506 
00507 
00508  
00509 
00510 <font class="comment"></font>
00511 <font class="comment">/** SCS addition (result is a normalised SCS number).</font>
00512 <font class="comment"></font>
00513 <font class="comment"> */</font>
<a name="l00514"></a><a class="code" href="addition__scs_8c.html#a8">00514</a> <font class="keywordtype">void</font> <font class="keyword">inline</font> <a class="code" href="addition__scs_8c.html#a8">scs_add</a>(<a class="code" href="structscs.html">scs_ptr</a> result, <a class="code" href="structscs.html">scs_ptr</a> x, <a class="code" href="structscs.html">scs_ptr</a> y)
00515 {
00516     
00517   <font class="keywordflow">if</font> (x-&gt;<a class="code" href="structscs.html#m1">exception</a>.i[HI_ENDIAN]==0){<a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, y); <font class="keywordflow">return</font>; }
00518   <font class="keywordflow">if</font> (y-&gt;<a class="code" href="structscs.html#m1">exception</a>.i[HI_ENDIAN]==0){<a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, x); <font class="keywordflow">return</font>; }  
00519 
00520   <font class="keywordflow">if</font> (X_SGN == Y_SGN){
00521     <font class="keywordflow">if</font>(X_IND &gt;= Y_IND)
00522       do_add(result,x,y);
00523     <font class="keywordflow">else</font>
00524       do_add(result,y,x);
00525   }<font class="keywordflow">else</font> {  
00526     <font class="keywordflow">if</font>(X_IND&gt;=Y_IND){
00527       do_sub(result,x,y);
00528     }<font class="keywordflow">else</font> { 
00529       do_sub(result,y,x); 
00530     } 
00531   } <font class="keywordflow">return</font>; 
00532 }
00533 <font class="comment"></font>
00534 <font class="comment">/** SCS subtraction (result is a normalised SCS number).</font>
00535 <font class="comment"></font>
00536 <font class="comment"> The arguments x, y and result may point to the same memory</font>
00537 <font class="comment"> location. </font>
00538 <font class="comment"> */</font>
<a name="l00539"></a><a class="code" href="addition__scs_8c.html#a9">00539</a> <font class="keywordtype">void</font> <font class="keyword">inline</font> <a class="code" href="addition__scs_8c.html#a9">scs_sub</a>(<a class="code" href="structscs.html">scs_ptr</a> result, <a class="code" href="structscs.html">scs_ptr</a> x, <a class="code" href="structscs.html">scs_ptr</a> y)
00540 {
00541   <font class="keywordflow">if</font> (x-&gt;<a class="code" href="structscs.html#m1">exception</a>.i[HI_ENDIAN]==0)
00542     { <a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, y); R_SGN = -R_SGN; <font class="keywordflow">return</font>; }
00543   <font class="keywordflow">if</font> (y-&gt;<a class="code" href="structscs.html#m1">exception</a>.i[HI_ENDIAN]==0)
00544     { <a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, x); <font class="keywordflow">return</font>; }
00545 
00546   <font class="keywordflow">if</font> (X_SGN == Y_SGN) {
00547     <font class="comment">/* Same sign, so it's a sub   */</font>
00548     <font class="keywordflow">if</font>(X_IND&gt;=Y_IND)
00549       do_sub(result,x,y);
00550     <font class="keywordflow">else</font>{
00551       do_sub(result,y,x);
00552       R_SGN = -R_SGN;
00553     }
00554   }<font class="keywordflow">else</font> {
00555     <font class="keywordflow">if</font>(X_IND&gt;=Y_IND)
00556       do_add(result,x,y);
00557     <font class="keywordflow">else</font>{
00558       do_add(result,y,x);
00559       R_SGN = -R_SGN; 
00560     }
00561   }
00562   <font class="keywordflow">return</font>;
00563 }
00564 
00565 
</pre></div><hr><address align="right"><small>Generated on Tue Jun 17 10:15:51 2003 for SCSLib by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 
width=110 height=53></a>1.2.15 </small></address>
</body>
</html>