[t][TT #1119] Convert t/op/bitwise.t to PIR
[parrot.git] / src / byteorder.c
blobb345a439686aae14dc672ecd9d1fa6d3021348ed
1 /*
2 Copyright (C) 2001-2009, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/byteorder.c - Byteordering functions
9 =head1 DESCRIPTION
11 These are assigned to a vtable when the PBC file is loaded.
13 If the vtable method for conversion from the native byteorder is called,
14 it is a I<no op> and will work, but the caller should know if the
15 byteorder in the PBC file is native and skip the conversion and just map
16 it in.
18 =head2 Byte order handlers
20 Configure will have checked for supported word sizes.
22 =over 4
24 =cut
28 #include "parrot/parrot.h"
29 #include "parrot/packfile.h"
31 /* HEADERIZER HFILE: include/parrot/packfile.h */
35 =item C<INTVAL fetch_iv_le(INTVAL w)>
37 This function converts a 4 or 8 byte C<INTVAL> into little endian
38 format. If the native format is already little endian, then no
39 conversion is done.
41 =cut
45 PARROT_WARN_UNUSED_RESULT
46 PARROT_CONST_FUNCTION
47 INTVAL
48 fetch_iv_le(INTVAL w)
50 ASSERT_ARGS(fetch_iv_le)
51 #if !PARROT_BIGENDIAN
52 return w;
53 #else
54 # if INTVAL_SIZE == 4
55 return (w << 24) | ((w & 0xff00) << 8) | ((w & 0xff0000) >> 8) | (w >> 24);
56 # else
57 # if INTVAL_SIZE == 8
58 INTVAL r;
60 r = w << 56;
61 r |= (w & 0xff00) << 40;
62 r |= (w & 0xff0000) << 24;
63 r |= (w & 0xff000000) << 8;
64 r |= (w & 0xff00000000) >> 8;
65 r |= (w & 0xff0000000000) >> 24;
66 r |= (w & 0xff000000000000) >> 40;
67 r |= (w & 0xff00000000000000) >> 56;
68 return r;
69 # else
70 exit_fatal(1, "Unsupported INTVAL_SIZE=%d\n",
71 INTVAL_SIZE);
72 # endif
73 # endif
74 #endif
79 =item C<INTVAL fetch_iv_be(INTVAL w)>
81 This function converts a 4 or 8 byte C<INTVAL> into big endian format.
82 If the native format is already big endian, then no conversion is done.
84 =cut
88 PARROT_WARN_UNUSED_RESULT
89 PARROT_CONST_FUNCTION
90 INTVAL
91 fetch_iv_be(INTVAL w)
93 ASSERT_ARGS(fetch_iv_be)
94 #if PARROT_BIGENDIAN
95 return w;
96 #else
97 # if INTVAL_SIZE == 4
98 return (w << 24) | ((w & 0xff00) << 8) | ((w & 0xff0000) >> 8) | (w >> 24);
99 # else
100 # if INTVAL_SIZE == 8
101 INTVAL r;
102 r = w << 56;
103 r |= (w & 0xff00) << 40;
104 r |= (w & 0xff0000) << 24;
105 r |= (w & 0xff000000) << 8;
106 r |= (w & 0xff00000000) >> 8;
107 r |= (w & 0xff0000000000) >> 24;
108 r |= (w & 0xff000000000000) >> 40;
109 r |= (w & 0xff00000000000000) >> 56;
110 return r;
111 # else
112 exit_fatal(1, "Unsupported INTVAL_SIZE=%d\n",
113 INTVAL_SIZE);
114 # endif
115 # endif
116 #endif
121 =item C<opcode_t fetch_op_be(opcode_t w)>
123 Same as C<fetch_iv_be> for opcode_t
125 =cut
129 PARROT_WARN_UNUSED_RESULT
130 PARROT_CONST_FUNCTION
131 opcode_t
132 fetch_op_be(opcode_t w)
134 ASSERT_ARGS(fetch_op_be)
135 #if PARROT_BIGENDIAN
136 return w;
137 #else
138 # if OPCODE_T_SIZE == 4
139 return (w << 24) | ((w & 0x0000ff00) << 8) | ((w & 0x00ff0000) >> 8) |
140 ((w & 0xff000000) >> 24);
141 # else
142 opcode_t r;
144 r = w << 56;
145 r |= (w & 0xff00) << 40;
146 r |= (w & 0xff0000) << 24;
147 r |= (w & 0xff000000) << 8;
148 r |= (w & 0xff00000000) >> 8;
149 r |= (w & 0xff0000000000) >> 24;
150 r |= (w & 0xff000000000000) >> 40;
151 r |= (w & 0xff00000000000000) >> 56;
152 return r;
153 # endif
154 #endif
159 =item C<opcode_t fetch_op_le(opcode_t w)>
161 Same as C<fetch_iv_le> for opcode_t
163 =cut
167 PARROT_WARN_UNUSED_RESULT
168 PARROT_CONST_FUNCTION
169 opcode_t
170 fetch_op_le(opcode_t w)
172 ASSERT_ARGS(fetch_op_le)
173 #if !PARROT_BIGENDIAN
174 return w;
175 #else
176 # if OPCODE_T_SIZE == 4
177 return (w << 24) | ((w & 0x0000ff00) << 8) | ((w & 0x00ff0000) >> 8) |
178 ((w & 0xff000000) >> 24);
179 # else
180 opcode_t r;
182 r = w << 56;
183 r |= (w & 0xff00) << 40;
184 r |= (w & 0xff0000) << 24;
185 r |= (w & 0xff000000) << 8;
186 r |= (w & 0xff00000000) >> 8;
187 r |= (w & 0xff0000000000) >> 24;
188 r |= (w & 0xff000000000000) >> 40;
189 r |= (w & 0xff00000000000000) >> 56;
190 return r;
191 # endif
192 #endif
197 =pod
199 Unrolled routines for swapping various sizes from 32-128 bits. These
200 should only be used if alignment is unknown or we are pulling something
201 out of a padded buffer.
203 =cut
209 =item C<void fetch_buf_be_4(unsigned char *rb, const unsigned char *b)>
211 Converts a 4-byte big-endian buffer C<b> into a little-endian C<rb>.
213 =cut
217 void
218 fetch_buf_be_4(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b))
220 ASSERT_ARGS(fetch_buf_be_4)
221 #if PARROT_BIGENDIAN
222 memcpy(rb, b, 4);
223 #else
224 rb[0] = b[3];
225 rb[1] = b[2];
226 rb[2] = b[1];
227 rb[3] = b[0];
228 #endif
233 =item C<void fetch_buf_le_4(unsigned char *rb, const unsigned char *b)>
235 Converts a 4-byte little-endian buffer C<b> into a big-endian buffer C<rb>.
237 =cut
241 void
242 fetch_buf_le_4(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b))
244 ASSERT_ARGS(fetch_buf_le_4)
245 #if !PARROT_BIGENDIAN
246 memcpy(rb, b, 4);
247 #else
248 rb[0] = b[3];
249 rb[1] = b[2];
250 rb[2] = b[1];
251 rb[3] = b[0];
252 #endif
257 =item C<void fetch_buf_be_8(unsigned char *rb, const unsigned char *b)>
259 Converts an 8-byte big-endian buffer C<b> into a little-endian buffer C<rb>
261 =cut
265 void
266 fetch_buf_be_8(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b))
268 ASSERT_ARGS(fetch_buf_be_8)
269 #if PARROT_BIGENDIAN
270 memcpy(rb, b, 8);
271 #else
272 rb[0] = b[7];
273 rb[1] = b[6];
274 rb[2] = b[5];
275 rb[3] = b[4];
276 rb[4] = b[3];
277 rb[5] = b[2];
278 rb[6] = b[1];
279 rb[7] = b[0];
280 #endif
285 =item C<void fetch_buf_le_8(unsigned char *rb, const unsigned char *b)>
287 Converts an 8-byte little-endian buffer C<b> into a big-endian buffer C<rb>.
289 =cut
293 void
294 fetch_buf_le_8(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b))
296 ASSERT_ARGS(fetch_buf_le_8)
297 #if !PARROT_BIGENDIAN
298 memcpy(rb, b, 8);
299 #else
300 rb[0] = b[7];
301 rb[1] = b[6];
302 rb[2] = b[5];
303 rb[3] = b[4];
304 rb[4] = b[3];
305 rb[5] = b[2];
306 rb[6] = b[1];
307 rb[7] = b[0];
308 #endif
313 =item C<void fetch_buf_le_12(unsigned char *rb, const unsigned char *b)>
315 Converts a 12-byte little-endian buffer C<b> into a big-endian buffer C<b>.
317 =cut
321 void
322 fetch_buf_le_12(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b))
324 ASSERT_ARGS(fetch_buf_le_12)
325 #if !PARROT_BIGENDIAN
326 memcpy(rb, b, 12);
327 #else
328 rb[0] = b[11];
329 rb[1] = b[10];
330 rb[2] = b[9];
331 rb[3] = b[8];
332 rb[4] = b[7];
333 rb[5] = b[6];
334 rb[6] = b[5];
335 rb[7] = b[4];
336 rb[8] = b[3];
337 rb[9] = b[2];
338 rb[10] = b[1];
339 rb[11] = b[0];
340 #endif
345 =item C<void fetch_buf_be_12(unsigned char *rb, const unsigned char *b)>
347 Converts a 12-byte big-endian buffer C<b> into a little-endian buffer C<b>.
349 =cut
353 void
354 fetch_buf_be_12(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b))
356 ASSERT_ARGS(fetch_buf_be_12)
357 #if PARROT_BIGENDIAN
358 memcpy(rb, b, 12);
359 #else
360 rb[0] = b[11];
361 rb[1] = b[10];
362 rb[2] = b[9];
363 rb[3] = b[8];
364 rb[4] = b[7];
365 rb[5] = b[6];
366 rb[6] = b[5];
367 rb[7] = b[4];
368 rb[8] = b[3];
369 rb[9] = b[2];
370 rb[10] = b[1];
371 rb[11] = b[0];
372 #endif
377 =item C<void fetch_buf_le_16(unsigned char *rb, const unsigned char *b)>
379 Converts a 16-byte little-endian buffer C<b> into a big-endian buffer C<b>.
381 =cut
385 void
386 fetch_buf_le_16(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b))
388 ASSERT_ARGS(fetch_buf_le_16)
389 #if !PARROT_BIGENDIAN
390 memcpy(rb, b, 16);
391 #else
392 rb[0] = b[15];
393 rb[1] = b[14];
394 rb[2] = b[13];
395 rb[3] = b[12];
396 rb[4] = b[11];
397 rb[5] = b[10];
398 rb[6] = b[9];
399 rb[7] = b[8];
400 rb[8] = b[7];
401 rb[9] = b[6];
402 rb[10] = b[5];
403 rb[11] = b[4];
404 rb[12] = b[3];
405 rb[13] = b[2];
406 rb[14] = b[1];
407 rb[15] = b[0];
408 #endif
413 =item C<void fetch_buf_be_16(unsigned char *rb, const unsigned char *b)>
415 Converts a 16-byte big-endian buffer C<b> into a little-endian buffer C<b>.
417 =cut
421 void
422 fetch_buf_be_16(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b))
424 ASSERT_ARGS(fetch_buf_be_16)
425 #if PARROT_BIGENDIAN
426 memcpy(rb, b, 16);
427 #else
428 rb[0] = b[15];
429 rb[1] = b[14];
430 rb[2] = b[13];
431 rb[3] = b[12];
432 rb[4] = b[11];
433 rb[5] = b[10];
434 rb[6] = b[9];
435 rb[7] = b[8];
436 rb[8] = b[7];
437 rb[9] = b[6];
438 rb[10] = b[5];
439 rb[11] = b[4];
440 rb[12] = b[3];
441 rb[13] = b[2];
442 rb[14] = b[1];
443 rb[15] = b[0];
444 #endif
449 =item C<void fetch_buf_le_32(unsigned char *rb, const unsigned char *b)>
451 Converts a 32-byte little-endian buffer C<b> into a big-endian buffer C<b>.
453 =cut
457 void
458 fetch_buf_le_32(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b))
460 ASSERT_ARGS(fetch_buf_le_32)
461 #if !PARROT_BIGENDIAN
462 memcpy(rb, b, 32);
463 #else
464 rb[0] = b[31];
465 rb[1] = b[30];
466 rb[2] = b[29];
467 rb[3] = b[28];
468 rb[4] = b[27];
469 rb[5] = b[26];
470 rb[6] = b[25];
471 rb[7] = b[24];
472 rb[8] = b[23];
473 rb[9] = b[22];
474 rb[10] = b[21];
475 rb[11] = b[20];
476 rb[12] = b[19];
477 rb[13] = b[18];
478 rb[14] = b[17];
479 rb[15] = b[16];
480 rb[16] = b[15];
481 rb[17] = b[14];
482 rb[18] = b[13];
483 rb[19] = b[12];
484 rb[20] = b[11];
485 rb[21] = b[10];
486 rb[22] = b[9];
487 rb[23] = b[8];
488 rb[24] = b[7];
489 rb[25] = b[6];
490 rb[26] = b[5];
491 rb[27] = b[4];
492 rb[28] = b[3];
493 rb[29] = b[2];
494 rb[30] = b[1];
495 rb[31] = b[0];
496 #endif
501 =item C<void fetch_buf_be_32(unsigned char *rb, const unsigned char *b)>
503 Converts a 32-byte big-endian buffer C<b> into a little-endian buffer C<b>.
505 =cut
509 void
510 fetch_buf_be_32(ARGOUT(unsigned char *rb), ARGIN(const unsigned char *b))
512 ASSERT_ARGS(fetch_buf_be_32)
513 #if PARROT_BIGENDIAN
514 memcpy(rb, b, 32);
515 #else
516 rb[0] = b[31];
517 rb[1] = b[30];
518 rb[2] = b[29];
519 rb[3] = b[28];
520 rb[4] = b[27];
521 rb[5] = b[26];
522 rb[6] = b[25];
523 rb[7] = b[24];
524 rb[8] = b[23];
525 rb[9] = b[22];
526 rb[10] = b[21];
527 rb[11] = b[20];
528 rb[12] = b[19];
529 rb[13] = b[18];
530 rb[14] = b[17];
531 rb[15] = b[16];
532 rb[16] = b[15];
533 rb[17] = b[14];
534 rb[18] = b[13];
535 rb[19] = b[12];
536 rb[20] = b[11];
537 rb[21] = b[10];
538 rb[22] = b[9];
539 rb[23] = b[8];
540 rb[24] = b[7];
541 rb[25] = b[6];
542 rb[26] = b[5];
543 rb[27] = b[4];
544 rb[28] = b[3];
545 rb[29] = b[2];
546 rb[30] = b[1];
547 rb[31] = b[0];
548 #endif
553 =back
555 =head1 HISTORY
557 Initial version by Melvin on 2002/05/01
559 =cut
564 * Local variables:
565 * c-file-style: "parrot"
566 * End:
567 * vim: expandtab shiftwidth=4: