endian.cpp revision 12785:200804e4ba28
1/*
2 * Copyright (c) 2015, 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.    Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.    See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#include "endian.hpp"
27#include "inttypes.hpp"
28
29// Most modern compilers optimize the bswap routines to native instructions.
30inline static u2 bswap_16(u2 x) {
31    return ((x & 0xFF) << 8) |
32           ((x >> 8) & 0xFF);
33}
34
35inline static u4 bswap_32(u4 x) {
36    return ((x & 0xFF) << 24) |
37           ((x & 0xFF00) << 8) |
38           ((x >> 8) & 0xFF00) |
39           ((x >> 24) & 0xFF);
40}
41
42inline static u8 bswap_64(u8 x) {
43    return (u8)bswap_32((u4)x) << 32 |
44           (u8)bswap_32((u4)(x >> 32));
45}
46
47u2 NativeEndian::get(u2 x) { return x; }
48u4 NativeEndian::get(u4 x) { return x; }
49u8 NativeEndian::get(u8 x) { return x; }
50s2 NativeEndian::get(s2 x) { return x; }
51s4 NativeEndian::get(s4 x) { return x; }
52s8 NativeEndian::get(s8 x) { return x; }
53
54void NativeEndian::set(u2& x, u2 y) { x = y; }
55void NativeEndian::set(u4& x, u4 y) { x = y; }
56void NativeEndian::set(u8& x, u8 y) { x = y; }
57void NativeEndian::set(s2& x, s2 y) { x = y; }
58void NativeEndian::set(s4& x, s4 y) { x = y; }
59void NativeEndian::set(s8& x, s8 y) { x = y; }
60
61NativeEndian NativeEndian::_native;
62
63u2 SwappingEndian::get(u2 x) { return bswap_16(x); }
64u4 SwappingEndian::get(u4 x) { return bswap_32(x); }
65u8 SwappingEndian::get(u8 x) { return bswap_64(x); }
66s2 SwappingEndian::get(s2 x) { return bswap_16(x); }
67s4 SwappingEndian::get(s4 x) { return bswap_32(x); }
68s8 SwappingEndian::get(s8 x) { return bswap_64(x); }
69
70void SwappingEndian::set(u2& x, u2 y) { x = bswap_16(y); }
71void SwappingEndian::set(u4& x, u4 y) { x = bswap_32(y); }
72void SwappingEndian::set(u8& x, u8 y) { x = bswap_64(y); }
73void SwappingEndian::set(s2& x, s2 y) { x = bswap_16(y); }
74void SwappingEndian::set(s4& x, s4 y) { x = bswap_32(y); }
75void SwappingEndian::set(s8& x, s8 y) { x = bswap_64(y); }
76
77SwappingEndian SwappingEndian::_swapping;
78
79Endian* Endian::get_handler(bool big_endian) {
80    // If requesting little endian on a little endian machine or
81    // big endian on a big endian machine use native handler
82    if (big_endian == is_big_endian()) {
83        return NativeEndian::get_native();
84    } else {
85        // Use swapping handler.
86        return SwappingEndian::get_swapping();
87    }
88}
89
90// Return a platform u2 from an array in which Big Endian is applied.
91u2 Endian::get_java(u1* x) {
92    return (u2) (x[0]<<8 | x[1]);
93}
94
95// Add a platform u2 to the array as a Big Endian u2
96void Endian::set_java(u1* p, u2 x) {
97    p[0] = (x >> 8) & 0xff;
98    p[1] = x & 0xff;
99}
100
101Endian* Endian::get_native_handler() {
102    return NativeEndian::get_native();
103}
104