src/cpu/mips/vm/jniFastGetField_mips_64.cpp

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

author
fujie
date
Tue, 26 Jul 2016 17:06:17 +0800
changeset 41
d885f8d65c58
parent 1
2d8a650513c2
child 368
11ec15adb6c4
permissions
-rw-r--r--

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

aoqi@1 1 /*
aoqi@1 2 * Copyright (c) 2004, 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 #include "precompiled.hpp"
aoqi@1 27 #include "asm/macroAssembler.hpp"
aoqi@1 28 #include "memory/resourceArea.hpp"
aoqi@1 29 #include "prims/jniFastGetField.hpp"
aoqi@1 30 #include "prims/jvm_misc.hpp"
aoqi@1 31 #include "runtime/safepoint.hpp"
aoqi@1 32
aoqi@1 33 #define __ masm->
aoqi@1 34
aoqi@1 35 #define BUFFER_SIZE 30*wordSize
aoqi@1 36
aoqi@1 37 // Instead of issuing lfence for LoadLoad barrier, we create data dependency
aoqi@1 38 // between loads, which is more efficient than lfence.
aoqi@1 39
aoqi@1 40 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
aoqi@1 41 const char *name;
aoqi@1 42 switch (type) {
aoqi@1 43 case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
aoqi@1 44 case T_BYTE: name = "jni_fast_GetByteField"; break;
aoqi@1 45 case T_CHAR: name = "jni_fast_GetCharField"; break;
aoqi@1 46 case T_SHORT: name = "jni_fast_GetShortField"; break;
aoqi@1 47 case T_INT: name = "jni_fast_GetIntField"; break;
aoqi@1 48 case T_LONG: name = "jni_fast_GetLongField"; break;
aoqi@1 49 default: ShouldNotReachHere();
aoqi@1 50 }
aoqi@1 51 ResourceMark rm;
aoqi@1 52 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
aoqi@1 53 CodeBuffer cbuf(blob);
aoqi@1 54 MacroAssembler* masm = new MacroAssembler(&cbuf);
aoqi@1 55 address fast_entry = __ pc();
aoqi@1 56
aoqi@1 57 Label slow;
aoqi@1 58
aoqi@1 59 // return pc RA
aoqi@1 60 // jni env A0
aoqi@1 61 // obj A1
aoqi@1 62 // jfieldID A2
aoqi@1 63
aoqi@1 64 address counter_addr = SafepointSynchronize::safepoint_counter_addr();
aoqi@1 65 __ li48(AT, (long)counter_addr);
aoqi@1 66 __ lw(T1, AT, 0);
aoqi@1 67
aoqi@1 68 /* 2012/4/28 Jin: the parameters(A0~A3) should not be modified, since
aoqi@1 69 * they will be used in slow path. */
aoqi@1 70 __ andi(AT, T1, 1);
aoqi@1 71 __ bne(AT, R0, slow);
aoqi@1 72 __ delayed()->nop();
aoqi@1 73
aoqi@1 74 __ ld(T0, A1, 0); // unbox, *obj
aoqi@1 75 __ move(T2, A2);
aoqi@1 76 __ shr(T2, 2); // offset
aoqi@1 77 __ dadd(T0, T0, T2);
aoqi@1 78
aoqi@1 79 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
aoqi@1 80 speculative_load_pclist[count] = __ pc();
aoqi@1 81 switch (type) {
aoqi@1 82 case T_BOOLEAN: __ lbu (V0, T0, 0); break;
aoqi@1 83 case T_BYTE: __ lb (V0, T0, 0); break;
aoqi@1 84 case T_CHAR: __ lhu (V0, T0, 0); break;
aoqi@1 85 case T_SHORT: __ lh (V0, T0, 0); break;
aoqi@1 86 case T_INT: __ lw (V0, T0, 0); break;
aoqi@1 87 case T_LONG: __ ld (V0, T0, 0); break;
aoqi@1 88 default: ShouldNotReachHere();
aoqi@1 89 }
aoqi@1 90
aoqi@1 91 __ li48(AT, (long)counter_addr);
aoqi@1 92 __ lw(AT, AT, 0);
aoqi@1 93 __ bne(T1, AT, slow);
aoqi@1 94 __ delayed()->nop();
aoqi@1 95
aoqi@1 96 __ jr(RA);
aoqi@1 97 __ delayed()->nop();
aoqi@1 98
aoqi@1 99 slowcase_entry_pclist[count++] = __ pc();
aoqi@1 100 __ bind (slow);
aoqi@1 101 address slow_case_addr;
aoqi@1 102 switch (type) {
aoqi@1 103 case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
aoqi@1 104 case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;
aoqi@1 105 case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break;
aoqi@1 106 case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break;
aoqi@1 107 case T_INT: slow_case_addr = jni_GetIntField_addr(); break;
aoqi@1 108 case T_LONG: slow_case_addr = jni_GetLongField_addr();
aoqi@1 109 }
aoqi@1 110 __ jmp(slow_case_addr);
aoqi@1 111 __ delayed()->nop();
aoqi@1 112
aoqi@1 113 __ flush ();
aoqi@1 114
aoqi@1 115 return fast_entry;
aoqi@1 116 }
aoqi@1 117
aoqi@1 118 address JNI_FastGetField::generate_fast_get_boolean_field() {
aoqi@1 119 return generate_fast_get_int_field0(T_BOOLEAN);
aoqi@1 120 }
aoqi@1 121
aoqi@1 122 address JNI_FastGetField::generate_fast_get_byte_field() {
aoqi@1 123 return generate_fast_get_int_field0(T_BYTE);
aoqi@1 124 }
aoqi@1 125
aoqi@1 126 address JNI_FastGetField::generate_fast_get_char_field() {
aoqi@1 127 return generate_fast_get_int_field0(T_CHAR);
aoqi@1 128 }
aoqi@1 129
aoqi@1 130 address JNI_FastGetField::generate_fast_get_short_field() {
aoqi@1 131 return generate_fast_get_int_field0(T_SHORT);
aoqi@1 132 }
aoqi@1 133
aoqi@1 134 address JNI_FastGetField::generate_fast_get_int_field() {
aoqi@1 135 return generate_fast_get_int_field0(T_INT);
aoqi@1 136 }
aoqi@1 137
aoqi@1 138 address JNI_FastGetField::generate_fast_get_long_field() {
aoqi@1 139 return generate_fast_get_int_field0(T_LONG);
aoqi@1 140 /*
aoqi@1 141 const char *name = "jni_fast_GetLongField";
aoqi@1 142 ResourceMark rm;
aoqi@1 143 BufferBlob* b = BufferBlob::create(name, BUFFER_SIZE*wordSize);
aoqi@1 144 address fast_entry = b->instructions_begin();
aoqi@1 145 // CodeBuffer* cbuf = new CodeBuffer(fast_entry, b->instructions_size());
aoqi@1 146 CodeBuffer cbuf (fast_entry, b->instructions_size());
aoqi@1 147 MacroAssembler* masm = new MacroAssembler(&cbuf);
aoqi@1 148
aoqi@1 149 Label slow;
aoqi@1 150
aoqi@1 151 // return pc RA
aoqi@1 152 // jni env A0
aoqi@1 153 // obj A1
aoqi@1 154 // jfieldID A2
aoqi@1 155
aoqi@1 156 address counter_addr = SafepointSynchronize::safepoint_counter_addr();
aoqi@1 157 //__ move(AT, (int)counter_addr);
aoqi@1 158 //__ lw(T1, AT, 0);
aoqi@1 159 __ lui(AT, Assembler::split_high((intptr_t)counter_addr));
aoqi@1 160 __ lw(T1, AT, Assembler::split_low((intptr_t)counter_addr));
aoqi@1 161 __ andi(AT, T1, 1);
aoqi@1 162 __ bne(AT, R0, slow);
aoqi@1 163 __ delayed()->nop();
aoqi@1 164
aoqi@1 165 __ ld (A1, A1, 0); // unbox, *obj
aoqi@1 166 __ shr(A2, 2); // offset
aoqi@1 167 __ dadd(A1, A1, A2);
aoqi@1 168
aoqi@1 169 assert(count < LIST_CAPACITY-1, "LIST_CAPACITY too small");
aoqi@1 170 speculative_load_pclist[count++] = __ pc();
aoqi@1 171 __ ld(V0, A1, 0); // eax
aoqi@1 172 speculative_load_pclist[count] = __ pc();
aoqi@1 173 __ ld(V1, A1, 8);
aoqi@1 174
aoqi@1 175 __ lui(AT, Assembler::split_high((intptr_t)counter_addr));
aoqi@1 176 __ lw(AT, AT, Assembler::split_low((intptr_t)counter_addr));
aoqi@1 177 __ bne(T1, AT, slow);
aoqi@1 178 __ delayed()->nop();
aoqi@1 179
aoqi@1 180 __ jr(RA);
aoqi@1 181 __ delayed()->nop();
aoqi@1 182
aoqi@1 183 slowcase_entry_pclist[count-1] = __ pc();
aoqi@1 184 slowcase_entry_pclist[count++] = __ pc();
aoqi@1 185 __ bind (slow);
aoqi@1 186 address slow_case_addr = jni_GetLongField_addr();;
aoqi@1 187 // tail call
aoqi@1 188 __ jmp(slow_case_addr);
aoqi@1 189 __ delayed()->nop();
aoqi@1 190
aoqi@1 191 __ flush();
aoqi@1 192 return fast_entry;
aoqi@1 193 */
aoqi@1 194 }
aoqi@1 195
aoqi@1 196 address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
aoqi@1 197 const char *name;
aoqi@1 198 switch (type) {
aoqi@1 199 case T_FLOAT: name = "jni_fast_GetFloatField"; break;
aoqi@1 200 case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
aoqi@1 201 default: ShouldNotReachHere();
aoqi@1 202 }
aoqi@1 203 ResourceMark rm;
aoqi@1 204 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE);
aoqi@1 205 CodeBuffer cbuf(blob);
aoqi@1 206 MacroAssembler* masm = new MacroAssembler(&cbuf);
aoqi@1 207 address fast_entry = __ pc();
aoqi@1 208
aoqi@1 209 Label slow;
aoqi@1 210
aoqi@1 211 // return pc RA
aoqi@1 212 // jni env A0
aoqi@1 213 // obj A1
aoqi@1 214 // jfieldID A2
aoqi@1 215
aoqi@1 216 address counter_addr = SafepointSynchronize::safepoint_counter_addr();
aoqi@1 217 //__ move(AT, (int)counter_addr);
aoqi@1 218 //__ lw(T1, AT, 0);
aoqi@1 219 #ifdef _LP64
aoqi@1 220 __ li48(AT, (intptr_t)counter_addr);
aoqi@1 221 __ lw(T1, AT, 0);
aoqi@1 222 #else
aoqi@1 223 __ lui(AT, Assembler::split_high((intptr_t)counter_addr));
aoqi@1 224 __ lw(T1, AT, Assembler::split_low((intptr_t)counter_addr));
aoqi@1 225 #endif
aoqi@1 226 __ andi(AT, T1, 1);
aoqi@1 227 __ bne(AT, R0, slow);
aoqi@1 228 __ delayed()->nop();
aoqi@1 229
aoqi@1 230 #ifdef _LP64
aoqi@1 231 __ ld(A1, A1, 0); // unbox, *obj
aoqi@1 232 #else
aoqi@1 233 __ lw(A1, A1, 0); // unbox, *obj
aoqi@1 234 #endif
aoqi@1 235 __ shr(A2, 2); // offset
aoqi@1 236 __ add(A1, A1, A2);
aoqi@1 237
aoqi@1 238 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
aoqi@1 239 speculative_load_pclist[count] = __ pc();
aoqi@1 240 switch (type) {
aoqi@1 241 case T_FLOAT:
aoqi@1 242 __ lwc1(F0, A1, 0);
aoqi@1 243 break;
aoqi@1 244 case T_DOUBLE:
aoqi@1 245 #ifdef _LP64
aoqi@1 246 __ ldc1(F0, A1, 0);
aoqi@1 247 #else
aoqi@1 248 __ lwc1(F0, A1, 0);
aoqi@1 249 __ lwc1(F1, A1, 4);
aoqi@1 250 #endif
aoqi@1 251 break;
aoqi@1 252 default: ShouldNotReachHere();
aoqi@1 253 }
aoqi@1 254
aoqi@1 255 #ifdef _LP64
aoqi@1 256 __ li48(AT, (intptr_t)counter_addr);
aoqi@1 257 __ lw(AT, AT, 0);
aoqi@1 258 #else
aoqi@1 259 __ lui(AT, Assembler::split_high((intptr_t)counter_addr));
aoqi@1 260 __ lw(AT, AT, Assembler::split_low((intptr_t)counter_addr));
aoqi@1 261 #endif
aoqi@1 262 __ bne(T1, AT, slow);
aoqi@1 263 __ delayed()->nop();
aoqi@1 264
aoqi@1 265 __ jr(RA);
aoqi@1 266 __ delayed()->nop();
aoqi@1 267
aoqi@1 268
aoqi@1 269 slowcase_entry_pclist[count++] = __ pc();
aoqi@1 270 __ bind (slow);
aoqi@1 271 address slow_case_addr;
aoqi@1 272 switch (type) {
aoqi@1 273 case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;
aoqi@1 274 case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
aoqi@1 275 default: ShouldNotReachHere();
aoqi@1 276 }
aoqi@1 277 __ jmp(slow_case_addr);
aoqi@1 278 __ delayed()->nop();
aoqi@1 279
aoqi@1 280 __ flush ();
aoqi@1 281 return fast_entry;
aoqi@1 282 }
aoqi@1 283
aoqi@1 284 address JNI_FastGetField::generate_fast_get_float_field() {
aoqi@1 285 return generate_fast_get_float_field0(T_FLOAT);
aoqi@1 286 }
aoqi@1 287
aoqi@1 288 address JNI_FastGetField::generate_fast_get_double_field() {
aoqi@1 289 return generate_fast_get_float_field0(T_DOUBLE);
aoqi@1 290 }

mercurial