src/cpu/mips/vm/bytes_mips.hpp

Tue, 26 Jul 2016 17:06:17 +0800

author
fujie
date
Tue, 26 Jul 2016 17:06:17 +0800
changeset 41
d885f8d65c58
parent 6
fbd9470e188d
child 6880
52ea28d233d2
permissions
-rw-r--r--

Add multiply word to GPR instruction (mul) in MIPS assembler.

aoqi@1 1 /*
aoqi@1 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
aoqi@1 3 * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
aoqi@1 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@1 5 *
aoqi@1 6 * This code is free software; you can redistribute it and/or modify it
aoqi@1 7 * under the terms of the GNU General Public License version 2 only, as
aoqi@1 8 * published by the Free Software Foundation.
aoqi@1 9 *
aoqi@1 10 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@1 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@1 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@1 13 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@1 14 * accompanied this code).
aoqi@1 15 *
aoqi@1 16 * You should have received a copy of the GNU General Public License version
aoqi@1 17 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@1 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@1 19 *
aoqi@1 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@1 21 * or visit www.oracle.com if you need additional information or have any
aoqi@1 22 * questions.
aoqi@1 23 *
aoqi@1 24 */
aoqi@1 25
aoqi@1 26 #ifndef CPU_MIPS_VM_BYTES_MIPS_HPP
aoqi@1 27 #define CPU_MIPS_VM_BYTES_MIPS_HPP
aoqi@1 28
aoqi@1 29 #include "memory/allocation.hpp"
aoqi@1 30
aoqi@1 31 class Bytes: AllStatic {
aoqi@1 32 private:
aoqi@1 33 // Helper function for swap_u8, not used in Loongson.
aoqi@1 34 static inline u8 swap_u8_base(u4 x, u4 y) {} // compiler-dependent implementation
aoqi@1 35
aoqi@1 36 public:
aoqi@1 37 // Returns true if the byte ordering used by Java is different from the native byte ordering
aoqi@1 38 // of the underlying machine. For example, this is true for Intel x86, but false for Solaris
aoqi@1 39 // on Sparc.
aoqi@1 40 // we use mipsel, so return true
aoqi@1 41 static inline bool is_Java_byte_ordering_different(){ return true; }
aoqi@1 42
aoqi@1 43
aoqi@1 44 // Efficient reading and writing of unaligned unsigned data in platform-specific byte ordering
aoqi@1 45 // (no special code is needed since x86 CPUs can access unaligned data)
aoqi@1 46 static inline u2 get_native_u2(address p) {
aoqi@1 47 if ((intptr_t)p & 0x1) {
aoqi@1 48 return ((u2)p[1] << 8) | (u2)p[0];
aoqi@1 49 } else {
aoqi@1 50 return *(u2*)p;
aoqi@1 51 }
aoqi@1 52 }
aoqi@1 53
aoqi@1 54 static inline u4 get_native_u4(address p) {
aoqi@1 55 if ((intptr_t)p & 3) {
aoqi@1 56 u4 res;
aoqi@1 57 __asm__ __volatile__ (
aoqi@1 58 " .set push\n"
aoqi@1 59 " .set mips64\n"
aoqi@1 60 " .set noreorder\n"
aoqi@1 61
aoqi@1 62 " lwr %[res], 0(%[addr]) \n"
aoqi@1 63 " lwl %[res], 3(%[addr]) \n"
aoqi@1 64
aoqi@1 65 " .set pop"
aoqi@1 66 : [res] "=&r" (res)
aoqi@1 67 : [addr] "r" (p)
aoqi@1 68 : "memory"
aoqi@1 69 );
aoqi@1 70 return res;
aoqi@1 71 } else {
aoqi@1 72 return *(u4*)p;
aoqi@1 73 }
aoqi@1 74 }
aoqi@1 75
aoqi@1 76 static inline u8 get_native_u8(address p) {
aoqi@1 77 u8 res;
aoqi@1 78 u8 temp;
aoqi@1 79 // u4 tp;//tmp register
aoqi@1 80 __asm__ __volatile__ (
aoqi@1 81 " .set push\n"
aoqi@1 82 " .set mips64\n"
aoqi@1 83 " .set noreorder\n"
aoqi@1 84 " .set noat\n"
aoqi@1 85 " andi $1,%[addr],0x7 \n"
aoqi@1 86 " beqz $1,1f \n"
aoqi@1 87 " nop \n"
aoqi@1 88 " ldr %[temp], 0(%[addr]) \n"
aoqi@1 89 " ldl %[temp], 7(%[addr]) \n"
aoqi@1 90 " b 2f \n"
aoqi@1 91 " nop \n"
aoqi@1 92 " 1:\t ld %[temp],0(%[addr]) \n"
aoqi@1 93 " 2:\t sd %[temp], %[res] \n"
aoqi@1 94
aoqi@1 95 " .set at\n"
aoqi@1 96 " .set pop\n"
aoqi@1 97 : [addr]"=r"(p), [temp]"=r" (temp)
aoqi@1 98 : "[addr]"(p), "[temp]" (temp), [res]"m" (*(volatile jint*)&res)
aoqi@1 99 : "memory"
aoqi@1 100 );
aoqi@1 101
aoqi@1 102 return res;
aoqi@1 103 }
aoqi@1 104 //use mips unaligned load instructions
aoqi@1 105 static inline void put_native_u2(address p, u2 x) {
aoqi@1 106 if((intptr_t)p & 0x1) {
aoqi@1 107 p[0] = (u_char)(x);
aoqi@1 108 p[1] = (u_char)(x>>8);
aoqi@1 109 } else {
aoqi@1 110 *(u2*)p = x;
aoqi@1 111 }
aoqi@1 112 }
aoqi@1 113 static inline void put_native_u4(address p, u4 x) {
Jin@6 114 /* 2016/5/8 Jin: refer to sparc implementation.
Jin@6 115 Note that sparc is big-endian, while mips is little-endian */
Jin@6 116 switch ( intptr_t(p) & 3 ) {
Jin@6 117 case 0: *(u4*)p = x;
Jin@6 118 break;
Jin@6 119
Jin@6 120 case 2: ((u2*)p)[1] = x >> 16;
Jin@6 121 ((u2*)p)[0] = x;
Jin@6 122 break;
Jin@6 123
Jin@6 124 default: ((u1*)p)[3] = x >> 24;
Jin@6 125 ((u1*)p)[2] = x >> 16;
Jin@6 126 ((u1*)p)[1] = x >> 8;
Jin@6 127 ((u1*)p)[0] = x;
Jin@6 128 break;
Jin@6 129 }
aoqi@1 130 /* if ((int)p&3) {
aoqi@1 131 __asm__ __volatile__ (
aoqi@1 132 " .set push\n"
aoqi@1 133 " .set mips64\n"
aoqi@1 134 " .set noreorder\n"
aoqi@1 135
aoqi@1 136 " swr %[x], 0(%[addr]) \n"
aoqi@1 137 " swl %[x], 3(%[addr]) \n"
aoqi@1 138
aoqi@1 139 " .set pop"
aoqi@1 140 :
aoqi@1 141 : [addr] "r" (p), [x] "r" (x)
aoqi@1 142 : "memory"
aoqi@1 143 );
aoqi@1 144 } else {
aoqi@1 145 *(u4*)p = x;
aoqi@1 146 }*/
aoqi@1 147 }
aoqi@1 148 static inline void put_native_u8(address p, u8 x) {
Jin@6 149 /* 2016/5/8 Jin: refer to sparc implementation.
Jin@6 150 Note that sparc is big-endian, while mips is little-endian */
Jin@6 151 switch ( intptr_t(p) & 7 ) {
Jin@6 152 case 0: *(u8*)p = x;
Jin@6 153 break;
Jin@6 154
Jin@6 155 case 4: ((u4*)p)[1] = x >> 32;
Jin@6 156 ((u4*)p)[0] = x;
Jin@6 157 break;
Jin@6 158
Jin@6 159 case 2: ((u2*)p)[3] = x >> 48;
Jin@6 160 ((u2*)p)[2] = x >> 32;
Jin@6 161 ((u2*)p)[1] = x >> 16;
Jin@6 162 ((u2*)p)[0] = x;
Jin@6 163 break;
Jin@6 164
Jin@6 165 default: ((u1*)p)[7] = x >> 56;
Jin@6 166 ((u1*)p)[6] = x >> 48;
Jin@6 167 ((u1*)p)[5] = x >> 40;
Jin@6 168 ((u1*)p)[4] = x >> 32;
Jin@6 169 ((u1*)p)[3] = x >> 24;
Jin@6 170 ((u1*)p)[2] = x >> 16;
Jin@6 171 ((u1*)p)[1] = x >> 8;
Jin@6 172 ((u1*)p)[0] = x;
Jin@6 173 }
aoqi@1 174 /*if ((int)p&7) {
aoqi@1 175
aoqi@1 176 __asm__ __volatile__ (
aoqi@1 177 " .set push\n"
aoqi@1 178 " .set mips64\n"
aoqi@1 179 " .set noreorder\n"
aoqi@1 180 " .set noat\n"
aoqi@1 181 " sdr %[x], 0(%[addr]) \n"
aoqi@1 182 " sdl %[x], 7(%[addr]) \n"
aoqi@1 183
aoqi@1 184 " .set at\n"
aoqi@1 185 " .set pop\n"
aoqi@1 186 :
aoqi@1 187 : [addr] "r" (p), [x]"r" (x)
aoqi@1 188 : "memory"
aoqi@1 189 );
aoqi@1 190 } else {
aoqi@1 191
aoqi@1 192 *(u8*)p = x;
aoqi@1 193 }*/
aoqi@1 194
aoqi@1 195 }
aoqi@1 196
aoqi@1 197
aoqi@1 198 // Efficient reading and writing of unaligned unsigned data in Java
aoqi@1 199 // byte ordering (i.e. big-endian ordering). Byte-order reversal is
aoqi@1 200 // needed since x86 CPUs use little-endian format.
aoqi@1 201 static inline u2 get_Java_u2(address p) { return swap_u2(get_native_u2(p)); }
aoqi@1 202 static inline u4 get_Java_u4(address p) { return swap_u4(get_native_u4(p)); }
aoqi@1 203 static inline u8 get_Java_u8(address p) { return swap_u8(get_native_u8(p)); }
aoqi@1 204
aoqi@1 205 static inline void put_Java_u2(address p, u2 x) { put_native_u2(p, swap_u2(x)); }
aoqi@1 206 static inline void put_Java_u4(address p, u4 x) { put_native_u4(p, swap_u4(x)); }
aoqi@1 207 static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, swap_u8(x)); }
aoqi@1 208
aoqi@1 209
aoqi@1 210 // Efficient swapping of byte ordering
aoqi@1 211 static inline u2 swap_u2(u2 x); // compiler-dependent implementation
aoqi@1 212 static inline u4 swap_u4(u4 x); // compiler-dependent implementation
aoqi@1 213 static inline u8 swap_u8(u8 x);
aoqi@1 214 };
aoqi@1 215
aoqi@1 216
aoqi@1 217 // The following header contains the implementations of swap_u2, swap_u4, and swap_u8[_base]
aoqi@1 218 #ifdef TARGET_OS_ARCH_linux_mips
aoqi@1 219 # include "bytes_linux_mips.inline.hpp"
aoqi@1 220 #endif
aoqi@1 221 #ifdef TARGET_OS_ARCH_solaris_mips
aoqi@1 222 # include "bytes_solaris_mips.inline.hpp"
aoqi@1 223 #endif
aoqi@1 224 #ifdef TARGET_OS_ARCH_windows_mips
aoqi@1 225 # include "bytes_windows_mips.inline.hpp"
aoqi@1 226 #endif
aoqi@1 227 #ifdef TARGET_OS_ARCH_bsd_mips
aoqi@1 228 # include "bytes_bsd_mips.inline.hpp"
aoqi@1 229 #endif
aoqi@1 230
aoqi@1 231
aoqi@1 232 #endif // CPU_MIPS_VM_BYTES_MIPS_HPP
aoqi@1 233

mercurial