2 Copyright (C) 2001-2009, Parrot Foundation.
7 src/packfile/pf_items.c - Fetch/store packfile data
11 Low level packfile functions to fetch and store Parrot data, i.e.
12 C<INTVAL>, C<FLOATVAL>, C<STRING> ...
14 C<< PF_fetch_<item>() >> functions retrieve the datatype item from the
15 opcode stream and convert byteordering or binary format on the fly,
16 depending on the packfile header.
18 C<< PF_store_<item>() >> functions write the datatype item to the stream
19 as is. These functions don't check the available size.
21 C<< PF_size_<item>() >> functions return the store size of item in
24 C<BE> and C<be> are short for "Big-endian", while C<LE> and C<le> are short
35 #include "parrot/parrot.h"
37 /* HEADERIZER HFILE: include/parrot/packfile.h */
39 /* HEADERIZER BEGIN: static */
40 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
42 static void cvt_num12_num16(
43 ARGOUT(unsigned char *dest
),
44 ARGIN(const unsigned char *src
))
45 __attribute__nonnull__(1)
46 __attribute__nonnull__(2)
49 static void cvt_num12_num16_le(
50 ARGOUT(unsigned char *dest
),
51 ARGIN(const unsigned char *src
))
52 __attribute__nonnull__(1)
53 __attribute__nonnull__(2)
56 static void cvt_num12_num8(
57 ARGOUT(unsigned char *dest
),
58 ARGIN(const unsigned char *src
))
59 __attribute__nonnull__(1)
60 __attribute__nonnull__(2)
63 static void cvt_num12_num8_le(
64 ARGOUT(unsigned char *dest
),
65 ARGIN(const unsigned char *src
))
66 __attribute__nonnull__(1)
67 __attribute__nonnull__(2)
70 static void cvt_num16_num12(
71 ARGOUT(unsigned char *dest
),
72 ARGIN(const unsigned char *src
))
73 __attribute__nonnull__(1)
74 __attribute__nonnull__(2)
77 static void cvt_num16_num12_be(
78 ARGOUT(unsigned char *dest
),
79 ARGIN(const unsigned char *src
))
80 __attribute__nonnull__(1)
81 __attribute__nonnull__(2)
84 static void cvt_num16_num8(
85 ARGOUT(unsigned char *dest
),
86 ARGIN(const unsigned char *src
))
87 __attribute__nonnull__(1)
88 __attribute__nonnull__(2)
91 static void cvt_num16_num8_be(
92 ARGOUT(unsigned char *dest
),
93 ARGIN(const unsigned char *src
))
94 __attribute__nonnull__(1)
95 __attribute__nonnull__(2)
98 static void cvt_num16_num8_le(
99 ARGOUT(unsigned char *dest
),
100 ARGIN(const unsigned char *src
))
101 __attribute__nonnull__(1)
102 __attribute__nonnull__(2)
103 FUNC_MODIFIES(*dest
);
105 static void cvt_num8_num12(
106 ARGOUT(unsigned char *dest
),
107 ARGIN(const unsigned char *src
))
108 __attribute__nonnull__(1)
109 __attribute__nonnull__(2)
110 FUNC_MODIFIES(*dest
);
112 static void cvt_num8_num12_be(
113 ARGOUT(unsigned char *dest
),
114 ARGIN(const unsigned char *src
))
115 __attribute__nonnull__(1)
116 __attribute__nonnull__(2)
117 FUNC_MODIFIES(*dest
);
119 static void cvt_num8_num16(
120 ARGOUT(unsigned char *dest
),
121 ARGIN(const unsigned char *src
))
122 __attribute__nonnull__(1)
123 __attribute__nonnull__(2)
124 FUNC_MODIFIES(*dest
);
126 static void cvt_num8_num16_be(
127 ARGOUT(unsigned char *dest
),
128 ARGIN(const unsigned char *src
))
129 __attribute__nonnull__(1)
130 __attribute__nonnull__(2)
131 FUNC_MODIFIES(*dest
);
133 static void cvt_num8_num16_le(
134 ARGOUT(unsigned char *dest
),
135 ARGIN(const unsigned char *src
))
136 __attribute__nonnull__(1)
137 __attribute__nonnull__(2)
138 FUNC_MODIFIES(*dest
);
140 PARROT_WARN_UNUSED_RESULT
141 static opcode_t
fetch_op_be_4(ARGIN(const unsigned char *b
))
142 __attribute__nonnull__(1);
144 PARROT_WARN_UNUSED_RESULT
145 static opcode_t
fetch_op_be_8(ARGIN(const unsigned char *b
))
146 __attribute__nonnull__(1);
148 PARROT_WARN_UNUSED_RESULT
149 static opcode_t
fetch_op_le_4(ARGIN(const unsigned char *b
))
150 __attribute__nonnull__(1);
152 PARROT_WARN_UNUSED_RESULT
153 static opcode_t
fetch_op_le_8(ARGIN(const unsigned char *b
))
154 __attribute__nonnull__(1);
156 PARROT_WARN_UNUSED_RESULT
157 static opcode_t
fetch_op_mixed_be(ARGIN(const unsigned char *b
))
158 __attribute__nonnull__(1);
160 PARROT_WARN_UNUSED_RESULT
161 static opcode_t
fetch_op_mixed_le(ARGIN(const unsigned char *b
))
162 __attribute__nonnull__(1);
164 #define ASSERT_ARGS_cvt_num12_num16 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
165 PARROT_ASSERT_ARG(dest) \
166 , PARROT_ASSERT_ARG(src))
167 #define ASSERT_ARGS_cvt_num12_num16_le __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
168 PARROT_ASSERT_ARG(dest) \
169 , PARROT_ASSERT_ARG(src))
170 #define ASSERT_ARGS_cvt_num12_num8 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
171 PARROT_ASSERT_ARG(dest) \
172 , PARROT_ASSERT_ARG(src))
173 #define ASSERT_ARGS_cvt_num12_num8_le __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
174 PARROT_ASSERT_ARG(dest) \
175 , PARROT_ASSERT_ARG(src))
176 #define ASSERT_ARGS_cvt_num16_num12 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
177 PARROT_ASSERT_ARG(dest) \
178 , PARROT_ASSERT_ARG(src))
179 #define ASSERT_ARGS_cvt_num16_num12_be __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
180 PARROT_ASSERT_ARG(dest) \
181 , PARROT_ASSERT_ARG(src))
182 #define ASSERT_ARGS_cvt_num16_num8 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
183 PARROT_ASSERT_ARG(dest) \
184 , PARROT_ASSERT_ARG(src))
185 #define ASSERT_ARGS_cvt_num16_num8_be __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
186 PARROT_ASSERT_ARG(dest) \
187 , PARROT_ASSERT_ARG(src))
188 #define ASSERT_ARGS_cvt_num16_num8_le __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
189 PARROT_ASSERT_ARG(dest) \
190 , PARROT_ASSERT_ARG(src))
191 #define ASSERT_ARGS_cvt_num8_num12 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
192 PARROT_ASSERT_ARG(dest) \
193 , PARROT_ASSERT_ARG(src))
194 #define ASSERT_ARGS_cvt_num8_num12_be __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
195 PARROT_ASSERT_ARG(dest) \
196 , PARROT_ASSERT_ARG(src))
197 #define ASSERT_ARGS_cvt_num8_num16 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
198 PARROT_ASSERT_ARG(dest) \
199 , PARROT_ASSERT_ARG(src))
200 #define ASSERT_ARGS_cvt_num8_num16_be __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
201 PARROT_ASSERT_ARG(dest) \
202 , PARROT_ASSERT_ARG(src))
203 #define ASSERT_ARGS_cvt_num8_num16_le __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
204 PARROT_ASSERT_ARG(dest) \
205 , PARROT_ASSERT_ARG(src))
206 #define ASSERT_ARGS_fetch_op_be_4 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
207 PARROT_ASSERT_ARG(b))
208 #define ASSERT_ARGS_fetch_op_be_8 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
209 PARROT_ASSERT_ARG(b))
210 #define ASSERT_ARGS_fetch_op_le_4 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
211 PARROT_ASSERT_ARG(b))
212 #define ASSERT_ARGS_fetch_op_le_8 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
213 PARROT_ASSERT_ARG(b))
214 #define ASSERT_ARGS_fetch_op_mixed_be __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
215 PARROT_ASSERT_ARG(b))
216 #define ASSERT_ARGS_fetch_op_mixed_le __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
217 PARROT_ASSERT_ARG(b))
218 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
219 /* HEADERIZER END: static */
222 * round val up to whole size, return result in bytes
224 #define ROUND_UP_B(val, size) ((((val) + ((size) - 1))/(size)) * (size))
227 * round val up to whole opcode_t, return result in opcodes
229 #define ROUND_UP(val, size) (((val) + ((size) - 1))/(size))
232 * offset not in ptr diff, but in byte
234 #define OFFS(pf, cursor) ((pf) ? ((const char *)(cursor) - (const char *)((pf)->src)) : 0)
237 * low level FLOATVAL fetch and convert functions
239 * Floattype 0 = IEEE-754 8 byte double
240 * Floattype 1 = x86 little endian 12 byte long double
241 * Floattype 2 = IEEE-754 16 byte long double
247 =item C<static void cvt_num12_num8(unsigned char *dest, const unsigned char
250 Converts i386 LE 12-byte long double to IEEE 754 8-byte double.
259 cvt_num12_num8(ARGOUT(unsigned char *dest
), ARGIN(const unsigned char *src
))
261 ASSERT_ARGS(cvt_num12_num8
)
268 12-byte double (96 bits):
272 to 8-byte double (64 bits):
277 +-------+-------+-------+-------+-------+-------+--...--+-------+
278 |src[11]|src[10]|src[9] |src[8] |src[7] |src[6] | ... |src[0] |
280 +-------+-------+-------+-------+-------+-------+--...--+-------+
281 1|<-----15----->|<----------------80 bits---------------------->|
282 <----------------------------96 bits---------------------------->
284 +-------+-------+-------+-------+-------+-------+-------+-------+
285 |dest[7]|dest[6]|dest[5]|dest[4]|dest[3]|dest[2]|dest[1]|dest[0]|
287 +-------+-------+-------+-------+-------+-------+-------+-------+
288 1|<---11-->|<---------------------52 bits---------------------->|
289 <----------------------------64 bits---------------------------->
290 8-byte DOUBLE FLOATING-POINT
294 /* exponents 15 -> 11 bits */
295 s
= src
[9] & 0x80; /* sign */
296 expo
= ((src
[9] & 0x7f)<< 8 | src
[8]);
304 /* Yet again, LCC blows up mysteriously until a temporary variable is
306 expo2
= expo
- 16383;
309 expo
-= 16383; /* - bias */
311 expo
+= 1023; /* + bias 8byte */
312 if (expo
<= 0) /* underflow */
314 if (expo
> 0x7ff) { /* inf/nan */
316 dest
[6] = src
[7] == 0xc0 ? 0xf8 : 0xf0 ;
320 dest
[6] = (expo
& 0xff);
321 dest
[7] = (expo
& 0x7f00) >> 8;
324 /* long double frac 63 bits => 52 bits
325 src[7] &= 0x7f; reset integer bit */
326 for (i
= 0; i
< 6; i
++) {
327 dest
[i
+1] |= (i
==5 ? src
[7]&0x7f : src
[i
+2]) >> 3;
328 dest
[i
] |= (src
[i
+2] & 0x1f) << 5;
330 dest
[0] |= src
[1] >> 3;
335 =item C<static void cvt_num16_num12(unsigned char *dest, const unsigned char
338 Converts IEEE 754 LE 16-byte long double to i386 LE 12-byte long double .
339 See http://babbage.cs.qc.cuny.edu/IEEE-754/References.xhtml
347 #if (NUMVAL_SIZE == 12) && !PARROT_BIGENDIAN
349 cvt_num16_num12(ARGOUT(unsigned char *dest
), ARGIN(const unsigned char *src
))
351 ASSERT_ARGS(cvt_num16_num12
)
354 16-byte double (128 bits):
358 to 12-byte double (96 bits):
363 +-------+-------+-------+-------+-------+-------+--...--+-------+
364 |src[15]|src[14]|src[13]|src[12]|src[11]|src[10]| ... |src[0] |
366 +-------+-------+-------+-------+-------+-------+--...--+-------+
367 1|<-----15----->|<----------------112 bits--------------------->|
368 <---------------------------128 bits---------------------------->
369 16-byte LONG DOUBLE FLOATING-POINT (IA64 or BE 64-bit)
371 +-------+-------+-------+-------+-------+-------+--...--+-------+
372 |dest[11]dest[10]dest[9]|dest[8]|dest[7]|dest[6]| ... |dest[0]|
374 +-------+-------+-------+-------+-------+-------+--...--+-------+
375 1|<-----15----->|<----------------80 bits---------------------->|
376 <----------------------------96 bits---------------------------->
377 12-byte LONG DOUBLE FLOATING-POINT (i386 special)
382 /* simply copy over sign + exp */
383 TRACE_PRINTF_2((" cvt_num16_num12: sign+exp=0x%2x\n", src
[15]));
386 /* and trunc the rest */
387 memcpy(&dest
[10], &src
[13], 10);
388 TRACE_PRINTF_2((" cvt_num16_num12: mantissa=0x%10x, double=%lf\n",
389 src
[13], (long double)*dest
));
395 =item C<static void cvt_num12_num16(unsigned char *dest, const unsigned char
398 Converts i386 LE 12-byte long double to IEEE 754 LE 16-byte long double.
401 Fallback 12->8->16 disabled.
407 #if (NUMVAL_SIZE == 16)
409 cvt_num12_num16(ARGOUT(unsigned char *dest
), ARGIN(const unsigned char *src
))
411 ASSERT_ARGS(cvt_num12_num16
)
414 cvt_num12_num8(b
, src
);
415 cvt_num8_num16(dest
, b
);
418 12-byte double (96 bits):
422 to 16-byte double (128 bits):
427 +-------+-------+-------+-------+-------+-------+--...--+-------+
428 |src[11]|src[10]| src[9]| src[8]| src[7]| src[6]| ... | src[0]|
430 +-------+-------+-------+-------+-------+-------+--...--+-------+
431 1|<-----15----->|<----------------80 bits---------------------->|
432 <----------------------------96 bits---------------------------->
433 12-byte LONG DOUBLE FLOATING-POINT (i386 special)
435 +-------+-------+-------+-------+-------+-------+--...--+-------+
436 |dest[15]dest[14]dest[13]dest[12]dest[11]dest[10] ... |dest[0]|
438 +-------+-------+-------+-------+-------+-------+--...--+-------+
439 1|<-----15----->|<----------------112 bits--------------------->|
440 <---------------------------128 bits---------------------------->
441 16-byte LONG DOUBLE FLOATING-POINT (IA64 or BE 64-bit)
446 /* simply copy over sign + exp */
447 TRACE_PRINTF_2((" cvt_num12_num16: sign+exp=0x%2x\n", src
[11]));
450 /* and trunc the rest */
451 memcpy(&dest
[13], &src
[9], 10);
452 TRACE_PRINTF_2((" cvt_num12_num15: mantissa=0x%10x, double=%lf\n",
453 src
[19], (long double)*dest
));
458 =item C<static void cvt_num16_num8(unsigned char *dest, const unsigned char
461 Converts IEEE 754 16-byte long double to IEEE 754 8 byte double.
463 First variant ok, 2nd not ok.
470 cvt_num16_num8(ARGOUT(unsigned char *dest
), ARGIN(const unsigned char *src
))
472 ASSERT_ARGS(cvt_num16_num8
)
474 if ((sizeof (long double) == 16) && (sizeof (double) == 8)) {
479 memcpy(&ld
, src
, 16);
480 d
= (double)ld
; /* compiler cast */
485 /* FIXME: This codepath fails */
490 exit_fatal(1, "cvt_num16_num8: long double conversion unsupported");
492 /* Have only 12-byte long double, or no long double at all. Need to disect it */
495 16-byte double (128 bits):
499 to 8-byte double (64 bits):
504 +-------+-------+-------+-------+-------+-------+--...--+-------+
505 |src[15]|src[14]|src[13]|src[12]|src[11]|src[10]| ... |src[0] |
507 +-------+-------+-------+-------+-------+-------+--...--+-------+
508 1|<-----15----->|<----------------112 bits--------------------->|
509 <---------------------------128 bits---------------------------->
510 16-byte LONG DOUBLE FLOATING-POINT (IA64 or BE 64-bit)
512 +-------+-------+-------+-------+-------+-------+-------+-------+
513 |dest[7]|dest[6]|dest[5]|dest[4]|dest[3]|dest[2]|dest[1]|dest[0]|
515 +-------+-------+-------+-------+-------+-------+-------+-------+
516 1|<---11-->|<---------------------52 bits---------------------->|
517 <----------------------------64 bits---------------------------->
518 8-byte DOUBLE FLOATING-POINT
523 s
= src
[15] & 0x80; /* 10000000 */
524 /* 15->11 exponents bits */
525 expo
= ((src
[15] & 0x7f)<< 8 | src
[14]);
533 /* LCC blows up mysteriously until a temporary variable is
535 expo2
= expo
- 16383;
538 expo
-= 16383; /* - same bias as with 12-byte */
540 expo
+= 1023; /* + bias 8byte */
541 if (expo
<= 0) /* underflow */
543 if (expo
> 0x7ff) { /* inf/nan */
545 dest
[6] = src
[7] == 0xc0 ? 0xf8 : 0xf0 ;
549 dest
[6] = (expo
& 0xff);
550 dest
[7] = (expo
& 0x7f00) >> 8;
553 /* long double frac 112 bits => 52 bits
554 src[13] &= 0x7f; reset integer bit */
555 for (i
= 0; i
< 6; i
++) {
556 dest
[i
+1] |= (i
==5 ? src
[13]&0x7f : src
[i
+7]) >> 3;
557 dest
[i
] |= (src
[i
+7] & 0x1f) << 5;
559 dest
[0] |= src
[1] >> 3;
565 =item C<static void cvt_num8_num16(unsigned char *dest, const unsigned char
568 Converts IEEE 754 8-byte double to IEEE 754 16 byte long double.
576 #if (NUMVAL_SIZE == 16)
578 cvt_num8_num16(ARGOUT(unsigned char *dest
), ARGIN(const unsigned char *src
))
580 ASSERT_ARGS(cvt_num8_num16
)
581 /* The compiler can do this for us */
585 ld
= (long double)d
; /* TODO: test compiler cast */
586 /*TRACE_PRINTF_2((" cvt_num8_num16: d=%f, ld=%lf\n", d, ld));*/
587 memcpy(dest
, &ld
, 16);
593 =item C<static void cvt_num8_num12(unsigned char *dest, const unsigned char
596 Converts i386 8-byte double to i386 12 byte long double.
604 #if (NUMVAL_SIZE == 12) && !PARROT_BIGENDIAN
606 cvt_num8_num12(ARGOUT(unsigned char *dest
), ARGIN(const unsigned char *src
))
608 ASSERT_ARGS(cvt_num8_num12
)
612 ld
= (long double)d
; /* compiler cast */
613 /*TRACE_PRINTF_2((" cvt_num8_num12: ld=%lf, d=%f\n", ld, d));*/
614 memcpy(dest
, &ld
, 12);
621 =item C<static void cvt_num8_num12_be(unsigned char *dest, const unsigned char
624 Converts a big-endian IEEE 754 8-byte double to i386 LE 12-byte long double.
632 #if (NUMVAL_SIZE == 12) && !PARROT_BIGENDIAN
634 cvt_num8_num12_be(ARGOUT(unsigned char *dest
), ARGIN(const unsigned char *src
))
636 ASSERT_ARGS(cvt_num8_num12_be
)
638 fetch_buf_be_8(b
, src
);
639 /*TRACE_PRINTF_2((" cvt_num8_num12_be: 0x%8x\n", b));*/
640 cvt_num8_num12(dest
, b
);
646 =item C<static void cvt_num8_num16_le(unsigned char *dest, const unsigned char
649 Converts a little-endian IEEE 754 8-byte double to big-endian 16-byte long double.
657 #if (NUMVAL_SIZE == 16) && PARROT_BIGENDIAN
659 cvt_num8_num16_le(ARGOUT(unsigned char *dest
), ARGIN(const unsigned char *src
))
661 ASSERT_ARGS(cvt_num8_num16_le
)
663 fetch_buf_be_8(b
, src
); /* TODO test endianize */
664 TRACE_PRINTF_2((" cvt_num8_num16_le: 0x%8x\n", b
));
665 cvt_num8_num16(dest
, b
);
671 =item C<static void cvt_num12_num16_le(unsigned char *dest, const unsigned char
674 Converts a little-endian 12-byte double to big-endian 16-byte long double.
682 #if (NUMVAL_SIZE == 16) && PARROT_BIGENDIAN
684 cvt_num12_num16_le(ARGOUT(unsigned char *dest
), ARGIN(const unsigned char *src
))
686 ASSERT_ARGS(cvt_num12_num16_le
)
688 fetch_buf_be_12(b
, src
); /* TODO test endianize */
689 TRACE_PRINTF_2((" cvt_num12_num16_le: 0x%8x\n", b
));
690 cvt_num12_num16(dest
, b
);
696 =item C<static void cvt_num12_num8_le(unsigned char *dest, const unsigned char
699 Converts a little-endian 12-byte i386 long double into a big-endian IEEE 754 8-byte double.
709 cvt_num12_num8_le(ARGOUT(unsigned char *dest
), ARGIN(const unsigned char *src
))
711 ASSERT_ARGS(cvt_num12_num8_le
)
713 fetch_buf_le_12(b
, src
); /* TODO test endianize */
714 TRACE_PRINTF_2((" cvt_num12_num8_le: 0x%12x\n", b
));
715 cvt_num12_num8(dest
, b
);
716 exit_fatal(1, "cvt_num12_num8_le: long double conversion unsupported");
722 =item C<static void cvt_num16_num8_le(unsigned char *dest, const unsigned char
725 Converts a little-endian IEEE 754 intel 16-byte long double into a
726 big-endian IEEE 754 8-byte double.
728 Tested nok. Produces all zeros.
736 cvt_num16_num8_le(ARGOUT(unsigned char *dest
), ARGIN(const unsigned char *src
))
738 ASSERT_ARGS(cvt_num16_num8_le
)
740 fetch_buf_le_16(b
, src
);
741 TRACE_PRINTF_2((" cvt_num16_num8_le: 0x%16x\n", b
));
742 cvt_num16_num8(dest
, b
);
743 exit_fatal(1, "cvt_num16_num8_le: long double conversion unsupported");
749 =item C<static void cvt_num16_num8_be(unsigned char *dest, const unsigned char
752 Converts a big-endian IEEE 754 16-byte long double into a IEEE 754 8-byte double.
760 #if !PARROT_BIGENDIAN
762 cvt_num16_num8_be(ARGOUT(unsigned char *dest
), ARGIN(const unsigned char *src
))
764 ASSERT_ARGS(cvt_num16_num8_be
)
766 fetch_buf_be_16(b
, src
);
767 TRACE_PRINTF_2((" cvt_num16_num8_be: 0x%16x\n", b
));
768 cvt_num16_num8(dest
, b
);
774 =item C<static void cvt_num16_num12_be(unsigned char *dest, const unsigned char
777 Converts a big-endian IEEE 754 16-byte long double into a 12-byte i386 long double.
785 #if (NUMVAL_SIZE == 12) && !PARROT_BIGENDIAN
787 cvt_num16_num12_be(ARGOUT(unsigned char *dest
), ARGIN(const unsigned char *src
))
789 ASSERT_ARGS(cvt_num16_num12_be
)
791 fetch_buf_be_16(b
, src
);
792 TRACE_PRINTF_2((" cvt_num16_num12_be: 0x%16x\n", b
));
793 cvt_num16_num12(dest
, b
);
799 =item C<static void cvt_num8_num16_be(unsigned char *dest, const unsigned char
802 Converts a big-endian IEEE 754 8-byte double to little-endian IEEE 754 16 byte
811 #if (NUMVAL_SIZE == 16) && !PARROT_BIGENDIAN
813 cvt_num8_num16_be(ARGOUT(unsigned char *dest
), ARGIN(const unsigned char *src
))
815 ASSERT_ARGS(cvt_num8_num16_be
)
817 fetch_buf_be_8(b
, src
);
818 cvt_num8_num16(dest
, b
);
826 =item C<static opcode_t fetch_op_mixed_le(const unsigned char *b)>
828 opcode fetch helper function
830 This is mostly wrong or at least untested
832 Fetch an opcode and convert to LE
838 PARROT_WARN_UNUSED_RESULT
840 fetch_op_mixed_le(ARGIN(const unsigned char *b
))
842 ASSERT_ARGS(fetch_op_mixed_le
)
843 # if OPCODE_T_SIZE == 4
845 unsigned char buf
[8];
848 /* wordsize = 8 then */
849 fetch_buf_le_8(u
.buf
, b
);
850 return u
.o
[0]; /* or u.o[1] */
853 unsigned char buf
[4];
859 fetch_buf_le_4(u
.buf
, b
);
866 =item C<static opcode_t fetch_op_mixed_be(const unsigned char *b)>
868 Fetch an opcode and convert to BE. Determines size of opcode from
869 C<OPCODE_T_SIZE> macro, and proceeds accordingly.
875 PARROT_WARN_UNUSED_RESULT
877 fetch_op_mixed_be(ARGIN(const unsigned char *b
))
879 ASSERT_ARGS(fetch_op_mixed_be
)
880 # if OPCODE_T_SIZE == 4
882 unsigned char buf
[8];
885 /* wordsize = 8 then */
886 fetch_buf_be_8(u
.buf
, b
);
887 return u
.o
[1]; /* or u.o[0] */
890 unsigned char buf
[4];
895 fetch_buf_be_4(u
.buf
, b
);
904 =item C<static opcode_t fetch_op_be_4(const unsigned char *b)>
906 Fetches a 4-byte big-endian opcode.
912 PARROT_WARN_UNUSED_RESULT
914 fetch_op_be_4(ARGIN(const unsigned char *b
))
916 ASSERT_ARGS(fetch_op_be_4
)
918 unsigned char buf
[4];
921 fetch_buf_be_4(u
.buf
, b
);
923 # if OPCODE_T_SIZE == 8
924 return (Parrot_Int4
)(u
.o
>> 32);
929 # if OPCODE_T_SIZE == 8
930 return (Parrot_Int4
)(fetch_iv_le((INTVAL
)u
.o
) & 0xffffffff);
932 return (opcode_t
) fetch_iv_le((INTVAL
)u
.o
);
939 =item C<static opcode_t fetch_op_be_8(const unsigned char *b)>
941 Fetches an 8-byte big-endian opcode.
947 PARROT_WARN_UNUSED_RESULT
949 fetch_op_be_8(ARGIN(const unsigned char *b
))
951 ASSERT_ARGS(fetch_op_be_8
)
953 unsigned char buf
[8];
956 fetch_buf_be_8(u
.buf
, b
);
958 # if OPCODE_T_SIZE == 8
964 return (opcode_t
) fetch_iv_le((INTVAL
)u
.o
[0]);
970 =item C<static opcode_t fetch_op_le_4(const unsigned char *b)>
972 Fetches a 4-byte little-endian opcode
978 PARROT_WARN_UNUSED_RESULT
980 fetch_op_le_4(ARGIN(const unsigned char *b
))
982 ASSERT_ARGS(fetch_op_le_4
)
984 unsigned char buf
[4];
987 fetch_buf_le_4(u
.buf
, b
);
989 # if OPCODE_T_SIZE == 8
990 return (Parrot_Int4
)(u
.o
>> 32);
992 return (opcode_t
) fetch_iv_be((INTVAL
)u
.o
);
995 # if OPCODE_T_SIZE == 8
996 /* without the cast we would not get a negative int, the vtable indices */
997 return (Parrot_Int4
)(u
.o
& 0xffffffff);
1006 =item C<static opcode_t fetch_op_le_8(const unsigned char *b)>
1008 Fetches an 8-byte little-endian opcode
1014 PARROT_WARN_UNUSED_RESULT
1016 fetch_op_le_8(ARGIN(const unsigned char *b
))
1018 ASSERT_ARGS(fetch_op_le_8
)
1020 unsigned char buf
[8];
1023 fetch_buf_le_8(u
.buf
, b
);
1024 #if PARROT_BIGENDIAN
1025 # if OPCODE_T_SIZE == 8
1028 return (opcode_t
) fetch_op_be((INTVAL
)u
.o
[1]);
1037 =item C<opcode_t PF_fetch_opcode(const PackFile *pf, const opcode_t **stream)>
1039 Fetches an C<opcode_t> from the stream, converting byteorder if needed.
1041 When used for freeze/thaw the C<pf> argument might be NULL.
1047 PARROT_WARN_UNUSED_RESULT
1048 PARROT_CANNOT_RETURN_NULL
1050 PF_fetch_opcode(ARGIN_NULLOK(const PackFile
*pf
), ARGMOD(const opcode_t
**stream
))
1052 ASSERT_ARGS(PF_fetch_opcode
)
1054 if (!pf
|| !pf
->fetch_op
)
1055 return *(*stream
)++;
1056 o
= (pf
->fetch_op
)(*((const unsigned char **)stream
));
1057 TRACE_PRINTF_VAL((" PF_fetch_opcode: 0x%lx (%ld), at 0x%x\n",
1058 o
, o
, OFFS(pf
, *stream
)));
1059 *((const unsigned char **) (stream
)) += pf
->header
->wordsize
;
1065 =item C<opcode_t* PF_store_opcode(opcode_t *cursor, opcode_t val)>
1067 Stores an C<opcode_t> to stream as-is.
1073 PARROT_WARN_UNUSED_RESULT
1074 PARROT_CANNOT_RETURN_NULL
1076 PF_store_opcode(ARGOUT(opcode_t
*cursor
), opcode_t val
)
1078 ASSERT_ARGS(PF_store_opcode
)
1085 =item C<size_t PF_size_opcode(void)>
1087 Returns the size of an item in C<opcode_t> units. The size of C<opcode_t>
1088 is 1 I<per definition>.
1094 PARROT_CONST_FUNCTION
1096 PF_size_opcode(void)
1098 ASSERT_ARGS(PF_size_opcode
)
1104 =item C<INTVAL PF_fetch_integer(PackFile *pf, const opcode_t **stream)>
1106 Fetches an C<INTVAL> from the stream, converting byteorder if needed.
1108 XXX assumes C<sizeof (INTVAL) == sizeof (opcode_t)> - we don't have
1109 C<INTVAL> size in the PackFile header.
1111 When used for freeze/thaw the C<pf> argument might be NULL.
1117 PARROT_WARN_UNUSED_RESULT
1119 PF_fetch_integer(ARGIN_NULLOK(PackFile
*pf
), ARGIN(const opcode_t
**stream
))
1121 ASSERT_ARGS(PF_fetch_integer
)
1124 if (!pf
|| pf
->fetch_iv
== NULL
)
1125 return *(*stream
)++;
1126 i
= (pf
->fetch_iv
)(*((const unsigned char **)stream
));
1127 TRACE_PRINTF_VAL((" PF_fetch_integer: 0x%x (%d) at 0x%x\n", i
, i
,
1128 OFFS(pf
, *stream
)));
1129 /* XXX assume sizeof (opcode_t) == sizeof (INTVAL) on the
1130 * machine producing this PBC.
1132 * TODO TT #364 on Sparc 64bit: On pbc wordsize=4 but native ptrsize=8 and
1133 * ptr_alignment=8 the advance by 4 will signal BUS (invalid address alignment)
1134 * in PF_fetch_integer and elsewhere.
1136 *((const unsigned char **) (stream
)) += pf
->header
->wordsize
;
1143 =item C<opcode_t* PF_store_integer(opcode_t *cursor, INTVAL val)>
1145 Stores an C<INTVAL> to stream as is.
1151 PARROT_WARN_UNUSED_RESULT
1152 PARROT_CANNOT_RETURN_NULL
1154 PF_store_integer(ARGOUT(opcode_t
*cursor
), INTVAL val
)
1156 ASSERT_ARGS(PF_store_integer
)
1157 *cursor
++ = (opcode_t
)val
; /* XXX */
1163 =item C<size_t PF_size_integer(void)>
1165 Returns stored size of C<INTVAL> in C<opcode_t> units.
1171 PARROT_CONST_FUNCTION
1173 PF_size_integer(void)
1175 ASSERT_ARGS(PF_size_integer
)
1176 return sizeof (INTVAL
) / sizeof (opcode_t
);
1181 =item C<FLOATVAL PF_fetch_number(PackFile *pf, const opcode_t **stream)>
1183 Fetches a C<FLOATVAL> from the stream, converting byteorder if needed.
1184 Then advances the stream pointer by the packfile float size.
1190 PARROT_WARN_UNUSED_RESULT
1192 PF_fetch_number(ARGIN_NULLOK(PackFile
*pf
), ARGIN(const opcode_t
**stream
))
1194 ASSERT_ARGS(PF_fetch_number
)
1195 /* When we have alignment all squared away we don't need
1196 * to use memcpy() for native byteorder. */
1199 if (!pf
|| !pf
->fetch_nv
) {
1200 TRACE_PRINTF(("PF_fetch_number: Native [%d bytes]\n",
1201 sizeof (FLOATVAL
)));
1202 memcpy(&f
, (const char *)*stream
, sizeof (FLOATVAL
));
1203 TRACE_PRINTF_VAL(("PF_fetch_number: %f at 0x%x\n", f
, OFFS(pf
, *stream
)));
1204 (*stream
) += (sizeof (FLOATVAL
) + sizeof (opcode_t
) - 1)/
1209 TRACE_PRINTF(("PF_fetch_number at 0x%x: Converting...\n", OFFS(pf
, *stream
)));
1210 /* 12->8 has a messy cast. */
1211 if (NUMVAL_SIZE
== 8 && pf
->header
->floattype
== FLOATTYPE_12
) {
1212 (pf
->fetch_nv
)((unsigned char *)&d
, (const unsigned char *) *stream
);
1214 TRACE_PRINTF_VAL(("PF_fetch_number: cast %f\n", f
));
1217 (pf
->fetch_nv
)((unsigned char *)&f
, (const unsigned char *) *stream
);
1218 TRACE_PRINTF_VAL(("PF_fetch_number: %f\n", f
));
1220 if (pf
->header
->floattype
== FLOATTYPE_8
) {
1221 *((const unsigned char **) (stream
)) += 8;
1223 else if (pf
->header
->floattype
== FLOATTYPE_12
) {
1224 *((const unsigned char **) (stream
)) += 12;
1226 else if (pf
->header
->floattype
== FLOATTYPE_16
) {
1227 *((const unsigned char **) (stream
)) += 16;
1229 else if (pf
->header
->floattype
== FLOATTYPE_16MIPS
) {
1230 *((const unsigned char **) (stream
)) += 16;
1232 else if (pf
->header
->floattype
== FLOATTYPE_16AIX
) {
1233 *((const unsigned char **) (stream
)) += 16;
1235 else if (pf
->header
->floattype
== FLOATTYPE_4
) {
1236 *((const unsigned char **) (stream
)) += 4;
1243 =item C<opcode_t* PF_store_number(opcode_t *cursor, const FLOATVAL *val)>
1245 Writes a C<FLOATVAL> to the opcode stream as-is.
1251 PARROT_WARN_UNUSED_RESULT
1252 PARROT_CANNOT_RETURN_NULL
1254 PF_store_number(ARGOUT(opcode_t
*cursor
), ARGIN(const FLOATVAL
*val
))
1256 ASSERT_ARGS(PF_store_number
)
1257 opcode_t padded_size
= (sizeof (FLOATVAL
) + sizeof (opcode_t
) - 1) /
1259 mem_sys_memcopy(cursor
, val
, sizeof (FLOATVAL
));
1260 cursor
+= padded_size
;
1266 =item C<size_t PF_size_number(void)>
1268 Returns stored size of FLOATVAL in C<opcode_t> units.
1274 PARROT_CONST_FUNCTION
1276 PF_size_number(void)
1278 ASSERT_ARGS(PF_size_number
)
1279 return ROUND_UP(sizeof (FLOATVAL
), sizeof (opcode_t
));
1284 =item C<STRING * PF_fetch_string(PARROT_INTERP, PackFile *pf, const opcode_t
1287 Fetches a C<STRING> from bytecode and return a new C<STRING>.
1297 When used for freeze/thaw the C<pf> argument might be NULL.
1303 PARROT_WARN_UNUSED_RESULT
1304 PARROT_CANNOT_RETURN_NULL
1306 PF_fetch_string(PARROT_INTERP
, ARGIN_NULLOK(PackFile
*pf
), ARGIN(const opcode_t
**cursor
))
1308 ASSERT_ARGS(PF_fetch_string
)
1310 UINTVAL flags
= PF_fetch_opcode(pf
, cursor
);
1311 const int wordsize
= pf
? pf
->header
->wordsize
: sizeof (opcode_t
);
1313 opcode_t charset_nr
;
1315 /* don't let PBC mess our internals - only constant or not */
1316 flags
&= (PObj_constant_FLAG
| PObj_private7_FLAG
);
1317 charset_nr
= PF_fetch_opcode(pf
, cursor
);
1319 /* These may need to be separate */
1320 size
= (size_t)PF_fetch_opcode(pf
, cursor
);
1322 TRACE_PRINTF(("PF_fetch_string(): flags=0x%04x, ", flags
));
1323 TRACE_PRINTF(("charset_nr=%ld, ", charset_nr
));
1324 TRACE_PRINTF(("size=%ld.\n", size
));
1326 s
= string_make_from_charset(interp
, (const char *)*cursor
,
1327 size
, charset_nr
, flags
);
1329 /* print only printable characters */
1330 TRACE_PRINTF_VAL(("PF_fetch_string(): string is '%s' at 0x%x\n",
1331 s
->strstart
, OFFS(pf
, *cursor
)));
1333 TRACE_PRINTF_ALIGN(("-s ROUND_UP_B: cursor=0x%x, size=%d, wordsize=%d\n",
1334 (const char *)*cursor
+ size
, size
, wordsize
));
1336 size
= ROUND_UP_B(size
, wordsize
);
1338 TRACE_PRINTF(("PF_fetch_string(): round size up to %ld.\n", size
));
1339 *((const unsigned char **) (cursor
)) += size
;
1341 TRACE_PRINTF_ALIGN(("+s ROUND_UP_B: cursor=0x%x, size=%d\n", *cursor
, size
));
1348 =item C<opcode_t* PF_store_string(opcode_t *cursor, const STRING *s)>
1350 Writes a C<STRING> to the opcode stream.
1356 PARROT_WARN_UNUSED_RESULT
1357 PARROT_CANNOT_RETURN_NULL
1359 PF_store_string(ARGOUT(opcode_t
*cursor
), ARGIN(const STRING
*s
))
1361 ASSERT_ARGS(PF_store_string
)
1362 opcode_t padded_size
= s
->bufused
;
1365 #if TRACE_PACKFILE == 3
1366 Parrot_io_eprintf(NULL
, "PF_store_string(): size is %ld...\n", s
->bufused
);
1369 if (padded_size
% sizeof (opcode_t
)) {
1370 padded_size
+= sizeof (opcode_t
) - (padded_size
% sizeof (opcode_t
));
1373 *cursor
++ = PObj_get_FLAGS(s
); /* only constant_FLAG and private7 */
1375 * TODO as soon as we have dynamically loadable charsets
1376 * we have to store the charset name, not the number
1380 * see also PF_fetch_string
1382 *cursor
++ = Parrot_charset_number_of_str(NULL
, s
);
1383 *cursor
++ = s
->bufused
;
1385 /* Switch to char * since rest of string is addressed by
1386 * characters to ensure padding. */
1387 charcursor
= (char *)cursor
;
1390 mem_sys_memcopy(charcursor
, s
->strstart
, s
->bufused
);
1391 charcursor
+= s
->bufused
;
1392 /* Pad up to sizeof (opcode_t) boundary. */
1393 while ((unsigned long) (charcursor
- (char *) cursor
) % sizeof (opcode_t
)) {
1397 PARROT_ASSERT(((unsigned long) (charcursor
- (char *) cursor
) % sizeof (opcode_t
)) == 0);
1398 cursor
+= (charcursor
- (char *) cursor
) / sizeof (opcode_t
);
1405 =item C<size_t PF_size_string(const STRING *s)>
1407 Reports stored size of C<STRING> in C<opcode_t> units.
1413 PARROT_PURE_FUNCTION
1415 PF_size_string(ARGIN(const STRING
*s
))
1417 ASSERT_ARGS(PF_size_string
)
1418 opcode_t padded_size
= s
->bufused
;
1420 if (padded_size
% sizeof (opcode_t
)) {
1421 padded_size
+= sizeof (opcode_t
) - (padded_size
% sizeof (opcode_t
));
1424 /* Include space for flags, representation, and size fields. */
1425 return 3 + (size_t)padded_size
/ sizeof (opcode_t
);
1430 =item C<char * PF_fetch_cstring(PackFile *pf, const opcode_t **cursor)>
1432 Fetches a cstring from bytecode and returns an allocated copy
1439 PARROT_CANNOT_RETURN_NULL
1441 PF_fetch_cstring(ARGIN(PackFile
*pf
), ARGIN(const opcode_t
**cursor
))
1443 ASSERT_ARGS(PF_fetch_cstring
)
1444 const size_t str_len
= strlen((const char *)(*cursor
)) + 1;
1445 char * const p
= (char *)mem_sys_allocate(str_len
);
1446 const int wordsize
= pf
->header
->wordsize
;
1448 TRACE_PRINTF(("PF_fetch_cstring(): size is %ld...\n", str_len
));
1449 strcpy(p
, (const char*) (*cursor
));
1450 TRACE_PRINTF_VAL(("PF_fetch_cstring(): string is '%s' at 0x%x\n",
1451 p
, OFFS(pf
, *cursor
)));
1452 TRACE_PRINTF_ALIGN(("-s ROUND_UP_B: cursor=0x%x, size=%d, wordsize=%d (cstring)\n",
1453 *cursor
, str_len
, wordsize
));
1454 *((const unsigned char **) (cursor
)) += ROUND_UP_B(str_len
, wordsize
);
1455 TRACE_PRINTF_ALIGN(("+s ROUND_UP_B: cursor=0x%x, offset=0x%x\n",
1456 *cursor
, OFFS(pf
, *cursor
)));
1463 =item C<opcode_t* PF_store_cstring(opcode_t *cursor, const char *s)>
1465 Writes a C<NULL>-terminated string to the stream.
1471 PARROT_WARN_UNUSED_RESULT
1472 PARROT_CANNOT_RETURN_NULL
1474 PF_store_cstring(ARGOUT(opcode_t
*cursor
), ARGIN(const char *s
))
1476 ASSERT_ARGS(PF_store_cstring
)
1478 * This is not very efficient for filling padding with zeros.
1479 * But it's more efficient than calculate strlen twice.
1481 size_t store_size
= PF_size_cstring(s
);
1482 memset((char *) cursor
, 0, store_size
* sizeof (opcode_t
));
1483 strcpy((char *) cursor
, s
);
1484 return cursor
+ store_size
;
1489 =item C<size_t PF_size_cstring(const char *s)>
1491 Returns store size of a C-string in C<opcode_t> units.
1497 PARROT_PURE_FUNCTION
1499 PF_size_cstring(ARGIN(const char *s
))
1501 ASSERT_ARGS(PF_size_cstring
)
1505 str_len
= strlen(s
);
1506 return ROUND_UP(str_len
+ 1, sizeof (opcode_t
));
1511 =item C<void PackFile_assign_transforms(PackFile *pf)>
1513 Assigns transform functions to the vtable.
1520 PackFile_assign_transforms(ARGMOD(PackFile
*pf
))
1522 ASSERT_ARGS(PackFile_assign_transforms
)
1523 const int need_endianize
= pf
->header
->byteorder
!= PARROT_BIGENDIAN
;
1524 const int need_wordsize
= pf
->header
->wordsize
!= sizeof (opcode_t
);
1526 pf
->need_endianize
= need_endianize
;
1527 pf
->need_wordsize
= need_wordsize
;
1529 #if PARROT_BIGENDIAN
1530 /* this Parrot is on a BIG ENDIAN machine */
1531 if (need_endianize
) {
1532 if (pf
->header
->wordsize
== 4)
1533 pf
->fetch_op
= fetch_op_le_4
;
1535 pf
->fetch_op
= fetch_op_le_8
;
1536 pf
->fetch_iv
= pf
->fetch_op
;
1538 switch (pf
->header
->floattype
) {
1539 # if NUMVAL_SIZE == 8
1541 pf
->fetch_nv
= fetch_buf_le_8
;
1544 pf
->fetch_nv
= cvt_num12_num8_le
;
1547 pf
->fetch_nv
= cvt_num16_num8_le
;
1550 # if NUMVAL_SIZE == 16
1552 pf
->fetch_nv
= cvt_num8_num16_le
;
1555 pf
->fetch_nv
= cvt_num12_num16_le
;
1558 pf
->fetch_nv
= fetch_buf_le_16
;
1563 "PackFile_unpack: unsupported float conversion %d to %d, "
1564 "PARROT_BIGENDIAN=%d\n",
1565 NUMVAL_SIZE
, pf
->header
->floattype
, PARROT_BIGENDIAN
);
1570 else { /* no need_endianize */
1571 if (pf
->header
->wordsize
== 4)
1572 pf
->fetch_op
= fetch_op_be_4
;
1574 pf
->fetch_op
= fetch_op_be_8
;
1575 pf
->fetch_iv
= pf
->fetch_op
;
1577 switch (pf
->header
->floattype
) {
1578 # if NUMVAL_SIZE == 8
1579 case FLOATTYPE_8
: /* native */
1582 pf
->fetch_nv
= cvt_num12_num8
;
1585 pf
->fetch_nv
= cvt_num16_num8
;
1588 # if NUMVAL_SIZE == 16
1590 pf
->fetch_nv
= cvt_num8_num16
;
1593 pf
->fetch_nv
= cvt_num12_num16
;
1595 case FLOATTYPE_16
: /* native */
1600 "PackFile_unpack: unsupported float conversion %d to %d, "
1601 "PARROT_BIGENDIAN=%d\n",
1602 NUMVAL_SIZE
, pf
->header
->floattype
, PARROT_BIGENDIAN
);
1610 /* this Parrot is on a LITTLE ENDIAN machine */
1611 if (need_endianize
) {
1612 if (pf
->header
->wordsize
== 4)
1613 pf
->fetch_op
= fetch_op_be_4
;
1615 pf
->fetch_op
= fetch_op_be_8
;
1616 pf
->fetch_iv
= pf
->fetch_op
;
1618 switch (pf
->header
->floattype
) {
1619 # if NUMVAL_SIZE == 8
1621 pf
->fetch_nv
= fetch_buf_be_8
;
1624 exit_fatal(1, "PackFile_unpack: invalid floattype 1 big-endian");
1627 pf
->fetch_nv
= cvt_num16_num8_be
;
1630 # if NUMVAL_SIZE == 12
1632 pf
->fetch_nv
= cvt_num8_num12_be
;
1635 exit_fatal(1, "PackFile_unpack: invalid floattype 1 big-endian");
1638 pf
->fetch_nv
= cvt_num16_num12_be
;
1641 # if NUMVAL_SIZE == 16
1643 pf
->fetch_nv
= cvt_num8_num16_be
;
1646 exit_fatal(1, "PackFile_unpack: invalid floattype 1 big-endian");
1649 pf
->fetch_nv
= fetch_buf_be_16
;
1654 "PackFile_unpack: unsupported float conversion %d to %d, "
1655 "PARROT_BIGENDIAN=%d\n",
1656 NUMVAL_SIZE
, pf
->header
->floattype
, PARROT_BIGENDIAN
);
1662 if (pf
->header
->wordsize
== 4)
1663 pf
->fetch_op
= fetch_op_le_4
;
1665 pf
->fetch_op
= fetch_op_le_8
;
1666 pf
->fetch_iv
= pf
->fetch_op
;
1668 switch (pf
->header
->floattype
) {
1669 # if NUMVAL_SIZE == 8
1670 case FLOATTYPE_8
: /* native */
1673 pf
->fetch_nv
= cvt_num12_num8
;
1676 pf
->fetch_nv
= cvt_num16_num8
;
1679 # if NUMVAL_SIZE == 12
1681 pf
->fetch_nv
= cvt_num8_num12
;
1683 case FLOATTYPE_12
: /* native */
1686 pf
->fetch_nv
= cvt_num16_num12
;
1689 # if NUMVAL_SIZE == 16
1691 pf
->fetch_nv
= cvt_num8_num16
;
1694 pf
->fetch_nv
= cvt_num12_num16
;
1696 case FLOATTYPE_16
: /* native */
1701 "PackFile_unpack: unsupported float conversion %d to %d, "
1702 "PARROT_BIGENDIAN=%d\n",
1703 NUMVAL_SIZE
, pf
->header
->floattype
, PARROT_BIGENDIAN
);
1717 Initial review by leo 2003.11.21
1719 Most routines moved from F<src/packfile.c>.
1721 Renamed PackFile_* to PF_*
1723 Added 16 byte types.
1727 C<<PF_store_<type>()>> - write an opcode_t stream to cursor in natural
1730 C<<PF_fetch_<type>()>> - read items and possibly convert the foreign
1733 C<<PF_size_<type>()>> - return the needed size in C<opcode_t> units.
1742 * c-file-style: "parrot"
1744 * vim: expandtab shiftwidth=4: