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