Mantid
Loading...
Searching...
No Matches
vms_convert.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7/*
8 * Module: vms_convert
9 * Author: Freddie Akeroyd, ISIS
10 * Purpose: Routines to convert from VAX to local integer
11 *representations
12 *
13 * $Id: vms_convert.cpp 4 2004-09-09 22:03:23Z faa59 $
14 */
15#include "vms_convert.h"
17
18/*
19 * Byte swaps for int and short
20 */
21
22#if 0
23inline unsigned swap_int(unsigned a)
24{
25 union { unsigned u; unsigned char c[4]; } temp;
26 unsigned char ctemp;
27 temp.u = a;
28 ctemp = temp.c[0]; temp.c[0] = temp.c[3]; temp.c[3] = ctemp;
29 ctemp = temp.c[1]; temp.c[1] = temp.c[2]; temp.c[2] = ctemp;
30 return temp.u;
31}
32#endif
33
34#define swap_int(a) (((a) << 24) | (((a) << 8) & 0x00ff0000) | (((a) >> 8) & 0x0000ff00) | ((unsigned long)(a) >> 24))
35
36#define swap_short(a) (((a & 0xff) << 8) | ((unsigned short)(a) >> 8))
37
38/* VAXes are little endian */
39
40unsigned short local_to_vax_short(const unsigned short *s) {
41#if defined(WORDS_BIGENDIAN)
42 return swap_short(*s);
43#else
44 return *s;
45#endif /* WORDS_BIGENDIAN */
46}
47
48unsigned short vax_to_local_short(const unsigned short *s) {
49#if defined(WORDS_BIGENDIAN)
50 return swap_short(*s);
51#else
52 return *s;
53#endif /* WORDS_BIGENDIAN */
54}
55
56unsigned local_to_vax_int(const fort_int *i) {
57#if defined(WORDS_BIGENDIAN)
58 return swap_int(*(unsigned *)i);
59#else
60 return *i;
61#endif /* WORDS_BIGENDIAN */
62}
63
64unsigned vax_to_local_int(const fort_int *i) {
65#if defined(WORDS_BIGENDIAN)
66 return swap_int(*(unsigned *)i);
67#else
68 return *i;
69#endif /* WORDS_BIGENDIAN */
70}
71
72void local_to_vax_shorts(const unsigned short *sa, const int *n) {
73#if defined(WORDS_BIGENDIAN)
74 int i;
75 for (i = 0; i < *n; i++) {
76 sa[i] = swap_short(sa[i]);
77 }
78#endif /* WORDS_BIGENDIAN */
79 (void)sa;
80 (void)n; // Avoid compiler warning
81}
82
83void vax_to_local_shorts(const unsigned short *sa, const int *n) {
84#if defined(WORDS_BIGENDIAN)
85 int i;
86 for (i = 0; i < *n; i++) {
87 sa[i] = swap_short(sa[i]);
88 }
89#endif /* WORDS_BIGENDIAN */
90 (void)sa;
91 (void)n; // Avoid compiler warning
92}
93
94void local_to_vax_ints(const fort_int *ia, const fort_int *n) {
95#if defined(WORDS_BIGENDIAN)
96 int i;
97 unsigned *uia = (unsigned *)ia;
98 for (i = 0; i < *n; i++) {
99 uia[i] = swap_int(uia[i]);
100 }
101#endif /* WORDS_BIGENDIAN */
102 (void)ia;
103 (void)n; // Avoid compiler warning
104}
105
106void vax_to_local_ints(const fort_int *ia, const fort_int *n) {
107#if defined(WORDS_BIGENDIAN)
108 int i;
109 unsigned *uia = (unsigned *)ia;
110 for (i = 0; i < *n; i++) {
111 uia[i] = swap_int(uia[i]);
112 }
113#endif /* WORDS_BIGENDIAN */
114 (void)ia;
115 (void)n; // Avoid compiler warning
116}
117
118/*
119 * determine a few things we need to know to write machine independent data
120 */
121
122#ifndef __VMS
123#define IEEEFP 1
124#endif /* __VMS */
125
126#ifdef __VMS
127/* set up codes for use of CVT$CONVERT_FLOAT */
128#if __IEEE_FLOAT
129#define IEEEFP 1
130#define VMS_FLOAT_NATIVE CVT$K_IEEE_S
131#define VMS_DOUBLE_NATIVE CVT$K_IEEE_T
132#elif __D_FLOAT
133#define VAXFP 1
134#define VMS_FLOAT_NATIVE CVT$K_VAX_F
135#define VMS_DOUBLE_NATIVE CVT$K_VAX_D
136#elif __G_FLOAT
137#define VAXFP 1
138#define VMS_FLOAT_NATIVE CVT$K_VAX_F
139#define VMS_DOUBLE_NATIVE CVT$K_VAX_G
140#else
141#error Cannot determine VMS floating point format
142#endif
143#endif /* __VMS */
144
145#if WORDS_BIGENDIAN
146
147/* What IEEE single precision floating point looks like on local machine */
148struct ieee_single {
149 unsigned int sign : 1;
150 unsigned int exp : 8;
151 unsigned int mantissa : 23;
152};
153
154/* Vax single precision floating point */
155struct vax_single {
156 unsigned int mantissa2 : 16;
157 unsigned int sign : 1;
158 unsigned int exp : 8;
159 unsigned int mantissa1 : 7;
160};
161
162#else
163
166 unsigned int mantissa : 23;
167 unsigned int exp : 8;
168 unsigned int sign : 1;
169};
170
173 unsigned int mantissa1 : 7;
174 unsigned int exp : 8;
175 unsigned int sign : 1;
176 unsigned int mantissa2 : 16;
177};
178
179#endif /* WORDS_BIGENDIAN */
180
181#define VAX_SNG_BIAS 0x81
182#define IEEE_SNG_BIAS 0x7f
183
185static const struct sgl_limits_struct {
186 struct vax_single s;
188} sgl_limits[2] = {
189 {{0x7f, 0xff, 0x0, 0xffff}, /* Max Vax */
190 {0x0, 0xff, 0x0}}, /* Max IEEE */
191 {{0x0, 0x0, 0x0, 0x0}, /* Min Vax */
192 {0x0, 0x0, 0x0}} /* Min IEEE */
194
195#define mmax sgl_limits[0]
196#define mmin sgl_limits[1]
197
198#if WORDS_BIGENDIAN
199
200/* What IEEE double precision floating point looks like */
201struct ieee_double {
202 unsigned int mantissa2 : 32;
203 unsigned int sign : 1;
204 unsigned int exp : 11;
205 unsigned int mantissa1 : 20;
206};
207
208/* Vax double precision floating point */
209struct vax_double {
210 // unsigned int mantissa4 : 16;
211 // unsigned int mantissa3 : 16;
212 unsigned int mantissa2 : 16;
213 unsigned int sign : 1;
214 unsigned int exp : 8;
215 unsigned int mantissa1 : 7;
216};
217
218#else
219
222 unsigned int mantissa1 : 20;
223 unsigned int exp : 11;
224 unsigned int sign : 1;
225 unsigned int mantissa2 : 32;
226};
227
230 unsigned int mantissa1 : 7;
231 unsigned int exp : 8;
232 unsigned int sign : 1;
233 unsigned int mantissa2 : 16;
234 // unsigned int mantissa3 : 16; ///<mantissa 3
235 // unsigned int mantissa4 : 16; ///<mantissa 4
236};
237
238#endif /* WORDS_BIGENDIAN */
239
240#define VAX_DBL_BIAS 0x81
241#define IEEE_DBL_BIAS 0x3ff
242#define MASK(nbits) ((1 << nbits) - 1)
243
244// static struct dbl_limits {
245// struct vax_double d;
246// struct ieee_double ieee;
247//} dbl_limits[2] = {
248// {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */
249// { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */
250// {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */
251// { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */
252//};
253
254/* VAX is little endian, so we may need to flip */
255#if WORDS_BIGENDIAN
256static int maybe_flip_bytes(void *p, size_t n) {
257 unsigned i;
258 unsigned char c_tmp, *c_p = (unsigned char *)p;
259 for (i = 0; i < n / 2; i++) {
260 c_tmp = c_p[i];
261 c_p[i] = c_p[n - i - 1];
262 c_p[n - i - 1] = c_tmp;
263 }
264 return 0;
265}
266#else
267#define maybe_flip_bytes(__p, __n)
268#endif /* WORDS_BIGENDIAN */
269
270GNU_DIAG_OFF("uninitialized")
271
272/* convert VAX F FLOAT into a local IEEE single float */
273static int vax_to_ieee_float(float *fp) {
274 struct ieee_single is;
275 struct vax_single vs;
276 struct sgl_limits_struct;
277 maybe_flip_bytes(fp, sizeof(float));
278 vs = *(reinterpret_cast<struct vax_single *>(fp));
279 switch (vs.exp) {
280 case 0:
281 /* all vax float with zero exponent map to zero */
282 is = mmin.ieee;
283 break;
284 case 2:
285 case 1:
286 /* These will map to subnormals */
287 is.exp = 0;
288 is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
289 /* lose some precision */
290 is.mantissa >>= 3 - vs.exp;
291 is.mantissa += (1 << (20 + vs.exp));
292 break;
293 case 0xff: /* mmax.s.exp */
294 if (vs.mantissa2 == mmax.s.mantissa2 && vs.mantissa1 == mmax.s.mantissa1) {
295 /* map largest vax float to ieee infinity */
296 is = mmax.ieee;
297 break;
298 } /* else, fall thru */
299 default:
300 is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
301 is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
302 }
303
304 is.sign = vs.sign;
305 *fp = *(reinterpret_cast<float *>(&is));
306 return 0;
307}
308
309/* convert a local IEEE single float to little endian VAX F FLOAT format */
310static int ieee_to_vax_float(float *fp) {
311 struct ieee_single is;
312 struct vax_single vs;
313 struct sgl_limits_struct;
314 is = *(reinterpret_cast<struct ieee_single *>(fp));
315 switch (is.exp) {
316 case 0:
317 if (is.mantissa == mmin.ieee.mantissa) {
318 vs = mmin.s;
319 } else {
320 unsigned tmp = is.mantissa >> 20;
321 if (tmp >= 4) {
322 vs.exp = 2;
323 } else if (tmp >= 2) {
324 vs.exp = 1;
325 } else {
326 vs = mmin.s;
327 break;
328 } /* else */
329 tmp = is.mantissa - (1 << (20 + vs.exp));
330 tmp <<= 3 - vs.exp;
331 vs.mantissa2 = tmp;
332 vs.mantissa1 = (tmp >> 16);
333 }
334 break;
335 case 0xfe:
336 case 0xff:
337 vs = mmax.s;
338 break;
339 default:
340 vs.exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
341 vs.mantissa2 = is.mantissa;
342 vs.mantissa1 = (is.mantissa >> 16);
343 }
344
345 vs.sign = is.sign;
346 *fp = *(reinterpret_cast<float *>(&vs));
347 maybe_flip_bytes(fp, sizeof(float)); /* Make little endian */
348 return 0;
349}
350
351GNU_DIAG_ON("uninitialized")
352
353void vaxf_to_local(float *val, const int *n, int *errcode) {
354#if defined(VAXFP)
355#include <cvt$routines>
356#include <cvtdef>
357#endif
358 int i;
359 *errcode = 0;
360#if defined(VAXFP)
361 /* Do a null conversion to replace invalid values (prevents floating
362 * exceptions later on) */
363 for (i = 0; i < *n; i++) {
364 if (cvt$ftof(val + i, CVT$K_VAX_F, val + i, CVT$K_VAX_F, CVT$M_REPORT_ALL) != CVT$K_NORMAL) {
365 val[i] = 0.0; /* Fix with a safe value when status shows an invalid real
366 is being converted */
367 }
368 }
369#elif defined(IEEEFP)
370 for (i = 0; i < *n; i++) {
371 if (vax_to_ieee_float(i + val) != 0) {
372 *errcode = 1;
373 }
374 }
375#else
376#error Unknown floating point format
377#endif
378}
379
380void local_to_vaxf(float *val, const int *n, int *errcode) {
381 *errcode = 0;
382#if defined(VAXFP)
383/* nothing required */
384#elif defined(IEEEFP)
385 for (int i = 0; i < *n; i++) {
386 if (ieee_to_vax_float(i + val) != 0) {
387 *errcode = 1;
388 }
389 }
390#else
391#error Unknown floating point format
392#endif
393}
394
395void ieee_float_to_local(const float *val, const int *n, int *errcode) {
396#if defined(IEEEFP)
397 (void)val;
398 (void)n; // Avoid compiler warning
399 *errcode = 0;
400#elif defined(VAXFP)
401 int i;
402 *errcode = 0;
403 for (i = 0; i < *n; i++) {
404 // if (ieee_to_vax_float(i+val) != 0)
405 if (cvt$ftof(val + i, CVT$K_IEEE_S, val + i, VMS_FLOAT_NATIVE, 0) != CVT$K_NORMAL) {
406 *errcode = 1;
407 val[i] = 0.0;
408 }
409 }
410#else
411#error Unknown floating point format
412#endif
413}
414
415void ieee_double_to_local(const double *val, const int *n, int *errcode) {
416#if defined(IEEEFP)
417 (void)val;
418 (void)n; // Avoid compiler warning
419 *errcode = 0;
420#elif defined(VAXFP)
421#include <cvt$routines>
422#include <cvtdef>
423 int i;
424 *errcode = 0;
425 for (i = 0; i < *n; i++) {
426 if (cvt$ftof(val + i, CVT$K_IEEE_T, val + i, VMS_DOUBLE_NATIVE, CVT$M_REPORT_ALL) != CVT$K_NORMAL) {
427 val[i] = 0.0;
428 *errcode = 1;
429 }
430 }
431#else
432#error Unknown floating point format
433#endif
434}
435
436void local_to_ieee_float(const float *val, const int *n, int *errcode) {
437#if defined(IEEEFP)
438 (void)val;
439 (void)n; // Avoid compiler warning
440 *errcode = 0;
441#elif defined(VAXFP)
442#include <cvt$routines>
443#include <cvtdef>
444 int i;
445 *errcode = 0;
446 for (i = 0; i < *n; i++) {
447 if (cvt$ftof(val + i, VMS_FLOAT_NATIVE, val + i, CVT$K_IEEE_S, CVT$M_REPORT_ALL) != CVT$K_NORMAL) {
448 val[i] = 0.0;
449 *errcode = 1;
450 }
451 }
452#else
453#error Unknown floating point format
454#endif
455}
456
457void local_to_ieee_double(const double *val, const int *n, int *errcode) {
458#if defined(IEEEFP)
459 (void)val;
460 (void)n; // Avoid compiler warning
461 *errcode = 0;
462#elif defined(VAXFP)
463 int i;
464 *errcode = 0;
465 for (i = 0; i < *n; i++) {
466 if (cvt$ftof(val + i, VMS_DOUBLE_NATIVE, val + i, CVT$K_IEEE_T, CVT$M_REPORT_ALL) != CVT$K_NORMAL) {
467 val[i] = 0.0;
468 *errcode = 1;
469 }
470 }
471#else
472#error Unknown floating point format
473#endif
474}
475
476#if 0
477static unsigned char flip_bits(unsigned char cc)
478{
479 static int init = 0;
480 static unsigned char ct[256];
481 if (!init)
482 {
483 unsigned _i,_j;
484 for(_i=0; _i<256; _i++)
485 {
486 ct[_i] = 0;
487 for(_j=0; _j<8; _j++)
488 {
489 if (_i & (1<<_j)) { ct[_i] |= (128 >> _j); }
490 }
491 }
492 init = 1;
493 }
494 return ct[cc];
495}
496#endif
gsl_vector * tmp
#define GNU_DIAG_ON(x)
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
What IEEE double precision floating point looks like.
unsigned int exp
exponential
unsigned int mantissa1
mantissa 1
unsigned int sign
sign
unsigned int mantissa2
mantissa 2
What IEEE single precision floating point looks like on local machine.
unsigned int sign
sign
unsigned int exp
Exponential.
unsigned int mantissa
mantissa
Structure holding the limits of s single.
struct ieee_single ieee
ieee single struct
struct vax_single s
vax single struct
Vax double precision floating point.
unsigned int mantissa2
mantissa 2
unsigned int sign
sign
unsigned int exp
exponential
unsigned int mantissa1
mantissa 1
Vax single precision floating point.
unsigned int mantissa2
mantissa 2
unsigned int sign
sign
unsigned int mantissa1
mantissa 1
unsigned int exp
Exponential.
void local_to_vax_ints(const fort_int *ia, const fort_int *n)
#define VAX_SNG_BIAS
void vax_to_local_ints(const fort_int *ia, const fort_int *n)
static int ieee_to_vax_float(float *fp)
void ieee_float_to_local(const float *val, const int *n, int *errcode)
void vaxf_to_local(float *val, const int *n, int *errcode)
void local_to_vaxf(float *val, const int *n, int *errcode)
void ieee_double_to_local(const double *val, const int *n, int *errcode)
#define IEEE_SNG_BIAS
unsigned local_to_vax_int(const fort_int *i)
#define mmax
static const struct sgl_limits_struct sgl_limits[2]
void local_to_ieee_double(const double *val, const int *n, int *errcode)
#define swap_short(a)
#define mmin
static int vax_to_ieee_float(float *fp)
#define swap_int(a)
void local_to_vax_shorts(const unsigned short *sa, const int *n)
unsigned short vax_to_local_short(const unsigned short *s)
void vax_to_local_shorts(const unsigned short *sa, const int *n)
#define maybe_flip_bytes(__p, __n)
unsigned vax_to_local_int(const fort_int *i)
unsigned short local_to_vax_short(const unsigned short *s)
void local_to_ieee_float(const float *val, const int *n, int *errcode)
int fort_int
Definition vms_convert.h:17