src/cpu/sparc/vm/jniFastGetField_sparc.cpp

Fri, 25 Mar 2011 09:35:39 +0100

author
roland
date
Fri, 25 Mar 2011 09:35:39 +0100
changeset 2683
7e88bdae86ec
parent 2314
f95d63e2154a
child 4323
f0c2369fda5a
permissions
-rw-r--r--

7029017: Additional architecture support for c2 compiler
Summary: Enables cross building of a c2 VM. Support masking of shift counts when the processor architecture mandates it.
Reviewed-by: kvn, never

duke@435 1 /*
twisti@2103 2 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #include "precompiled.hpp"
stefank@2314 26 #include "assembler_sparc.inline.hpp"
stefank@2314 27 #include "memory/resourceArea.hpp"
stefank@2314 28 #include "prims/jniFastGetField.hpp"
stefank@2314 29 #include "prims/jvm_misc.hpp"
stefank@2314 30 #include "runtime/safepoint.hpp"
duke@435 31
duke@435 32 // TSO ensures that loads are blocking and ordered with respect to
duke@435 33 // to earlier loads, so we don't need LoadLoad membars.
duke@435 34
duke@435 35 #define __ masm->
duke@435 36
duke@435 37 #define BUFFER_SIZE 30*sizeof(jint)
duke@435 38
duke@435 39 // Common register usage:
duke@435 40 // O0: env
duke@435 41 // O1: obj
duke@435 42 // O2: jfieldID
duke@435 43 // O4: offset (O2 >> 2)
duke@435 44 // G4: old safepoint counter
duke@435 45
duke@435 46 address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
duke@435 47 const char *name;
duke@435 48 switch (type) {
duke@435 49 case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
duke@435 50 case T_BYTE: name = "jni_fast_GetByteField"; break;
duke@435 51 case T_CHAR: name = "jni_fast_GetCharField"; break;
duke@435 52 case T_SHORT: name = "jni_fast_GetShortField"; break;
duke@435 53 case T_INT: name = "jni_fast_GetIntField"; break;
duke@435 54 default: ShouldNotReachHere();
duke@435 55 }
duke@435 56 ResourceMark rm;
twisti@2103 57 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
twisti@2103 58 CodeBuffer cbuf(blob);
duke@435 59 MacroAssembler* masm = new MacroAssembler(&cbuf);
twisti@2103 60 address fast_entry = __ pc();
duke@435 61
duke@435 62 Label label1, label2;
duke@435 63
twisti@1162 64 AddressLiteral cnt_addrlit(SafepointSynchronize::safepoint_counter_addr());
twisti@1162 65 __ sethi (cnt_addrlit, O3);
twisti@1162 66 Address cnt_addr(O3, cnt_addrlit.low10());
twisti@1162 67 __ ld (cnt_addr, G4);
duke@435 68 __ andcc (G4, 1, G0);
duke@435 69 __ br (Assembler::notZero, false, Assembler::pn, label1);
duke@435 70 __ delayed()->srl (O2, 2, O4);
duke@435 71 __ ld_ptr (O1, 0, O5);
duke@435 72
duke@435 73 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
duke@435 74 speculative_load_pclist[count] = __ pc();
duke@435 75 switch (type) {
duke@435 76 case T_BOOLEAN: __ ldub (O5, O4, G3); break;
duke@435 77 case T_BYTE: __ ldsb (O5, O4, G3); break;
duke@435 78 case T_CHAR: __ lduh (O5, O4, G3); break;
duke@435 79 case T_SHORT: __ ldsh (O5, O4, G3); break;
duke@435 80 case T_INT: __ ld (O5, O4, G3); break;
duke@435 81 default: ShouldNotReachHere();
duke@435 82 }
duke@435 83
twisti@1162 84 __ ld (cnt_addr, O5);
duke@435 85 __ cmp (O5, G4);
duke@435 86 __ br (Assembler::notEqual, false, Assembler::pn, label2);
duke@435 87 __ delayed()->mov (O7, G1);
duke@435 88 __ retl ();
duke@435 89 __ delayed()->mov (G3, O0);
duke@435 90
duke@435 91 slowcase_entry_pclist[count++] = __ pc();
duke@435 92 __ bind (label1);
duke@435 93 __ mov (O7, G1);
duke@435 94
duke@435 95 address slow_case_addr;
duke@435 96 switch (type) {
duke@435 97 case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
duke@435 98 case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;
duke@435 99 case T_CHAR: slow_case_addr = jni_GetCharField_addr(); break;
duke@435 100 case T_SHORT: slow_case_addr = jni_GetShortField_addr(); break;
duke@435 101 case T_INT: slow_case_addr = jni_GetIntField_addr(); break;
duke@435 102 default: ShouldNotReachHere();
duke@435 103 }
duke@435 104 __ bind (label2);
duke@435 105 __ call (slow_case_addr, relocInfo::none);
duke@435 106 __ delayed()->mov (G1, O7);
duke@435 107
duke@435 108 __ flush ();
duke@435 109
duke@435 110 return fast_entry;
duke@435 111 }
duke@435 112
duke@435 113 address JNI_FastGetField::generate_fast_get_boolean_field() {
duke@435 114 return generate_fast_get_int_field0(T_BOOLEAN);
duke@435 115 }
duke@435 116
duke@435 117 address JNI_FastGetField::generate_fast_get_byte_field() {
duke@435 118 return generate_fast_get_int_field0(T_BYTE);
duke@435 119 }
duke@435 120
duke@435 121 address JNI_FastGetField::generate_fast_get_char_field() {
duke@435 122 return generate_fast_get_int_field0(T_CHAR);
duke@435 123 }
duke@435 124
duke@435 125 address JNI_FastGetField::generate_fast_get_short_field() {
duke@435 126 return generate_fast_get_int_field0(T_SHORT);
duke@435 127 }
duke@435 128
duke@435 129 address JNI_FastGetField::generate_fast_get_int_field() {
duke@435 130 return generate_fast_get_int_field0(T_INT);
duke@435 131 }
duke@435 132
duke@435 133 address JNI_FastGetField::generate_fast_get_long_field() {
duke@435 134 const char *name = "jni_fast_GetLongField";
duke@435 135 ResourceMark rm;
twisti@2103 136 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
twisti@2103 137 CodeBuffer cbuf(blob);
duke@435 138 MacroAssembler* masm = new MacroAssembler(&cbuf);
twisti@2103 139 address fast_entry = __ pc();
duke@435 140
duke@435 141 Label label1, label2;
duke@435 142
twisti@1162 143 AddressLiteral cnt_addrlit(SafepointSynchronize::safepoint_counter_addr());
twisti@1162 144 __ sethi (cnt_addrlit, G3);
twisti@1162 145 Address cnt_addr(G3, cnt_addrlit.low10());
twisti@1162 146 __ ld (cnt_addr, G4);
duke@435 147 __ andcc (G4, 1, G0);
duke@435 148 __ br (Assembler::notZero, false, Assembler::pn, label1);
duke@435 149 __ delayed()->srl (O2, 2, O4);
duke@435 150 __ ld_ptr (O1, 0, O5);
duke@435 151 __ add (O5, O4, O5);
duke@435 152
duke@435 153 #ifndef _LP64
duke@435 154 assert(count < LIST_CAPACITY-1, "LIST_CAPACITY too small");
duke@435 155 speculative_load_pclist[count++] = __ pc();
duke@435 156 __ ld (O5, 0, G2);
duke@435 157
duke@435 158 speculative_load_pclist[count] = __ pc();
duke@435 159 __ ld (O5, 4, O3);
duke@435 160 #else
duke@435 161 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
duke@435 162 speculative_load_pclist[count] = __ pc();
duke@435 163 __ ldx (O5, 0, O3);
duke@435 164 #endif
duke@435 165
twisti@1162 166 __ ld (cnt_addr, G1);
duke@435 167 __ cmp (G1, G4);
duke@435 168 __ br (Assembler::notEqual, false, Assembler::pn, label2);
duke@435 169 __ delayed()->mov (O7, G1);
duke@435 170
duke@435 171 #ifndef _LP64
duke@435 172 __ mov (G2, O0);
duke@435 173 __ retl ();
duke@435 174 __ delayed()->mov (O3, O1);
duke@435 175 #else
duke@435 176 __ retl ();
duke@435 177 __ delayed()->mov (O3, O0);
duke@435 178 #endif
duke@435 179
duke@435 180 #ifndef _LP64
duke@435 181 slowcase_entry_pclist[count-1] = __ pc();
duke@435 182 slowcase_entry_pclist[count++] = __ pc() ;
duke@435 183 #else
duke@435 184 slowcase_entry_pclist[count++] = __ pc();
duke@435 185 #endif
duke@435 186
duke@435 187 __ bind (label1);
duke@435 188 __ mov (O7, G1);
duke@435 189
duke@435 190 address slow_case_addr = jni_GetLongField_addr();
duke@435 191 __ bind (label2);
duke@435 192 __ call (slow_case_addr, relocInfo::none);
duke@435 193 __ delayed()->mov (G1, O7);
duke@435 194
duke@435 195 __ flush ();
duke@435 196
duke@435 197 return fast_entry;
duke@435 198 }
duke@435 199
duke@435 200 address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
duke@435 201 const char *name;
duke@435 202 switch (type) {
duke@435 203 case T_FLOAT: name = "jni_fast_GetFloatField"; break;
duke@435 204 case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
duke@435 205 default: ShouldNotReachHere();
duke@435 206 }
duke@435 207 ResourceMark rm;
twisti@2103 208 BufferBlob* blob = BufferBlob::create(name, BUFFER_SIZE*wordSize);
twisti@2103 209 CodeBuffer cbuf(blob);
duke@435 210 MacroAssembler* masm = new MacroAssembler(&cbuf);
twisti@2103 211 address fast_entry = __ pc();
duke@435 212
duke@435 213 Label label1, label2;
duke@435 214
twisti@1162 215 AddressLiteral cnt_addrlit(SafepointSynchronize::safepoint_counter_addr());
twisti@1162 216 __ sethi (cnt_addrlit, O3);
twisti@1162 217 Address cnt_addr(O3, cnt_addrlit.low10());
twisti@1162 218 __ ld (cnt_addr, G4);
duke@435 219 __ andcc (G4, 1, G0);
duke@435 220 __ br (Assembler::notZero, false, Assembler::pn, label1);
duke@435 221 __ delayed()->srl (O2, 2, O4);
duke@435 222 __ ld_ptr (O1, 0, O5);
duke@435 223
duke@435 224 assert(count < LIST_CAPACITY, "LIST_CAPACITY too small");
duke@435 225 speculative_load_pclist[count] = __ pc();
duke@435 226 switch (type) {
duke@435 227 case T_FLOAT: __ ldf (FloatRegisterImpl::S, O5, O4, F0); break;
duke@435 228 case T_DOUBLE: __ ldf (FloatRegisterImpl::D, O5, O4, F0); break;
duke@435 229 default: ShouldNotReachHere();
duke@435 230 }
duke@435 231
twisti@1162 232 __ ld (cnt_addr, O5);
duke@435 233 __ cmp (O5, G4);
duke@435 234 __ br (Assembler::notEqual, false, Assembler::pn, label2);
duke@435 235 __ delayed()->mov (O7, G1);
duke@435 236
duke@435 237 __ retl ();
duke@435 238 __ delayed()-> nop ();
duke@435 239
duke@435 240 slowcase_entry_pclist[count++] = __ pc();
duke@435 241 __ bind (label1);
duke@435 242 __ mov (O7, G1);
duke@435 243
duke@435 244 address slow_case_addr;
duke@435 245 switch (type) {
duke@435 246 case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;
duke@435 247 case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
duke@435 248 default: ShouldNotReachHere();
duke@435 249 }
duke@435 250 __ bind (label2);
duke@435 251 __ call (slow_case_addr, relocInfo::none);
duke@435 252 __ delayed()->mov (G1, O7);
duke@435 253
duke@435 254 __ flush ();
duke@435 255
duke@435 256 return fast_entry;
duke@435 257 }
duke@435 258
duke@435 259 address JNI_FastGetField::generate_fast_get_float_field() {
duke@435 260 return generate_fast_get_float_field0(T_FLOAT);
duke@435 261 }
duke@435 262
duke@435 263 address JNI_FastGetField::generate_fast_get_double_field() {
duke@435 264 return generate_fast_get_float_field0(T_DOUBLE);
duke@435 265 }

mercurial