1 /*
   2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
   4  * Copyright (c) 2015, Linaro Ltd. All rights reserved.
   5  * Copyright (c) 2015-2018, Azul Systems, Inc. All rights reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  23  * or visit www.oracle.com if you need additional information or have any
  24  * questions.
  25  *
  26  */
  27 
  28 #ifndef CPU_AARCH32_VM_BYTES_AARCH32_HPP
  29 #define CPU_AARCH32_VM_BYTES_AARCH32_HPP
  30 
  31 #include "memory/allocation.hpp"
  32 
  33 class Bytes: AllStatic {
  34  public:
  35 
  36   // Efficient reading and writing of unaligned unsigned data in platform-specific byte ordering.
  37   // Since ARMv6 unaligned short and word accesses are handled by hardware.
  38   // However, unaligned double-word access causes kernel trap and software processing,
  39   // so we turn it to fast unalinged word access.
  40   static inline u2   get_native_u2(address p)         { return *(u2*)p; }
  41   static inline u4   get_native_u4(address p)         { return *(u4*)p; }
  42   static inline u8   get_native_u8(address p)         {
  43     if (!(uintptr_t(p) & 3)) {
  44       return *(u8*)p;
  45     }
  46     u4 *const a = (u4*) p;
  47     return (u8(a[1]) << 32) | a[0];
  48   }
  49 
  50   static inline void put_native_u2(address p, u2 x)   { *(u2*)p = x; }
  51   static inline void put_native_u4(address p, u4 x)   { *(u4*)p = x; }
  52   static inline void put_native_u8(address p, u8 x)   { *(u8*)p = x; }
  53 
  54 
  55   // Efficient reading and writing of unaligned unsigned data in Java
  56   // byte ordering (i.e. big-endian ordering). Byte-order reversal is
  57   // needed since AArch32 use little-endian format.
  58   static inline u2   get_Java_u2(address p)           { return swap_u2(get_native_u2(p)); }
  59   static inline u4   get_Java_u4(address p)           { return swap_u4(get_native_u4(p)); }
  60   static inline u8   get_Java_u8(address p)           { return swap_u8(get_native_u8(p)); }
  61 
  62   static inline void put_Java_u2(address p, u2 x)     { put_native_u2(p, swap_u2(x)); }
  63   static inline void put_Java_u4(address p, u4 x)     { put_native_u4(p, swap_u4(x)); }
  64   static inline void put_Java_u8(address p, u8 x)     {
  65     const u8 nx = swap_u8(x);
  66     if (!(uintptr_t(p) & 3)) {
  67       *(u8*)p = nx;
  68     } else {
  69       u4 *const a = (u4*) p;
  70       a[0] = nx;
  71       a[1] = nx >> 32;
  72     }
  73   }
  74 
  75   // Efficient swapping of byte ordering
  76   static inline u2   swap_u2(u2 x);                   // compiler-dependent implementation
  77   static inline u4   swap_u4(u4 x);                   // compiler-dependent implementation
  78   static inline u8   swap_u8(u8 x);
  79 };
  80 
  81 
  82 // The following header contains the implementations of swap_u2, swap_u4, and swap_u8[_base]
  83 
  84 #include OS_CPU_HEADER_INLINE(bytes)
  85 
  86 #endif // CPU_AARCH32_VM_BYTES_AARCH32_HPP