xdr_float.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:9k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* xdr_float.c - generic XDR routines implementation */
  2. /* Copyright 1984-1997 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5.  * Copyright (c) 1987 Wind River Systems, Inc.
  6.  * Copyright (C) 1984, Sun Microsystems, Inc.
  7.  *
  8.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  9.  * unrestricted use provided that this legend is included on all tape
  10.  * media and as a part of the software program in whole or part.  Users
  11.  * may copy or modify Sun RPC without charge, but are not authorized
  12.  * to license or distribute it to anyone else except as part of a product or
  13.  * program developed by the user.
  14.  *
  15.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  16.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  17.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  18.  *
  19.  * Sun RPC is provided with no support and without any obligation on the
  20.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  21.  * modification or enhancement.
  22.  *
  23.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  24.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  25.  * OR ANY PART THEREOF.
  26.  *
  27.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  28.  * or profits or other special, indirect and consequential damages, even if
  29.  * Sun has been advised of the possibility of such damages.
  30.  *
  31.  * Sun Microsystems, Inc.
  32.  * 2550 Garcia Avenue
  33.  * Mountain View, California  94043
  34.  */
  35. /*
  36. modification history
  37. --------------------
  38. 02f,22oct01,dee  Add CPU coldfire
  39. 02e,07mar00,zl   added Hitachi SH support.
  40. 02d,06may98,cym  added SIMNT to portable list.
  41. 02c,23jan97,cdp  make ARM use big-endian word order in xdr_double.
  42. 02b,28nov96,cdp  added ARM support.
  43. 02a,27may94,yao  added PPC support.
  44. 01s,31aug95,ms   fixed xdr_double for little endian machines (SPR #4205)
  45. 01s,28nov95,ism  updated for vxsim/solaris
  46. 01r,19mar95,dvs  removed tron references.
  47. 01q,02dec93,pme  added Am29K support
  48. 01p,11aug93,rrr  vxsim hppa.
  49. 01o,23jun93,rrr  vxsim.
  50. 01n,09jun93,hdn  added a support for I80X86
  51. 01m,26may92,rrr  the tree shuffle
  52. 01l,04oct91,rrr  passed through the ansification filter
  53.   -changed includes to have absolute path from h/
  54.   -fixed #else and #endif
  55.   -changed copyright notice
  56. 01k,06aug91,ajm   added proper definitions of "mipsr3k".
  57. 01j,29apr91,hdn   added defines and macros for TRON architecture.
  58. 01i,01apr91,elh   added xdr_floatInclude.
  59. 01h,25mar91,del   modified CPU_FAMILY checking for floating point type.
  60. 01g,17oct90,gae   changed #elif to ordinary #if for the sake of some compilers.
  61. 01f,08oct90,hjb   added proper definitions of "mc68000" and "sparc".
  62. 01e,30apr90,gae   fixed compiler dependent definitions.
  63. 01d,19apr90,hjb   de-linted.
  64. 01c,27oct89,hjb   upgraded to 4.0
  65. 01b,11nov87,jlf   added wrs copyright, title, mod history, etc.
  66. 01a,01nov87,rdc   first VxWorks version
  67. */
  68. #ifndef lint
  69. /* static char sccsid[] = "@(#)xdr_float.c 1.1 86/02/03 Copyr 1984 Sun Micro"; */
  70. #endif
  71. /*
  72.  * xdr_float.c, Generic XDR routines impelmentation.
  73.  *
  74.  * These are the "floating point" xdr routines used to (de)serialize
  75.  * most common data items.  See xdr.h for more info on the interface to
  76.  * xdr.
  77.  */
  78. #include "rpc/rpctypes.h"
  79. #include "rpc/xdr.h"
  80. #include "vxWorks.h"
  81. #if ((CPU_FAMILY == MC680X0) || (CPU_FAMILY == I960) || (CPU_FAMILY==SPARC) || 
  82.      (CPU_FAMILY == MIPS) || (CPU_FAMILY == SIMSPARCSUNOS) || 
  83.      (CPU_FAMILY == SIMHPPA) || (CPU_FAMILY == AM29XXX) || 
  84.      (CPU_FAMILY == I80X86) || (CPU_FAMILY == SIMSPARCSOLARIS) || 
  85.      (CPU_FAMILY == SIMNT) || (CPU_FAMILY == ARM) || (CPU_FAMILY == PPC) || 
  86.      (CPU_FAMILY == SH) || (CPU_FAMILY == COLDFIRE))
  87. #define FLOAT_NORM
  88. #endif /* (CPU_FAMILY) */
  89. /*
  90.  * NB: Not portable.
  91.  * This routine works on Suns (Sky / 68000's) and Vaxen.
  92.  */
  93. /* What IEEE single precision floating point looks like on a Vax */
  94. struct  ieee_single {
  95. unsigned int mantissa: 23;
  96. unsigned int exp     : 8;
  97. unsigned int sign    : 1;
  98. };
  99. /* Vax single precision floating point */
  100. struct  vax_single {
  101. unsigned int mantissa1 : 7;
  102. unsigned int exp       : 8;
  103. unsigned int sign      : 1;
  104. unsigned int mantissa2 : 16;
  105. };
  106. #define VAX_SNG_BIAS    0x81
  107. #define IEEE_SNG_BIAS   0x7f
  108. #if !defined(FLOAT_NORM) /* 4.0 */
  109. static struct sgl_limits {
  110. struct vax_single s;
  111. struct ieee_single ieee;
  112. } sgl_limits[2] = {
  113. {{ 0x3f, 0xff, 0x0, 0xffff }, /* Max Vax */
  114. { 0x0, 0xff, 0x0 }}, /* Max IEEE */
  115. {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */
  116. { 0x0, 0x0, 0x0 }} /* Min IEEE */
  117. };
  118. #endif
  119. void xdr_floatInclude ()
  120.     {
  121.     }
  122. bool_t
  123. xdr_float(xdrs, fp)
  124. register XDR *xdrs;
  125. register float *fp;
  126. {
  127. #if !defined(FLOAT_NORM)
  128. struct ieee_single is;
  129. struct vax_single vs, *vsp;
  130. struct sgl_limits *lim;
  131. int i;
  132. #endif
  133. switch (xdrs->x_op) {
  134. case XDR_ENCODE:
  135. #if defined(FLOAT_NORM)
  136. return (XDR_PUTLONG(xdrs, (long *)fp));
  137. #else
  138. vs = *((struct vax_single *)fp);
  139. for (i = 0, lim = sgl_limits;
  140. i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
  141. i++, lim++) {
  142. if ((vs.mantissa2 == lim->s.mantissa2) &&
  143. (vs.exp == lim->s.exp) &&
  144. (vs.mantissa1 == lim->s.mantissa1)) {
  145. is = lim->ieee;
  146. goto shipit;
  147. }
  148. }
  149. is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
  150. is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
  151. shipit:
  152. is.sign = vs.sign;
  153. return (XDR_PUTLONG(xdrs, (long *)&is));
  154. #endif
  155. case XDR_DECODE:
  156. #if defined(FLOAT_NORM) /* 4.0 */
  157. return (XDR_GETLONG(xdrs, (long *)fp));
  158. #else
  159. vsp = (struct vax_single *)fp;
  160. if (!XDR_GETLONG(xdrs, (long *)&is))
  161. return (FALSE);
  162. for (i = 0, lim = sgl_limits;
  163. i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
  164. i++, lim++) {
  165. if ((is.exp == lim->ieee.exp) &&
  166. (is.mantissa = lim->ieee.mantissa)) {
  167. *vsp = lim->s;
  168. goto doneit;
  169. }
  170. }
  171. vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
  172. vsp->mantissa2 = is.mantissa;
  173. vsp->mantissa1 = (is.mantissa >> 16);
  174. doneit:
  175. vsp->sign = is.sign;
  176. return (TRUE);
  177. #endif
  178. case XDR_FREE:
  179. return (TRUE);
  180. }
  181. return (FALSE);
  182. }
  183. /*
  184.  * This routine works on Suns (Sky / 68000's) and Vaxen.
  185.  */
  186. #ifdef vax /* 4.0 */
  187. /* What IEEE double precision floating point looks like on a Vax */
  188. struct  ieee_double {
  189. unsigned int mantissa1 : 20;
  190. unsigned int exp   : 11;
  191. unsigned int sign   : 1;
  192. unsigned int mantissa2 : 32;
  193. };
  194. /* Vax double precision floating point */
  195. struct  vax_double {
  196. unsigned int mantissa1 : 7;
  197. unsigned int exp       : 8;
  198. unsigned int sign      : 1;
  199. unsigned int mantissa2 : 16;
  200. unsigned int mantissa3 : 16;
  201. unsigned int mantissa4 : 16;
  202. };
  203. #define VAX_DBL_BIAS    0x81
  204. #define IEEE_DBL_BIAS   0x3ff
  205. #define MASK(nbits)     ((1 << nbits) - 1)
  206. static struct dbl_limits {
  207. struct  vax_double d;
  208. struct  ieee_double ieee;
  209. } dbl_limits[2] = {
  210. {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
  211. { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */
  212. {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */
  213. { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */
  214. };
  215. #endif /* vax */ /* 4.0 */
  216. bool_t
  217. xdr_double(xdrs, dp)
  218. register XDR *xdrs;
  219. double *dp;
  220. {
  221. register long *lp;
  222. #if !defined(FLOAT_NORM) /* 4.0 */
  223. struct  ieee_double id;
  224. struct  vax_double vd;
  225. register struct dbl_limits *lim;
  226. int i;
  227. #endif
  228. switch (xdrs->x_op) {
  229. case XDR_ENCODE:
  230. #if defined(FLOAT_NORM) /* 4.0 */
  231. lp = (long *)dp;
  232. #else
  233. vd = *((struct  vax_double *)dp);
  234. for (i = 0, lim = dbl_limits;
  235. i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
  236. i++, lim++) {
  237. if ((vd.mantissa4 == lim->d.mantissa4) &&
  238. (vd.mantissa3 == lim->d.mantissa3) &&
  239. (vd.mantissa2 == lim->d.mantissa2) &&
  240. (vd.mantissa1 == lim->d.mantissa1) &&
  241. (vd.exp == lim->d.exp)) {
  242. id = lim->ieee;
  243. goto shipit;
  244. }
  245. }
  246. id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
  247. id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
  248. id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
  249. (vd.mantissa3 << 13) |
  250. ((vd.mantissa4 >> 3) & MASK(13));
  251. shipit:
  252. id.sign = vd.sign;
  253. lp = (long *)&id;
  254. #endif
  255. #if (_BYTE_ORDER == _BIG_ENDIAN) || (CPU_FAMILY == ARM)
  256. return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
  257. #else /* _BYTE_ORDER == _LITTLE_ENDIAN */
  258. return (XDR_PUTLONG(xdrs, lp+1) && XDR_PUTLONG(xdrs, lp));
  259. #endif /* _BYTE_ORDER == _BIG_ENDIAN */
  260. case XDR_DECODE:
  261. #if defined(FLOAT_NORM) /* 4.0 */
  262. lp = (long *)dp;
  263. #if (_BYTE_ORDER == _BIG_ENDIAN) || (CPU_FAMILY == ARM)
  264. return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
  265. #else /* _BYTE_ORDER == _LITTLE_ENDIAN */
  266. return (XDR_GETLONG(xdrs, lp+1) && XDR_GETLONG(xdrs, lp));
  267. #endif /* _BYTE_ORDER == _BIG_ENDIAN */
  268. #else
  269. lp = (long *)&id;
  270. if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
  271. return (FALSE);
  272. for (i = 0, lim = dbl_limits;
  273. i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
  274. i++, lim++) {
  275. if ((id.mantissa2 == lim->ieee.mantissa2) &&
  276. (id.mantissa1 == lim->ieee.mantissa1) &&
  277. (id.exp == lim->ieee.exp)) {
  278. vd = lim->d;
  279. goto doneit;
  280. }
  281. }
  282. vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
  283. vd.mantissa1 = (id.mantissa1 >> 13);
  284. vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
  285. (id.mantissa2 >> 29);
  286. vd.mantissa3 = (id.mantissa2 >> 13);
  287. vd.mantissa4 = (id.mantissa2 << 3);
  288. doneit:
  289. vd.sign = id.sign;
  290. *dp = *((double *)&vd);
  291. return (TRUE);
  292. #endif
  293. case XDR_FREE:
  294. return (TRUE);
  295. }
  296. return (FALSE);
  297. }