Tue, 10 Apr 2018 10:21:49 +0800
[Upgrade] jdk8u77-b03 --> jdk8u91-b15 (ztos support for MIPS)
1 /*
2 * Copyright (c) 2003, 2013, 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 #include "precompiled.hpp"
27 #include "asm/macroAssembler.hpp"
28 #include "interpreter/interpreter.hpp"
29 #include "interpreter/interpreterRuntime.hpp"
30 #include "interpreter/templateTable.hpp"
31 #include "memory/universe.inline.hpp"
32 #include "oops/methodData.hpp"
33 #include "oops/objArrayKlass.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "prims/methodHandles.hpp"
36 #include "runtime/sharedRuntime.hpp"
37 #include "runtime/stubRoutines.hpp"
38 #include "runtime/synchronizer.hpp"
41 #ifndef CC_INTERP
43 #define __ _masm->
45 // Platform-dependent initialization
47 void TemplateTable::pd_initialize() {
48 // No mips specific initialization
49 }
51 // Address computation: local variables
53 static inline Address iaddress(int n) {
54 return Address(LVP, Interpreter::local_offset_in_bytes(n));
55 }
57 static inline Address laddress(int n) {
58 return iaddress(n + 1);
59 }
61 static inline Address faddress(int n) {
62 return iaddress(n);
63 }
65 static inline Address daddress(int n) {
66 return laddress(n);
67 }
69 static inline Address aaddress(int n) {
70 return iaddress(n);
71 }
72 static inline Address haddress(int n) { return iaddress(n + 0); }
75 static inline Address at_sp() { return Address(SP, 0); }
76 static inline Address at_sp_p1() { return Address(SP, 1 * wordSize); }
77 static inline Address at_sp_p2() { return Address(SP, 2 * wordSize); }
79 // At top of Java expression stack which may be different than esp(). It
80 // isn't for category 1 objects.
81 static inline Address at_tos () {
82 Address tos = Address(SP, Interpreter::expr_offset_in_bytes(0));
83 return tos;
84 }
86 static inline Address at_tos_p1() {
87 return Address(SP, Interpreter::expr_offset_in_bytes(1));
88 }
90 static inline Address at_tos_p2() {
91 return Address(SP, Interpreter::expr_offset_in_bytes(2));
92 }
94 static inline Address at_tos_p3() {
95 return Address(SP, Interpreter::expr_offset_in_bytes(3));
96 }
98 // we use S0 as bcp, be sure you have bcp in S0 before you call any of the Template generator
99 Address TemplateTable::at_bcp(int offset) {
100 assert(_desc->uses_bcp(), "inconsistent uses_bcp information");
101 return Address(BCP, offset);
102 }
104 // Miscelaneous helper routines
105 // Store an oop (or NULL) at the address described by obj.
106 // If val == noreg this means store a NULL
108 // rdx --> T3
109 // rbx --> T1
110 // r8 --> T9
111 // r15 --> TREG
112 static void do_oop_store(InterpreterMacroAssembler* _masm,
113 Address obj,
114 Register val,
115 BarrierSet::Name barrier,
116 bool precise) {
117 assert(val == noreg || val == V0, "parameter is just for looks");
118 switch (barrier) {
119 #if INCLUDE_ALL_GCS
120 case BarrierSet::G1SATBCT:
121 case BarrierSet::G1SATBCTLogging:
122 {
123 // flatten object address if needed
124 if (obj.index() == noreg && obj.disp() == 0) {
125 if (obj.base() != T3) {
126 __ move(T3, obj.base());
127 }
128 } else {
129 __ lea(T3, obj);
130 }
131 __ g1_write_barrier_pre(T3 /* obj */,
132 T1 /* pre_val */,
133 TREG /* thread */,
134 T9 /* tmp */,
135 val != noreg /* tosca_live */,
136 false /* expand_call */);
137 if (val == noreg) {
138 __ store_heap_oop_null(Address(T3, 0));
139 } else {
140 // G1 barrier needs uncompressed oop for region cross check.
141 Register new_val = val;
142 if (UseCompressedOops) {
143 new_val = T1;
144 __ move(new_val, val);
145 }
146 __ store_heap_oop(Address(T3, 0), val);
147 __ g1_write_barrier_post(T3 /* store_adr */,
148 new_val /* new_val */,
149 TREG /* thread */,
150 T9 /* tmp */,
151 T1 /* tmp2 */);
152 }
153 }
154 break;
155 #endif // INCLUDE_ALL_GCS
156 case BarrierSet::CardTableModRef:
157 case BarrierSet::CardTableExtension:
158 {
159 if (val == noreg) {
160 __ store_heap_oop_null(obj);
161 } else {
162 __ store_heap_oop(obj, val);
163 // flatten object address if needed
164 if (!precise || (obj.index() == noreg && obj.disp() == 0)) {
165 __ store_check(obj.base());
166 } else {
167 __ lea(T9, obj);
168 __ store_check(T9);
169 }
170 }
171 }
172 break;
173 case BarrierSet::ModRef:
174 case BarrierSet::Other:
175 if (val == noreg) {
176 __ store_heap_oop_null(obj);
177 } else {
178 __ store_heap_oop(obj, val);
179 }
180 break;
181 default :
182 ShouldNotReachHere();
184 }
185 }
187 // bytecode folding
188 void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
189 Register tmp_reg, bool load_bc_into_bc_reg/*=true*/,
190 int byte_no) {
191 if (!RewriteBytecodes) return;
192 Label L_patch_done;
194 switch (bc) {
195 case Bytecodes::_fast_aputfield:
196 case Bytecodes::_fast_bputfield:
197 case Bytecodes::_fast_zputfield:
198 case Bytecodes::_fast_cputfield:
199 case Bytecodes::_fast_dputfield:
200 case Bytecodes::_fast_fputfield:
201 case Bytecodes::_fast_iputfield:
202 case Bytecodes::_fast_lputfield:
203 case Bytecodes::_fast_sputfield:
204 {
205 // We skip bytecode quickening for putfield instructions when
206 // the put_code written to the constant pool cache is zero.
207 // This is required so that every execution of this instruction
208 // calls out to InterpreterRuntime::resolve_get_put to do
209 // additional, required work.
210 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
211 assert(load_bc_into_bc_reg, "we use bc_reg as temp");
212 __ get_cache_and_index_and_bytecode_at_bcp(tmp_reg, bc_reg, tmp_reg, byte_no, 1);
213 __ daddi(bc_reg, R0, bc);
214 __ beq(tmp_reg, R0, L_patch_done);
215 __ delayed()->nop();
216 }
217 break;
218 default:
219 assert(byte_no == -1, "sanity");
220 // the pair bytecodes have already done the load.
221 if (load_bc_into_bc_reg) {
222 __ move(bc_reg, bc);
223 }
224 }
226 if (JvmtiExport::can_post_breakpoint()) {
227 Label L_fast_patch;
228 // if a breakpoint is present we can't rewrite the stream directly
229 __ lbu(tmp_reg, at_bcp(0));
230 __ move(AT, Bytecodes::_breakpoint);
231 __ bne(tmp_reg, AT, L_fast_patch);
232 __ delayed()->nop();
234 __ get_method(tmp_reg);
235 // Let breakpoint table handling rewrite to quicker bytecode
236 __ call_VM(NOREG, CAST_FROM_FN_PTR(address,
237 InterpreterRuntime::set_original_bytecode_at), tmp_reg, BCP, bc_reg);
239 __ b(L_patch_done);
240 __ delayed()->nop();
241 __ bind(L_fast_patch);
242 }
244 #ifdef ASSERT
245 Label L_okay;
246 __ lbu(tmp_reg, at_bcp(0));
247 __ move(AT, (int)Bytecodes::java_code(bc));
248 __ beq(tmp_reg, AT, L_okay);
249 __ delayed()->nop();
250 __ beq(tmp_reg, bc_reg, L_patch_done);
251 __ delayed()->nop();
252 __ stop("patching the wrong bytecode");
253 __ bind(L_okay);
254 #endif
256 // patch bytecode
257 __ sb(bc_reg, at_bcp(0));
258 __ bind(L_patch_done);
259 }
262 // Individual instructions
264 void TemplateTable::nop() {
265 transition(vtos, vtos);
266 // nothing to do
267 }
269 void TemplateTable::shouldnotreachhere() {
270 transition(vtos, vtos);
271 __ stop("shouldnotreachhere bytecode");
272 }
274 void TemplateTable::aconst_null() {
275 transition(vtos, atos);
276 __ move(FSR, R0);
277 }
279 void TemplateTable::iconst(int value) {
280 transition(vtos, itos);
281 if (value == 0) {
282 __ move(FSR, R0);
283 } else {
284 __ move(FSR, value);
285 }
286 }
288 void TemplateTable::lconst(int value) {
289 transition(vtos, ltos);
290 if (value == 0) {
291 __ move(FSR, R0);
292 } else {
293 __ move(FSR, value);
294 }
295 }
297 void TemplateTable::fconst(int value) {
298 transition(vtos, ftos);
299 switch( value ) {
300 case 0: __ mtc1(R0, FSF); return;
301 case 1: __ addiu(AT, R0, 1); break;
302 case 2: __ addiu(AT, R0, 2); break;
303 default: ShouldNotReachHere();
304 }
305 __ mtc1(AT, FSF);
306 __ cvt_s_w(FSF, FSF);
307 }
309 void TemplateTable::dconst(int value) {
310 transition(vtos, dtos);
311 switch( value ) {
312 case 0: __ dmtc1(R0, FSF);
313 return;
314 case 1: __ daddiu(AT, R0, 1);
315 __ dmtc1(AT, FSF);
316 __ cvt_d_w(FSF, FSF);
317 break;
318 default: ShouldNotReachHere();
319 }
320 }
322 void TemplateTable::bipush() {
323 transition(vtos, itos);
324 __ lb(FSR, at_bcp(1));
325 }
327 void TemplateTable::sipush() {
328 transition(vtos, itos);
329 __ lb(FSR, BCP, 1);
330 __ lbu(AT, BCP, 2);
331 __ dsll(FSR, FSR, 8);
332 __ orr(FSR, FSR, AT);
333 }
335 // T1 : tags
336 // T2 : index
337 // T3 : cpool
338 // T8 : tag
339 void TemplateTable::ldc(bool wide) {
340 transition(vtos, vtos);
341 Label call_ldc, notFloat, notClass, Done;
342 // get index in cpool
343 if (wide) {
344 __ get_unsigned_2_byte_index_at_bcp(T2, 1);
345 } else {
346 __ lbu(T2, at_bcp(1));
347 }
349 __ get_cpool_and_tags(T3, T1);
351 const int base_offset = ConstantPool::header_size() * wordSize;
352 const int tags_offset = Array<u1>::base_offset_in_bytes();
354 // get type
355 if (UseLoongsonISA && Assembler::is_simm(sizeof(tags_offset), 8)) {
356 __ gslbx(T1, T1, T2, tags_offset);
357 } else {
358 __ dadd(AT, T1, T2);
359 __ lb(T1, AT, tags_offset);
360 }
361 //now T1 is the tag
363 // unresolved class - get the resolved class
364 __ daddiu(AT, T1, - JVM_CONSTANT_UnresolvedClass);
365 __ beq(AT, R0, call_ldc);
366 __ delayed()->nop();
368 // unresolved class in error (resolution failed) - call into runtime
369 // so that the same error from first resolution attempt is thrown.
370 __ daddiu(AT, T1, -JVM_CONSTANT_UnresolvedClassInError);
371 __ beq(AT, R0, call_ldc);
372 __ delayed()->nop();
374 // resolved class - need to call vm to get java mirror of the class
375 __ daddiu(AT, T1, - JVM_CONSTANT_Class);
376 __ bne(AT, R0, notClass);
377 __ delayed()->dsll(T2, T2, Address::times_8);
379 __ bind(call_ldc);
380 __ move(A1, wide);
381 call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), A1);
382 //__ push(atos);
383 __ sd(FSR, SP, - Interpreter::stackElementSize);
384 __ b(Done);
385 __ delayed()->daddiu(SP, SP, - Interpreter::stackElementSize);
386 __ nop(); // added for performance issue
388 __ bind(notClass);
389 __ daddiu(AT, T1, -JVM_CONSTANT_Float);
390 __ bne(AT, R0, notFloat);
391 __ delayed()->nop();
392 // ftos
393 if (UseLoongsonISA && Assembler::is_simm(sizeof(base_offset), 8)) {
394 __ gslwxc1(FSF, T3, T2, base_offset);
395 } else {
396 __ dadd(AT, T3, T2);
397 __ lwc1(FSF, AT, base_offset);
398 }
399 //__ push_f();
400 __ swc1(FSF, SP, - Interpreter::stackElementSize);
401 __ b(Done);
402 __ delayed()->daddiu(SP, SP, - Interpreter::stackElementSize);
404 __ bind(notFloat);
405 #ifdef ASSERT
406 {
407 Label L;
408 __ daddiu(AT, T1, -JVM_CONSTANT_Integer);
409 __ beq(AT, R0, L);
410 __ delayed()->nop();
411 __ stop("unexpected tag type in ldc");
412 __ bind(L);
413 }
414 #endif
415 // itos JVM_CONSTANT_Integer only
416 if (UseLoongsonISA && Assembler::is_simm(sizeof(base_offset), 8)) {
417 __ gslwx(FSR, T3, T2, base_offset);
418 } else {
419 __ dadd(T0, T3, T2);
420 __ lw(FSR, T0, base_offset);
421 }
422 __ push(itos);
423 __ bind(Done);
424 }
426 // Fast path for caching oop constants.
427 void TemplateTable::fast_aldc(bool wide) {
428 transition(vtos, atos);
430 Register result = FSR;
431 Register tmp = SSR;
432 int index_size = wide ? sizeof(u2) : sizeof(u1);
434 Label resolved;
436 // We are resolved if the resolved reference cache entry contains a
437 // non-null object (String, MethodType, etc.)
438 assert_different_registers(result, tmp);
439 __ get_cache_index_at_bcp(tmp, 1, index_size);
440 __ load_resolved_reference_at_index(result, tmp);
441 __ bne(result, R0, resolved);
442 __ delayed()->nop();
444 address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);
445 // first time invocation - must resolve first
446 int i = (int)bytecode();
447 __ move(tmp, i);
448 __ call_VM(result, entry, tmp);
450 __ bind(resolved);
452 if (VerifyOops) {
453 __ verify_oop(result);
454 }
455 }
458 // used register: T2, T3, T1
459 // T2 : index
460 // T3 : cpool
461 // T1 : tag
462 void TemplateTable::ldc2_w() {
463 transition(vtos, vtos);
464 Label Long, Done;
466 // get index in cpool
467 __ get_unsigned_2_byte_index_at_bcp(T2, 1);
469 __ get_cpool_and_tags(T3, T1);
471 const int base_offset = ConstantPool::header_size() * wordSize;
472 const int tags_offset = Array<u1>::base_offset_in_bytes();
474 // get type in T1
475 if (UseLoongsonISA && Assembler::is_simm(tags_offset, 8)) {
476 __ gslbx(T1, T1, T2, tags_offset);
477 } else {
478 __ dadd(AT, T1, T2);
479 __ lb(T1, AT, tags_offset);
480 }
482 __ daddiu(AT, T1, - JVM_CONSTANT_Double);
483 __ bne(AT, R0, Long);
484 __ delayed()->dsll(T2, T2, Address::times_8);
486 // dtos
487 if (UseLoongsonISA && Assembler::is_simm(base_offset, 8)) {
488 __ gsldxc1(FSF, T3, T2, base_offset);
489 } else {
490 __ daddu(AT, T3, T2);
491 __ ldc1(FSF, AT, base_offset);
492 }
493 __ sdc1(FSF, SP, - 2 * wordSize);
494 __ b(Done);
495 __ delayed()->daddi(SP, SP, - 2 * wordSize);
497 // ltos
498 __ bind(Long);
499 if (UseLoongsonISA && Assembler::is_simm(base_offset, 8)) {
500 __ gsldx(FSR, T3, T2, base_offset);
501 } else {
502 __ dadd(AT, T3, T2);
503 __ ld(FSR, AT, base_offset);
504 }
505 __ push(ltos);
507 __ bind(Done);
508 }
510 // we compute the actual local variable address here
511 // the x86 dont do so for it has scaled index memory access model, we dont have, so do here
512 void TemplateTable::locals_index(Register reg, int offset) {
513 __ lbu(reg, at_bcp(offset));
514 __ dsll(reg, reg, Address::times_8);
515 __ dsub(reg, LVP, reg);
516 }
518 // this method will do bytecode folding of the two form:
519 // iload iload iload caload
520 // used register : T2, T3
521 // T2 : bytecode
522 // T3 : folded code
523 void TemplateTable::iload() {
524 transition(vtos, itos);
525 if (RewriteFrequentPairs) {
526 Label rewrite, done;
527 // get the next bytecode in T2
528 __ lbu(T2, at_bcp(Bytecodes::length_for(Bytecodes::_iload)));
529 // if _iload, wait to rewrite to iload2. We only want to rewrite the
530 // last two iloads in a pair. Comparing against fast_iload means that
531 // the next bytecode is neither an iload or a caload, and therefore
532 // an iload pair.
533 __ move(AT, Bytecodes::_iload);
534 __ beq(AT, T2, done);
535 __ delayed()->nop();
537 __ move(T3, Bytecodes::_fast_iload2);
538 __ move(AT, Bytecodes::_fast_iload);
539 __ beq(AT, T2, rewrite);
540 __ delayed()->nop();
542 // if _caload, rewrite to fast_icaload
543 __ move(T3, Bytecodes::_fast_icaload);
544 __ move(AT, Bytecodes::_caload);
545 __ beq(AT, T2, rewrite);
546 __ delayed()->nop();
548 // rewrite so iload doesn't check again.
549 __ move(T3, Bytecodes::_fast_iload);
551 // rewrite
552 // T3 : fast bytecode
553 __ bind(rewrite);
554 patch_bytecode(Bytecodes::_iload, T3, T2, false);
555 __ bind(done);
556 }
558 // Get the local value into tos
559 locals_index(T2);
560 __ lw(FSR, T2, 0);
561 }
563 // used register T2
564 // T2 : index
565 void TemplateTable::fast_iload2() {
566 transition(vtos, itos);
567 locals_index(T2);
568 __ lw(FSR, T2, 0);
569 __ push(itos);
570 locals_index(T2, 3);
571 __ lw(FSR, T2, 0);
572 }
574 // used register T2
575 // T2 : index
576 void TemplateTable::fast_iload() {
577 transition(vtos, itos);
578 locals_index(T2);
579 __ lw(FSR, T2, 0);
580 }
582 // used register T2
583 // T2 : index
584 void TemplateTable::lload() {
585 transition(vtos, ltos);
586 locals_index(T2);
587 __ ld(FSR, T2, -wordSize);
588 }
590 // used register T2
591 // T2 : index
592 void TemplateTable::fload() {
593 transition(vtos, ftos);
594 locals_index(T2);
595 __ lwc1(FSF, T2, 0);
596 }
598 // used register T2
599 // T2 : index
600 void TemplateTable::dload() {
601 transition(vtos, dtos);
602 locals_index(T2);
603 __ ldc1(FSF, T2, -wordSize);
604 }
606 // used register T2
607 // T2 : index
608 void TemplateTable::aload() {
609 transition(vtos, atos);
610 locals_index(T2);
611 __ ld(FSR, T2, 0);
612 }
614 void TemplateTable::locals_index_wide(Register reg) {
615 __ get_unsigned_2_byte_index_at_bcp(reg, 2);
616 __ dsll(reg, reg, Address::times_8);
617 __ dsub(reg, LVP, reg);
618 }
620 // used register T2
621 // T2 : index
622 void TemplateTable::wide_iload() {
623 transition(vtos, itos);
624 locals_index_wide(T2);
625 __ ld(FSR, T2, 0);
626 }
628 // used register T2
629 // T2 : index
630 void TemplateTable::wide_lload() {
631 transition(vtos, ltos);
632 locals_index_wide(T2);
633 __ ld(FSR, T2, -wordSize);
634 }
636 // used register T2
637 // T2 : index
638 void TemplateTable::wide_fload() {
639 transition(vtos, ftos);
640 locals_index_wide(T2);
641 __ lwc1(FSF, T2, 0);
642 }
644 // used register T2
645 // T2 : index
646 void TemplateTable::wide_dload() {
647 transition(vtos, dtos);
648 locals_index_wide(T2);
649 __ ldc1(FSF, T2, -wordSize);
650 }
652 // used register T2
653 // T2 : index
654 void TemplateTable::wide_aload() {
655 transition(vtos, atos);
656 locals_index_wide(T2);
657 __ ld(FSR, T2, 0);
658 }
660 // we use A2 as the regiser for index, BE CAREFUL!
661 // we dont use our tge 29 now, for later optimization
662 void TemplateTable::index_check(Register array, Register index) {
663 // Pop ptr into array
664 __ pop_ptr(array);
665 index_check_without_pop(array, index);
666 }
668 void TemplateTable::index_check_without_pop(Register array, Register index) {
669 // destroys ebx
670 // check array
671 __ null_check(array, arrayOopDesc::length_offset_in_bytes());
673 #ifdef _LP64
674 // sign extend since tos (index) might contain garbage in upper bits
675 __ sll(index, index, 0);
676 #endif // _LP64
678 // check index
679 Label ok;
680 __ lw(AT, array, arrayOopDesc::length_offset_in_bytes());
681 #ifndef OPT_RANGECHECK
682 __ sltu(AT, index, AT);
683 __ bne(AT, R0, ok);
684 __ delayed()->nop();
686 //throw_ArrayIndexOutOfBoundsException assume abberrant index in A2
687 if (A2 != index) __ move(A2, index);
688 __ jmp(Interpreter::_throw_ArrayIndexOutOfBoundsException_entry);
689 __ delayed()->nop();
690 __ bind(ok);
691 #else
692 __ lw(AT, array, arrayOopDesc::length_offset_in_bytes());
693 __ move(A2, index);
694 __ tgeu(A2, AT, 29);
695 #endif
696 }
698 void TemplateTable::iaload() {
699 transition(itos, itos);
700 if(UseBoundCheckInstruction) {
701 __ pop(SSR); //SSR:array FSR: index
702 __ dsll(FSR, FSR, 2);
703 __ dadd(FSR, SSR, FSR);
704 __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_INT));
706 __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes()); //bound
707 __ dsll(AT, AT, 2);
708 __ dadd(AT, SSR, AT);
709 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_INT));
711 __ gslwle(FSR, FSR, AT);
712 } else {
713 index_check(SSR, FSR);
714 __ dsll(FSR, FSR, 2);
715 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_INT), 8)) {
716 __ gslwx(FSR, FSR, SSR, arrayOopDesc::base_offset_in_bytes(T_INT));
717 } else {
718 __ dadd(FSR, SSR, FSR);
719 __ lw(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_INT));
720 }
721 }
722 }
724 void TemplateTable::laload() {
725 transition(itos, ltos);
726 if(UseBoundCheckInstruction) {
727 __ pop(SSR); //SSR:array FSR: index
728 __ dsll(FSR, FSR, Address::times_8);
729 __ dadd(FSR, SSR, FSR);
730 __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);
732 __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes()); //bound
733 __ dsll(AT, AT, Address::times_8);
734 __ dadd(AT, SSR, AT);
735 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);
737 __ gsldle(FSR, FSR, AT);
738 } else {
739 index_check(SSR, FSR);
740 __ dsll(AT, FSR, Address::times_8);
741 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_LONG), 8)) {
742 __ gsldx(FSR, SSR, AT, arrayOopDesc::base_offset_in_bytes(T_LONG));
743 } else {
744 __ dadd(AT, SSR, AT);
745 __ ld(FSR, AT, arrayOopDesc::base_offset_in_bytes(T_LONG));
746 }
747 }
748 }
750 void TemplateTable::faload() {
751 transition(itos, ftos);
752 if(UseBoundCheckInstruction) {
753 __ pop(SSR); //SSR:array FSR: index
754 __ shl(FSR, 2);
755 __ dadd(FSR, SSR, FSR);
756 __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
758 __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes()); //bound
759 __ shl(AT, 2);
760 __ dadd(AT, SSR, AT);
761 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
763 __ gslwlec1(FSF, FSR, AT);
764 } else {
765 index_check(SSR, FSR);
766 __ shl(FSR, 2);
767 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_FLOAT), 8)) {
768 __ gslwxc1(FSF, SSR, FSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
769 } else {
770 __ dadd(FSR, SSR, FSR);
771 __ lwc1(FSF, FSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
772 }
773 }
774 }
776 void TemplateTable::daload() {
777 transition(itos, dtos);
778 if(UseBoundCheckInstruction) {
779 __ pop(SSR); //SSR:array FSR: index
780 __ dsll(FSR, FSR, 3);
781 __ dadd(FSR, SSR, FSR);
782 __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);
784 __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes()); //bound
785 __ dsll(AT, AT, 3);
786 __ dadd(AT, SSR, AT);
787 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);
789 __ gsldlec1(FSF, FSR, AT);
790 } else {
791 index_check(SSR, FSR);
792 __ dsll(AT, FSR, 3);
793 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_DOUBLE), 8)) {
794 __ gsldxc1(FSF, SSR, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE));
795 } else {
796 __ dadd(AT, SSR, AT);
797 __ ldc1(FSF, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE));
798 }
799 }
800 }
802 void TemplateTable::aaload() {
803 transition(itos, atos);
804 index_check(SSR, FSR);
805 __ dsll(FSR, FSR, UseCompressedOops ? Address::times_4 : Address::times_8);
806 __ dadd(FSR, SSR, FSR);
807 //add for compressedoops
808 __ load_heap_oop(FSR, Address(FSR, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
809 }
811 void TemplateTable::baload() {
812 transition(itos, itos);
813 if(UseBoundCheckInstruction) {
814 __ pop(SSR); //SSR:array FSR:index
815 __ dadd(FSR, SSR, FSR);
816 __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_BYTE)); //base
818 __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes());
819 __ dadd(AT, SSR, AT);
820 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_BYTE)); //bound
822 __ gslble(FSR, FSR, AT);
823 } else {
824 index_check(SSR, FSR);
825 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_BYTE), 8)) {
826 __ gslbx(FSR, SSR, FSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
827 } else {
828 __ dadd(FSR, SSR, FSR);
829 __ lb(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
830 }
831 }
832 }
834 void TemplateTable::caload() {
835 transition(itos, itos);
836 index_check(SSR, FSR);
837 __ dsll(FSR, FSR, Address::times_2);
838 __ dadd(FSR, SSR, FSR);
839 __ lhu(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_CHAR));
840 }
842 // iload followed by caload frequent pair
843 // used register : T2
844 // T2 : index
845 void TemplateTable::fast_icaload() {
846 transition(vtos, itos);
847 // load index out of locals
848 locals_index(T2);
849 __ lw(FSR, T2, 0);
850 index_check(SSR, FSR);
851 __ dsll(FSR, FSR, 1);
852 __ dadd(FSR, SSR, FSR);
853 __ lhu(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_CHAR));
854 }
856 void TemplateTable::saload() {
857 transition(itos, itos);
858 if(UseBoundCheckInstruction) {
859 __ pop(SSR); //SSR:array FSR: index
860 __ dsll(FSR, FSR, Address::times_2);
861 __ dadd(FSR, SSR, FSR);
862 __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_SHORT));
864 __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes()); //bound
865 __ dsll(AT, AT, Address::times_2);
866 __ dadd(AT, SSR, AT);
867 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_SHORT));
869 __ gslhle(FSR, FSR, AT);
870 } else {
871 index_check(SSR, FSR);
872 __ dsll(FSR, FSR, Address::times_2);
873 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_SHORT), 8)) {
874 __ gslhx(FSR, SSR, FSR, arrayOopDesc::base_offset_in_bytes(T_SHORT));
875 } else {
876 __ dadd(FSR, SSR, FSR);
877 __ lh(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_SHORT));
878 }
879 }
880 }
882 void TemplateTable::iload(int n) {
883 transition(vtos, itos);
884 __ lw(FSR, iaddress(n));
885 }
887 void TemplateTable::lload(int n) {
888 transition(vtos, ltos);
889 __ ld(FSR, laddress(n));
890 }
892 void TemplateTable::fload(int n) {
893 transition(vtos, ftos);
894 __ lwc1(FSF, faddress(n));
895 }
897 void TemplateTable::dload(int n) {
898 transition(vtos, dtos);
899 __ ldc1(FSF, laddress(n));
900 }
902 void TemplateTable::aload(int n) {
903 transition(vtos, atos);
904 __ ld(FSR, aaddress(n));
905 }
907 // used register : T2, T3
908 // T2 : bytecode
909 // T3 : folded code
910 void TemplateTable::aload_0() {
911 transition(vtos, atos);
912 // According to bytecode histograms, the pairs:
913 //
914 // _aload_0, _fast_igetfield
915 // _aload_0, _fast_agetfield
916 // _aload_0, _fast_fgetfield
917 //
918 // occur frequently. If RewriteFrequentPairs is set, the (slow)
919 // _aload_0 bytecode checks if the next bytecode is either
920 // _fast_igetfield, _fast_agetfield or _fast_fgetfield and then
921 // rewrites the current bytecode into a pair bytecode; otherwise it
922 // rewrites the current bytecode into _fast_aload_0 that doesn't do
923 // the pair check anymore.
924 //
925 // Note: If the next bytecode is _getfield, the rewrite must be
926 // delayed, otherwise we may miss an opportunity for a pair.
927 //
928 // Also rewrite frequent pairs
929 // aload_0, aload_1
930 // aload_0, iload_1
931 // These bytecodes with a small amount of code are most profitable
932 // to rewrite
933 if (RewriteFrequentPairs) {
934 Label rewrite, done;
935 // get the next bytecode in T2
936 __ lbu(T2, at_bcp(Bytecodes::length_for(Bytecodes::_aload_0)));
938 // do actual aload_0
939 aload(0);
941 // if _getfield then wait with rewrite
942 __ move(AT, Bytecodes::_getfield);
943 __ beq(AT, T2, done);
944 __ delayed()->nop();
946 // if _igetfield then reqrite to _fast_iaccess_0
947 assert(Bytecodes::java_code(Bytecodes::_fast_iaccess_0) ==
948 Bytecodes::_aload_0,
949 "fix bytecode definition");
950 __ move(T3, Bytecodes::_fast_iaccess_0);
951 __ move(AT, Bytecodes::_fast_igetfield);
952 __ beq(AT, T2, rewrite);
953 __ delayed()->nop();
955 // if _agetfield then reqrite to _fast_aaccess_0
956 assert(Bytecodes::java_code(Bytecodes::_fast_aaccess_0) ==
957 Bytecodes::_aload_0,
958 "fix bytecode definition");
959 __ move(T3, Bytecodes::_fast_aaccess_0);
960 __ move(AT, Bytecodes::_fast_agetfield);
961 __ beq(AT, T2, rewrite);
962 __ delayed()->nop();
964 // if _fgetfield then reqrite to _fast_faccess_0
965 assert(Bytecodes::java_code(Bytecodes::_fast_faccess_0) ==
966 Bytecodes::_aload_0,
967 "fix bytecode definition");
968 __ move(T3, Bytecodes::_fast_faccess_0);
969 __ move(AT, Bytecodes::_fast_fgetfield);
970 __ beq(AT, T2, rewrite);
971 __ delayed()->nop();
973 // else rewrite to _fast_aload0
974 assert(Bytecodes::java_code(Bytecodes::_fast_aload_0) ==
975 Bytecodes::_aload_0,
976 "fix bytecode definition");
977 __ move(T3, Bytecodes::_fast_aload_0);
979 // rewrite
980 __ bind(rewrite);
981 patch_bytecode(Bytecodes::_aload_0, T3, T2, false);
983 __ bind(done);
984 } else {
985 aload(0);
986 }
987 }
989 void TemplateTable::istore() {
990 transition(itos, vtos);
991 locals_index(T2);
992 __ sw(FSR, T2, 0);
993 }
995 void TemplateTable::lstore() {
996 transition(ltos, vtos);
997 locals_index(T2);
998 __ sd(FSR, T2, -wordSize);
999 }
1001 void TemplateTable::fstore() {
1002 transition(ftos, vtos);
1003 locals_index(T2);
1004 __ swc1(FSF, T2, 0);
1005 }
1007 void TemplateTable::dstore() {
1008 transition(dtos, vtos);
1009 locals_index(T2);
1010 __ sdc1(FSF, T2, -wordSize);
1011 }
1013 void TemplateTable::astore() {
1014 transition(vtos, vtos);
1015 __ pop_ptr(FSR);
1016 locals_index(T2);
1017 __ sd(FSR, T2, 0);
1018 }
1020 void TemplateTable::wide_istore() {
1021 transition(vtos, vtos);
1022 __ pop_i(FSR);
1023 locals_index_wide(T2);
1024 __ sd(FSR, T2, 0);
1025 }
1027 void TemplateTable::wide_lstore() {
1028 transition(vtos, vtos);
1029 __ pop_l(FSR);
1030 locals_index_wide(T2);
1031 __ sd(FSR, T2, -wordSize);
1032 }
1034 void TemplateTable::wide_fstore() {
1035 wide_istore();
1036 }
1038 void TemplateTable::wide_dstore() {
1039 wide_lstore();
1040 }
1042 void TemplateTable::wide_astore() {
1043 transition(vtos, vtos);
1044 __ pop_ptr(FSR);
1045 locals_index_wide(T2);
1046 __ sd(FSR, T2, 0);
1047 }
1049 // used register : T2
1050 void TemplateTable::iastore() {
1051 transition(itos, vtos);
1052 __ pop_i(SSR); // T2: array SSR: index
1053 if(UseBoundCheckInstruction) {
1054 __ pop_ptr(T2);
1055 __ dsll(SSR, SSR, Address::times_4);
1056 __ dadd(SSR, T2, SSR);
1057 __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_INT)); // base
1059 __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());
1060 __ dsll(AT, AT, Address::times_4);
1061 __ dadd(AT, T2, AT);
1062 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_INT)); //bound
1064 __ gsswle(FSR, SSR, AT);
1065 } else {
1066 index_check(T2, SSR); // prefer index in ebx
1067 __ dsll(SSR, SSR, Address::times_4);
1068 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_INT), 8)) {
1069 __ gsswx(FSR, T2, SSR, arrayOopDesc::base_offset_in_bytes(T_INT));
1070 } else {
1071 __ dadd(T2, T2, SSR);
1072 __ sw(FSR, T2, arrayOopDesc::base_offset_in_bytes(T_INT));
1073 }
1074 }
1075 }
1079 // used register T2, T3
1080 void TemplateTable::lastore() {
1081 transition(ltos, vtos);
1082 __ pop_i (T2);
1083 if(UseBoundCheckInstruction) {
1084 __ pop_ptr(T3);
1085 __ dsll(T2, T2, Address::times_8);
1086 __ dadd(T2, T3, T2);
1087 __ addi(T2, T2, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize); // base
1089 __ lw(AT, T3, arrayOopDesc::length_offset_in_bytes());
1090 __ dsll(AT, AT, Address::times_8);
1091 __ dadd(AT, T3, AT);
1092 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize); //bound
1094 __ gssdle(FSR, T2, AT);
1095 } else {
1096 index_check(T3, T2);
1097 __ dsll(T2, T2, Address::times_8);
1098 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_LONG), 8)) {
1099 __ gssdx(FSR, T3, T2, arrayOopDesc::base_offset_in_bytes(T_LONG));
1100 } else {
1101 __ dadd(T3, T3, T2);
1102 __ sd(FSR, T3, arrayOopDesc::base_offset_in_bytes(T_LONG));
1103 }
1104 }
1105 }
1107 // used register T2
1108 void TemplateTable::fastore() {
1109 transition(ftos, vtos);
1110 __ pop_i(SSR);
1111 if(UseBoundCheckInstruction) {
1112 __ pop_ptr(T2);
1113 __ dsll(SSR, SSR, Address::times_4);
1114 __ dadd(SSR, T2, SSR);
1115 __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT)); // base
1117 __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());
1118 __ dsll(AT, AT, Address::times_4);
1119 __ dadd(AT, T2, AT);
1120 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_FLOAT)); //bound
1122 __ gsswlec1(FSF, SSR, AT);
1123 } else {
1124 index_check(T2, SSR);
1125 __ dsll(SSR, SSR, Address::times_4);
1126 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_FLOAT), 8)) {
1127 __ gsswxc1(FSF, T2, SSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
1128 } else {
1129 __ dadd(T2, T2, SSR);
1130 __ swc1(FSF, T2, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
1131 }
1132 }
1133 }
1135 // used register T2, T3
1136 void TemplateTable::dastore() {
1137 transition(dtos, vtos);
1138 __ pop_i (T2);
1139 if(UseBoundCheckInstruction) {
1140 __ pop_ptr(T3);
1141 __ dsll(T2, T2, Address::times_8);
1142 __ dadd(T2, T3, T2);
1143 __ addi(T2, T2, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize); // base
1145 __ lw(AT, T3, arrayOopDesc::length_offset_in_bytes());
1146 __ dsll(AT, AT, Address::times_8);
1147 __ dadd(AT, T3, AT);
1148 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize); //bound
1150 __ gssdlec1(FSF, T2, AT);
1151 } else {
1152 index_check(T3, T2);
1153 __ dsll(T2, T2, Address::times_8);
1154 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_DOUBLE), 8)) {
1155 __ gssdxc1(FSF, T3, T2, arrayOopDesc::base_offset_in_bytes(T_DOUBLE));
1156 } else {
1157 __ daddu(T3, T3, T2);
1158 __ sdc1(FSF, T3, arrayOopDesc::base_offset_in_bytes(T_DOUBLE));
1159 }
1160 }
1161 }
1163 // used register : T2, T3, T8
1164 // T2 : array
1165 // T3 : subklass
1166 // T8 : supklass
1167 void TemplateTable::aastore() {
1168 Label is_null, ok_is_subtype, done;
1169 transition(vtos, vtos);
1170 // stack: ..., array, index, value
1171 __ ld(FSR, at_tos()); // Value
1172 __ lw(SSR, at_tos_p1()); // Index
1173 __ ld(T2, at_tos_p2()); // Array
1175 // index_check(T2, SSR);
1176 index_check_without_pop(T2, SSR);
1177 // do array store check - check for NULL value first
1178 __ beq(FSR, R0, is_null);
1179 __ delayed()->nop();
1181 // Move subklass into T3
1182 //add for compressedoops
1183 __ load_klass(T3, FSR);
1184 // Move superklass into T8
1185 //add for compressedoops
1186 __ load_klass(T8, T2);
1187 __ ld(T8, Address(T8, ObjArrayKlass::element_klass_offset()));
1188 // Compress array+index*4+12 into a single register. T2
1189 __ dsll(AT, SSR, UseCompressedOops? Address::times_4 : Address::times_8);
1190 __ dadd(T2, T2, AT);
1191 __ daddi(T2, T2, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
1193 // Generate subtype check.
1194 // Superklass in T8. Subklass in T3.
1195 __ gen_subtype_check(T8, T3, ok_is_subtype);
1196 // Come here on failure
1197 // object is at FSR
1198 __ jmp(Interpreter::_throw_ArrayStoreException_entry);
1199 __ delayed()->nop();
1200 // Come here on success
1201 __ bind(ok_is_subtype);
1202 do_oop_store(_masm, Address(T2, 0), FSR, _bs->kind(), true);
1203 __ b(done);
1204 __ delayed()->nop();
1206 // Have a NULL in FSR, EDX=T2, SSR=index. Store NULL at ary[idx]
1207 __ bind(is_null);
1208 __ profile_null_seen(T9);
1209 __ dsll(AT, SSR, UseCompressedOops? Address::times_4 : Address::times_8);
1210 __ dadd(T2, T2, AT);
1211 do_oop_store(_masm, Address(T2, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), noreg, _bs->kind(), true);
1213 __ bind(done);
1214 __ daddi(SP, SP, 3 * Interpreter::stackElementSize);
1215 }
1217 void TemplateTable::bastore() {
1218 transition(itos, vtos);
1219 __ pop_i(SSR);
1220 if(UseBoundCheckInstruction) {
1221 guarantee(false, "unimplemented yet!");
1222 __ pop_ptr(T2);
1223 __ dadd(SSR, T2, SSR);
1224 __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // base
1226 __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());
1227 __ dadd(AT, T2, AT);
1228 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_BYTE)); //bound
1230 __ gssble(FSR, SSR, AT);
1231 } else {
1232 index_check(T2, SSR);
1234 // Need to check whether array is boolean or byte
1235 // since both types share the bastore bytecode.
1236 __ load_klass(T9, T2);
1237 __ lw(T9, T9, in_bytes(Klass::layout_helper_offset()));
1239 int diffbit = Klass::layout_helper_boolean_diffbit();
1240 __ move(AT, diffbit);
1242 Label L_skip;
1243 __ andr(AT, T9, AT);
1244 __ beq(AT, R0, L_skip);
1245 __ nop();
1246 __ andi(FSR, FSR, 0x1);
1247 __ bind(L_skip);
1249 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_BYTE), 8)) {
1250 __ gssbx(FSR, T2, SSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
1251 } else {
1252 __ dadd(SSR, T2, SSR);
1253 __ sb(FSR, SSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
1254 }
1255 }
1256 }
1258 void TemplateTable::castore() {
1259 transition(itos, vtos);
1260 __ pop_i(SSR);
1261 if(UseBoundCheckInstruction) {
1262 __ pop_ptr(T2);
1263 __ dsll(SSR, SSR, Address::times_2);
1264 __ dadd(SSR, T2, SSR);
1265 __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_CHAR)); // base
1267 __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());
1268 __ dsll(AT, AT, Address::times_2);
1269 __ dadd(AT, T2, AT);
1270 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_CHAR)); //bound
1272 __ gsshle(FSR, SSR, AT);
1273 } else {
1274 index_check(T2, SSR);
1275 __ dsll(SSR, SSR, Address::times_2);
1276 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_CHAR), 8)) {
1277 __ gsshx(FSR, T2, SSR, arrayOopDesc::base_offset_in_bytes(T_CHAR));
1278 } else {
1279 __ dadd(SSR, T2, SSR);
1280 __ sh(FSR, SSR, arrayOopDesc::base_offset_in_bytes(T_CHAR));
1281 }
1282 }
1283 }
1285 void TemplateTable::sastore() {
1286 castore();
1287 }
1289 void TemplateTable::istore(int n) {
1290 transition(itos, vtos);
1291 __ sw(FSR, iaddress(n));
1292 }
1294 void TemplateTable::lstore(int n) {
1295 transition(ltos, vtos);
1296 __ sd(FSR, laddress(n));
1297 }
1299 void TemplateTable::fstore(int n) {
1300 transition(ftos, vtos);
1301 __ swc1(FSF, faddress(n));
1302 }
1304 void TemplateTable::dstore(int n) {
1305 transition(dtos, vtos);
1306 __ sdc1(FSF, laddress(n));
1307 }
1309 void TemplateTable::astore(int n) {
1310 transition(vtos, vtos);
1311 __ pop_ptr(FSR);
1312 __ sd(FSR, aaddress(n));
1313 }
1315 void TemplateTable::pop() {
1316 transition(vtos, vtos);
1317 __ daddi(SP, SP, Interpreter::stackElementSize);
1318 }
1320 void TemplateTable::pop2() {
1321 transition(vtos, vtos);
1322 __ daddi(SP, SP, 2 * Interpreter::stackElementSize);
1323 }
1325 void TemplateTable::dup() {
1326 transition(vtos, vtos);
1327 // stack: ..., a
1328 __ load_ptr(0, FSR);
1329 __ push_ptr(FSR);
1330 // stack: ..., a, a
1331 }
1333 // blows FSR
1334 void TemplateTable::dup_x1() {
1335 transition(vtos, vtos);
1336 // stack: ..., a, b
1337 __ load_ptr(0, FSR); // load b
1338 __ load_ptr(1, A5); // load a
1339 __ store_ptr(1, FSR); // store b
1340 __ store_ptr(0, A5); // store a
1341 __ push_ptr(FSR); // push b
1342 // stack: ..., b, a, b
1343 }
1345 // blows FSR
1346 void TemplateTable::dup_x2() {
1347 transition(vtos, vtos);
1348 // stack: ..., a, b, c
1349 __ load_ptr(0, FSR); // load c
1350 __ load_ptr(2, A5); // load a
1351 __ store_ptr(2, FSR); // store c in a
1352 __ push_ptr(FSR); // push c
1353 // stack: ..., c, b, c, c
1354 __ load_ptr(2, FSR); // load b
1355 __ store_ptr(2, A5); // store a in b
1356 // stack: ..., c, a, c, c
1357 __ store_ptr(1, FSR); // store b in c
1358 // stack: ..., c, a, b, c
1359 }
1361 // blows FSR
1362 void TemplateTable::dup2() {
1363 transition(vtos, vtos);
1364 // stack: ..., a, b
1365 __ load_ptr(1, FSR); // load a
1366 __ push_ptr(FSR); // push a
1367 __ load_ptr(1, FSR); // load b
1368 __ push_ptr(FSR); // push b
1369 // stack: ..., a, b, a, b
1370 }
1372 // blows FSR
1373 void TemplateTable::dup2_x1() {
1374 transition(vtos, vtos);
1375 // stack: ..., a, b, c
1376 __ load_ptr(0, T2); // load c
1377 __ load_ptr(1, FSR); // load b
1378 __ push_ptr(FSR); // push b
1379 __ push_ptr(T2); // push c
1380 // stack: ..., a, b, c, b, c
1381 __ store_ptr(3, T2); // store c in b
1382 // stack: ..., a, c, c, b, c
1383 __ load_ptr(4, T2); // load a
1384 __ store_ptr(2, T2); // store a in 2nd c
1385 // stack: ..., a, c, a, b, c
1386 __ store_ptr(4, FSR); // store b in a
1387 // stack: ..., b, c, a, b, c
1389 // stack: ..., b, c, a, b, c
1390 }
1392 // blows FSR, SSR
1393 void TemplateTable::dup2_x2() {
1394 transition(vtos, vtos);
1395 // stack: ..., a, b, c, d
1396 // stack: ..., a, b, c, d
1397 __ load_ptr(0, T2); // load d
1398 __ load_ptr(1, FSR); // load c
1399 __ push_ptr(FSR); // push c
1400 __ push_ptr(T2); // push d
1401 // stack: ..., a, b, c, d, c, d
1402 __ load_ptr(4, FSR); // load b
1403 __ store_ptr(2, FSR); // store b in d
1404 __ store_ptr(4, T2); // store d in b
1405 // stack: ..., a, d, c, b, c, d
1406 __ load_ptr(5, T2); // load a
1407 __ load_ptr(3, FSR); // load c
1408 __ store_ptr(3, T2); // store a in c
1409 __ store_ptr(5, FSR); // store c in a
1410 // stack: ..., c, d, a, b, c, d
1412 // stack: ..., c, d, a, b, c, d
1413 }
1415 // blows FSR
1416 void TemplateTable::swap() {
1417 transition(vtos, vtos);
1418 // stack: ..., a, b
1420 __ load_ptr(1, A5); // load a
1421 __ load_ptr(0, FSR); // load b
1422 __ store_ptr(0, A5); // store a in b
1423 __ store_ptr(1, FSR); // store b in a
1425 // stack: ..., b, a
1426 }
1428 void TemplateTable::iop2(Operation op) {
1429 transition(itos, itos);
1431 __ pop_i(SSR);
1432 switch (op) {
1433 case add : __ addu32(FSR, SSR, FSR); break;
1434 case sub : __ subu32(FSR, SSR, FSR); break;
1435 case mul : __ mul(FSR, SSR, FSR); break;
1436 case _and : __ andr(FSR, SSR, FSR); break;
1437 case _or : __ orr(FSR, SSR, FSR); break;
1438 case _xor : __ xorr(FSR, SSR, FSR); break;
1439 case shl : __ sllv(FSR, SSR, FSR); break; // implicit masking of lower 5 bits by Intel shift instr. mips also
1440 case shr : __ srav(FSR, SSR, FSR); break; // implicit masking of lower 5 bits by Intel shift instr. mips also
1441 case ushr : __ srlv(FSR, SSR, FSR); break; // implicit masking of lower 5 bits by Intel shift instr. mips also
1442 default : ShouldNotReachHere();
1443 }
1444 }
1446 // the result stored in FSR, SSR,
1447 // used registers : T2, T3
1448 void TemplateTable::lop2(Operation op) {
1449 transition(ltos, ltos);
1450 __ pop_l(T2);
1452 switch (op) {
1453 case add : __ daddu(FSR, T2, FSR); break;
1454 case sub : __ dsubu(FSR, T2, FSR); break;
1455 case _and: __ andr(FSR, T2, FSR); break;
1456 case _or : __ orr(FSR, T2, FSR); break;
1457 case _xor: __ xorr(FSR, T2, FSR); break;
1458 default : ShouldNotReachHere();
1459 }
1460 }
1462 // java require this bytecode could handle 0x80000000/-1, dont cause a overflow exception,
1463 // the result is 0x80000000
1464 // the godson2 cpu do the same, so we need not handle this specially like x86
1465 void TemplateTable::idiv() {
1466 transition(itos, itos);
1467 Label not_zero;
1469 __ bne(FSR, R0, not_zero);
1470 __ delayed()->nop();
1471 __ jmp(Interpreter::_throw_ArithmeticException_entry);
1472 __ delayed()->nop();
1473 __ bind(not_zero);
1475 __ pop_i(SSR);
1476 if (UseLoongsonISA) {
1477 __ gsdiv(FSR, SSR, FSR);
1478 } else {
1479 __ div(SSR, FSR);
1480 __ mflo(FSR);
1481 }
1482 }
1484 void TemplateTable::irem() {
1485 transition(itos, itos);
1486 Label not_zero;
1487 __ pop_i(SSR);
1488 __ div(SSR, FSR);
1490 __ bne(FSR, R0, not_zero);
1491 __ delayed()->nop();
1492 //__ brk(7);
1493 __ jmp(Interpreter::_throw_ArithmeticException_entry);
1494 __ delayed()->nop();
1496 __ bind(not_zero);
1497 __ mfhi(FSR);
1498 }
1500 void TemplateTable::lmul() {
1501 transition(ltos, ltos);
1502 __ pop_l(T2);
1503 if(UseLoongsonISA){
1504 __ gsdmult(FSR, T2, FSR);
1505 } else {
1506 __ dmult(T2, FSR);
1507 __ mflo(FSR);
1508 }
1509 }
1511 // NOTE: i DONT use the Interpreter::_throw_ArithmeticException_entry
1512 void TemplateTable::ldiv() {
1513 transition(ltos, ltos);
1514 Label normal;
1516 __ bne(FSR, R0, normal);
1517 __ delayed()->nop();
1519 //__ brk(7); //generate FPE
1520 __ jmp(Interpreter::_throw_ArithmeticException_entry);
1521 __ delayed()->nop();
1523 __ bind(normal);
1524 __ pop_l(A2);
1525 if (UseLoongsonISA) {
1526 __ gsddiv(FSR, A2, FSR);
1527 } else {
1528 __ ddiv(A2, FSR);
1529 __ mflo(FSR);
1530 }
1531 }
1533 // NOTE: i DONT use the Interpreter::_throw_ArithmeticException_entry
1534 void TemplateTable::lrem() {
1535 transition(ltos, ltos);
1536 Label normal;
1538 __ bne(FSR, R0, normal);
1539 __ delayed()->nop();
1541 __ jmp(Interpreter::_throw_ArithmeticException_entry);
1542 __ delayed()->nop();
1544 __ bind(normal);
1545 __ pop_l (A2);
1547 if(UseLoongsonISA){
1548 __ gsdmod(FSR, A2, FSR);
1549 } else {
1550 __ ddiv(A2, FSR);
1551 __ mfhi(FSR);
1552 }
1553 }
1555 // result in FSR
1556 // used registers : T0
1557 void TemplateTable::lshl() {
1558 transition(itos, ltos);
1559 __ pop_l(T0);
1560 __ dsllv(FSR, T0, FSR);
1561 }
1563 // used registers : T0
1564 void TemplateTable::lshr() {
1565 transition(itos, ltos);
1566 __ pop_l(T0);
1567 __ dsrav(FSR, T0, FSR);
1568 }
1570 // used registers : T0
1571 void TemplateTable::lushr() {
1572 transition(itos, ltos);
1573 __ pop_l(T0);
1574 __ dsrlv(FSR, T0, FSR);
1575 }
1577 // result in FSF
1578 void TemplateTable::fop2(Operation op) {
1579 transition(ftos, ftos);
1580 switch (op) {
1581 case add:
1582 __ lwc1(FTF, at_sp());
1583 __ add_s(FSF, FTF, FSF);
1584 break;
1585 case sub:
1586 __ lwc1(FTF, at_sp());
1587 __ sub_s(FSF, FTF, FSF);
1588 break;
1589 case mul:
1590 __ lwc1(FTF, at_sp());
1591 __ mul_s(FSF, FTF, FSF);
1592 break;
1593 case div:
1594 __ lwc1(FTF, at_sp());
1595 __ div_s(FSF, FTF, FSF);
1596 break;
1597 case rem:
1598 __ mov_s(F13, FSF);
1599 __ lwc1(F12, at_sp());
1600 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::frem), 2);
1601 break;
1602 default : ShouldNotReachHere();
1603 }
1605 __ daddi(SP, SP, 1 * wordSize);
1606 }
1608 // result in SSF||FSF
1609 // i dont handle the strict flags
1610 void TemplateTable::dop2(Operation op) {
1611 transition(dtos, dtos);
1612 switch (op) {
1613 case add:
1614 __ ldc1(FTF, at_sp());
1615 __ add_d(FSF, FTF, FSF);
1616 break;
1617 case sub:
1618 __ ldc1(FTF, at_sp());
1619 __ sub_d(FSF, FTF, FSF);
1620 break;
1621 case mul:
1622 __ ldc1(FTF, at_sp());
1623 __ mul_d(FSF, FTF, FSF);
1624 break;
1625 case div:
1626 __ ldc1(FTF, at_sp());
1627 __ div_d(FSF, FTF, FSF);
1628 break;
1629 case rem:
1630 __ mov_d(F13, FSF);
1631 __ ldc1(F12, at_sp());
1632 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::drem), 2);
1633 break;
1634 default : ShouldNotReachHere();
1635 }
1637 __ daddi(SP, SP, 2 * wordSize);
1638 }
1640 void TemplateTable::ineg() {
1641 transition(itos, itos);
1642 __ subu32(FSR, R0, FSR);
1643 }
1645 void TemplateTable::lneg() {
1646 transition(ltos, ltos);
1647 __ dsubu(FSR, R0, FSR);
1648 }
1650 void TemplateTable::fneg() {
1651 transition(ftos, ftos);
1652 __ neg_s(FSF, FSF);
1653 }
1655 void TemplateTable::dneg() {
1656 transition(dtos, dtos);
1657 __ neg_d(FSF, FSF);
1658 }
1660 // used registers : T2
1661 void TemplateTable::iinc() {
1662 transition(vtos, vtos);
1663 locals_index(T2);
1664 __ lw(FSR, T2, 0);
1665 __ lb(AT, at_bcp(2)); // get constant
1666 __ daddu(FSR, FSR, AT);
1667 __ sw(FSR, T2, 0);
1668 }
1670 // used register : T2
1671 void TemplateTable::wide_iinc() {
1672 transition(vtos, vtos);
1673 locals_index_wide(T2);
1674 __ get_2_byte_integer_at_bcp(FSR, AT, 4);
1675 __ hswap(FSR);
1676 __ lw(AT, T2, 0);
1677 __ daddu(FSR, AT, FSR);
1678 __ sw(FSR, T2, 0);
1679 }
1681 void TemplateTable::convert() {
1682 // Checking
1683 #ifdef ASSERT
1684 {
1685 TosState tos_in = ilgl;
1686 TosState tos_out = ilgl;
1687 switch (bytecode()) {
1688 case Bytecodes::_i2l: // fall through
1689 case Bytecodes::_i2f: // fall through
1690 case Bytecodes::_i2d: // fall through
1691 case Bytecodes::_i2b: // fall through
1692 case Bytecodes::_i2c: // fall through
1693 case Bytecodes::_i2s: tos_in = itos; break;
1694 case Bytecodes::_l2i: // fall through
1695 case Bytecodes::_l2f: // fall through
1696 case Bytecodes::_l2d: tos_in = ltos; break;
1697 case Bytecodes::_f2i: // fall through
1698 case Bytecodes::_f2l: // fall through
1699 case Bytecodes::_f2d: tos_in = ftos; break;
1700 case Bytecodes::_d2i: // fall through
1701 case Bytecodes::_d2l: // fall through
1702 case Bytecodes::_d2f: tos_in = dtos; break;
1703 default : ShouldNotReachHere();
1704 }
1705 switch (bytecode()) {
1706 case Bytecodes::_l2i: // fall through
1707 case Bytecodes::_f2i: // fall through
1708 case Bytecodes::_d2i: // fall through
1709 case Bytecodes::_i2b: // fall through
1710 case Bytecodes::_i2c: // fall through
1711 case Bytecodes::_i2s: tos_out = itos; break;
1712 case Bytecodes::_i2l: // fall through
1713 case Bytecodes::_f2l: // fall through
1714 case Bytecodes::_d2l: tos_out = ltos; break;
1715 case Bytecodes::_i2f: // fall through
1716 case Bytecodes::_l2f: // fall through
1717 case Bytecodes::_d2f: tos_out = ftos; break;
1718 case Bytecodes::_i2d: // fall through
1719 case Bytecodes::_l2d: // fall through
1720 case Bytecodes::_f2d: tos_out = dtos; break;
1721 default : ShouldNotReachHere();
1722 }
1723 transition(tos_in, tos_out);
1724 }
1725 #endif // ASSERT
1727 // Conversion
1728 // (Note: use pushl(ecx)/popl(ecx) for 1/2-word stack-ptr manipulation)
1729 switch (bytecode()) {
1730 case Bytecodes::_i2l:
1731 __ sll(FSR, FSR, 0);
1732 break;
1733 case Bytecodes::_i2f:
1734 __ mtc1(FSR, FSF);
1735 __ cvt_s_w(FSF, FSF);
1736 break;
1737 case Bytecodes::_i2d:
1738 __ mtc1(FSR, FSF);
1739 __ cvt_d_w(FSF, FSF);
1740 break;
1741 case Bytecodes::_i2b:
1742 __ seb(FSR, FSR);
1743 break;
1744 case Bytecodes::_i2c:
1745 __ andi(FSR, FSR, 0xFFFF); // truncate upper 56 bits
1746 break;
1747 case Bytecodes::_i2s:
1748 __ seh(FSR, FSR);
1749 break;
1750 case Bytecodes::_l2i:
1751 __ sll(FSR, FSR, 0);
1752 break;
1753 case Bytecodes::_l2f:
1754 __ dmtc1(FSR, FSF);
1755 __ cvt_s_l(FSF, FSF);
1756 break;
1757 case Bytecodes::_l2d:
1758 __ dmtc1(FSR, FSF);
1759 __ cvt_d_l(FSF, FSF);
1760 break;
1761 case Bytecodes::_f2i:
1762 {
1763 Label L;
1765 __ trunc_w_s(F12, FSF);
1766 __ move(AT, 0x7fffffff);
1767 __ mfc1(FSR, F12);
1768 __ c_un_s(FSF, FSF); //NaN?
1769 __ movt(FSR, R0);
1771 __ bne(AT, FSR, L);
1772 __ delayed()->lui(T9, 0x8000);
1774 __ mfc1(AT, FSF);
1775 __ andr(AT, AT, T9);
1777 __ movn(FSR, T9, AT);
1779 __ bind(L);
1780 }
1781 break;
1782 case Bytecodes::_f2l:
1783 {
1784 Label L;
1786 __ trunc_l_s(F12, FSF);
1787 __ daddiu(AT, R0, -1);
1788 __ dsrl(AT, AT, 1);
1789 __ dmfc1(FSR, F12);
1790 __ c_un_s(FSF, FSF); //NaN?
1791 __ movt(FSR, R0);
1793 __ bne(AT, FSR, L);
1794 __ delayed()->lui(T9, 0x8000);
1796 __ mfc1(AT, FSF);
1797 __ andr(AT, AT, T9);
1799 __ dsll32(T9, T9, 0);
1800 __ movn(FSR, T9, AT);
1802 __ bind(L);
1803 }
1804 break;
1805 case Bytecodes::_f2d:
1806 __ cvt_d_s(FSF, FSF);
1807 break;
1808 case Bytecodes::_d2i:
1809 {
1810 Label L;
1812 __ trunc_w_d(F12, FSF);
1813 __ move(AT, 0x7fffffff);
1814 __ mfc1(FSR, F12);
1816 __ bne(FSR, AT, L);
1817 __ delayed()->mtc1(R0, F12);
1819 __ cvt_d_w(F12, F12);
1820 __ c_ult_d(FSF, F12);
1821 __ bc1f(L);
1822 __ delayed()->addiu(T9, R0, -1);
1824 __ c_un_d(FSF, FSF); //NaN?
1825 __ subu32(FSR, T9, AT);
1826 __ movt(FSR, R0);
1828 __ bind(L);
1829 }
1830 break;
1831 case Bytecodes::_d2l:
1832 {
1833 Label L;
1835 __ trunc_l_d(F12, FSF);
1836 __ daddiu(AT, R0, -1);
1837 __ dsrl(AT, AT, 1);
1838 __ dmfc1(FSR, F12);
1840 __ bne(FSR, AT, L);
1841 __ delayed()->mtc1(R0, F12);
1843 __ cvt_d_w(F12, F12);
1844 __ c_ult_d(FSF, F12);
1845 __ bc1f(L);
1846 __ delayed()->daddiu(T9, R0, -1);
1848 __ c_un_d(FSF, FSF); //NaN?
1849 __ subu(FSR, T9, AT);
1850 __ movt(FSR, R0);
1852 __ bind(L);
1853 }
1854 break;
1855 case Bytecodes::_d2f:
1856 __ cvt_s_d(FSF, FSF);
1857 break;
1858 default :
1859 ShouldNotReachHere();
1860 }
1861 }
1863 void TemplateTable::lcmp() {
1864 transition(ltos, itos);
1866 Label low, high, done;
1867 __ pop(T0);
1868 __ pop(R0);
1869 __ slt(AT, T0, FSR);
1870 __ bne(AT, R0, low);
1871 __ delayed()->nop();
1873 __ bne(T0, FSR, high);
1874 __ delayed()->nop();
1876 __ li(FSR, (long)0);
1877 __ b(done);
1878 __ delayed()->nop();
1880 __ bind(low);
1881 __ li(FSR, (long)-1);
1882 __ b(done);
1883 __ delayed()->nop();
1885 __ bind(high);
1886 __ li(FSR, (long)1);
1887 __ b(done);
1888 __ delayed()->nop();
1890 __ bind(done);
1891 }
1893 void TemplateTable::float_cmp(bool is_float, int unordered_result) {
1894 Label less, done;
1896 __ move(FSR, R0);
1898 if (is_float) {
1899 __ lwc1(FTF, at_sp());
1900 __ c_eq_s(FTF, FSF);
1901 __ bc1t(done);
1902 __ delayed()->daddi(SP, SP, 1 * wordSize);
1904 if (unordered_result<0)
1905 __ c_ult_s(FTF, FSF);
1906 else
1907 __ c_olt_s(FTF, FSF);
1908 } else {
1909 __ ldc1(FTF, at_sp());
1910 __ c_eq_d(FTF, FSF);
1911 __ bc1t(done);
1912 __ delayed()->daddi(SP, SP, 2 * wordSize);
1914 if (unordered_result<0)
1915 __ c_ult_d(FTF, FSF);
1916 else
1917 __ c_olt_d(FTF, FSF);
1918 }
1919 __ bc1t(less);
1920 __ delayed()->nop();
1921 __ move(FSR, 1);
1922 __ b(done);
1923 __ delayed()->nop();
1924 __ bind(less);
1925 __ move(FSR, -1);
1926 __ bind(done);
1927 }
1930 // used registers : T3, A7, Rnext
1931 // FSR : return bci, this is defined by the vm specification
1932 // T2 : MDO taken count
1933 // T3 : method
1934 // A7 : offset
1935 // Rnext : next bytecode, this is required by dispatch_base
1936 void TemplateTable::branch(bool is_jsr, bool is_wide) {
1937 __ get_method(T3);
1938 __ profile_taken_branch(A7, T2); // only C2 meaningful
1940 #ifndef CORE
1941 const ByteSize be_offset = MethodCounters::backedge_counter_offset() +
1942 InvocationCounter::counter_offset();
1943 const ByteSize inv_offset = MethodCounters::invocation_counter_offset() +
1944 InvocationCounter::counter_offset();
1945 #endif // CORE
1947 // Load up T4 with the branch displacement
1948 if (!is_wide) {
1949 __ lb(A7, BCP, 1);
1950 __ lbu(AT, BCP, 2);
1951 __ dsll(A7, A7, 8);
1952 __ orr(A7, A7, AT);
1953 } else {
1954 __ get_4_byte_integer_at_bcp(A7, AT, 1);
1955 __ swap(A7);
1956 }
1958 // Handle all the JSR stuff here, then exit.
1959 // It's much shorter and cleaner than intermingling with the non-JSR
1960 // normal-branch stuff occuring below.
1961 if (is_jsr) {
1962 // Pre-load the next target bytecode into Rnext
1963 __ dadd(AT, BCP, A7);
1964 __ lbu(Rnext, AT, 0);
1966 // compute return address as bci in FSR
1967 __ daddi(FSR, BCP, (is_wide?5:3) - in_bytes(ConstMethod::codes_offset()));
1968 __ ld(AT, T3, in_bytes(Method::const_offset()));
1969 __ dsub(FSR, FSR, AT);
1970 // Adjust the bcp in BCP by the displacement in A7
1971 __ dadd(BCP, BCP, A7);
1972 // jsr returns atos that is not an oop
1973 // Push return address
1974 __ push_i(FSR);
1975 // jsr returns vtos
1976 __ dispatch_only_noverify(vtos);
1978 return;
1979 }
1981 // Normal (non-jsr) branch handling
1983 // Adjust the bcp in S0 by the displacement in T4
1984 __ dadd(BCP, BCP, A7);
1986 #ifdef CORE
1987 // Pre-load the next target bytecode into EBX
1988 __ lbu(Rnext, BCP, 0);
1989 // continue with the bytecode @ target
1990 __ dispatch_only(vtos);
1991 #else
1992 assert(UseLoopCounter || !UseOnStackReplacement, "on-stack-replacement requires loop counters");
1993 Label backedge_counter_overflow;
1994 Label profile_method;
1995 Label dispatch;
1996 if (UseLoopCounter) {
1997 // increment backedge counter for backward branches
1998 // eax: MDO
1999 // ebx: MDO bumped taken-count
2000 // T3: method
2001 // T4: target offset
2002 // BCP: target bcp
2003 // LVP: locals pointer
2004 __ bgtz(A7, dispatch); // check if forward or backward branch
2005 __ delayed()->nop();
2007 // check if MethodCounters exists
2008 Label has_counters;
2009 __ ld(AT, T3, in_bytes(Method::method_counters_offset())); // use AT as MDO, TEMP
2010 __ bne(AT, R0, has_counters);
2011 __ nop();
2012 __ push(T3);
2013 //__ push(A7);
2014 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::build_method_counters),
2015 T3);
2016 //__ pop(A7);
2017 __ pop(T3);
2018 __ ld(AT, T3, in_bytes(Method::method_counters_offset())); // use AT as MDO, TEMP
2019 __ beq(AT, R0, dispatch);
2020 __ nop();
2021 __ bind(has_counters);
2023 // increment back edge counter
2024 __ ld(T1, T3, in_bytes(Method::method_counters_offset()));
2025 __ lw(T0, T1, in_bytes(be_offset));
2026 __ increment(T0, InvocationCounter::count_increment);
2027 __ sw(T0, T1, in_bytes(be_offset));
2029 // load invocation counter
2030 __ lw(T1, T1, in_bytes(inv_offset));
2031 // buffer bit added, mask no needed
2033 // dadd backedge counter & invocation counter
2034 __ dadd(T1, T1, T0);
2036 if (ProfileInterpreter) {
2037 // Test to see if we should create a method data oop
2038 // T1 : backedge counter & invocation counter
2039 if (Assembler::is_simm16(InvocationCounter::InterpreterProfileLimit)) {
2040 __ slti(AT, T1, InvocationCounter::InterpreterProfileLimit);
2041 } else {
2042 __ li(AT, (long)&InvocationCounter::InterpreterProfileLimit);
2043 __ lw(AT, AT, 0);
2044 __ slt(AT, T1, AT);
2045 }
2047 __ bne(AT, R0, dispatch);
2048 __ delayed()->nop();
2050 // if no method data exists, go to profile method
2051 __ test_method_data_pointer(T1, profile_method);
2053 if (UseOnStackReplacement) {
2054 if (Assembler::is_simm16(InvocationCounter::InterpreterBackwardBranchLimit)) {
2055 __ slti(AT, T2, InvocationCounter::InterpreterBackwardBranchLimit);
2056 } else {
2057 __ li(AT, (long)&InvocationCounter::InterpreterBackwardBranchLimit);
2058 __ lw(AT, AT, 0);
2059 __ slt(AT, T2, AT);
2060 }
2062 __ bne(AT, R0, dispatch);
2063 __ delayed()->nop();
2065 // When ProfileInterpreter is on, the backedge_count comes
2066 // from the methodDataOop, which value does not get reset on
2067 // the call to frequency_counter_overflow().
2068 // To avoid excessive calls to the overflow routine while
2069 // the method is being compiled, dadd a second test to make
2070 // sure the overflow function is called only once every
2071 // overflow_frequency.
2072 const int overflow_frequency = 1024;
2073 __ andi(AT, T2, overflow_frequency-1);
2074 __ beq(AT, R0, backedge_counter_overflow);
2075 __ delayed()->nop();
2076 }
2077 } else {
2078 if (UseOnStackReplacement) {
2079 // check for overflow against eax, which is the sum of the counters
2080 __ li(AT, (long)&InvocationCounter::InterpreterBackwardBranchLimit);
2081 __ lw(AT, AT, 0);
2082 __ slt(AT, T1, AT);
2083 __ beq(AT, R0, backedge_counter_overflow);
2084 __ delayed()->nop();
2085 }
2086 }
2087 __ bind(dispatch);
2088 }
2090 // Pre-load the next target bytecode into Rnext
2091 __ lbu(Rnext, BCP, 0);
2093 // continue with the bytecode @ target
2094 // FSR: return bci for jsr's, unused otherwise
2095 // Rnext: target bytecode
2096 // BCP: target bcp
2097 __ dispatch_only(vtos);
2099 if (UseLoopCounter) {
2100 if (ProfileInterpreter) {
2101 // Out-of-line code to allocate method data oop.
2102 __ bind(profile_method);
2103 __ call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
2104 __ lbu(Rnext, BCP, 0);
2105 __ set_method_data_pointer_for_bcp();
2106 __ b(dispatch);
2107 __ delayed()->nop();
2108 }
2110 if (UseOnStackReplacement) {
2111 // invocation counter overflow
2112 __ bind(backedge_counter_overflow);
2113 __ sub(A7, BCP, A7); // branch bcp
2114 call_VM(NOREG, CAST_FROM_FN_PTR(address,
2115 InterpreterRuntime::frequency_counter_overflow), A7);
2116 __ lbu(Rnext, BCP, 0);
2118 // V0: osr nmethod (osr ok) or NULL (osr not possible)
2119 // V1: osr adapter frame return address
2120 // Rnext: target bytecode
2121 // LVP: locals pointer
2122 // BCP: bcp
2123 __ beq(V0, R0, dispatch);
2124 __ delayed()->nop();
2125 // nmethod may have been invalidated (VM may block upon call_VM return)
2126 __ lw(T3, V0, nmethod::entry_bci_offset());
2127 __ move(AT, InvalidOSREntryBci);
2128 __ beq(AT, T3, dispatch);
2129 __ delayed()->nop();
2130 // We need to prepare to execute the OSR method. First we must
2131 // migrate the locals and monitors off of the stack.
2132 //eax V0: osr nmethod (osr ok) or NULL (osr not possible)
2133 //ebx V1: osr adapter frame return address
2134 //edx Rnext: target bytecode
2135 //edi LVP: locals pointer
2136 //esi BCP: bcp
2137 __ move(BCP, V0);
2138 // const Register thread = ecx;
2139 const Register thread = TREG;
2140 #ifndef OPT_THREAD
2141 __ get_thread(thread);
2142 #endif
2143 call_VM(noreg, CAST_FROM_FN_PTR(address,
2144 SharedRuntime::OSR_migration_begin));
2145 // eax is OSR buffer, move it to expected parameter location
2146 //refer to osrBufferPointer in c1_LIRAssembler_mips.cpp
2147 __ move(T0, V0);
2149 // pop the interpreter frame
2150 __ ld(A7, Address(FP, frame::interpreter_frame_sender_sp_offset * wordSize));
2151 //FIXME, shall we keep the return address on the stack?
2152 __ leave(); // remove frame anchor
2153 __ move(LVP, RA);
2154 __ move(SP, A7);
2156 __ move(AT, -(StackAlignmentInBytes));
2157 __ andr(SP , SP , AT);
2159 // push the (possibly adjusted) return address
2160 //refer to osr_entry in c1_LIRAssembler_mips.cpp
2161 __ ld(AT, BCP, nmethod::osr_entry_point_offset());
2162 __ jr(AT);
2163 __ delayed()->nop();
2164 }
2165 }
2166 #endif // not CORE
2167 }
2170 void TemplateTable::if_0cmp(Condition cc) {
2171 transition(itos, vtos);
2172 // assume branch is more often taken than not (loops use backward branches)
2173 Label not_taken;
2174 switch(cc) {
2175 case not_equal:
2176 __ beq(FSR, R0, not_taken);
2177 break;
2178 case equal:
2179 __ bne(FSR, R0, not_taken);
2180 break;
2181 case less:
2182 __ bgez(FSR, not_taken);
2183 break;
2184 case less_equal:
2185 __ bgtz(FSR, not_taken);
2186 break;
2187 case greater:
2188 __ blez(FSR, not_taken);
2189 break;
2190 case greater_equal:
2191 __ bltz(FSR, not_taken);
2192 break;
2193 }
2194 __ delayed()->nop();
2196 branch(false, false);
2198 __ bind(not_taken);
2199 __ profile_not_taken_branch(FSR);
2200 }
2202 void TemplateTable::if_icmp(Condition cc) {
2203 transition(itos, vtos);
2204 // assume branch is more often taken than not (loops use backward branches)
2205 Label not_taken;
2207 __ pop_i(SSR);
2208 switch(cc) {
2209 case not_equal:
2210 __ beq(SSR, FSR, not_taken);
2211 break;
2212 case equal:
2213 __ bne(SSR, FSR, not_taken);
2214 break;
2215 case less:
2216 __ slt(AT, SSR, FSR);
2217 __ beq(AT, R0, not_taken);
2218 break;
2219 case less_equal:
2220 __ slt(AT, FSR, SSR);
2221 __ bne(AT, R0, not_taken);
2222 break;
2223 case greater:
2224 __ slt(AT, FSR, SSR);
2225 __ beq(AT, R0, not_taken);
2226 break;
2227 case greater_equal:
2228 __ slt(AT, SSR, FSR);
2229 __ bne(AT, R0, not_taken);
2230 break;
2231 }
2232 __ delayed()->nop();
2234 branch(false, false);
2235 __ bind(not_taken);
2236 __ profile_not_taken_branch(FSR);
2237 }
2239 void TemplateTable::if_nullcmp(Condition cc) {
2240 transition(atos, vtos);
2241 // assume branch is more often taken than not (loops use backward branches)
2242 Label not_taken;
2243 switch(cc) {
2244 case not_equal:
2245 __ beq(FSR, R0, not_taken);
2246 break;
2247 case equal:
2248 __ bne(FSR, R0, not_taken);
2249 break;
2250 default:
2251 ShouldNotReachHere();
2252 }
2253 __ delayed()->nop();
2255 branch(false, false);
2256 __ bind(not_taken);
2257 __ profile_not_taken_branch(FSR);
2258 }
2261 void TemplateTable::if_acmp(Condition cc) {
2262 transition(atos, vtos);
2263 // assume branch is more often taken than not (loops use backward branches)
2264 Label not_taken;
2265 // __ lw(SSR, SP, 0);
2266 __ pop_ptr(SSR);
2267 switch(cc) {
2268 case not_equal:
2269 __ beq(SSR, FSR, not_taken);
2270 break;
2271 case equal:
2272 __ bne(SSR, FSR, not_taken);
2273 break;
2274 default:
2275 ShouldNotReachHere();
2276 }
2277 __ delayed()->nop();
2279 branch(false, false);
2281 __ bind(not_taken);
2282 __ profile_not_taken_branch(FSR);
2283 }
2285 // used registers : T1, T2, T3
2286 // T1 : method
2287 // T2 : returb bci
2288 void TemplateTable::ret() {
2289 transition(vtos, vtos);
2291 locals_index(T2);
2292 __ ld(T2, T2, 0);
2293 __ profile_ret(T2, T3);
2295 __ get_method(T1);
2296 __ ld(BCP, T1, in_bytes(Method::const_offset()));
2297 __ dadd(BCP, BCP, T2);
2298 __ daddi(BCP, BCP, in_bytes(ConstMethod::codes_offset()));
2300 __ dispatch_next(vtos);
2301 }
2303 // used registers : T1, T2, T3
2304 // T1 : method
2305 // T2 : returb bci
2306 void TemplateTable::wide_ret() {
2307 transition(vtos, vtos);
2309 locals_index_wide(T2);
2310 __ ld(T2, T2, 0); // get return bci, compute return bcp
2311 __ profile_ret(T2, T3);
2313 __ get_method(T1);
2314 __ ld(BCP, T1, in_bytes(Method::const_offset()));
2315 __ dadd(BCP, BCP, T2);
2316 __ daddi(BCP, BCP, in_bytes(ConstMethod::codes_offset()));
2318 __ dispatch_next(vtos);
2319 }
2321 // used register T2, T3, A7, Rnext
2322 // T2 : bytecode pointer
2323 // T3 : low
2324 // A7 : high
2325 // Rnext : dest bytecode, required by dispatch_base
2326 void TemplateTable::tableswitch() {
2327 Label default_case, continue_execution;
2328 transition(itos, vtos);
2330 // align BCP
2331 __ daddi(T2, BCP, BytesPerInt);
2332 __ li(AT, -BytesPerInt);
2333 __ andr(T2, T2, AT);
2335 // load lo & hi
2336 __ lw(T3, T2, 1 * BytesPerInt);
2337 __ swap(T3);
2338 __ lw(A7, T2, 2 * BytesPerInt);
2339 __ swap(A7);
2341 // check against lo & hi
2342 __ slt(AT, FSR, T3);
2343 __ bne(AT, R0, default_case);
2344 __ delayed()->nop();
2346 __ slt(AT, A7, FSR);
2347 __ bne(AT, R0, default_case);
2348 __ delayed()->nop();
2350 // lookup dispatch offset, in A7 big endian
2351 __ dsub(FSR, FSR, T3);
2352 __ dsll(AT, FSR, Address::times_4);
2353 __ dadd(AT, T2, AT);
2354 __ lw(A7, AT, 3 * BytesPerInt);
2355 __ profile_switch_case(FSR, T9, T3);
2357 __ bind(continue_execution);
2358 __ swap(A7);
2359 __ dadd(BCP, BCP, A7);
2360 __ lbu(Rnext, BCP, 0);
2361 __ dispatch_only(vtos);
2363 // handle default
2364 __ bind(default_case);
2365 __ profile_switch_default(FSR);
2366 __ lw(A7, T2, 0);
2367 __ b(continue_execution);
2368 __ delayed()->nop();
2369 }
2371 void TemplateTable::lookupswitch() {
2372 transition(itos, itos);
2373 __ stop("lookupswitch bytecode should have been rewritten");
2374 }
2376 // used registers : T2, T3, A7, Rnext
2377 // T2 : bytecode pointer
2378 // T3 : pair index
2379 // A7 : offset
2380 // Rnext : dest bytecode
2381 // the data after the opcode is the same as lookupswitch
2382 // see Rewriter::rewrite_method for more information
2383 void TemplateTable::fast_linearswitch() {
2384 transition(itos, vtos);
2385 Label loop_entry, loop, found, continue_execution;
2387 // swap eax so we can avoid swapping the table entries
2388 __ swap(FSR);
2390 // align BCP
2391 __ daddi(T2, BCP, BytesPerInt);
2392 __ li(AT, -BytesPerInt);
2393 __ andr(T2, T2, AT);
2395 // set counter
2396 __ lw(T3, T2, BytesPerInt);
2397 __ swap(T3);
2398 __ b(loop_entry);
2399 __ delayed()->nop();
2401 // table search
2402 __ bind(loop);
2403 // get the entry value
2404 __ dsll(AT, T3, Address::times_8);
2405 __ dadd(AT, T2, AT);
2406 __ lw(AT, AT, 2 * BytesPerInt);
2408 // found?
2409 __ beq(FSR, AT, found);
2410 __ delayed()->nop();
2412 __ bind(loop_entry);
2413 __ bgtz(T3, loop);
2414 __ delayed()->daddiu(T3, T3, -1);
2416 // default case
2417 __ profile_switch_default(FSR);
2418 __ lw(A7, T2, 0);
2419 __ b(continue_execution);
2420 __ delayed()->nop();
2422 // entry found -> get offset
2423 __ bind(found);
2424 __ dsll(AT, T3, Address::times_8);
2425 __ dadd(AT, T2, AT);
2426 __ lw(A7, AT, 3 * BytesPerInt);
2427 __ profile_switch_case(T3, FSR, T2);
2429 // continue execution
2430 __ bind(continue_execution);
2431 __ swap(A7);
2432 __ dadd(BCP, BCP, A7);
2433 __ lbu(Rnext, BCP, 0);
2434 __ dispatch_only(vtos);
2435 }
2437 // used registers : T0, T1, T2, T3, A7, Rnext
2438 // T2 : pairs address(array)
2439 // Rnext : dest bytecode
2440 // the data after the opcode is the same as lookupswitch
2441 // see Rewriter::rewrite_method for more information
2442 void TemplateTable::fast_binaryswitch() {
2443 transition(itos, vtos);
2444 // Implementation using the following core algorithm:
2445 //
2446 // int binary_search(int key, LookupswitchPair* array, int n) {
2447 // // Binary search according to "Methodik des Programmierens" by
2448 // // Edsger W. Dijkstra and W.H.J. Feijen, Addison Wesley Germany 1985.
2449 // int i = 0;
2450 // int j = n;
2451 // while (i+1 < j) {
2452 // // invariant P: 0 <= i < j <= n and (a[i] <= key < a[j] or Q)
2453 // // with Q: for all i: 0 <= i < n: key < a[i]
2454 // // where a stands for the array and assuming that the (inexisting)
2455 // // element a[n] is infinitely big.
2456 // int h = (i + j) >> 1;
2457 // // i < h < j
2458 // if (key < array[h].fast_match()) {
2459 // j = h;
2460 // } else {
2461 // i = h;
2462 // }
2463 // }
2464 // // R: a[i] <= key < a[i+1] or Q
2465 // // (i.e., if key is within array, i is the correct index)
2466 // return i;
2467 // }
2469 // register allocation
2470 const Register array = T2;
2471 const Register i = T3, j = A7;
2472 const Register h = T1;
2473 const Register temp = T0;
2474 const Register key = FSR;
2476 // setup array
2477 __ daddi(array, BCP, 3*BytesPerInt);
2478 __ li(AT, -BytesPerInt);
2479 __ andr(array, array, AT);
2481 // initialize i & j
2482 __ move(i, R0);
2483 __ lw(j, array, - 1 * BytesPerInt);
2484 // Convert j into native byteordering
2485 __ swap(j);
2487 // and start
2488 Label entry;
2489 __ b(entry);
2490 __ delayed()->nop();
2492 // binary search loop
2493 {
2494 Label loop;
2495 __ bind(loop);
2496 // int h = (i + j) >> 1;
2497 __ dadd(h, i, j);
2498 __ dsrl(h, h, 1);
2499 // if (key < array[h].fast_match()) {
2500 // j = h;
2501 // } else {
2502 // i = h;
2503 // }
2504 // Convert array[h].match to native byte-ordering before compare
2505 __ dsll(AT, h, Address::times_8);
2506 __ dadd(AT, array, AT);
2507 __ lw(temp, AT, 0 * BytesPerInt);
2508 __ swap(temp);
2510 {
2511 Label set_i, end_of_if;
2512 __ slt(AT, key, temp);
2513 __ beq(AT, R0, set_i);
2514 __ delayed()->nop();
2516 __ b(end_of_if);
2517 __ delayed(); __ move(j, h);
2519 __ bind(set_i);
2520 __ move(i, h);
2522 __ bind(end_of_if);
2523 }
2524 // while (i+1 < j)
2525 __ bind(entry);
2526 __ daddi(h, i, 1);
2527 __ slt(AT, h, j);
2528 __ bne(AT, R0, loop);
2529 __ delayed()->nop();
2530 }
2532 // end of binary search, result index is i (must check again!)
2533 Label default_case;
2534 // Convert array[i].match to native byte-ordering before compare
2535 __ dsll(AT, i, Address::times_8);
2536 __ dadd(AT, array, AT);
2537 __ lw(temp, AT, 0 * BytesPerInt);
2538 __ swap(temp);
2539 __ bne(key, temp, default_case);
2540 __ delayed()->nop();
2542 // entry found -> j = offset
2543 __ dsll(AT, i, Address::times_8);
2544 __ dadd(AT, array, AT);
2545 __ lw(j, AT, 1 * BytesPerInt);
2546 __ profile_switch_case(i, key, array);
2547 __ swap(j);
2549 __ dadd(BCP, BCP, j);
2550 __ lbu(Rnext, BCP, 0);
2551 __ dispatch_only(vtos);
2553 // default case -> j = default offset
2554 __ bind(default_case);
2555 __ profile_switch_default(i);
2556 __ lw(j, array, - 2 * BytesPerInt);
2557 __ swap(j);
2558 __ dadd(BCP, BCP, j);
2559 __ lbu(Rnext, BCP, 0);
2560 __ dispatch_only(vtos);
2561 }
2563 void TemplateTable::_return(TosState state) {
2564 transition(state, state);
2565 assert(_desc->calls_vm(),
2566 "inconsistent calls_vm information"); // call in remove_activation
2568 if (_desc->bytecode() == Bytecodes::_return_register_finalizer) {
2569 assert(state == vtos, "only valid state");
2570 __ ld(T1, aaddress(0));
2571 __ load_klass(LVP, T1);
2572 __ lw(LVP, LVP, in_bytes(Klass::access_flags_offset()));
2573 __ move(AT, JVM_ACC_HAS_FINALIZER);
2574 __ andr(AT, AT, LVP);//by_css
2575 Label skip_register_finalizer;
2576 __ beq(AT, R0, skip_register_finalizer);
2577 __ delayed()->nop();
2578 __ call_VM(noreg, CAST_FROM_FN_PTR(address,
2579 InterpreterRuntime::register_finalizer), T1);
2580 __ bind(skip_register_finalizer);
2581 }
2583 // Narrow result if state is itos but result type is smaller.
2584 // Need to narrow in the return bytecode rather than in generate_return_entry
2585 // since compiled code callers expect the result to already be narrowed.
2586 if (state == itos) {
2587 __ narrow(FSR);
2588 }
2590 __ remove_activation(state, T9);
2591 __ sync();
2593 __ jr(T9);
2594 __ delayed()->nop();
2595 }
2597 // ----------------------------------------------------------------------------
2598 // Volatile variables demand their effects be made known to all CPU's
2599 // in order. Store buffers on most chips allow reads & writes to
2600 // reorder; the JMM's ReadAfterWrite.java test fails in -Xint mode
2601 // without some kind of memory barrier (i.e., it's not sufficient that
2602 // the interpreter does not reorder volatile references, the hardware
2603 // also must not reorder them).
2604 //
2605 // According to the new Java Memory Model (JMM):
2606 // (1) All volatiles are serialized wrt to each other. ALSO reads &
2607 // writes act as aquire & release, so:
2608 // (2) A read cannot let unrelated NON-volatile memory refs that
2609 // happen after the read float up to before the read. It's OK for
2610 // non-volatile memory refs that happen before the volatile read to
2611 // float down below it.
2612 // (3) Similar a volatile write cannot let unrelated NON-volatile
2613 // memory refs that happen BEFORE the write float down to after the
2614 // write. It's OK for non-volatile memory refs that happen after the
2615 // volatile write to float up before it.
2616 //
2617 // We only put in barriers around volatile refs (they are expensive),
2618 // not _between_ memory refs (that would require us to track the
2619 // flavor of the previous memory refs). Requirements (2) and (3)
2620 // require some barriers before volatile stores and after volatile
2621 // loads. These nearly cover requirement (1) but miss the
2622 // volatile-store-volatile-load case. This final case is placed after
2623 // volatile-stores although it could just as well go before
2624 // volatile-loads.
2625 void TemplateTable::volatile_barrier() {
2626 if(os::is_MP()) __ sync();
2627 }
2629 // we dont shift left 2 bits in get_cache_and_index_at_bcp
2630 // for we always need shift the index we use it. the ConstantPoolCacheEntry
2631 // is 16-byte long, index is the index in
2632 // ConstantPoolCache, so cache + base_offset() + index * 16 is
2633 // the corresponding ConstantPoolCacheEntry
2634 // used registers : T2
2635 // NOTE : the returned index need also shift left 4 to get the address!
2636 void TemplateTable::resolve_cache_and_index(int byte_no,
2637 Register Rcache,
2638 Register index,
2639 size_t index_size) {
2640 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
2641 const Register temp = A1;
2642 assert_different_registers(Rcache, index);
2644 Label resolved;
2645 __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size);
2646 // is resolved?
2647 int i = (int)bytecode();
2648 __ addi(temp, temp, -i);
2649 __ beq(temp, R0, resolved);
2650 __ delayed()->nop();
2651 // resolve first time through
2652 address entry;
2653 switch (bytecode()) {
2654 case Bytecodes::_getstatic : // fall through
2655 case Bytecodes::_putstatic : // fall through
2656 case Bytecodes::_getfield : // fall through
2657 case Bytecodes::_putfield :
2658 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put);
2659 break;
2660 case Bytecodes::_invokevirtual : // fall through
2661 case Bytecodes::_invokespecial : // fall through
2662 case Bytecodes::_invokestatic : // fall through
2663 case Bytecodes::_invokeinterface:
2664 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);
2665 break;
2666 case Bytecodes::_invokehandle:
2667 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle);
2668 break;
2669 case Bytecodes::_invokedynamic:
2670 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);
2671 break;
2672 default :
2673 fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode())));
2674 break;
2675 }
2677 __ move(temp, i);
2678 __ call_VM(NOREG, entry, temp);
2680 // Update registers with resolved info
2681 __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
2682 __ bind(resolved);
2683 }
2685 // The Rcache and index registers must be set before call
2686 void TemplateTable::load_field_cp_cache_entry(Register obj,
2687 Register cache,
2688 Register index,
2689 Register off,
2690 Register flags,
2691 bool is_static = false) {
2692 assert_different_registers(cache, index, flags, off);
2694 ByteSize cp_base_offset = ConstantPoolCache::base_offset();
2695 // Field offset
2696 __ dsll(AT, index, Address::times_ptr);
2697 __ dadd(AT, cache, AT);
2698 __ ld(off, AT, in_bytes(cp_base_offset + ConstantPoolCacheEntry::f2_offset()));
2699 // Flags
2700 __ ld(flags, AT, in_bytes(cp_base_offset + ConstantPoolCacheEntry::flags_offset()));
2702 // klass overwrite register
2703 if (is_static) {
2704 __ ld(obj, AT, in_bytes(cp_base_offset + ConstantPoolCacheEntry::f1_offset()));
2705 const int mirror_offset = in_bytes(Klass::java_mirror_offset());
2706 __ ld(obj, Address(obj, mirror_offset));
2708 __ verify_oop(obj);
2709 }
2710 }
2712 // get the method, itable_index and flags of the current invoke
2713 void TemplateTable::load_invoke_cp_cache_entry(int byte_no,
2714 Register method,
2715 Register itable_index,
2716 Register flags,
2717 bool is_invokevirtual,
2718 bool is_invokevfinal, /*unused*/
2719 bool is_invokedynamic) {
2720 // setup registers
2721 const Register cache = T3;
2722 const Register index = T1;
2723 assert_different_registers(method, flags);
2724 assert_different_registers(method, cache, index);
2725 assert_different_registers(itable_index, flags);
2726 assert_different_registers(itable_index, cache, index);
2727 assert(is_invokevirtual == (byte_no == f2_byte), "is invokevirtual flag redundant");
2728 // determine constant pool cache field offsets
2729 const int method_offset = in_bytes(
2730 ConstantPoolCache::base_offset() +
2731 ((byte_no == f2_byte)
2732 ? ConstantPoolCacheEntry::f2_offset()
2733 : ConstantPoolCacheEntry::f1_offset()));
2734 const int flags_offset = in_bytes(ConstantPoolCache::base_offset() +
2735 ConstantPoolCacheEntry::flags_offset());
2736 // access constant pool cache fields
2737 const int index_offset = in_bytes(ConstantPoolCache::base_offset() +
2738 ConstantPoolCacheEntry::f2_offset());
2740 size_t index_size = (is_invokedynamic ? sizeof(u4): sizeof(u2));
2741 resolve_cache_and_index(byte_no, cache, index, index_size);
2743 //assert(wordSize == 8, "adjust code below");
2744 // note we shift 4 not 2, for we get is the true inde
2745 // of ConstantPoolCacheEntry, not the shifted 2-bit index as x86 version
2746 __ dsll(AT, index, Address::times_ptr);
2747 __ dadd(AT, cache, AT);
2748 __ ld(method, AT, method_offset);
2750 if (itable_index != NOREG) {
2751 __ ld(itable_index, AT, index_offset);
2752 }
2753 __ ld(flags, AT, flags_offset);
2754 }
2756 // The registers cache and index expected to be set before call.
2757 // Correct values of the cache and index registers are preserved.
2758 void TemplateTable::jvmti_post_field_access(Register cache, Register index,
2759 bool is_static, bool has_tos) {
2760 // do the JVMTI work here to avoid disturbing the register state below
2761 // We use c_rarg registers here because we want to use the register used in
2762 // the call to the VM
2763 if (JvmtiExport::can_post_field_access()) {
2764 // Check to see if a field access watch has been set before we
2765 // take the time to call into the VM.
2766 Label L1;
2767 // kill FSR
2768 Register tmp1 = T2;
2769 Register tmp2 = T1;
2770 Register tmp3 = T3;
2771 assert_different_registers(cache, index, AT);
2772 __ li(AT, (intptr_t)JvmtiExport::get_field_access_count_addr());
2773 __ lw(AT, AT, 0);
2774 __ beq(AT, R0, L1);
2775 __ delayed()->nop();
2777 __ get_cache_and_index_at_bcp(tmp2, tmp3, 1);
2779 // cache entry pointer
2780 __ daddi(tmp2, tmp2, in_bytes(ConstantPoolCache::base_offset()));
2781 __ shl(tmp3, LogBytesPerWord);
2782 __ dadd(tmp2, tmp2, tmp3);
2783 if (is_static) {
2784 __ move(tmp1, R0);
2785 } else {
2786 __ ld(tmp1, SP, 0);
2787 __ verify_oop(tmp1);
2788 }
2789 // tmp1: object pointer or NULL
2790 // tmp2: cache entry pointer
2791 // tmp3: jvalue object on the stack
2792 __ call_VM(NOREG, CAST_FROM_FN_PTR(address,
2793 InterpreterRuntime::post_field_access),
2794 tmp1, tmp2, tmp3);
2795 __ get_cache_and_index_at_bcp(cache, index, 1);
2796 __ bind(L1);
2797 }
2798 }
2800 void TemplateTable::pop_and_check_object(Register r) {
2801 __ pop_ptr(r);
2802 __ null_check(r); // for field access must check obj.
2803 __ verify_oop(r);
2804 }
2806 // used registers : T1, T2, T3, T1
2807 // T1 : flags
2808 // T2 : off
2809 // T3 : obj
2810 // T1 : field address
2811 // The flags 31, 30, 29, 28 together build a 4 bit number 0 to 8 with the
2812 // following mapping to the TosState states:
2813 // btos: 0
2814 // ctos: 1
2815 // stos: 2
2816 // itos: 3
2817 // ltos: 4
2818 // ftos: 5
2819 // dtos: 6
2820 // atos: 7
2821 // vtos: 8
2822 // see ConstantPoolCacheEntry::set_field for more info
2823 void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
2824 transition(vtos, vtos);
2826 const Register cache = T3;
2827 const Register index = T0;
2829 const Register obj = T3;
2830 const Register off = T2;
2831 const Register flags = T1;
2833 const Register scratch = T8;
2835 resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
2836 jvmti_post_field_access(cache, index, is_static, false);
2837 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
2839 {
2840 __ move(scratch, 1 << ConstantPoolCacheEntry::is_volatile_shift);
2841 __ andr(scratch, scratch, flags);
2843 Label notVolatile;
2844 __ beq(scratch, R0, notVolatile);
2845 __ nop();
2846 volatile_barrier();
2847 __ bind(notVolatile);
2848 }
2850 if (!is_static) pop_and_check_object(obj);
2851 __ dadd(index, obj, off);
2854 Label Done, notByte, notBool, notInt, notShort, notChar,
2855 notLong, notFloat, notObj, notDouble;
2857 assert(btos == 0, "change code, btos != 0");
2858 __ dsrl(flags, flags, ConstantPoolCacheEntry::tos_state_shift);
2859 __ andi(flags, flags, ConstantPoolCacheEntry::tos_state_mask);
2860 __ bne(flags, R0, notByte);
2861 __ delayed()->nop();
2863 // btos
2864 __ lb(FSR, index, 0);
2865 __ sd(FSR, SP, - wordSize);
2867 // Rewrite bytecode to be faster
2868 if (!is_static) {
2869 patch_bytecode(Bytecodes::_fast_bgetfield, T3, T2);
2870 }
2871 __ b(Done);
2872 __ delayed()->daddi(SP, SP, - wordSize);
2875 __ bind(notByte);
2876 __ move(AT, ztos);
2877 __ bne(flags, AT, notBool);
2878 __ delayed()->nop();
2880 // ztos
2881 __ lb(FSR, index, 0);
2882 __ sd(FSR, SP, - wordSize);
2884 // Rewrite bytecode to be faster
2885 if (!is_static) {
2886 // patch_bytecode(Bytecodes::_fast_igetfield, T3, T2);
2887 patch_bytecode(Bytecodes::_fast_bgetfield, T3, T2);
2888 }
2889 __ b(Done);
2890 __ delayed()->daddi(SP, SP, - wordSize);
2893 __ bind(notBool);
2894 __ move(AT, itos);
2895 __ bne(flags, AT, notInt);
2896 __ delayed()->nop();
2898 // itos
2899 __ lw(FSR, index, 0);
2900 __ sd(FSR, SP, - wordSize);
2902 // Rewrite bytecode to be faster
2903 if (!is_static) {
2904 // patch_bytecode(Bytecodes::_fast_igetfield, T3, T2);
2905 patch_bytecode(Bytecodes::_fast_igetfield, T3, T2);
2906 }
2907 __ b(Done);
2908 __ delayed()->daddi(SP, SP, - wordSize);
2910 __ bind(notInt);
2911 __ move(AT, atos);
2912 __ bne(flags, AT, notObj);
2913 __ delayed()->nop();
2915 // atos
2916 //add for compressedoops
2917 __ load_heap_oop(FSR, Address(index, 0));
2918 __ sd(FSR, SP, - wordSize);
2920 if (!is_static) {
2921 //patch_bytecode(Bytecodes::_fast_agetfield, T3, T2);
2922 patch_bytecode(Bytecodes::_fast_agetfield, T3, T2);
2923 }
2924 __ b(Done);
2925 __ delayed()->daddi(SP, SP, - wordSize);
2927 __ bind(notObj);
2928 __ move(AT, ctos);
2929 __ bne(flags, AT, notChar);
2930 __ delayed()->nop();
2932 // ctos
2933 __ lhu(FSR, index, 0);
2934 __ sd(FSR, SP, - wordSize);
2936 if (!is_static) {
2937 patch_bytecode(Bytecodes::_fast_cgetfield, T3, T2);
2938 }
2939 __ b(Done);
2940 __ delayed()->daddi(SP, SP, - wordSize);
2942 __ bind(notChar);
2943 __ move(AT, stos);
2944 __ bne(flags, AT, notShort);
2945 __ delayed()->nop();
2947 // stos
2948 __ lh(FSR, index, 0);
2949 __ sd(FSR, SP, - wordSize);
2951 if (!is_static) {
2952 patch_bytecode(Bytecodes::_fast_sgetfield, T3, T2);
2953 }
2954 __ b(Done);
2955 __ delayed()->daddi(SP, SP, - wordSize);
2957 __ bind(notShort);
2958 __ move(AT, ltos);
2959 __ bne(flags, AT, notLong);
2960 __ delayed()->nop();
2962 // FIXME : the load/store should be atomic, we have no simple method to do this in mips32
2963 // ltos
2964 __ ld(FSR, index, 0 * wordSize);
2965 __ sd(FSR, SP, -2 * wordSize);
2966 __ sd(R0, SP, -1 * wordSize);
2968 // Don't rewrite to _fast_lgetfield for potential volatile case.
2969 __ b(Done);
2970 __ delayed()->daddi(SP, SP, - 2 * wordSize);
2972 __ bind(notLong);
2973 __ move(AT, ftos);
2974 __ bne(flags, AT, notFloat);
2975 __ delayed()->nop();
2977 // ftos
2978 __ lwc1(FSF, index, 0);
2979 __ sdc1(FSF, SP, - wordSize);
2981 if (!is_static) {
2982 patch_bytecode(Bytecodes::_fast_fgetfield, T3, T2);
2983 }
2984 __ b(Done);
2985 __ delayed()->daddi(SP, SP, - wordSize);
2987 __ bind(notFloat);
2988 __ move(AT, dtos);
2989 #ifdef ASSERT
2990 __ bne(flags, AT, notDouble);
2991 __ delayed()->nop();
2992 #endif
2994 // dtos
2995 __ ldc1(FSF, index, 0 * wordSize);
2996 __ sdc1(FSF, SP, - 2 * wordSize);
2997 __ sd(R0, SP, - 1 * wordSize);
2999 if (!is_static) {
3000 patch_bytecode(Bytecodes::_fast_dgetfield, T3, T2);
3001 }
3003 __ daddi(SP, SP, - 2 * wordSize);
3005 #ifdef ASSERT
3006 __ b(Done);
3007 __ nop();
3008 __ bind(notDouble);
3009 __ stop("Bad state");
3010 #endif
3012 __ bind(Done);
3014 {
3015 Label notVolatile;
3016 __ beq(scratch, R0, notVolatile);
3017 __ nop();
3018 volatile_barrier();
3019 __ bind(notVolatile);
3020 }
3021 }
3024 void TemplateTable::getfield(int byte_no) {
3025 getfield_or_static(byte_no, false);
3026 }
3028 void TemplateTable::getstatic(int byte_no) {
3029 getfield_or_static(byte_no, true);
3030 }
3032 // The registers cache and index expected to be set before call.
3033 // The function may destroy various registers, just not the cache and index registers.
3034 void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is_static) {
3035 transition(vtos, vtos);
3037 ByteSize cp_base_offset = ConstantPoolCache::base_offset();
3039 if (JvmtiExport::can_post_field_modification()) {
3040 // Check to see if a field modification watch has been set before
3041 // we take the time to call into the VM.
3042 Label L1;
3043 //kill AT, T1, T2, T3, T9
3044 Register tmp1 = T2;
3045 Register tmp2 = T1;
3046 Register tmp3 = T3;
3047 Register tmp4 = T9;
3048 assert_different_registers(cache, index, tmp4);
3050 __ li(AT, JvmtiExport::get_field_modification_count_addr());
3051 __ lw(AT, AT, 0);
3052 __ beq(AT, R0, L1);
3053 __ delayed()->nop();
3055 __ get_cache_and_index_at_bcp(tmp2, tmp4, 1);
3057 if (is_static) {
3058 __ move(tmp1, R0);
3059 } else {
3060 // Life is harder. The stack holds the value on top, followed by
3061 // the object. We don't know the size of the value, though; it
3062 // could be one or two words depending on its type. As a result,
3063 // we must find the type to determine where the object is.
3064 Label two_word, valsize_known;
3065 __ dsll(AT, tmp4, Address::times_8);
3066 __ dadd(AT, tmp2, AT);
3067 __ ld(tmp3, AT, in_bytes(cp_base_offset +
3068 ConstantPoolCacheEntry::flags_offset()));
3069 __ shr(tmp3, ConstantPoolCacheEntry::tos_state_shift);
3071 // Make sure we don't need to mask ecx for tos_state_shift
3072 // after the above shift
3073 ConstantPoolCacheEntry::verify_tos_state_shift();
3074 __ move(tmp1, SP);
3075 __ move(AT, ltos);
3076 __ beq(tmp3, AT, two_word);
3077 __ delayed()->nop();
3078 __ move(AT, dtos);
3079 __ beq(tmp3, AT, two_word);
3080 __ delayed()->nop();
3081 __ b(valsize_known);
3082 __ delayed()->daddi(tmp1, tmp1, Interpreter::expr_offset_in_bytes(1) );
3084 __ bind(two_word);
3085 __ daddi(tmp1, tmp1, Interpreter::expr_offset_in_bytes(2));
3087 __ bind(valsize_known);
3088 // setup object pointer
3089 __ ld(tmp1, tmp1, 0*wordSize);
3090 }
3091 // cache entry pointer
3092 __ daddi(tmp2, tmp2, in_bytes(cp_base_offset));
3093 __ shl(tmp4, LogBytesPerWord);
3094 __ daddu(tmp2, tmp2, tmp4);
3095 // object (tos)
3096 __ move(tmp3, SP);
3097 // tmp1: object pointer set up above (NULL if static)
3098 // tmp2: cache entry pointer
3099 // tmp3: jvalue object on the stack
3100 __ call_VM(NOREG,
3101 CAST_FROM_FN_PTR(address,
3102 InterpreterRuntime::post_field_modification),
3103 tmp1, tmp2, tmp3);
3104 __ get_cache_and_index_at_bcp(cache, index, 1);
3105 __ bind(L1);
3106 }
3107 }
3109 // used registers : T0, T1, T2, T3, T8
3110 // T1 : flags
3111 // T2 : off
3112 // T3 : obj
3113 // T8 : volatile bit
3114 // see ConstantPoolCacheEntry::set_field for more info
3115 void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
3116 transition(vtos, vtos);
3118 const Register cache = T3;
3119 const Register index = T0;
3120 const Register obj = T3;
3121 const Register off = T2;
3122 const Register flags = T1;
3123 const Register bc = T3;
3125 const Register scratch = T8;
3127 resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
3128 jvmti_post_field_mod(cache, index, is_static);
3129 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
3131 Label Done;
3132 {
3133 __ move(scratch, 1 << ConstantPoolCacheEntry::is_volatile_shift);
3134 __ andr(scratch, scratch, flags);
3136 Label notVolatile;
3137 __ beq(scratch, R0, notVolatile);
3138 __ nop();
3139 volatile_barrier();
3140 __ bind(notVolatile);
3141 }
3144 Label notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
3146 assert(btos == 0, "change code, btos != 0");
3148 // btos
3149 __ dsrl(flags, flags, ConstantPoolCacheEntry::tos_state_shift);
3150 __ andi(flags, flags, ConstantPoolCacheEntry::tos_state_mask);
3151 __ bne(flags, R0, notByte);
3152 __ delayed()->nop();
3154 __ pop(btos);
3155 if (!is_static) {
3156 pop_and_check_object(obj);
3157 }
3158 __ dadd(AT, obj, off);
3159 __ sb(FSR, AT, 0);
3161 if (!is_static) {
3162 patch_bytecode(Bytecodes::_fast_bputfield, bc, off, true, byte_no);
3163 }
3164 __ b(Done);
3165 __ delayed()->nop();
3167 // ztos
3168 __ bind(notByte);
3169 __ move(AT, ztos);
3170 __ bne(flags, AT, notBool);
3171 __ delayed()->nop();
3173 __ pop(ztos);
3174 if (!is_static) {
3175 pop_and_check_object(obj);
3176 }
3177 __ dadd(AT, obj, off);
3178 __ andi(FSR, FSR, 0x1);
3179 __ sb(FSR, AT, 0);
3181 if (!is_static) {
3182 patch_bytecode(Bytecodes::_fast_zputfield, bc, off, true, byte_no);
3183 }
3184 __ b(Done);
3185 __ delayed()->nop();
3187 // itos
3188 __ bind(notBool);
3189 __ move(AT, itos);
3190 __ bne(flags, AT, notInt);
3191 __ delayed()->nop();
3193 __ pop(itos);
3194 if (!is_static) {
3195 pop_and_check_object(obj);
3196 }
3197 __ dadd(AT, obj, off);
3198 __ sw(FSR, AT, 0);
3200 if (!is_static) {
3201 patch_bytecode(Bytecodes::_fast_iputfield, bc, off, true, byte_no);
3202 }
3203 __ b(Done);
3204 __ delayed()->nop();
3206 // atos
3207 __ bind(notInt);
3208 __ move(AT, atos);
3209 __ bne(flags, AT, notObj);
3210 __ delayed()->nop();
3212 __ pop(atos);
3213 if (!is_static) {
3214 pop_and_check_object(obj);
3215 }
3217 do_oop_store(_masm, Address(obj, off, Address::times_1, 0), FSR, _bs->kind(), false);
3219 if (!is_static) {
3220 patch_bytecode(Bytecodes::_fast_aputfield, bc, off, true, byte_no);
3221 }
3222 __ b(Done);
3223 __ delayed()->nop();
3225 // ctos
3226 __ bind(notObj);
3227 __ move(AT, ctos);
3228 __ bne(flags, AT, notChar);
3229 __ delayed()->nop();
3231 __ pop(ctos);
3232 if (!is_static) {
3233 pop_and_check_object(obj);
3234 }
3235 __ dadd(AT, obj, off);
3236 __ sh(FSR, AT, 0);
3237 if (!is_static) {
3238 patch_bytecode(Bytecodes::_fast_cputfield, bc, off, true, byte_no);
3239 }
3240 __ b(Done);
3241 __ delayed()->nop();
3243 // stos
3244 __ bind(notChar);
3245 __ move(AT, stos);
3246 __ bne(flags, AT, notShort);
3247 __ delayed()->nop();
3249 __ pop(stos);
3250 if (!is_static) {
3251 pop_and_check_object(obj);
3252 }
3253 __ dadd(AT, obj, off);
3254 __ sh(FSR, AT, 0);
3255 if (!is_static) {
3256 patch_bytecode(Bytecodes::_fast_sputfield, bc, off, true, byte_no);
3257 }
3258 __ b(Done);
3259 __ delayed()->nop();
3261 // ltos
3262 __ bind(notShort);
3263 __ move(AT, ltos);
3264 __ bne(flags, AT, notLong);
3265 __ delayed()->nop();
3267 __ pop(ltos);
3268 if (!is_static) {
3269 pop_and_check_object(obj);
3270 }
3271 __ dadd(AT, obj, off);
3272 __ sd(FSR, AT, 0);
3273 if (!is_static) {
3274 patch_bytecode(Bytecodes::_fast_lputfield, bc, off, true, byte_no);
3275 }
3276 __ b(Done);
3277 __ delayed()->nop();
3279 // ftos
3280 __ bind(notLong);
3281 __ move(AT, ftos);
3282 __ bne(flags, AT, notFloat);
3283 __ delayed()->nop();
3285 __ pop(ftos);
3286 if (!is_static) {
3287 pop_and_check_object(obj);
3288 }
3289 __ dadd(AT, obj, off);
3290 __ swc1(FSF, AT, 0);
3291 if (!is_static) {
3292 patch_bytecode(Bytecodes::_fast_fputfield, bc, off, true, byte_no);
3293 }
3294 __ b(Done);
3295 __ delayed()->nop();
3298 // dtos
3299 __ bind(notFloat);
3300 __ move(AT, dtos);
3301 #ifdef ASSERT
3302 __ bne(flags, AT, notDouble);
3303 __ delayed()->nop();
3304 #endif
3306 __ pop(dtos);
3307 if (!is_static) {
3308 pop_and_check_object(obj);
3309 }
3310 __ dadd(AT, obj, off);
3311 __ sdc1(FSF, AT, 0);
3312 if (!is_static) {
3313 patch_bytecode(Bytecodes::_fast_dputfield, bc, off, true, byte_no);
3314 }
3316 #ifdef ASSERT
3317 __ b(Done);
3318 __ delayed()->nop();
3320 __ bind(notDouble);
3321 __ stop("Bad state");
3322 #endif
3324 __ bind(Done);
3326 {
3327 Label notVolatile;
3328 __ beq(scratch, R0, notVolatile);
3329 __ nop();
3330 volatile_barrier();
3331 __ bind(notVolatile);
3332 }
3333 }
3335 void TemplateTable::putfield(int byte_no) {
3336 putfield_or_static(byte_no, false);
3337 }
3339 void TemplateTable::putstatic(int byte_no) {
3340 putfield_or_static(byte_no, true);
3341 }
3343 // used registers : T1, T2, T3
3344 // T1 : cp_entry
3345 // T2 : obj
3346 // T3 : value pointer
3347 void TemplateTable::jvmti_post_fast_field_mod() {
3348 if (JvmtiExport::can_post_field_modification()) {
3349 // Check to see if a field modification watch has been set before
3350 // we take the time to call into the VM.
3351 Label L2;
3352 //kill AT, T1, T2, T3, T9
3353 Register tmp1 = T2;
3354 Register tmp2 = T1;
3355 Register tmp3 = T3;
3356 Register tmp4 = T9;
3357 __ li(AT, JvmtiExport::get_field_modification_count_addr());
3358 __ lw(tmp3, AT, 0);
3359 __ beq(tmp3, R0, L2);
3360 __ delayed()->nop();
3361 __ pop_ptr(tmp1);
3362 __ verify_oop(tmp1);
3363 __ push_ptr(tmp1);
3364 switch (bytecode()) { // load values into the jvalue object
3365 case Bytecodes::_fast_aputfield: __ push_ptr(FSR); break;
3366 case Bytecodes::_fast_bputfield: // fall through
3367 case Bytecodes::_fast_zputfield: // fall through
3368 case Bytecodes::_fast_sputfield: // fall through
3369 case Bytecodes::_fast_cputfield: // fall through
3370 case Bytecodes::_fast_iputfield: __ push_i(FSR); break;
3371 case Bytecodes::_fast_dputfield: __ push_d(FSF); break;
3372 case Bytecodes::_fast_fputfield: __ push_f(); break;
3373 case Bytecodes::_fast_lputfield: __ push_l(FSR); break;
3374 default: ShouldNotReachHere();
3375 }
3376 __ move(tmp3, SP);
3377 // access constant pool cache entry
3378 __ get_cache_entry_pointer_at_bcp(tmp2, FSR, 1);
3379 __ verify_oop(tmp1);
3380 // tmp1: object pointer copied above
3381 // tmp2: cache entry pointer
3382 // tmp3: jvalue object on the stack
3383 __ call_VM(NOREG,
3384 CAST_FROM_FN_PTR(address,
3385 InterpreterRuntime::post_field_modification),
3386 tmp1, tmp2, tmp3);
3388 switch (bytecode()) { // restore tos values
3389 case Bytecodes::_fast_aputfield: __ pop_ptr(FSR); break;
3390 case Bytecodes::_fast_bputfield: // fall through
3391 case Bytecodes::_fast_zputfield: // fall through
3392 case Bytecodes::_fast_sputfield: // fall through
3393 case Bytecodes::_fast_cputfield: // fall through
3394 case Bytecodes::_fast_iputfield: __ pop_i(FSR); break;
3395 case Bytecodes::_fast_dputfield: __ pop_d(); break;
3396 case Bytecodes::_fast_fputfield: __ pop_f(); break;
3397 case Bytecodes::_fast_lputfield: __ pop_l(FSR); break;
3398 }
3399 __ bind(L2);
3400 }
3401 }
3403 // used registers : T2, T3, T1
3404 // T2 : index & off & field address
3405 // T3 : cache & obj
3406 // T1 : flags
3407 void TemplateTable::fast_storefield(TosState state) {
3408 transition(state, vtos);
3410 const Register scratch = T8;
3412 ByteSize base = ConstantPoolCache::base_offset();
3414 jvmti_post_fast_field_mod();
3416 // access constant pool cache
3417 __ get_cache_and_index_at_bcp(T3, T2, 1);
3419 // test for volatile with edx but edx is tos register for lputfield.
3420 __ dsll(AT, T2, Address::times_8);
3421 __ dadd(AT, T3, AT);
3422 __ ld(T1, AT, in_bytes(base + ConstantPoolCacheEntry::flags_offset()));
3424 // replace index with field offset from cache entry
3425 __ ld(T2, AT, in_bytes(base + ConstantPoolCacheEntry::f2_offset()));
3427 Label Done;
3428 {
3429 __ move(scratch, 1 << ConstantPoolCacheEntry::is_volatile_shift);
3430 __ andr(scratch, scratch, T1);
3432 Label notVolatile;
3433 __ beq(scratch, R0, notVolatile);
3434 __ nop();
3435 volatile_barrier();
3436 __ bind(notVolatile);
3437 }
3439 // Get object from stack
3440 pop_and_check_object(T3);
3442 if (bytecode() != Bytecodes::_fast_aputfield) {
3443 // field address
3444 __ dadd(T2, T3, T2);
3445 }
3447 // access field
3448 switch (bytecode()) {
3449 case Bytecodes::_fast_zputfield:
3450 __ andi(FSR, FSR, 0x1); // boolean is true if LSB is 1
3451 // fall through to bputfield
3452 case Bytecodes::_fast_bputfield:
3453 __ sb(FSR, T2, 0);
3454 break;
3455 case Bytecodes::_fast_sputfield: // fall through
3456 case Bytecodes::_fast_cputfield:
3457 __ sh(FSR, T2, 0);
3458 break;
3459 case Bytecodes::_fast_iputfield:
3460 __ sw(FSR, T2, 0);
3461 break;
3462 case Bytecodes::_fast_lputfield:
3463 __ sd(FSR, T2, 0 * wordSize);
3464 break;
3465 case Bytecodes::_fast_fputfield:
3466 __ swc1(FSF, T2, 0);
3467 break;
3468 case Bytecodes::_fast_dputfield:
3469 __ sdc1(FSF, T2, 0 * wordSize);
3470 break;
3471 case Bytecodes::_fast_aputfield:
3472 do_oop_store(_masm, Address(T3, T2, Address::times_1, 0), FSR, _bs->kind(), false);
3473 break;
3474 default:
3475 ShouldNotReachHere();
3476 }
3478 {
3479 Label notVolatile;
3480 __ beq(scratch, R0, notVolatile);
3481 __ nop();
3482 volatile_barrier();
3483 __ bind(notVolatile);
3484 }
3485 }
3487 // used registers : T2, T3, T1
3488 // T3 : cp_entry & cache
3489 // T2 : index & offset
3490 void TemplateTable::fast_accessfield(TosState state) {
3491 transition(atos, state);
3493 const Register scratch = T8;
3495 // do the JVMTI work here to avoid disturbing the register state below
3496 if (JvmtiExport::can_post_field_access()) {
3497 // Check to see if a field access watch has been set before we take
3498 // the time to call into the VM.
3499 Label L1;
3500 __ li(AT, (intptr_t)JvmtiExport::get_field_access_count_addr());
3501 __ lw(T3, AT, 0);
3502 __ beq(T3, R0, L1);
3503 __ delayed()->nop();
3504 // access constant pool cache entry
3505 __ get_cache_entry_pointer_at_bcp(T3, T1, 1);
3506 __ move(TSR, FSR);
3507 __ verify_oop(FSR);
3508 // FSR: object pointer copied above
3509 // T3: cache entry pointer
3510 __ call_VM(NOREG,
3511 CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access),
3512 FSR, T3);
3513 __ move(FSR, TSR);
3514 __ bind(L1);
3515 }
3517 // access constant pool cache
3518 __ get_cache_and_index_at_bcp(T3, T2, 1);
3519 // replace index with field offset from cache entry
3520 __ dsll(AT, T2, Address::times_8);
3521 __ dadd(AT, T3, AT);
3522 __ ld(T2, AT, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset()));
3524 {
3525 __ ld(AT, AT, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
3526 __ move(scratch, 1 << ConstantPoolCacheEntry::is_volatile_shift);
3527 __ andr(scratch, scratch, AT);
3529 Label notVolatile;
3530 __ beq(scratch, R0, notVolatile);
3531 __ nop();
3532 volatile_barrier();
3533 __ bind(notVolatile);
3534 }
3536 // eax: object
3537 __ verify_oop(FSR);
3538 __ null_check(FSR);
3539 // field addresses
3540 __ dadd(FSR, FSR, T2);
3542 // access field
3543 switch (bytecode()) {
3544 case Bytecodes::_fast_bgetfield:
3545 __ lb(FSR, FSR, 0);
3546 break;
3547 case Bytecodes::_fast_sgetfield:
3548 __ lh(FSR, FSR, 0);
3549 break;
3550 case Bytecodes::_fast_cgetfield:
3551 __ lhu(FSR, FSR, 0);
3552 break;
3553 case Bytecodes::_fast_igetfield:
3554 __ lw(FSR, FSR, 0);
3555 break;
3556 case Bytecodes::_fast_lgetfield:
3557 __ stop("should not be rewritten");
3558 break;
3559 case Bytecodes::_fast_fgetfield:
3560 __ lwc1(FSF, FSR, 0);
3561 break;
3562 case Bytecodes::_fast_dgetfield:
3563 __ ldc1(FSF, FSR, 0);
3564 break;
3565 case Bytecodes::_fast_agetfield:
3566 //add for compressedoops
3567 __ load_heap_oop(FSR, Address(FSR, 0));
3568 __ verify_oop(FSR);
3569 break;
3570 default:
3571 ShouldNotReachHere();
3572 }
3574 {
3575 Label notVolatile;
3576 __ beq(scratch, R0, notVolatile);
3577 __ nop();
3578 volatile_barrier();
3579 __ bind(notVolatile);
3580 }
3581 }
3583 // generator for _fast_iaccess_0, _fast_aaccess_0, _fast_faccess_0
3584 // used registers : T1, T2, T3, T1
3585 // T1 : obj & field address
3586 // T2 : off
3587 // T3 : cache
3588 // T1 : index
3589 void TemplateTable::fast_xaccess(TosState state) {
3590 transition(vtos, state);
3592 const Register scratch = T8;
3594 // get receiver
3595 __ ld(T1, aaddress(0));
3596 // access constant pool cache
3597 __ get_cache_and_index_at_bcp(T3, T2, 2);
3598 __ dsll(AT, T2, Address::times_8);
3599 __ dadd(AT, T3, AT);
3600 __ ld(T2, AT, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset()));
3602 {
3603 __ ld(AT, AT, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
3604 __ move(scratch, 1 << ConstantPoolCacheEntry::is_volatile_shift);
3605 __ andr(scratch, scratch, AT);
3607 Label notVolatile;
3608 __ beq(scratch, R0, notVolatile);
3609 __ nop();
3610 volatile_barrier();
3611 __ bind(notVolatile);
3612 }
3614 // make sure exception is reported in correct bcp range (getfield is
3615 // next instruction)
3616 __ daddi(BCP, BCP, 1);
3617 __ null_check(T1);
3618 __ dadd(T1, T1, T2);
3620 if (state == itos) {
3621 __ lw(FSR, T1, 0);
3622 } else if (state == atos) {
3623 __ load_heap_oop(FSR, Address(T1, 0));
3624 __ verify_oop(FSR);
3625 } else if (state == ftos) {
3626 __ lwc1(FSF, T1, 0);
3627 } else {
3628 ShouldNotReachHere();
3629 }
3630 __ daddi(BCP, BCP, -1);
3632 {
3633 Label notVolatile;
3634 __ beq(scratch, R0, notVolatile);
3635 __ nop();
3636 volatile_barrier();
3637 __ bind(notVolatile);
3638 }
3639 }
3643 //-----------------------------------------------------------------------------
3644 // Calls
3646 void TemplateTable::count_calls(Register method, Register temp) {
3647 // implemented elsewhere
3648 ShouldNotReachHere();
3649 }
3651 // method, index, recv, flags: T1, T2, T3, T1
3652 // byte_no = 2 for _invokevirtual, 1 else
3653 // T0 : return address
3654 // get the method & index of the invoke, and push the return address of
3655 // the invoke(first word in the frame)
3656 // this address is where the return code jmp to.
3657 // NOTE : this method will set T3&T1 as recv&flags
3658 void TemplateTable::prepare_invoke(int byte_no,
3659 Register method, // linked method (or i-klass)
3660 Register index, // itable index, MethodType, etc.
3661 Register recv, // if caller wants to see it
3662 Register flags // if caller wants to test it
3663 ) {
3664 // determine flags
3665 const Bytecodes::Code code = bytecode();
3666 const bool is_invokeinterface = code == Bytecodes::_invokeinterface;
3667 const bool is_invokedynamic = code == Bytecodes::_invokedynamic;
3668 const bool is_invokehandle = code == Bytecodes::_invokehandle;
3669 const bool is_invokevirtual = code == Bytecodes::_invokevirtual;
3670 const bool is_invokespecial = code == Bytecodes::_invokespecial;
3671 const bool load_receiver = (recv != noreg);
3672 const bool save_flags = (flags != noreg);
3673 assert(load_receiver == (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic),"");
3674 assert(save_flags == (is_invokeinterface || is_invokevirtual), "need flags for vfinal");
3675 assert(flags == noreg || flags == T1, "error flags reg.");
3676 assert(recv == noreg || recv == T3, "error recv reg.");
3678 // setup registers & access constant pool cache
3679 if(recv == noreg) recv = T3;
3680 if(flags == noreg) flags = T1;
3681 assert_different_registers(method, index, recv, flags);
3683 // save 'interpreter return address'
3684 __ save_bcp();
3686 load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual, false, is_invokedynamic);
3688 if (is_invokedynamic || is_invokehandle) {
3689 Label L_no_push;
3690 __ move(AT, (1 << ConstantPoolCacheEntry::has_appendix_shift));
3691 __ andr(AT, AT, flags);
3692 __ beq(AT, R0, L_no_push);
3693 __ delayed()->nop();
3694 // Push the appendix as a trailing parameter.
3695 // This must be done before we get the receiver,
3696 // since the parameter_size includes it.
3697 Register tmp = SSR;
3698 __ push(tmp);
3699 __ move(tmp, index);
3700 assert(ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset == 0, "appendix expected at index+0");
3701 __ load_resolved_reference_at_index(index, tmp);
3702 __ pop(tmp);
3703 __ push(index); // push appendix (MethodType, CallSite, etc.)
3704 __ bind(L_no_push);
3705 }
3707 // load receiver if needed (after appendix is pushed so parameter size is correct)
3708 // Note: no return address pushed yet
3709 if (load_receiver) {
3710 __ move(AT, ConstantPoolCacheEntry::parameter_size_mask);
3711 __ andr(recv, flags, AT);
3712 // 2014/07/31 Fu: Since we won't push RA on stack, no_return_pc_pushed_yet should be 0.
3713 const int no_return_pc_pushed_yet = 0; // argument slot correction before we push return address
3714 const int receiver_is_at_end = -1; // back off one slot to get receiver
3715 Address recv_addr = __ argument_address(recv, no_return_pc_pushed_yet + receiver_is_at_end);
3716 __ ld(recv, recv_addr);
3717 __ verify_oop(recv);
3718 }
3719 if(save_flags) {
3720 __ move(BCP, flags);
3721 }
3723 // compute return type
3724 __ dsrl(flags, flags, ConstantPoolCacheEntry::tos_state_shift);
3725 __ andi(flags, flags, 0xf);
3727 // Make sure we don't need to mask flags for tos_state_shift after the above shift
3728 ConstantPoolCacheEntry::verify_tos_state_shift();
3729 // load return address
3730 {
3731 const address table = (address) Interpreter::invoke_return_entry_table_for(code);
3732 __ li(AT, (long)table);
3733 __ dsll(flags, flags, LogBytesPerWord);
3734 __ dadd(AT, AT, flags);
3735 __ ld(RA, AT, 0);
3736 }
3738 if (save_flags) {
3739 __ move(flags, BCP);
3740 __ restore_bcp();
3741 }
3742 }
3744 // used registers : T0, T3, T1, T2
3745 // T3 : recv, this two register using convention is by prepare_invoke
3746 // T1 : flags, klass
3747 // Rmethod : method, index must be Rmethod
3748 void TemplateTable::invokevirtual_helper(Register index,
3749 Register recv,
3750 Register flags) {
3752 assert_different_registers(index, recv, flags, T2);
3754 // Test for an invoke of a final method
3755 Label notFinal;
3756 __ move(AT, (1 << ConstantPoolCacheEntry::is_vfinal_shift));
3757 __ andr(AT, flags, AT);
3758 __ beq(AT, R0, notFinal);
3759 __ delayed()->nop();
3761 Register method = index; // method must be Rmethod
3762 assert(method == Rmethod, "methodOop must be Rmethod for interpreter calling convention");
3764 // do the call - the index is actually the method to call
3765 // the index is indeed methodOop, for this is vfinal,
3766 // see ConstantPoolCacheEntry::set_method for more info
3768 __ verify_oop(method);
3770 // It's final, need a null check here!
3771 __ null_check(recv);
3773 // profile this call
3774 __ profile_final_call(T2);
3776 // 2014/11/24 Fu
3777 // T2: tmp, used for mdp
3778 // method: callee
3779 // T9: tmp
3780 // is_virtual: true
3781 __ profile_arguments_type(T2, method, T9, true);
3783 __ jump_from_interpreted(method, T2);
3785 __ bind(notFinal);
3787 // get receiver klass
3788 __ null_check(recv, oopDesc::klass_offset_in_bytes());
3789 __ load_klass(T2, recv);
3790 __ verify_oop(T2);
3792 // profile this call
3793 __ profile_virtual_call(T2, T0, T1);
3795 // get target methodOop & entry point
3796 const int base = InstanceKlass::vtable_start_offset() * wordSize;
3797 assert(vtableEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
3798 __ dsll(AT, index, Address::times_ptr);
3799 // T2: receiver
3800 __ dadd(AT, T2, AT);
3801 //this is a ualign read
3802 __ ld(method, AT, base + vtableEntry::method_offset_in_bytes());
3803 __ profile_arguments_type(T2, method, T9, true);
3804 __ jump_from_interpreted(method, T2);
3806 }
3808 void TemplateTable::invokevirtual(int byte_no) {
3809 transition(vtos, vtos);
3810 assert(byte_no == f2_byte, "use this argument");
3811 prepare_invoke(byte_no, Rmethod, NOREG, T3, T1);
3812 // now recv & flags in T3, T1
3813 invokevirtual_helper(Rmethod, T3, T1);
3814 }
3816 // T9 : entry
3817 // Rmethod : method
3818 void TemplateTable::invokespecial(int byte_no) {
3819 transition(vtos, vtos);
3820 assert(byte_no == f1_byte, "use this argument");
3821 prepare_invoke(byte_no, Rmethod, NOREG, T3);
3822 // now recv & flags in T3, T1
3823 __ verify_oop(T3);
3824 __ null_check(T3);
3825 __ profile_call(T9);
3827 // 2014/11/24 Fu
3828 // T8: tmp, used for mdp
3829 // Rmethod: callee
3830 // T9: tmp
3831 // is_virtual: false
3832 __ profile_arguments_type(T8, Rmethod, T9, false);
3834 __ jump_from_interpreted(Rmethod, T9);
3835 __ move(T0, T3);//aoqi ?
3836 }
3838 void TemplateTable::invokestatic(int byte_no) {
3839 transition(vtos, vtos);
3840 assert(byte_no == f1_byte, "use this argument");
3841 prepare_invoke(byte_no, Rmethod, NOREG);
3842 __ verify_oop(Rmethod);
3844 __ profile_call(T9);
3846 // 2014/11/24 Fu
3847 // T8: tmp, used for mdp
3848 // Rmethod: callee
3849 // T9: tmp
3850 // is_virtual: false
3851 __ profile_arguments_type(T8, Rmethod, T9, false);
3853 __ jump_from_interpreted(Rmethod, T9);
3854 }
3856 // i have no idea what to do here, now. for future change. FIXME.
3857 void TemplateTable::fast_invokevfinal(int byte_no) {
3858 transition(vtos, vtos);
3859 assert(byte_no == f2_byte, "use this argument");
3860 __ stop("fast_invokevfinal not used on mips64");
3861 }
3863 // used registers : T0, T1, T2, T3, T1, A7
3864 // T0 : itable, vtable, entry
3865 // T1 : interface
3866 // T3 : receiver
3867 // T1 : flags, klass
3868 // Rmethod : index, method, this is required by interpreter_entry
3869 void TemplateTable::invokeinterface(int byte_no) {
3870 transition(vtos, vtos);
3871 //this method will use T1-T4 and T0
3872 assert(byte_no == f1_byte, "use this argument");
3873 prepare_invoke(byte_no, T2, Rmethod, T3, T1);
3874 // T2: Interface
3875 // Rmethod: index
3876 // T3: receiver
3877 // T1: flags
3879 // Special case of invokeinterface called for virtual method of
3880 // java.lang.Object. See cpCacheOop.cpp for details.
3881 // This code isn't produced by javac, but could be produced by
3882 // another compliant java compiler.
3883 Label notMethod;
3884 __ move(AT, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift));
3885 __ andr(AT, T1, AT);
3886 __ beq(AT, R0, notMethod);
3887 __ delayed()->nop();
3889 invokevirtual_helper(Rmethod, T3, T1);
3890 __ bind(notMethod);
3891 // Get receiver klass into T1 - also a null check
3892 //add for compressedoops
3893 __ load_klass(T1, T3);
3894 __ verify_oop(T1);
3896 // profile this call
3897 __ profile_virtual_call(T1, T0, FSR);
3899 // Compute start of first itableOffsetEntry (which is at the end of the vtable)
3900 // TODO: x86 add a new method lookup_interface_method // LEE
3901 const int base = InstanceKlass::vtable_start_offset() * wordSize;
3902 assert(vtableEntry::size() * wordSize == 8, "adjust the scaling in the code below");
3903 __ lw(AT, T1, InstanceKlass::vtable_length_offset() * wordSize);
3904 __ dsll(AT, AT, Address::times_8);
3905 __ dadd(T0, T1, AT);
3906 __ daddi(T0, T0, base);
3907 if (HeapWordsPerLong > 1) {
3908 // Round up to align_object_offset boundary
3909 __ round_to(T0, BytesPerLong);
3910 }
3911 // now T0 is the begin of the itable
3913 Label entry, search, interface_ok;
3915 ///__ jmp(entry);
3916 __ b(entry);
3917 __ delayed()->nop();
3919 __ bind(search);
3920 __ increment(T0, itableOffsetEntry::size() * wordSize);
3922 __ bind(entry);
3924 // Check that the entry is non-null. A null entry means that the receiver
3925 // class doesn't implement the interface, and wasn't the same as the
3926 // receiver class checked when the interface was resolved.
3927 __ ld(AT, T0, itableOffsetEntry::interface_offset_in_bytes());
3928 __ bne(AT, R0, interface_ok);
3929 __ delayed()->nop();
3930 // throw exception
3931 // the call_VM checks for exception, so we should never return here.
3933 //__ pop();//FIXME here,
3934 // pop return address (pushed by prepare_invoke).
3935 // no need now, we just save the value in RA now
3937 __ call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError));
3938 __ should_not_reach_here();
3940 __ bind(interface_ok);
3941 //NOTICE here, no pop as x86 do
3942 __ bne(AT, T2, search);
3943 __ delayed()->nop();
3945 // now we get vtable of the interface
3946 __ ld(T0, T0, itableOffsetEntry::offset_offset_in_bytes());
3947 __ daddu(T0, T1, T0);
3948 assert(itableMethodEntry::size() * wordSize == 8, "adjust the scaling in the code below");
3949 __ dsll(AT, Rmethod, Address::times_8);
3950 __ daddu(AT, T0, AT);
3951 // now we get the method
3952 __ ld(Rmethod, AT, 0);
3953 // Rnext: methodOop to call
3954 // T3: receiver
3955 // Check for abstract method error
3956 // Note: This should be done more efficiently via a throw_abstract_method_error
3957 // interpreter entry point and a conditional jump to it in case of a null
3958 // method.
3959 {
3960 Label L;
3961 __ bne(Rmethod, R0, L);
3962 __ delayed()->nop();
3964 // throw exception
3965 // note: must restore interpreter registers to canonical
3966 // state for exception handling to work correctly!
3967 ///__ popl(ebx); // pop return address (pushed by prepare_invoke)
3968 //__ restore_bcp(); // esi must be correct for exception handler
3969 //(was destroyed)
3970 //__ restore_locals(); // make sure locals pointer
3971 //is correct as well (was destroyed)
3972 ///__ call_VM(noreg, CAST_FROM_FN_PTR(address,
3973 //InterpreterRuntime::throw_AbstractMethodError));
3974 __ call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
3975 // the call_VM checks for exception, so we should never return here.
3976 __ should_not_reach_here();
3977 __ bind(L);
3978 }
3980 // 2014/11/24 Fu
3981 // T8: tmp, used for mdp
3982 // Rmethod: callee
3983 // T9: tmp
3984 // is_virtual: true
3985 __ profile_arguments_type(T8, Rmethod, T9, true);
3987 __ jump_from_interpreted(Rmethod, T9);
3988 }
3991 void TemplateTable::invokehandle(int byte_no) {
3992 transition(vtos, vtos);
3993 assert(byte_no == f1_byte, "use this argument");
3994 const Register T2_method = Rmethod;
3995 const Register FSR_mtype = FSR;
3996 const Register T3_recv = T3;
3998 if (!EnableInvokeDynamic) {
3999 // rewriter does not generate this bytecode
4000 __ should_not_reach_here();
4001 return;
4002 }
4004 prepare_invoke(byte_no, T2_method, FSR_mtype, T3_recv);
4005 //??__ verify_method_ptr(T2_method);
4006 __ verify_oop(T3_recv);
4007 __ null_check(T3_recv);
4009 // rax: MethodType object (from cpool->resolved_references[f1], if necessary)
4010 // rbx: MH.invokeExact_MT method (from f2)
4012 // Note: rax_mtype is already pushed (if necessary) by prepare_invoke
4014 // FIXME: profile the LambdaForm also
4015 __ profile_final_call(T9);
4017 // 2014/11/24 Fu
4018 // T8: tmp, used for mdp
4019 // T2_method: callee
4020 // T9: tmp
4021 // is_virtual: true
4022 __ profile_arguments_type(T8, T2_method, T9, true);
4024 __ jump_from_interpreted(T2_method, T9);
4025 }
4027 void TemplateTable::invokedynamic(int byte_no) {
4028 transition(vtos, vtos);
4029 assert(byte_no == f1_byte, "use this argument");
4031 if (!EnableInvokeDynamic) {
4032 // We should not encounter this bytecode if !EnableInvokeDynamic.
4033 // The verifier will stop it. However, if we get past the verifier,
4034 // this will stop the thread in a reasonable way, without crashing the JVM.
4035 __ call_VM(noreg, CAST_FROM_FN_PTR(address,
4036 InterpreterRuntime::throw_IncompatibleClassChangeError));
4037 // the call_VM checks for exception, so we should never return here.
4038 __ should_not_reach_here();
4039 return;
4040 }
4042 //const Register Rmethod = T2;
4043 const Register T2_callsite = T2;
4045 prepare_invoke(byte_no, Rmethod, T2_callsite);
4047 // rax: CallSite object (from cpool->resolved_references[f1])
4048 // rbx: MH.linkToCallSite method (from f2)
4050 // Note: rax_callsite is already pushed by prepare_invoke
4051 // %%% should make a type profile for any invokedynamic that takes a ref argument
4052 // profile this call
4053 __ profile_call(T9);
4055 // 2014/11/24 Fu
4056 // T8: tmp, used for mdp
4057 // Rmethod: callee
4058 // T9: tmp
4059 // is_virtual: false
4060 __ profile_arguments_type(T8, Rmethod, T9, false);
4062 __ verify_oop(T2_callsite);
4064 __ jump_from_interpreted(Rmethod, T9);
4065 }
4067 //-----------------------------------------------------------------------------
4068 // Allocation
4069 // T1 : tags & buffer end & thread
4070 // T2 : object end
4071 // T3 : klass
4072 // T1 : object size
4073 // A1 : cpool
4074 // A2 : cp index
4075 // return object in FSR
4076 void TemplateTable::_new() {
4077 transition(vtos, atos);
4078 __ get_unsigned_2_byte_index_at_bcp(A2, 1);
4080 Label slow_case;
4081 Label done;
4082 Label initialize_header;
4083 Label initialize_object; // including clearing the fields
4084 Label allocate_shared;
4086 // get InstanceKlass in T3
4087 __ get_cpool_and_tags(A1, T1);
4089 __ dsll(AT, A2, Address::times_8);
4090 if (UseLoongsonISA && Assembler::is_simm(sizeof(ConstantPool), 8)) {
4091 __ gsldx(T3, A1, AT, sizeof(ConstantPool));
4092 } else {
4093 __ dadd(AT, A1, AT);
4094 __ ld(T3, AT, sizeof(ConstantPool));
4095 }
4097 // make sure the class we're about to instantiate has been resolved.
4098 // Note: slow_case does a pop of stack, which is why we loaded class/pushed above
4099 const int tags_offset = Array<u1>::base_offset_in_bytes();
4100 if (UseLoongsonISA && Assembler::is_simm(tags_offset, 8)) {
4101 __ gslbx(AT, T1, A2, tags_offset);
4102 } else {
4103 __ dadd(T1, T1, A2);
4104 __ lb(AT, T1, tags_offset);
4105 }
4106 __ daddiu(AT, AT, - (int)JVM_CONSTANT_Class);
4107 __ bne(AT, R0, slow_case);
4108 //__ delayed()->nop();
4111 // make sure klass is initialized & doesn't have finalizer
4112 // make sure klass is fully initialized
4113 __ lhu(T1, T3, in_bytes(InstanceKlass::init_state_offset()));
4114 __ daddiu(AT, T1, - (int)InstanceKlass::fully_initialized);
4115 __ bne(AT, R0, slow_case);
4116 //__ delayed()->nop();
4118 // has_finalizer
4119 __ lw(T0, T3, in_bytes(Klass::layout_helper_offset()) );
4120 __ andi(AT, T0, Klass::_lh_instance_slow_path_bit);
4121 __ bne(AT, R0, slow_case);
4122 //__ delayed()->nop();
4124 // Allocate the instance
4125 // 1) Try to allocate in the TLAB
4126 // 2) if fail and the object is large allocate in the shared Eden
4127 // 3) if the above fails (or is not applicable), go to a slow case
4128 // (creates a new TLAB, etc.)
4130 const bool allow_shared_alloc =
4131 Universe::heap()->supports_inline_contig_alloc() && !CMSIncrementalMode;
4133 if (UseTLAB) {
4134 #ifndef OPT_THREAD
4135 const Register thread = T8;
4136 __ get_thread(thread);
4137 #else
4138 const Register thread = TREG;
4139 #endif
4140 // get tlab_top
4141 __ ld(FSR, thread, in_bytes(JavaThread::tlab_top_offset()));
4142 // get tlab_end
4143 __ ld(AT, thread, in_bytes(JavaThread::tlab_end_offset()));
4144 __ dadd(T2, FSR, T0);
4145 __ slt(AT, AT, T2);
4146 __ bne(AT, R0, allow_shared_alloc ? allocate_shared : slow_case);
4147 __ delayed()->nop();
4148 __ sd(T2, thread, in_bytes(JavaThread::tlab_top_offset()));
4150 if (ZeroTLAB) {
4151 // the fields have been already cleared
4152 __ beq(R0, R0, initialize_header);
4153 } else {
4154 // initialize both the header and fields
4155 __ beq(R0, R0, initialize_object);
4156 }
4157 __ delayed()->nop();
4158 }
4160 // Allocation in the shared Eden , if allowed
4161 // T0 : instance size in words
4162 if(allow_shared_alloc){
4163 __ bind(allocate_shared);
4165 Label retry;
4166 Address heap_top(T1);
4167 __ set64(T1, (long)Universe::heap()->top_addr());
4168 __ ld(FSR, heap_top);
4170 __ bind(retry);
4171 __ set64(AT, (long)Universe::heap()->end_addr());
4172 __ ld(AT, AT, 0);
4173 __ dadd(T2, FSR, T0);
4174 __ slt(AT, AT, T2);
4175 __ bne(AT, R0, slow_case);
4176 __ delayed()->nop();
4178 // Compare FSR with the top addr, and if still equal, store the new
4179 // top addr in ebx at the address of the top addr pointer. Sets ZF if was
4180 // equal, and clears it otherwise. Use lock prefix for atomicity on MPs.
4181 //
4182 // FSR: object begin
4183 // T2: object end
4184 // T0: instance size in words
4186 // if someone beat us on the allocation, try again, otherwise continue
4187 __ cmpxchg(T2, heap_top, FSR);
4188 __ beq(AT, R0, retry);
4189 __ delayed()->nop();
4190 }
4192 if (UseTLAB || Universe::heap()->supports_inline_contig_alloc()) {
4193 // The object is initialized before the header. If the object size is
4194 // zero, go directly to the header initialization.
4195 __ bind(initialize_object);
4196 __ set64(AT, - sizeof(oopDesc));
4197 __ daddu(T0, T0, AT);
4198 __ beq(T0, R0, initialize_header);
4199 __ delayed()->nop();
4201 // initialize remaining object fields: T0 is a multiple of 2
4202 {
4203 Label loop;
4204 __ dadd(T1, FSR, T0);
4205 __ daddi(T1, T1, -oopSize);
4207 __ bind(loop);
4208 __ sd(R0, T1, sizeof(oopDesc) + 0 * oopSize);
4209 __ bne(T1, FSR, loop); //dont clear header
4210 __ delayed()->daddi(T1, T1, -oopSize);
4211 }
4213 //klass in T3,
4214 // initialize object header only.
4215 __ bind(initialize_header);
4216 if (UseBiasedLocking) {
4217 __ ld(AT, T3, in_bytes(Klass::prototype_header_offset()));
4218 __ sd(AT, FSR, oopDesc::mark_offset_in_bytes ());
4219 } else {
4220 __ set64(AT, (long)markOopDesc::prototype());
4221 __ sd(AT, FSR, oopDesc::mark_offset_in_bytes());
4222 }
4224 __ store_klass_gap(FSR, R0);
4225 __ store_klass(FSR, T3);
4227 {
4228 SkipIfEqual skip_if(_masm, &DTraceAllocProbes, 0);
4229 // Trigger dtrace event for fastpath
4230 __ push(atos);
4231 __ call_VM_leaf(
4232 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc), FSR);
4233 __ pop(atos);
4235 }
4236 __ b(done);
4237 __ delayed()->nop();
4238 }
4240 // slow case
4241 __ bind(slow_case);
4242 call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), A1, A2);
4244 // continue
4245 __ bind(done);
4246 __ sync();
4247 }
4249 void TemplateTable::newarray() {
4250 transition(itos, atos);
4251 __ lbu(A1, at_bcp(1));
4252 //type, count
4253 call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::newarray), A1, FSR);
4254 __ sync();
4255 }
4257 void TemplateTable::anewarray() {
4258 transition(itos, atos);
4259 __ get_2_byte_integer_at_bcp(A2, AT, 1);
4260 __ huswap(A2);
4261 __ get_constant_pool(A1);
4262 // cp, index, count
4263 call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::anewarray), A1, A2, FSR);
4264 __ sync();
4265 }
4267 void TemplateTable::arraylength() {
4268 transition(atos, itos);
4269 __ null_check(FSR, arrayOopDesc::length_offset_in_bytes());
4270 __ lw(FSR, FSR, arrayOopDesc::length_offset_in_bytes());
4271 }
4273 // i use T2 as ebx, T3 as ecx, T1 as edx
4274 // when invoke gen_subtype_check, super in T3, sub in T2, object in FSR(it's always)
4275 // T2 : sub klass
4276 // T3 : cpool
4277 // T3 : super klass
4278 void TemplateTable::checkcast() {
4279 transition(atos, atos);
4280 Label done, is_null, ok_is_subtype, quicked, resolved;
4281 __ beq(FSR, R0, is_null);
4282 __ delayed()->nop();
4284 // Get cpool & tags index
4285 __ get_cpool_and_tags(T3, T1);
4286 __ get_2_byte_integer_at_bcp(T2, AT, 1);
4287 __ huswap(T2);
4289 // See if bytecode has already been quicked
4290 __ dadd(AT, T1, T2);
4291 __ lb(AT, AT, Array<u1>::base_offset_in_bytes());
4292 __ daddiu(AT, AT, - (int)JVM_CONSTANT_Class);
4293 __ beq(AT, R0, quicked);
4294 __ delayed()->nop();
4296 /* 2012/6/2 Jin: In InterpreterRuntime::quicken_io_cc, lots of new classes may be loaded.
4297 * Then, GC will move the object in V0 to another places in heap.
4298 * Therefore, We should never save such an object in register.
4299 * Instead, we should save it in the stack. It can be modified automatically by the GC thread.
4300 * After GC, the object address in FSR is changed to a new place.
4301 */
4302 __ push(atos);
4303 const Register thread = TREG;
4304 #ifndef OPT_THREAD
4305 __ get_thread(thread);
4306 #endif
4307 call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc));
4308 __ get_vm_result_2(T3, thread);
4309 __ pop_ptr(FSR);
4310 __ b(resolved);
4311 __ delayed()->nop();
4313 // klass already in cp, get superklass in T3
4314 __ bind(quicked);
4315 __ dsll(AT, T2, Address::times_8);
4316 __ dadd(AT, T3, AT);
4317 __ ld(T3, AT, sizeof(ConstantPool));
4319 __ bind(resolved);
4321 // get subklass in T2
4322 //add for compressedoops
4323 __ load_klass(T2, FSR);
4324 // Superklass in T3. Subklass in T2.
4325 __ gen_subtype_check(T3, T2, ok_is_subtype);
4327 // Come here on failure
4328 // object is at FSR
4329 __ jmp(Interpreter::_throw_ClassCastException_entry);
4330 __ delayed()->nop();
4332 // Come here on success
4333 __ bind(ok_is_subtype);
4335 // Collect counts on whether this check-cast sees NULLs a lot or not.
4336 if (ProfileInterpreter) {
4337 __ b(done);
4338 __ delayed()->nop();
4339 __ bind(is_null);
4340 __ profile_null_seen(T3);
4341 } else {
4342 __ bind(is_null);
4343 }
4344 __ bind(done);
4345 }
4347 // i use T3 as cpool, T1 as tags, T2 as index
4348 // object always in FSR, superklass in T3, subklass in T2
4349 void TemplateTable::instanceof() {
4350 transition(atos, itos);
4351 Label done, is_null, ok_is_subtype, quicked, resolved;
4353 __ beq(FSR, R0, is_null);
4354 __ delayed()->nop();
4356 // Get cpool & tags index
4357 __ get_cpool_and_tags(T3, T1);
4358 // get index
4359 __ get_2_byte_integer_at_bcp(T2, AT, 1);
4360 __ hswap(T2);
4362 // See if bytecode has already been quicked
4363 // quicked
4364 __ daddu(AT, T1, T2);
4365 __ lb(AT, AT, Array<u1>::base_offset_in_bytes());
4366 __ daddiu(AT, AT, - (int)JVM_CONSTANT_Class);
4367 __ beq(AT, R0, quicked);
4368 __ delayed()->nop();
4370 __ push(atos);
4371 const Register thread = TREG;
4372 #ifndef OPT_THREAD
4373 __ get_thread(thread);
4374 #endif
4375 call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc));
4376 __ get_vm_result_2(T3, thread);
4377 __ pop_ptr(FSR);
4378 __ b(resolved);
4379 __ delayed()->nop();
4381 // get superklass in T3, subklass in T2
4382 __ bind(quicked);
4383 __ dsll(AT, T2, Address::times_8);
4384 __ daddu(AT, T3, AT);
4385 __ ld(T3, AT, sizeof(ConstantPool));
4387 __ bind(resolved);
4388 // get subklass in T2
4389 //add for compressedoops
4390 __ load_klass(T2, FSR);
4392 // Superklass in T3. Subklass in T2.
4393 __ gen_subtype_check(T3, T2, ok_is_subtype);
4394 // Come here on failure
4395 __ b(done);
4396 __ delayed(); __ move(FSR, R0);
4398 // Come here on success
4399 __ bind(ok_is_subtype);
4400 __ move(FSR, 1);
4402 // Collect counts on whether this test sees NULLs a lot or not.
4403 if (ProfileInterpreter) {
4404 __ beq(R0, R0, done);
4405 __ nop();
4406 __ bind(is_null);
4407 __ profile_null_seen(T3);
4408 } else {
4409 __ bind(is_null); // same as 'done'
4410 }
4411 __ bind(done);
4412 // FSR = 0: obj == NULL or obj is not an instanceof the specified klass
4413 // FSR = 1: obj != NULL and obj is an instanceof the specified klass
4414 }
4416 //--------------------------------------------------------
4417 //--------------------------------------------
4418 // Breakpoints
4419 void TemplateTable::_breakpoint() {
4420 // Note: We get here even if we are single stepping..
4421 // jbug inists on setting breakpoints at every bytecode
4422 // even if we are in single step mode.
4424 transition(vtos, vtos);
4426 // get the unpatched byte code
4427 __ get_method(A1);
4428 __ call_VM(NOREG,
4429 CAST_FROM_FN_PTR(address,
4430 InterpreterRuntime::get_original_bytecode_at),
4431 A1, BCP);
4432 __ move(Rnext, V0); // Jin: Rnext will be used in dispatch_only_normal
4434 // post the breakpoint event
4435 __ get_method(A1);
4436 __ call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::_breakpoint), A1, BCP);
4438 // complete the execution of original bytecode
4439 __ dispatch_only_normal(vtos);
4440 }
4442 //-----------------------------------------------------------------------------
4443 // Exceptions
4445 void TemplateTable::athrow() {
4446 transition(atos, vtos);
4447 __ null_check(FSR);
4448 __ jmp(Interpreter::throw_exception_entry());
4449 __ delayed()->nop();
4450 }
4452 //-----------------------------------------------------------------------------
4453 // Synchronization
4454 //
4455 // Note: monitorenter & exit are symmetric routines; which is reflected
4456 // in the assembly code structure as well
4457 //
4458 // Stack layout:
4459 //
4460 // [expressions ] <--- SP = expression stack top
4461 // ..
4462 // [expressions ]
4463 // [monitor entry] <--- monitor block top = expression stack bot
4464 // ..
4465 // [monitor entry]
4466 // [frame data ] <--- monitor block bot
4467 // ...
4468 // [return addr ] <--- FP
4470 // we use T2 as monitor entry pointer, T3 as monitor top pointer, c_rarg0 as free slot pointer
4471 // object always in FSR
4472 void TemplateTable::monitorenter() {
4473 transition(atos, vtos);
4475 // check for NULL object
4476 __ null_check(FSR);
4478 const Address monitor_block_top(FP, frame::interpreter_frame_monitor_block_top_offset
4479 * wordSize);
4480 const int entry_size = (frame::interpreter_frame_monitor_size()* wordSize);
4481 Label allocated;
4483 // initialize entry pointer
4484 __ move(c_rarg0, R0);
4486 // find a free slot in the monitor block (result in edx)
4487 {
4488 Label entry, loop, exit, next;
4489 __ ld(T2, monitor_block_top);
4490 __ b(entry);
4491 __ delayed()->daddi(T3, FP, frame::interpreter_frame_initial_sp_offset * wordSize);
4493 // free slot?
4494 __ bind(loop);
4495 __ ld(AT, T2, BasicObjectLock::obj_offset_in_bytes());
4496 __ bne(AT, R0, next);
4497 __ delayed()->nop();
4498 __ move(c_rarg0, T2);
4500 __ bind(next);
4501 __ beq(FSR, AT, exit);
4502 __ delayed()->nop();
4503 __ daddi(T2, T2, entry_size);
4505 __ bind(entry);
4506 __ bne(T3, T2, loop);
4507 __ delayed()->nop();
4508 __ bind(exit);
4509 }
4511 __ bne(c_rarg0, R0, allocated);
4512 __ delayed()->nop();
4514 // allocate one if there's no free slot
4515 {
4516 Label entry, loop;
4517 // 1. compute new pointers // SP: old expression stack top
4518 __ ld(c_rarg0, monitor_block_top);
4519 __ daddi(SP, SP, - entry_size);
4520 __ daddi(c_rarg0, c_rarg0, - entry_size);
4521 __ sd(c_rarg0, monitor_block_top);
4522 __ b(entry);
4523 __ delayed(); __ move(T3, SP);
4525 // 2. move expression stack contents
4526 __ bind(loop);
4527 __ ld(AT, T3, entry_size);
4528 __ sd(AT, T3, 0);
4529 __ daddi(T3, T3, wordSize);
4530 __ bind(entry);
4531 __ bne(T3, c_rarg0, loop);
4532 __ delayed()->nop();
4533 }
4535 __ bind(allocated);
4536 // Increment bcp to point to the next bytecode,
4537 // so exception handling for async. exceptions work correctly.
4538 // The object has already been poped from the stack, so the
4539 // expression stack looks correct.
4540 __ daddi(BCP, BCP, 1);
4541 __ sd(FSR, c_rarg0, BasicObjectLock::obj_offset_in_bytes());
4542 __ lock_object(c_rarg0);
4543 // check to make sure this monitor doesn't cause stack overflow after locking
4544 __ save_bcp(); // in case of exception
4545 __ generate_stack_overflow_check(0);
4546 // The bcp has already been incremented. Just need to dispatch to next instruction.
4548 __ dispatch_next(vtos);
4549 }
4551 // T2 : top
4552 // c_rarg0 : entry
4553 void TemplateTable::monitorexit() {
4554 transition(atos, vtos);
4556 __ null_check(FSR);
4558 const int entry_size =(frame::interpreter_frame_monitor_size()* wordSize);
4559 Label found;
4561 // find matching slot
4562 {
4563 Label entry, loop;
4564 __ ld(c_rarg0, FP, frame::interpreter_frame_monitor_block_top_offset * wordSize);
4565 __ b(entry);
4566 __ delayed()->daddiu(T2, FP, frame::interpreter_frame_initial_sp_offset * wordSize);
4568 __ bind(loop);
4569 __ ld(AT, c_rarg0, BasicObjectLock::obj_offset_in_bytes());
4570 __ beq(FSR, AT, found);
4571 __ delayed()->nop();
4572 __ daddiu(c_rarg0, c_rarg0, entry_size);
4573 __ bind(entry);
4574 __ bne(T2, c_rarg0, loop);
4575 __ delayed()->nop();
4576 }
4578 // error handling. Unlocking was not block-structured
4579 Label end;
4580 __ call_VM(NOREG, CAST_FROM_FN_PTR(address,
4581 InterpreterRuntime::throw_illegal_monitor_state_exception));
4582 __ should_not_reach_here();
4584 // call run-time routine
4585 // c_rarg0: points to monitor entry
4586 __ bind(found);
4587 __ move(TSR, FSR);
4588 __ unlock_object(c_rarg0);
4589 __ move(FSR, TSR);
4590 __ bind(end);
4591 }
4594 // Wide instructions
4595 void TemplateTable::wide() {
4596 transition(vtos, vtos);
4597 // Note: the esi increment step is part of the individual wide bytecode implementations
4598 __ lbu(Rnext, at_bcp(1));
4599 __ dsll(T9, Rnext, Address::times_8);
4600 __ li(AT, (long)Interpreter::_wentry_point);
4601 __ dadd(AT, T9, AT);
4602 __ ld(T9, AT, 0);
4603 __ jr(T9);
4604 __ delayed()->nop();
4605 }
4608 void TemplateTable::multianewarray() {
4609 transition(vtos, atos);
4610 // last dim is on top of stack; we want address of first one:
4611 // first_addr = last_addr + (ndims - 1) * wordSize
4612 __ lbu(A1, at_bcp(3)); // dimension
4613 __ daddi(A1, A1, -1);
4614 __ dsll(A1, A1, Address::times_8);
4615 __ dadd(A1, SP, A1); // now A1 pointer to the count array on the stack
4616 call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::multianewarray), A1);
4617 __ lbu(AT, at_bcp(3));
4618 __ dsll(AT, AT, Address::times_8);
4619 __ dadd(SP, SP, AT);
4620 __ sync();
4621 }
4622 #endif // !CC_INTERP