miriad 4.1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,59 @@
1
+ // Common setup for NArray typemaps
2
+ //
3
+ // Requires NArray Ruby extension
4
+ //
5
+ // http://narray.rubyforge.org/
6
+ //
7
+
8
+ #if defined SWIGRUBY
9
+
10
+ %{
11
+ #include "narray.h"
12
+ extern const char * na_typestring[];
13
+
14
+ // Raises TypeError is v is not an NArray
15
+ #define Check_NArray(v) \
16
+ if(!NA_IsNArray(v)) { \
17
+ rb_raise(rb_eTypeError,"requires NArray, got %s", \
18
+ rb_class2name(CLASS_OF(v))); \
19
+ }
20
+
21
+ #define Check_NArrayType(v,tc) \
22
+ Check_NArray(v) \
23
+ if(tc >= NA_NTYPES) { \
24
+ rb_raise(rb_eArgError,"invalid type code check requested (%d)", tc); \
25
+ } \
26
+ if(NA_TYPE(v) >= NA_NTYPES) { \
27
+ rb_raise(rb_eArgError,"invalid type code found in NArray object (%d)", NA_TYPE(v)); \
28
+ } \
29
+ if(NA_TYPE(v) != tc) { \
30
+ rb_raise(rb_eTypeError,"requires type code %s (not %s)", \
31
+ na_typestring[tc], \
32
+ na_typestring[NA_TYPE(v)]); \
33
+ }
34
+
35
+ #define Check_NArrayType2(v,tc1,tc2) \
36
+ Check_NArray(v) \
37
+ if(tc1 >= NA_NTYPES) { \
38
+ rb_raise(rb_eArgError,"invalid type code check requested (%d)", tc1); \
39
+ } \
40
+ if(tc2 >= NA_NTYPES) { \
41
+ rb_raise(rb_eArgError,"invalid type code check requested (%d)", tc2); \
42
+ } \
43
+ if(NA_TYPE(v) >= NA_NTYPES) { \
44
+ rb_raise(rb_eArgError,"invalid type code found in NArray object (%d)", NA_TYPE(v)); \
45
+ } \
46
+ if(NA_TYPE(v) != tc1 && NA_TYPE(v) != tc2) { \
47
+ rb_raise(rb_eTypeError,"requires type code %s or %s (not %s)", \
48
+ na_typestring[tc1], \
49
+ na_typestring[tc2], \
50
+ na_typestring[NA_TYPE(v)]); \
51
+ }
52
+ %}
53
+
54
+ %init %{
55
+ rb_require("narray");
56
+ %}
57
+
58
+ // vim: set ts=2 sw=2 et sta syntax=c cindent :
59
+ #endif // SWIGRUBY
data/ext/pack.c ADDED
@@ -0,0 +1,639 @@
1
+ /* pack */
2
+ /* & pjt */
3
+ /* : low-level-i/o */
4
+ /* + */
5
+ /* */
6
+ /* This converts data between disk and internal */
7
+ /* format. Disk format is IEEE reals and 16 or 32 */
8
+ /* bit integers (most significant byte first). */
9
+ /* */
10
+ /* This assumes that these are the local machine format */
11
+ /* (float == IEEE real, int == 32 bit integer, */
12
+ /* short int == 16 bit integer). */
13
+ /* */
14
+ /* packx_c, unpackx_c, pack32_c and unpack32_c are */
15
+ /* implemented as macros (calling bcopy) in the */
16
+ /* system dependent include file. */
17
+ /*-- */
18
+ /* */
19
+ /* History: */
20
+ /* rjs Dark-ages Original version. */
21
+ /* bs ?????89 Improved efficiency using "register" declarations. */
22
+ /* rjs 1nov89 Incoporated Brian's changes. */
23
+ /* mjs 28feb91 Merge Sun and Cray versions. */
24
+ /* mjs 18mar91 Added convex definition. */
25
+ /* mjs 19feb93 Added mips definition. */
26
+ /* pjt 25jan95 linux kludge to include packALPHA.c */
27
+ /* pjt 14jun01 packALPHA.c now included in this source code */
28
+ /* and using the standard WORDS_BIGENDIAN macro */
29
+ /* pjt 21jun02 MIR4 prototyping */
30
+ /************************************************************************/
31
+
32
+ #include "sysdep.h"
33
+ #include "miriad.h"
34
+
35
+ #if defined(WORDS_BIGENDIAN)
36
+
37
+ static int words_bigendian = 1; /* never used actually, but handy symbol to find via nm(1) */
38
+
39
+ void pack16_c(register int *from,char *to,int n)
40
+ {
41
+ register short int *tto;
42
+ register int i;
43
+
44
+ tto = (short int *)to;
45
+ for (i=0; i < n; i++) *tto++ = *from++;
46
+ }
47
+ void unpack16_c(char *from,register int *to,int n)
48
+ {
49
+ register short int *ffrom;
50
+ register int i;
51
+
52
+ ffrom = (short int *)from;
53
+ for (i=0; i < n; i++) *to++ = *ffrom++;
54
+ }
55
+
56
+ void pack64_c(register int *from,char *to,int n)
57
+ {
58
+ register short int *tto;
59
+ register int i;
60
+
61
+ tto = (short int *)to;
62
+ for (i=0; i < n; i++) *tto++ = *from++;
63
+ }
64
+ void unpack64_c(char *from,register int *to,int n)
65
+ {
66
+ register short int *ffrom;
67
+ register int i;
68
+
69
+ ffrom = (short int *)from;
70
+ for (i=0; i < n; i++) *to++ = *ffrom++;
71
+ }
72
+
73
+ #endif
74
+
75
+
76
+ #ifndef WORDS_BIGENDIAN
77
+ #ifndef unicos
78
+ static int words_littleendian = 1; /* never used actually, but handy symbol to find via nm(1) */
79
+ /************************************************************************/
80
+ /* */
81
+ /* The pack routines -- these convert between the host format and */
82
+ /* the disk format. Disk format is IEEE 32 and 64 bit reals, and 2's */
83
+ /* complement integers. Byte order is the FITS byte order (most */
84
+ /* significant bytes first). */
85
+ /* */
86
+ /* This version is for a machine which uses IEEE internally, but which */
87
+ /* uses least significant bytes first (little endian), e.g. PCs and */
88
+ /* Alphas. */
89
+ /* */
90
+ /* History: */
91
+ /* rjs 21nov94 Original version. */
92
+ /************************************************************************/
93
+ void pack16_c(int *in,char *out,int n)
94
+ /*
95
+ Pack an integer array into 16 bit integers.
96
+ ------------------------------------------------------------------------*/
97
+ {
98
+ int i;
99
+ char *s;
100
+
101
+ s = (char *)in;
102
+ for(i=0; i < n; i++){
103
+ *out++ = *(s+1);
104
+ *out++ = *s;
105
+ s += sizeof(int);
106
+ }
107
+ }
108
+ /************************************************************************/
109
+ void unpack16_c(char *in,int *out,int n)
110
+ /*
111
+ Unpack an array of 16 bit integers into integers.
112
+ ------------------------------------------------------------------------*/
113
+ {
114
+ int i;
115
+ char *s;
116
+
117
+ s = (char *)out;
118
+ for(i=0; i < n; i++){
119
+ *s++ = *(in+1);
120
+ *s++ = *in;
121
+ if(0x80 & *in){
122
+ *s++ = 0xFF;
123
+ *s++ = 0xFF;
124
+ } else {
125
+ *s++ = 0;
126
+ *s++ = 0;
127
+ }
128
+ in += 2;
129
+ }
130
+ }
131
+ /************************************************************************/
132
+ void pack32_c(int *in,char *out,int n)
133
+ /*
134
+ Pack an array of integers into 32 bit integers.
135
+ ------------------------------------------------------------------------*/
136
+ {
137
+ int i;
138
+ char *s;
139
+
140
+ s = (char *)in;
141
+ for(i = 0; i < n; i++){
142
+ *out++ = *(s+3);
143
+ *out++ = *(s+2);
144
+ *out++ = *(s+1);
145
+ *out++ = *s;
146
+ s += 4;
147
+ }
148
+ }
149
+ /************************************************************************/
150
+ void unpack32_c(char *in,int *out,int n)
151
+ /*
152
+ Unpack an array of 32 bit integers into integers.
153
+ ------------------------------------------------------------------------*/
154
+ {
155
+ int i;
156
+ char *s;
157
+
158
+ s = (char *)out;
159
+ for(i = 0; i < n; i++){
160
+ *s++ = *(in+3);
161
+ *s++ = *(in+2);
162
+ *s++ = *(in+1);
163
+ *s++ = *in;
164
+ in += 4;
165
+ }
166
+ }
167
+ /************************************************************************/
168
+ void pack64_c(int8 *in,char *out,int n)
169
+ /*
170
+ Pack an integer array into 64 bit integers.
171
+ ------------------------------------------------------------------------*/
172
+ {
173
+ int i;
174
+ char *s;
175
+
176
+ s = (char *)in;
177
+ for(i=0; i < n; i++){
178
+ *out++ = *(s+7);
179
+ *out++ = *(s+6);
180
+ *out++ = *(s+5);
181
+ *out++ = *(s+4);
182
+ *out++ = *(s+3);
183
+ *out++ = *(s+2);
184
+ *out++ = *(s+1);
185
+ *out++ = *s;
186
+ s += 8;
187
+ }
188
+ }
189
+ /************************************************************************/
190
+ void unpack64_c(char *in,int8 *out,int n)
191
+ /*
192
+ Unpack an array of 64 bit integers into integers.
193
+ ------------------------------------------------------------------------*/
194
+ {
195
+ int i;
196
+ char *s;
197
+
198
+ s = (char *)out;
199
+ for(i=0; i < n; i++){
200
+ *s++ = *(in+7);
201
+ *s++ = *(in+6);
202
+ *s++ = *(in+5);
203
+ *s++ = *(in+4);
204
+ *s++ = *(in+3);
205
+ *s++ = *(in+2);
206
+ *s++ = *(in+1);
207
+ *s++ = *in;
208
+ in += 8;
209
+ }
210
+ }
211
+ /************************************************************************/
212
+ void packr_c(float *in,char *out,int n)
213
+ /*
214
+ Pack an array of reals into IEEE reals -- just do byte reversal.
215
+ ------------------------------------------------------------------------*/
216
+ {
217
+ int i;
218
+ char *s;
219
+
220
+ s = (char *)in;
221
+ for(i = 0; i < n; i++){
222
+ *out++ = *(s+3);
223
+ *out++ = *(s+2);
224
+ *out++ = *(s+1);
225
+ *out++ = *s;
226
+ s += 4;
227
+ }
228
+ }
229
+ /************************************************************************/
230
+ void unpackr_c(char *in,float *out,int n)
231
+ /*
232
+ Unpack an array of IEEE reals into reals -- just do byte reversal.
233
+ ------------------------------------------------------------------------*/
234
+ {
235
+ int i;
236
+ char *s;
237
+
238
+ s = (char *)out;
239
+ for(i = 0; i < n; i++){
240
+ *s++ = *(in+3);
241
+ *s++ = *(in+2);
242
+ *s++ = *(in+1);
243
+ *s++ = *in;
244
+ in += 4;
245
+ }
246
+ }
247
+ /************************************************************************/
248
+ void packd_c(double *in,char *out,int n)
249
+ /*
250
+ Pack an array of doubles -- this involves simply performing byte
251
+ reversal.
252
+ ------------------------------------------------------------------------*/
253
+ {
254
+ int i;
255
+ char *s;
256
+
257
+ s = (char *)in;
258
+ for(i = 0; i < n; i++){
259
+ *out++ = *(s+7);
260
+ *out++ = *(s+6);
261
+ *out++ = *(s+5);
262
+ *out++ = *(s+4);
263
+ *out++ = *(s+3);
264
+ *out++ = *(s+2);
265
+ *out++ = *(s+1);
266
+ *out++ = *s;
267
+ s += 8;
268
+ }
269
+ }
270
+ /************************************************************************/
271
+ void unpackd_c(char *in,double *out,int n)
272
+ /*
273
+ Unpack an array of doubles -- this involves simply performing byte
274
+ reversal.
275
+ ------------------------------------------------------------------------*/
276
+ {
277
+ int i;
278
+ char *s;
279
+
280
+ s = (char *)out;
281
+ for(i = 0; i < n; i++){
282
+ *s++ = *(in+7);
283
+ *s++ = *(in+6);
284
+ *s++ = *(in+5);
285
+ *s++ = *(in+4);
286
+ *s++ = *(in+3);
287
+ *s++ = *(in+2);
288
+ *s++ = *(in+1);
289
+ *s++ = *in;
290
+ in += 8;
291
+ }
292
+ }
293
+ #endif
294
+ #endif
295
+
296
+
297
+ #if defined(unicos)
298
+ static int words_unicos = 1;
299
+ #define TWO15 0x8000
300
+ #define TWO16 0x10000
301
+ #define TWO31 0x80000000
302
+ #define TWO32 0x100000000
303
+ #define HILONG 0xFFFFFFFF00000000
304
+ #define LOLONG 0x00000000FFFFFFFF
305
+ #define WORD0 0x000000000000FFFF
306
+ #define WORD1 0x00000000FFFF0000
307
+ #define WORD2 0x0000FFFF00000000
308
+ #define WORD3 0xFFFF000000000000
309
+
310
+ /* Masks for IEEE floating format (both hi and lo types). */
311
+
312
+ #define IEEE_HISIGN 0x8000000000000000
313
+ #define IEEE_HIEXPO 0x7F80000000000000
314
+ #define IEEE_HIMANT 0x007FFFFF00000000
315
+ #define IEEE_LOSIGN 0x0000000080000000
316
+ #define IEEE_LOEXPO 0x000000007F800000
317
+ #define IEEE_LOMANT 0x00000000007FFFFF
318
+ #define IEEE_DMANT 0x000FFFFFFFFFFFF0
319
+ #define IEEE_DEXPO 0x7FF0000000000000
320
+
321
+ /* Masks for Cray floating format. */
322
+
323
+ #define CRAY_MANT 0x0000FFFFFF000000 /* Including unhidden bit. */
324
+ #define CRAY_MANT1 0x00007FFFFF000000 /* No unhidden bit. */
325
+ #define CRAY_DMANT 0x0000FFFFFFFFFFFF
326
+ #define CRAY_DMANT1 0x00007FFFFFFFFFFF
327
+ #define CRAY_EXPO 0x7FFF000000000000
328
+ #define SIGN 0x8000000000000000
329
+
330
+ /* Mask of a pointer to char giving the character offset in a Cray word. */
331
+
332
+ #define CHAR_OFFSET 0xE000000000000000
333
+
334
+ /************************************************************************/
335
+ void pack16_c(int *in,char *out,int n)
336
+ /*
337
+ Pack an integer array into 16 bit integers for unicos
338
+ ------------------------------------------------------------------------*/
339
+ {
340
+ int temp,offset,*outd,in1,in2,in3,in4,i;
341
+
342
+ if(n <= 0)return; /* Return if nothing to do. */
343
+ temp = (int)out;
344
+ offset = ( temp & CHAR_OFFSET ) >> 62; /* Get offset of first word. */
345
+ outd = (int *)(temp & ~CHAR_OFFSET); /* Get address of words. */
346
+
347
+ /* Handle the first few which are not aligned on a Cray word. */
348
+
349
+ switch(offset){
350
+ case 1: *outd = (*outd & ~WORD2) | ((*in++ << 32) & WORD2);
351
+ if(--n == 0)break;
352
+ case 2: *outd = (*outd & ~WORD1) | ((*in++ << 16) & WORD1);
353
+ if(--n == 0)break;
354
+ case 3: *outd = (*outd & ~WORD0) | ((*in++ ) & WORD0);
355
+ outd++;
356
+ }
357
+
358
+ /* Handle the ones which are aligned on a Cray word. */
359
+
360
+ for(i=0; i < n-3; i=i+4){
361
+ in1 = *in++ << 48;
362
+ in2 = *in++ << 32;
363
+ in3 = *in++ << 16;
364
+ in4 = *in++;
365
+ *outd++ = (in1 & WORD3) | (in2 & WORD2) | (in3 & WORD1) | (in4 & WORD0);
366
+ }
367
+ n -= i;
368
+
369
+ /* Handle the last ones which are not aligned on a Cray word. */
370
+
371
+ if(n-- > 0){
372
+ *outd = (*outd & ~WORD3) | ((*in++ << 48) & WORD3);
373
+ if(n-- > 0){
374
+ *outd = (*outd & ~WORD2) | ((*in++ << 32) & WORD2);
375
+ if(n-- > 0){
376
+ *outd = (*outd & ~WORD1) | ((*in++ << 16) & WORD1);
377
+ }
378
+ }
379
+ }
380
+ }
381
+ /************************************************************************/
382
+ void unpack16_c(char *in,int *out,int n)
383
+ /*
384
+ Unpack an array of 16 bit integers into integers for unicos
385
+ ------------------------------------------------------------------------*/
386
+ {
387
+ int temp,offset,*ind,i;
388
+
389
+ if(n <= 0)return; /* Return if nothing to do. */
390
+ temp = (int)in;
391
+ offset = ( temp & CHAR_OFFSET ) >> 62; /* Get offset of first word. */
392
+ ind = (int *)(temp & ~CHAR_OFFSET); /* Get address of words. */
393
+
394
+ /* Handle the first few which are not word aligned. */
395
+
396
+ switch(offset){
397
+ case 1: temp = (*ind >> 32) & WORD0;
398
+ *out++ = (temp < TWO15 ? temp : temp - TWO16);
399
+ if(--n == 0) break;
400
+ case 2: temp = (*ind >> 16) & WORD0;
401
+ *out++ = (temp < TWO15 ? temp : temp - TWO16);
402
+ if(--n == 0) break;
403
+ case 3: temp = (*ind++ ) & WORD0;
404
+ *out++ = (temp < TWO15 ? temp : temp - TWO16);
405
+ if(--n == 0) break;
406
+ }
407
+
408
+ /* Handle those that are Cray-word-aligned. */
409
+
410
+ for(i=0; i < n-3; i=i+4){
411
+ temp = (*ind >> 48) & WORD0;
412
+ *out++ = (temp < TWO15 ? temp : temp - TWO16);
413
+ temp = (*ind >> 32) & WORD0;
414
+ *out++ = (temp < TWO15 ? temp : temp - TWO16);
415
+ temp = (*ind >> 16) & WORD0;
416
+ *out++ = (temp < TWO15 ? temp : temp - TWO16);
417
+ temp = (*ind++ ) & WORD0;
418
+ *out++ = (temp < TWO15 ? temp : temp - TWO16);
419
+ }
420
+ n -= i;
421
+
422
+ /* Handle the last few which are not Cray-word-aligned. */
423
+
424
+ if(n-- > 0){
425
+ temp = (*ind >> 48) & WORD0;
426
+ *out++ = (temp < TWO15 ? temp : temp - TWO16);
427
+ if(n-- > 0){
428
+ temp = (*ind >> 32) & WORD0;
429
+ *out++ = (temp < TWO15 ? temp : temp - TWO16);
430
+ if(n-- > 0){
431
+ temp = (*ind >> 16) & WORD0;
432
+ *out++ = (temp < TWO15 ? temp : temp - TWO16);
433
+ }
434
+ }
435
+ }
436
+ }
437
+ /************************************************************************/
438
+ void pack32_c(int *in,char *out,int n)
439
+ /*
440
+ Pack an array of integers into 32 bit integers for unicos
441
+ ------------------------------------------------------------------------*/
442
+ {
443
+ int temp,offset,*outd,i,in1,in2;
444
+
445
+ if(n <= 0)return; /* Return if nothing to do. */
446
+ temp = (int)out;
447
+ offset = ( temp & CHAR_OFFSET ) >> 63; /* Get offset of first long. */
448
+ outd = (int *)(temp & ~CHAR_OFFSET); /* Get address of words. */
449
+
450
+ /* Do the first one, if it is not aligned on a Cray word. */
451
+
452
+ if(offset==1){
453
+ *outd = (*outd & ~LOLONG) | (*in++ & LOLONG);
454
+ outd++;
455
+ }
456
+ n -= offset;
457
+
458
+ /* Do those which are Cray word aligned. */
459
+
460
+ for(i=0; i < n-1; i=i+2){
461
+ in1 = *in++ << 32;
462
+ in2 = *in++;
463
+ *outd++ = (in1 & HILONG) | (in2 & LOLONG);
464
+ }
465
+ n -= i;
466
+
467
+ /* Handle the last one, if there is one. */
468
+
469
+ if(n==1)*outd = (*outd & ~HILONG) | ((*in++ << 32) & HILONG);
470
+ }
471
+ /************************************************************************/
472
+ void unpack32_c(char *in,int *out,int n)
473
+ /*
474
+ Unpack an array of 32 bit integers into integers for unicos
475
+ ------------------------------------------------------------------------*/
476
+ {
477
+ int temp,offset,*ind,i;
478
+
479
+ if(n <= 0)return; /* Return if nothing to do. */
480
+ temp = (int)in;
481
+ offset = ( temp & CHAR_OFFSET ) >> 63; /* Get offset of first word. */
482
+ ind = (int *)(temp & ~CHAR_OFFSET); /* Get address of words. */
483
+
484
+ /* Handle one which is not Cray word aligned. */
485
+
486
+ if(offset==1){
487
+ temp = (*ind++ & LOLONG);
488
+ *out++ = (temp < TWO31 ? temp : temp - TWO32);
489
+ }
490
+ n -= offset;
491
+
492
+ /* Handle those which are Cray word aligned. */
493
+
494
+ for(i=0; i < n-1; i=i+2){
495
+ temp = (*ind >> 32) & LOLONG;
496
+ *out++ = (temp < TWO31 ? temp : temp - TWO32);
497
+ temp = (*ind++ ) & LOLONG;
498
+ *out++ = (temp < TWO31 ? temp : temp - TWO32);
499
+ }
500
+ n -= i;
501
+
502
+ /* Possibly handle a last one which is not Cray word aligned. */
503
+
504
+ if(n==1){
505
+ temp = (*ind >> 32) & LOLONG;
506
+ *out++ = (temp < TWO31 ? temp : temp - TWO32);
507
+ }
508
+ }
509
+ /************************************************************************/
510
+ void packr_c(float *in,char *out,int n)
511
+ /*
512
+ Pack an array of Cray reals into IEEE reals.
513
+ ------------------------------------------------------------------------*/
514
+ {
515
+ int temp,offset,*outd,bias,*ind,tin,tout,i;
516
+
517
+ if(n <= 0)return; /* Return if nothing to do. */
518
+ temp = (int)out;
519
+ offset = ( temp & CHAR_OFFSET ) >> 63; /* Get offset of first long. */
520
+ outd = (int *)(temp & ~CHAR_OFFSET); /* Get address of words. */
521
+ bias = (16384 - 126) << 48;
522
+ ind = (int *)in;
523
+
524
+ /* Do the first one, if it is not aligned on a Cray word. */
525
+
526
+ if(offset==1){
527
+ tin = *ind++;
528
+ *outd = (*outd & ~LOLONG) |
529
+ (tin & CRAY_MANT ? (((tin & CRAY_EXPO)-bias) >> 25) |
530
+ ((tin & CRAY_MANT1) >> 24) | ((tin & SIGN) >> 32) : 0);
531
+ outd++;
532
+ }
533
+ n -= offset;
534
+
535
+ /* Do those which are Cray word aligned. */
536
+
537
+ for(i=0; i < n-1; i=i+2){
538
+ tin = *ind++;
539
+ tout = (tin & CRAY_MANT ? (((tin & CRAY_EXPO)-bias) << 7) |
540
+ ((tin & CRAY_MANT1) << 8) | (tin & SIGN) : 0);
541
+ tin = *ind++;
542
+ *outd++ = tout |
543
+ (tin & CRAY_MANT ? (((tin & CRAY_EXPO)-bias) >> 25) |
544
+ ((tin & CRAY_MANT1) >> 24) | ((tin & SIGN) >> 32) : 0);
545
+ }
546
+ n -= i;
547
+
548
+ /* Handle the last one, if there is one. */
549
+
550
+ if(n==1){
551
+ tin = *ind;
552
+ *outd = (*outd & ~HILONG) |
553
+ (tin & CRAY_MANT ? (((tin & CRAY_EXPO)-bias) << 7) |
554
+ ((tin & CRAY_MANT1) << 8) | (tin & SIGN) : 0);
555
+ }
556
+ }
557
+ /************************************************************************/
558
+ void unpackr_c(char *in,float *out,int n)
559
+ /*
560
+ Unpack an array of IEEE reals into Cray reals.
561
+ ------------------------------------------------------------------------*/
562
+ {
563
+ int temp,tin,*ind,*outd,offset,i,bias;
564
+
565
+ if(n <= 0)return; /* Return if nothing to do. */
566
+ temp = (int)in;
567
+ offset = ( temp & CHAR_OFFSET ) >> 63; /* Get offset of first word. */
568
+ ind = (int *)(temp & ~CHAR_OFFSET); /* Get address of words. */
569
+ outd = (int *)out;
570
+ bias = ((16384-126) <<48) + (1 << 47);
571
+
572
+ /* Handle the first one if it is not aligned on a Cray word. */
573
+
574
+ if(offset==1){
575
+ tin = *ind++;
576
+ *outd++ = (tin & IEEE_LOEXPO ? (((tin & IEEE_LOEXPO) << 25)+bias) |
577
+ ((tin & IEEE_LOMANT) << 24) | ((tin & IEEE_LOSIGN) << 32) : 0);
578
+ }
579
+ n -= offset;
580
+
581
+ /* Handle the bulk of them that are aligned on Cray words. */
582
+
583
+ for(i=0; i < n-1; i=i+2){
584
+ tin = *ind++;
585
+ *outd++ = (tin & IEEE_HIEXPO ? (((tin & IEEE_HIEXPO) >> 7)+bias) |
586
+ ((tin & IEEE_HIMANT) >> 8 ) | (tin & IEEE_HISIGN) : 0);
587
+ *outd++ = (tin & IEEE_LOEXPO ? (((tin & IEEE_LOEXPO) << 25)+bias) |
588
+ ((tin & IEEE_LOMANT) << 24) | ((tin & IEEE_LOSIGN) << 32) : 0);
589
+ }
590
+ n -= i;
591
+
592
+ /* Handle the last one, if needed, which is not aligned on a Cray word. */
593
+
594
+ if(n==1){
595
+ tin = *ind;
596
+ *outd++ = (tin & IEEE_HIEXPO ? (((tin & IEEE_HIEXPO) >> 7)+bias) |
597
+ ((tin & IEEE_HIMANT) >> 8 ) | (tin & IEEE_HISIGN) : 0);
598
+ }
599
+ }
600
+ /************************************************************************/
601
+ void packd_c(double *in,char *out,int n)
602
+ /*
603
+ Pack an array of Cray reals into IEEE double precision. This assumes
604
+ that a "double" and a "float" are identical.
605
+ ------------------------------------------------------------------------*/
606
+ {
607
+ int *ind,*outd,bias,i,tin;
608
+
609
+ ind = (int *)in;
610
+ outd = (int *)out;
611
+ bias = (16384 - 1022) << 48;
612
+
613
+ for(i=0; i < n; i++){
614
+ tin = *ind++;
615
+ *outd++ = (tin & CRAY_DMANT ? (tin & SIGN) |
616
+ (((tin & CRAY_EXPO)-bias) << 4) | ((tin & CRAY_DMANT1) << 5) : 0 );
617
+ }
618
+ }
619
+ /************************************************************************/
620
+ void unpackd_c(char *in,double *out,int n)
621
+ /*
622
+ Unpack an array of IEEE double precision numbers into Cray reals. This
623
+ assumes that a "double" and a "float" are identical.
624
+ ------------------------------------------------------------------------*/
625
+ {
626
+ int *ind,*outd,bias,i,tin;
627
+
628
+ ind = (int *)in;
629
+ outd = (int *)out;
630
+ bias = ((16384 - 1022) << 48) | (1 << 47);
631
+
632
+ for(i=0; i < n; i++){
633
+ tin = *ind++;
634
+ *outd++ = (tin & IEEE_DEXPO ? (tin & SIGN) |
635
+ (((tin & IEEE_DEXPO) >> 4) + bias) | ((tin & IEEE_DMANT) >> 5) : 0 );
636
+ }
637
+ }
638
+
639
+ #endif