Home | History | Annotate | Download | only in gas
      1 /* flonum_copy.c - copy a flonum
      2    Copyright (C) 1987-2016 Free Software Foundation, Inc.
      3 
      4    This file is part of GAS, the GNU Assembler.
      5 
      6    GAS is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3, or (at your option)
      9    any later version.
     10 
     11    GAS is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with GAS; see the file COPYING.  If not, write to the Free
     18    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     19    02110-1301, USA.  */
     20 
     21 #include "as.h"
     22 
     23 void
     24 flonum_copy (FLONUM_TYPE *in, FLONUM_TYPE *out)
     25 {
     26   unsigned int in_length;	/* 0 origin */
     27   unsigned int out_length;	/* 0 origin */
     28 
     29   out->sign = in->sign;
     30   in_length = in->leader - in->low;
     31 
     32   if (in->leader < in->low)
     33     {
     34       out->leader = out->low - 1;	/* 0.0 case */
     35     }
     36   else
     37     {
     38       out_length = out->high - out->low;
     39       /* Assume no GAPS in packing of littlenums.
     40 	 I.e. sizeof(array) == sizeof(element) * number_of_elements.  */
     41       if (in_length <= out_length)
     42 	{
     43 	  {
     44 	    /* For defensive programming, zero any high-order
     45 	       littlenums we don't need.  This is destroying evidence
     46 	       and wasting time, so why bother???  */
     47 	    if (in_length < out_length)
     48 	      {
     49 		memset ((char *) (out->low + in_length + 1), '\0',
     50 			out_length - in_length);
     51 	      }
     52 	  }
     53 	  memcpy ((void *) (out->low), (void *) (in->low),
     54 		  ((in_length + 1) * sizeof (LITTLENUM_TYPE)));
     55 	  out->exponent = in->exponent;
     56 	  out->leader = in->leader - in->low + out->low;
     57 	}
     58       else
     59 	{
     60 	  int shorten;		/* 1-origin. Number of littlenums we drop.  */
     61 
     62 	  shorten = in_length - out_length;
     63 	  /* Assume out_length >= 0 ! */
     64 	  memcpy ((void *) (out->low), (void *) (in->low + shorten),
     65 		  ((out_length + 1) * sizeof (LITTLENUM_TYPE)));
     66 	  out->leader = out->high;
     67 	  out->exponent = in->exponent + shorten;
     68 	}
     69     }				/* if any significant bits */
     70 }
     71