LCOV - code coverage report
Current view: top level - toolbox - endianess.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 35 35 100.0 %
Date: 2015-06-10 18:10:59 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /* src/toolbox/endianess.hpp - utilities for reading/writing to/from a 
       2             :                                                            buffer in little or big endian
       3             : 
       4             :    Copyright (C) 1996-2013
       5             :    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
       6             : 
       7             :    This file is part of CACAO.
       8             : 
       9             :    This program is free software; you can redistribute it and/or
      10             :    modify it under the terms of the GNU General Public License as
      11             :    published by the Free Software Foundation; either version 2, or (at
      12             :    your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful, but
      15             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :    General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program; if not, write to the Free Software
      21             :    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      22             :    02110-1301, USA.
      23             : 
      24             : */
      25             : 
      26             : #ifndef CACAO_ENDIANESS_
      27             : #define CACAO_ENDIANESS_ 1
      28             : 
      29             : #include "mm/memory.hpp"
      30             : #include "toolbox/assert.hpp"
      31             : #include "vm/types.hpp"
      32             : 
      33             : namespace cacao {
      34             :         // ***** READ UNSIGNED, LITTLE ENDIAN **************************************
      35             : 
      36             : #if defined(__I386__) || defined(__X86_64__)
      37             : 
      38             :         // we can optimize the LE access on little endian machines without alignment
      39             : 
      40             :         static inline uint8_t  read_u1_le(const uint8_t *src) { return *src; }
      41     5346826 :         static inline uint16_t read_u2_le(const uint8_t *src) { return *((uint16_t*) src); }
      42     5285316 :         static inline uint32_t read_u4_le(const uint8_t *src) { return *((uint32_t*) src); }
      43             :         static inline uint64_t read_u8_le(const uint8_t *src) { return *((uint64_t*) src); }
      44             : 
      45             : #else // defined(__I386__) || defined(__X86_64__)
      46             : 
      47             :         static inline uint8_t read_u1_le(const uint8_t *src) {
      48             :                 return *src;
      49             :         }
      50             : 
      51             :         static inline uint16_t read_u2_le(const uint8_t *src) {
      52             :                 return (((uint16_t) src[1]) << 8) +
      53             :                         ((uint16_t) src[0]);
      54             :         }
      55             : 
      56             :         static inline uint32_t read_u4_le(const uint8_t *src) {
      57             :                 return (((uint32_t) src[3]) << 24) +
      58             :                        (((uint32_t) src[2]) << 16) +
      59             :                        (((uint32_t) src[1]) <<  8) +
      60             :                         ((uint32_t) src[0]);
      61             :         }
      62             : 
      63             :         static inline uint64_t read_u8_le(const uint8_t *src) {
      64             :                 return (((uint64_t) src[7]) << 56) +
      65             :                        (((uint64_t) src[6]) << 48) +
      66             :                        (((uint64_t) src[5]) << 40) +
      67             :                        (((uint64_t) src[4]) << 32) +
      68             :                        (((uint64_t) src[3]) << 24) +
      69             :                        (((uint64_t) src[2]) << 16) +
      70             :                        (((uint64_t) src[1]) <<  8) +
      71             :                         ((uint64_t) src[0]);
      72             :         }
      73             : 
      74             : #endif // defined(__I386__) || defined(__X86_64__)
      75             : 
      76             :         // ***** READ SIGNED, LITTLE ENDIAN ****************************************
      77             : 
      78             :         /// read int8_t from pointer little endian
      79             :         static inline int8_t  read_s1_le(const uint8_t *src) { return (int8_t) read_u1_le(src); }
      80             : 
      81             :         /// read int16_t from pointer little endian
      82             :         static inline int16_t read_s2_le(const uint8_t *src) { return (int16_t) read_u2_le(src); }
      83             : 
      84             :         /// read int32_t from pointer little endian
      85             :         static inline int32_t read_s4_le(const uint8_t *src) { return (int32_t) read_u4_le(src); }
      86             : 
      87             :         /// read int64_t from pointer little endian
      88             :         static inline int64_t read_s8_le(const uint8_t *src) { return (int64_t) read_u8_le(src); }
      89             : 
      90             :         // ***** READ UNSIGNED, BIG ENDIAN (for Java class files ) *****************
      91             : 
      92             :         /// read uint8_t from pointer big endian
      93     9690398 :         static inline uint8_t read_u1_be(const uint8_t *src) {
      94     9690398 :                 return *src;
      95             :         }
      96             : 
      97             :         /// read uint16_t from pointer big endian
      98    17297288 :         static inline uint16_t read_u2_be(const uint8_t *src) {
      99    17297288 :                 return (((uint16_t) src[0]) << 8) +
     100    17297288 :                         ((uint16_t) src[1]);
     101             :         }
     102             : 
     103             :         /// read uint32_t from pointer big endian
     104     1646673 :         static inline uint32_t read_u4_be(const uint8_t *src) {
     105     1646673 :                 return (((uint32_t) src[0]) << 24) +
     106     1646673 :                        (((uint32_t) src[1]) << 16) +
     107     1646673 :                        (((uint32_t) src[2]) <<  8) +
     108     4940019 :                         ((uint32_t) src[3]);
     109             :         }
     110             : 
     111             :         /// read uint64_t from pointer big endian
     112       10958 :         static inline uint64_t read_u8_be(const uint8_t *src) {
     113       10958 :                 return (((uint64_t) src[0]) << 56) +
     114       10958 :                        (((uint64_t) src[1]) << 48) +
     115       10958 :                        (((uint64_t) src[2]) << 40) +
     116       10958 :                        (((uint64_t) src[3]) << 32) +
     117       10958 :                        (((uint64_t) src[4]) << 24) +
     118       10958 :                        (((uint64_t) src[5]) << 16) +
     119       10958 :                        (((uint64_t) src[6]) <<  8) +
     120       76706 :                         ((uint64_t) src[7]);
     121             :         }
     122             : 
     123             :         // ***** READ SIGNED, BIG ENDIAN ************************
     124             : 
     125             :         /// read int8_t from pointer big endian
     126      581103 :         static inline int8_t  read_s1_be(const uint8_t *src) { return (int8_t)  read_u1_be(src); }
     127             : 
     128             :         /// read int16_t from pointer big endian
     129      643789 :         static inline int16_t read_s2_be(const uint8_t *src) { return (int16_t) read_u2_be(src); }
     130             : 
     131             :         /// read int32_t from pointer big endian
     132       30763 :         static inline int32_t read_s4_be(const uint8_t *src) { return (int32_t) read_u4_be(src); }
     133             : 
     134             :         /// read int64_t from pointer big endian
     135       10958 :         static inline int64_t read_s8_be(const uint8_t *src) { return (int64_t) read_u8_be(src); }
     136             : 
     137             :         // ***** READ FLOATING POINT, BIG ENDIAN ****************
     138             : 
     139        2501 :         static inline float read_float_be(const uint8_t *src) {
     140             :                 EXPENSIVE_ASSERT(sizeof(float) == 4);
     141             :                 
     142             :                 float f;
     143             : 
     144             :         #if WORDS_BIGENDIAN == 0
     145             :                 uint8_t  buffer[4];
     146             : 
     147       12505 :                 for (int i = 0; i < 4; i++)
     148       10004 :                         buffer[3 - i] = read_u1_be(src + i);
     149             : 
     150        2501 :                 MCOPY((uint8_t *) (&f), buffer, u1, 4);
     151             :         #else
     152             :                 MCOPY((uint8_t *) (&f), src,    u1, 4);
     153             :         #endif
     154             :                 
     155        2501 :                 return f;
     156             :         }
     157             : 
     158        2033 :         static inline double  read_double_be(const uint8_t *src) {
     159             :                 EXPENSIVE_ASSERT(sizeof(double) == 8);
     160             : 
     161             :                 double d;
     162             : 
     163             :         #if WORDS_BIGENDIAN == 0
     164             :                 uint8_t buffer[8];
     165             : 
     166             :         # if defined(__ARM__) && defined(__ARMEL__) && !defined(__VFP_FP__)
     167             :                 // On little endian ARM processors when using FPA, word order
     168             :                 // of doubles is still big endian. So take that into account
     169             :                 // here. When using VFP, word order of doubles follows byte
     170             :                 // order. (michi 2005/07/24)
     171             : 
     172             :                 for (int i = 0; i < 4; i++)
     173             :                         buffer[3 - i] = read_u1_be(src + i);
     174             :                 for (int i = 0; i < 4; i++)
     175             :                         buffer[7 - i] = read_u1_be(src + i + 4);
     176             :         # else
     177       18297 :                 for (int i = 0; i < 8; i++)
     178       16264 :                         buffer[7 - i] = read_u1_be(src + i);
     179             :         # endif
     180             : 
     181        2033 :           MCOPY((uint8_t *) (&d), buffer, u1, 8);
     182             :         #else 
     183             :           MCOPY((uint8_t *) (&d), src,    u1, 8);
     184             :         #endif
     185             : 
     186        2033 :                 return d;
     187             :         }
     188             : } // end namespace cacao
     189             : 
     190             : #endif // CACAO_ENDIANESS_
     191             : 
     192             : /*
     193             :  * These are local overrides for various environment variables in Emacs.
     194             :  * Please do not remove this and leave it at the end of the file, where
     195             :  * Emacs will automagically detect them.
     196             :  * ---------------------------------------------------------------------
     197             :  * Local variables:
     198             :  * mode: c++
     199             :  * indent-tabs-mode: t
     200             :  * c-basic-offset: 4
     201             :  * tab-width: 4
     202             :  * End:
     203             :  * vim:noexpandtab:sw=4:ts=4:
     204             :  */

Generated by: LCOV version 1.11