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