1 /*
   2  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright 2007, 2008, 2009 Red Hat, Inc.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #ifndef CPU_ZERO_VM_BYTES_ZERO_HPP
  27 #define CPU_ZERO_VM_BYTES_ZERO_HPP
  28 
  29 #include "memory/allocation.hpp"
  30 
  31 typedef union unaligned {
  32   u4 u;
  33   u2 us;
  34   u8 ul;
  35 } __attribute__((packed)) unaligned;
  36 
  37 class Bytes: AllStatic {
  38  public:
  39   // Returns true if the byte ordering used by Java is different
  40   // from the native byte ordering of the underlying machine.
  41   static inline bool is_Java_byte_ordering_different() {
  42 #ifdef VM_LITTLE_ENDIAN
  43     return true;
  44 #else
  45     return false;
  46 #endif
  47   }
  48 
  49   // Efficient reading and writing of unaligned unsigned data in
  50   // platform-specific byte ordering.
  51   static inline u2 get_native_u2(address p){
  52     unaligned *up = (unaligned *) p;
  53     return up->us;
  54   }
  55 
  56   static inline u4 get_native_u4(address p) {
  57     unaligned *up = (unaligned *) p;
  58     return up->u;
  59   }
  60 
  61   static inline u8 get_native_u8(address p) {
  62     unaligned *up = (unaligned *) p;
  63     return up->ul;
  64   }
  65 
  66   static inline void put_native_u2(address p, u2 x) {
  67     unaligned *up = (unaligned *) p;
  68     up->us = x;
  69   }
  70 
  71   static inline void put_native_u4(address p, u4 x) {
  72     unaligned *up = (unaligned *) p;
  73     up->u = x;
  74   }
  75 
  76   static inline void put_native_u8(address p, u8 x) {
  77     unaligned *up = (unaligned *) p;
  78     up->ul = x;
  79   }
  80 
  81   // Efficient reading and writing of unaligned unsigned data in Java
  82   // byte ordering (i.e. big-endian ordering).
  83 #ifdef VM_LITTLE_ENDIAN
  84   // Byte-order reversal is needed
  85   static inline u2 get_Java_u2(address p) {
  86     return (u2(p[0]) << 8) |
  87            (u2(p[1])     );
  88   }
  89   static inline u4 get_Java_u4(address p) {
  90     return (u4(p[0]) << 24) |
  91            (u4(p[1]) << 16) |
  92            (u4(p[2]) <<  8) |
  93            (u4(p[3])      );
  94   }
  95   static inline u8 get_Java_u8(address p) {
  96     u4 hi, lo;
  97     hi = (u4(p[0]) << 24) |
  98          (u4(p[1]) << 16) |
  99          (u4(p[2]) <<  8) |
 100          (u4(p[3])      );
 101     lo = (u4(p[4]) << 24) |
 102          (u4(p[5]) << 16) |
 103          (u4(p[6]) <<  8) |
 104          (u4(p[7])      );
 105     return u8(lo) | (u8(hi) << 32);
 106   }
 107 
 108   static inline void put_Java_u2(address p, u2 x) {
 109     p[0] = x >> 8;
 110     p[1] = x;
 111   }
 112   static inline void put_Java_u4(address p, u4 x) {
 113     p[0] = x >> 24;
 114     p[1] = x >> 16;
 115     p[2] = x >> 8;
 116     p[3] = x;
 117   }
 118   static inline void put_Java_u8(address p, u8 x) {
 119     u4 hi, lo;
 120     lo = x;
 121     hi = x >> 32;
 122     p[0] = hi >> 24;
 123     p[1] = hi >> 16;
 124     p[2] = hi >> 8;
 125     p[3] = hi;
 126     p[4] = lo >> 24;
 127     p[5] = lo >> 16;
 128     p[6] = lo >> 8;
 129     p[7] = lo;
 130   }
 131 
 132   // Efficient swapping of byte ordering
 133   static inline u2 swap_u2(u2 x);
 134   static inline u4 swap_u4(u4 x);
 135   static inline u8 swap_u8(u8 x);
 136 #else
 137   // No byte-order reversal is needed
 138   static inline u2 get_Java_u2(address p) {
 139     return get_native_u2(p);
 140   }
 141   static inline u4 get_Java_u4(address p) {
 142     return get_native_u4(p);
 143   }
 144   static inline u8 get_Java_u8(address p) {
 145     return get_native_u8(p);
 146   }
 147 
 148   static inline void put_Java_u2(address p, u2 x) {
 149     put_native_u2(p, x);
 150   }
 151   static inline void put_Java_u4(address p, u4 x) {
 152     put_native_u4(p, x);
 153   }
 154   static inline void put_Java_u8(address p, u8 x) {
 155     put_native_u8(p, x);
 156   }
 157 
 158   // No byte-order reversal is needed
 159   static inline u2 swap_u2(u2 x) { return x; }
 160   static inline u4 swap_u4(u4 x) { return x; }
 161   static inline u8 swap_u8(u8 x) { return x; }
 162 #endif // VM_LITTLE_ENDIAN
 163 };
 164 
 165 #ifdef VM_LITTLE_ENDIAN
 166 // The following header contains the implementations of swap_u2,
 167 // swap_u4, and swap_u8
 168 #ifdef TARGET_OS_ARCH_linux_zero
 169 # include "bytes_linux_zero.inline.hpp"
 170 #endif
 171 
 172 #endif // VM_LITTLE_ENDIAN
 173 
 174 #endif // CPU_ZERO_VM_BYTES_ZERO_HPP