Tue, 26 Jul 2016 17:06:17 +0800
Add multiply word to GPR instruction (mul) in MIPS assembler.
1 /*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
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 */
26 #ifndef CPU_MIPS_VM_BYTES_MIPS_HPP
27 #define CPU_MIPS_VM_BYTES_MIPS_HPP
29 #include "memory/allocation.hpp"
31 class Bytes: AllStatic {
32 private:
33 // Helper function for swap_u8, not used in Loongson.
34 static inline u8 swap_u8_base(u4 x, u4 y) {} // compiler-dependent implementation
36 public:
37 // Returns true if the byte ordering used by Java is different from the native byte ordering
38 // of the underlying machine. For example, this is true for Intel x86, but false for Solaris
39 // on Sparc.
40 // we use mipsel, so return true
41 static inline bool is_Java_byte_ordering_different(){ return true; }
44 // Efficient reading and writing of unaligned unsigned data in platform-specific byte ordering
45 // (no special code is needed since x86 CPUs can access unaligned data)
46 static inline u2 get_native_u2(address p) {
47 if ((intptr_t)p & 0x1) {
48 return ((u2)p[1] << 8) | (u2)p[0];
49 } else {
50 return *(u2*)p;
51 }
52 }
54 static inline u4 get_native_u4(address p) {
55 if ((intptr_t)p & 3) {
56 u4 res;
57 __asm__ __volatile__ (
58 " .set push\n"
59 " .set mips64\n"
60 " .set noreorder\n"
62 " lwr %[res], 0(%[addr]) \n"
63 " lwl %[res], 3(%[addr]) \n"
65 " .set pop"
66 : [res] "=&r" (res)
67 : [addr] "r" (p)
68 : "memory"
69 );
70 return res;
71 } else {
72 return *(u4*)p;
73 }
74 }
76 static inline u8 get_native_u8(address p) {
77 u8 res;
78 u8 temp;
79 // u4 tp;//tmp register
80 __asm__ __volatile__ (
81 " .set push\n"
82 " .set mips64\n"
83 " .set noreorder\n"
84 " .set noat\n"
85 " andi $1,%[addr],0x7 \n"
86 " beqz $1,1f \n"
87 " nop \n"
88 " ldr %[temp], 0(%[addr]) \n"
89 " ldl %[temp], 7(%[addr]) \n"
90 " b 2f \n"
91 " nop \n"
92 " 1:\t ld %[temp],0(%[addr]) \n"
93 " 2:\t sd %[temp], %[res] \n"
95 " .set at\n"
96 " .set pop\n"
97 : [addr]"=r"(p), [temp]"=r" (temp)
98 : "[addr]"(p), "[temp]" (temp), [res]"m" (*(volatile jint*)&res)
99 : "memory"
100 );
102 return res;
103 }
104 //use mips unaligned load instructions
105 static inline void put_native_u2(address p, u2 x) {
106 if((intptr_t)p & 0x1) {
107 p[0] = (u_char)(x);
108 p[1] = (u_char)(x>>8);
109 } else {
110 *(u2*)p = x;
111 }
112 }
113 static inline void put_native_u4(address p, u4 x) {
114 /* 2016/5/8 Jin: refer to sparc implementation.
115 Note that sparc is big-endian, while mips is little-endian */
116 switch ( intptr_t(p) & 3 ) {
117 case 0: *(u4*)p = x;
118 break;
120 case 2: ((u2*)p)[1] = x >> 16;
121 ((u2*)p)[0] = x;
122 break;
124 default: ((u1*)p)[3] = x >> 24;
125 ((u1*)p)[2] = x >> 16;
126 ((u1*)p)[1] = x >> 8;
127 ((u1*)p)[0] = x;
128 break;
129 }
130 /* if ((int)p&3) {
131 __asm__ __volatile__ (
132 " .set push\n"
133 " .set mips64\n"
134 " .set noreorder\n"
136 " swr %[x], 0(%[addr]) \n"
137 " swl %[x], 3(%[addr]) \n"
139 " .set pop"
140 :
141 : [addr] "r" (p), [x] "r" (x)
142 : "memory"
143 );
144 } else {
145 *(u4*)p = x;
146 }*/
147 }
148 static inline void put_native_u8(address p, u8 x) {
149 /* 2016/5/8 Jin: refer to sparc implementation.
150 Note that sparc is big-endian, while mips is little-endian */
151 switch ( intptr_t(p) & 7 ) {
152 case 0: *(u8*)p = x;
153 break;
155 case 4: ((u4*)p)[1] = x >> 32;
156 ((u4*)p)[0] = x;
157 break;
159 case 2: ((u2*)p)[3] = x >> 48;
160 ((u2*)p)[2] = x >> 32;
161 ((u2*)p)[1] = x >> 16;
162 ((u2*)p)[0] = x;
163 break;
165 default: ((u1*)p)[7] = x >> 56;
166 ((u1*)p)[6] = x >> 48;
167 ((u1*)p)[5] = x >> 40;
168 ((u1*)p)[4] = x >> 32;
169 ((u1*)p)[3] = x >> 24;
170 ((u1*)p)[2] = x >> 16;
171 ((u1*)p)[1] = x >> 8;
172 ((u1*)p)[0] = x;
173 }
174 /*if ((int)p&7) {
176 __asm__ __volatile__ (
177 " .set push\n"
178 " .set mips64\n"
179 " .set noreorder\n"
180 " .set noat\n"
181 " sdr %[x], 0(%[addr]) \n"
182 " sdl %[x], 7(%[addr]) \n"
184 " .set at\n"
185 " .set pop\n"
186 :
187 : [addr] "r" (p), [x]"r" (x)
188 : "memory"
189 );
190 } else {
192 *(u8*)p = x;
193 }*/
195 }
198 // Efficient reading and writing of unaligned unsigned data in Java
199 // byte ordering (i.e. big-endian ordering). Byte-order reversal is
200 // needed since x86 CPUs use little-endian format.
201 static inline u2 get_Java_u2(address p) { return swap_u2(get_native_u2(p)); }
202 static inline u4 get_Java_u4(address p) { return swap_u4(get_native_u4(p)); }
203 static inline u8 get_Java_u8(address p) { return swap_u8(get_native_u8(p)); }
205 static inline void put_Java_u2(address p, u2 x) { put_native_u2(p, swap_u2(x)); }
206 static inline void put_Java_u4(address p, u4 x) { put_native_u4(p, swap_u4(x)); }
207 static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, swap_u8(x)); }
210 // Efficient swapping of byte ordering
211 static inline u2 swap_u2(u2 x); // compiler-dependent implementation
212 static inline u4 swap_u4(u4 x); // compiler-dependent implementation
213 static inline u8 swap_u8(u8 x);
214 };
217 // The following header contains the implementations of swap_u2, swap_u4, and swap_u8[_base]
218 #ifdef TARGET_OS_ARCH_linux_mips
219 # include "bytes_linux_mips.inline.hpp"
220 #endif
221 #ifdef TARGET_OS_ARCH_solaris_mips
222 # include "bytes_solaris_mips.inline.hpp"
223 #endif
224 #ifdef TARGET_OS_ARCH_windows_mips
225 # include "bytes_windows_mips.inline.hpp"
226 #endif
227 #ifdef TARGET_OS_ARCH_bsd_mips
228 # include "bytes_bsd_mips.inline.hpp"
229 #endif
232 #endif // CPU_MIPS_VM_BYTES_MIPS_HPP