Thu, 19 Oct 2017 09:49:23 +0800
#6173 Fixed the subtraction in TemplateTable::ineg().
Reviewed-by: aoqi
Summary: The result of using subu32 and using dsubu in TemplateTable::ineg() to calculate 0 - 0x80000000 is different.
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 // bytecode folding
105 void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
106 Register tmp_reg, bool load_bc_into_bc_reg/*=true*/,
107 int byte_no) {
108 if (!RewriteBytecodes) return;
109 Label L_patch_done;
111 switch (bc) {
112 case Bytecodes::_fast_aputfield:
113 case Bytecodes::_fast_bputfield:
114 case Bytecodes::_fast_cputfield:
115 case Bytecodes::_fast_dputfield:
116 case Bytecodes::_fast_fputfield:
117 case Bytecodes::_fast_iputfield:
118 case Bytecodes::_fast_lputfield:
119 case Bytecodes::_fast_sputfield:
120 {
121 // We skip bytecode quickening for putfield instructions when
122 // the put_code written to the constant pool cache is zero.
123 // This is required so that every execution of this instruction
124 // calls out to InterpreterRuntime::resolve_get_put to do
125 // additional, required work.
126 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
127 assert(load_bc_into_bc_reg, "we use bc_reg as temp");
128 __ get_cache_and_index_and_bytecode_at_bcp(tmp_reg, bc_reg, tmp_reg, byte_no, 1);
129 __ daddi(bc_reg, R0, bc);
130 __ beq(tmp_reg, R0, L_patch_done);
131 __ delayed()->nop();
132 }
133 break;
134 default:
135 assert(byte_no == -1, "sanity");
136 // the pair bytecodes have already done the load.
137 if (load_bc_into_bc_reg) {
138 __ move(bc_reg, bc);
139 }
140 }
142 if (JvmtiExport::can_post_breakpoint()) {
143 Label L_fast_patch;
144 // if a breakpoint is present we can't rewrite the stream directly
145 __ lbu(tmp_reg, at_bcp(0));
146 __ move(AT, Bytecodes::_breakpoint);
147 __ bne(tmp_reg, AT, L_fast_patch);
148 __ delayed()->nop();
150 __ get_method(tmp_reg);
151 // Let breakpoint table handling rewrite to quicker bytecode
152 __ call_VM(NOREG, CAST_FROM_FN_PTR(address,
153 InterpreterRuntime::set_original_bytecode_at), tmp_reg, BCP, bc_reg);
155 __ b(L_patch_done);
156 __ delayed()->nop();
157 __ bind(L_fast_patch);
158 }
160 #ifdef ASSERT
161 Label L_okay;
162 __ lbu(tmp_reg, at_bcp(0));
163 __ move(AT, (int)Bytecodes::java_code(bc));
164 __ beq(tmp_reg, AT, L_okay);
165 __ delayed()->nop();
166 __ beq(tmp_reg, bc_reg, L_patch_done);
167 __ delayed()->nop();
168 __ stop("patching the wrong bytecode");
169 __ bind(L_okay);
170 #endif
172 // patch bytecode
173 __ sb(bc_reg, at_bcp(0));
174 __ bind(L_patch_done);
175 }
178 // Individual instructions
180 void TemplateTable::nop() {
181 transition(vtos, vtos);
182 // nothing to do
183 }
185 void TemplateTable::shouldnotreachhere() {
186 transition(vtos, vtos);
187 __ stop("shouldnotreachhere bytecode");
188 }
190 void TemplateTable::aconst_null() {
191 transition(vtos, atos);
192 __ move(FSR, R0);
193 }
195 void TemplateTable::iconst(int value) {
196 transition(vtos, itos);
197 if (value == 0) {
198 __ move(FSR, R0);
199 } else {
200 __ move(FSR, value);
201 }
202 }
204 void TemplateTable::lconst(int value) {
205 transition(vtos, ltos);
206 if (value == 0) {
207 __ move(FSR, R0);
208 } else {
209 __ move(FSR, value);
210 }
211 }
213 void TemplateTable::fconst(int value) {
214 transition(vtos, ftos);
215 switch( value ) {
216 case 0: __ mtc1(R0, FSF); return;
217 case 1: __ addiu(AT, R0, 1); break;
218 case 2: __ addiu(AT, R0, 2); break;
219 default: ShouldNotReachHere();
220 }
221 __ mtc1(AT, FSF);
222 __ cvt_s_w(FSF, FSF);
223 }
225 void TemplateTable::dconst(int value) {
226 transition(vtos, dtos);
227 switch( value ) {
228 case 0: __ dmtc1(R0, FSF);
229 return;
230 case 1: __ daddiu(AT, R0, 1);
231 __ dmtc1(AT, FSF);
232 __ cvt_d_w(FSF, FSF);
233 break;
234 default: ShouldNotReachHere();
235 }
236 }
238 void TemplateTable::bipush() {
239 transition(vtos, itos);
240 __ lb(FSR, at_bcp(1));
241 }
243 void TemplateTable::sipush() {
244 transition(vtos, itos);
245 __ lb(FSR, BCP, 1);
246 __ lbu(AT, BCP, 2);
247 __ dsll(FSR, FSR, 8);
248 __ orr(FSR, FSR, AT);
249 }
251 // T1 : tags
252 // T2 : index
253 // T3 : cpool
254 // T8 : tag
255 void TemplateTable::ldc(bool wide) {
256 transition(vtos, vtos);
257 Label call_ldc, notFloat, notClass, Done;
258 // get index in cpool
259 if (wide) {
260 __ get_unsigned_2_byte_index_at_bcp(T2, 1);
261 } else {
262 __ lbu(T2, at_bcp(1));
263 }
265 __ get_cpool_and_tags(T3, T1);
267 const int base_offset = ConstantPool::header_size() * wordSize;
268 const int tags_offset = Array<u1>::base_offset_in_bytes();
270 // get type
271 if (UseLoongsonISA && Assembler::is_simm(sizeof(tags_offset), 8)) {
272 __ gslbx(T1, T1, T2, tags_offset);
273 } else {
274 __ dadd(AT, T1, T2);
275 __ lb(T1, AT, tags_offset);
276 }
277 //now T1 is the tag
279 // unresolved class - get the resolved class
280 __ daddiu(AT, T1, - JVM_CONSTANT_UnresolvedClass);
281 __ beq(AT, R0, call_ldc);
282 __ delayed()->nop();
284 // unresolved class in error (resolution failed) - call into runtime
285 // so that the same error from first resolution attempt is thrown.
286 __ daddiu(AT, T1, -JVM_CONSTANT_UnresolvedClassInError);
287 __ beq(AT, R0, call_ldc);
288 __ delayed()->nop();
290 // resolved class - need to call vm to get java mirror of the class
291 __ daddiu(AT, T1, - JVM_CONSTANT_Class);
292 __ bne(AT, R0, notClass);
293 __ delayed()->dsll(T2, T2, Address::times_8);
295 __ bind(call_ldc);
296 __ move(A1, wide);
297 call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), A1);
298 //__ push(atos);
299 __ sd(FSR, SP, - Interpreter::stackElementSize);
300 __ b(Done);
301 __ delayed()->daddiu(SP, SP, - Interpreter::stackElementSize);
302 __ nop(); // added for performance issue
304 __ bind(notClass);
305 __ daddiu(AT, T1, -JVM_CONSTANT_Float);
306 __ bne(AT, R0, notFloat);
307 __ delayed()->nop();
308 // ftos
309 if (UseLoongsonISA && Assembler::is_simm(sizeof(base_offset), 8)) {
310 __ gslwxc1(FSF, T3, T2, base_offset);
311 } else {
312 __ dadd(AT, T3, T2);
313 __ lwc1(FSF, AT, base_offset);
314 }
315 //__ push_f();
316 __ swc1(FSF, SP, - Interpreter::stackElementSize);
317 __ b(Done);
318 __ delayed()->daddiu(SP, SP, - Interpreter::stackElementSize);
320 __ bind(notFloat);
321 #ifdef ASSERT
322 {
323 Label L;
324 __ daddiu(AT, T1, -JVM_CONSTANT_Integer);
325 __ beq(AT, R0, L);
326 __ delayed()->nop();
327 __ stop("unexpected tag type in ldc");
328 __ bind(L);
329 }
330 #endif
331 // itos JVM_CONSTANT_Integer only
332 if (UseLoongsonISA && Assembler::is_simm(sizeof(base_offset), 8)) {
333 __ gslwx(FSR, T3, T2, base_offset);
334 } else {
335 __ dadd(T0, T3, T2);
336 __ lw(FSR, T0, base_offset);
337 }
338 __ push(itos);
339 __ bind(Done);
340 }
342 // Fast path for caching oop constants.
343 void TemplateTable::fast_aldc(bool wide) {
344 transition(vtos, atos);
346 Register result = FSR;
347 Register tmp = SSR;
348 int index_size = wide ? sizeof(u2) : sizeof(u1);
350 Label resolved;
352 // We are resolved if the resolved reference cache entry contains a
353 // non-null object (String, MethodType, etc.)
354 assert_different_registers(result, tmp);
355 __ get_cache_index_at_bcp(tmp, 1, index_size);
356 __ load_resolved_reference_at_index(result, tmp);
357 __ bne(result, R0, resolved);
358 __ delayed()->nop();
360 address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);
361 // first time invocation - must resolve first
362 int i = (int)bytecode();
363 __ move(tmp, i);
364 __ call_VM(result, entry, tmp);
366 __ bind(resolved);
368 if (VerifyOops) {
369 __ verify_oop(result);
370 }
371 }
374 // used register: T2, T3, T1
375 // T2 : index
376 // T3 : cpool
377 // T1 : tag
378 void TemplateTable::ldc2_w() {
379 transition(vtos, vtos);
380 Label Long, Done;
382 // get index in cpool
383 __ get_unsigned_2_byte_index_at_bcp(T2, 1);
385 __ get_cpool_and_tags(T3, T1);
387 const int base_offset = ConstantPool::header_size() * wordSize;
388 const int tags_offset = Array<u1>::base_offset_in_bytes();
390 // get type in T1
391 if (UseLoongsonISA && Assembler::is_simm(tags_offset, 8)) {
392 __ gslbx(T1, T1, T2, tags_offset);
393 } else {
394 __ dadd(AT, T1, T2);
395 __ lb(T1, AT, tags_offset);
396 }
398 __ daddiu(AT, T1, - JVM_CONSTANT_Double);
399 __ bne(AT, R0, Long);
400 __ delayed()->dsll(T2, T2, Address::times_8);
402 // dtos
403 if (UseLoongsonISA && Assembler::is_simm(base_offset, 8)) {
404 __ gsldxc1(FSF, T3, T2, base_offset);
405 } else {
406 __ daddu(AT, T3, T2);
407 __ ldc1(FSF, AT, base_offset);
408 }
409 __ sdc1(FSF, SP, - 2 * wordSize);
410 __ b(Done);
411 __ delayed()->daddi(SP, SP, - 2 * wordSize);
413 // ltos
414 __ bind(Long);
415 if (UseLoongsonISA && Assembler::is_simm(base_offset, 8)) {
416 __ gsldx(FSR, T3, T2, base_offset);
417 } else {
418 __ dadd(AT, T3, T2);
419 __ ld(FSR, AT, base_offset);
420 }
421 __ push(ltos);
423 __ bind(Done);
424 }
426 // we compute the actual local variable address here
427 // the x86 dont do so for it has scaled index memory access model, we dont have, so do here
428 void TemplateTable::locals_index(Register reg, int offset) {
429 __ lbu(reg, at_bcp(offset));
430 __ dsll(reg, reg, Address::times_8);
431 __ dsub(reg, LVP, reg);
432 }
434 // this method will do bytecode folding of the two form:
435 // iload iload iload caload
436 // used register : T2, T3
437 // T2 : bytecode
438 // T3 : folded code
439 void TemplateTable::iload() {
440 transition(vtos, itos);
441 if (RewriteFrequentPairs) {
442 Label rewrite, done;
443 // get the next bytecode in T2
444 __ lbu(T2, at_bcp(Bytecodes::length_for(Bytecodes::_iload)));
445 // if _iload, wait to rewrite to iload2. We only want to rewrite the
446 // last two iloads in a pair. Comparing against fast_iload means that
447 // the next bytecode is neither an iload or a caload, and therefore
448 // an iload pair.
449 __ move(AT, Bytecodes::_iload);
450 __ beq(AT, T2, done);
451 __ delayed()->nop();
453 __ move(T3, Bytecodes::_fast_iload2);
454 __ move(AT, Bytecodes::_fast_iload);
455 __ beq(AT, T2, rewrite);
456 __ delayed()->nop();
458 // if _caload, rewrite to fast_icaload
459 __ move(T3, Bytecodes::_fast_icaload);
460 __ move(AT, Bytecodes::_caload);
461 __ beq(AT, T2, rewrite);
462 __ delayed()->nop();
464 // rewrite so iload doesn't check again.
465 __ move(T3, Bytecodes::_fast_iload);
467 // rewrite
468 // T3 : fast bytecode
469 __ bind(rewrite);
470 patch_bytecode(Bytecodes::_iload, T3, T2, false);
471 __ bind(done);
472 }
474 // Get the local value into tos
475 locals_index(T2);
476 __ lw(FSR, T2, 0);
477 }
479 // used register T2
480 // T2 : index
481 void TemplateTable::fast_iload2() {
482 transition(vtos, itos);
483 locals_index(T2);
484 __ lw(FSR, T2, 0);
485 __ push(itos);
486 locals_index(T2, 3);
487 __ lw(FSR, T2, 0);
488 }
490 // used register T2
491 // T2 : index
492 void TemplateTable::fast_iload() {
493 transition(vtos, itos);
494 locals_index(T2);
495 __ lw(FSR, T2, 0);
496 }
498 // used register T2
499 // T2 : index
500 void TemplateTable::lload() {
501 transition(vtos, ltos);
502 locals_index(T2);
503 __ ld(FSR, T2, -wordSize);
504 }
506 // used register T2
507 // T2 : index
508 void TemplateTable::fload() {
509 transition(vtos, ftos);
510 locals_index(T2);
511 __ lwc1(FSF, T2, 0);
512 }
514 // used register T2
515 // T2 : index
516 void TemplateTable::dload() {
517 transition(vtos, dtos);
518 locals_index(T2);
519 __ ldc1(FSF, T2, -wordSize);
520 }
522 // used register T2
523 // T2 : index
524 void TemplateTable::aload() {
525 transition(vtos, atos);
526 locals_index(T2);
527 __ ld(FSR, T2, 0);
528 }
530 void TemplateTable::locals_index_wide(Register reg) {
531 __ get_unsigned_2_byte_index_at_bcp(reg, 2);
532 __ dsll(reg, reg, Address::times_8);
533 __ dsub(reg, LVP, reg);
534 }
536 // used register T2
537 // T2 : index
538 void TemplateTable::wide_iload() {
539 transition(vtos, itos);
540 locals_index_wide(T2);
541 __ ld(FSR, T2, 0);
542 }
544 // used register T2
545 // T2 : index
546 void TemplateTable::wide_lload() {
547 transition(vtos, ltos);
548 locals_index_wide(T2);
549 __ ld(FSR, T2, -wordSize);
550 }
552 // used register T2
553 // T2 : index
554 void TemplateTable::wide_fload() {
555 transition(vtos, ftos);
556 locals_index_wide(T2);
557 __ lwc1(FSF, T2, 0);
558 }
560 // used register T2
561 // T2 : index
562 void TemplateTable::wide_dload() {
563 transition(vtos, dtos);
564 locals_index_wide(T2);
565 __ ldc1(FSF, T2, -wordSize);
566 }
568 // used register T2
569 // T2 : index
570 void TemplateTable::wide_aload() {
571 transition(vtos, atos);
572 locals_index_wide(T2);
573 __ ld(FSR, T2, 0);
574 }
576 // we use A2 as the regiser for index, BE CAREFUL!
577 // we dont use our tge 29 now, for later optimization
578 void TemplateTable::index_check(Register array, Register index) {
579 // Pop ptr into array
580 __ pop_ptr(array);
581 index_check_without_pop(array, index);
582 }
584 void TemplateTable::index_check_without_pop(Register array, Register index) {
585 // destroys ebx
586 // check array
587 __ null_check(array, arrayOopDesc::length_offset_in_bytes());
589 #ifdef _LP64
590 // sign extend since tos (index) might contain garbage in upper bits
591 __ sll(index, index, 0);
592 #endif // _LP64
594 // check index
595 Label ok;
596 __ lw(AT, array, arrayOopDesc::length_offset_in_bytes());
597 #ifndef OPT_RANGECHECK
598 __ sltu(AT, index, AT);
599 __ bne(AT, R0, ok);
600 __ delayed()->nop();
602 //throw_ArrayIndexOutOfBoundsException assume abberrant index in A2
603 if (A2 != index) __ move(A2, index);
604 __ jmp(Interpreter::_throw_ArrayIndexOutOfBoundsException_entry);
605 __ delayed()->nop();
606 __ bind(ok);
607 #else
608 __ lw(AT, array, arrayOopDesc::length_offset_in_bytes());
609 __ move(A2, index);
610 __ tgeu(A2, AT, 29);
611 #endif
612 }
614 void TemplateTable::iaload() {
615 transition(itos, itos);
616 if(UseBoundCheckInstruction) {
617 __ pop(SSR); //SSR:array FSR: index
618 __ dsll(FSR, FSR, 2);
619 __ dadd(FSR, SSR, FSR);
620 __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_INT));
622 __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes()); //bound
623 __ dsll(AT, AT, 2);
624 __ dadd(AT, SSR, AT);
625 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_INT));
627 __ gslwle(FSR, FSR, AT);
628 } else {
629 index_check(SSR, FSR);
630 __ dsll(FSR, FSR, 2);
631 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_INT), 8)) {
632 __ gslwx(FSR, FSR, SSR, arrayOopDesc::base_offset_in_bytes(T_INT));
633 } else {
634 __ dadd(FSR, SSR, FSR);
635 __ lw(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_INT));
636 }
637 }
638 }
640 void TemplateTable::laload() {
641 transition(itos, ltos);
642 if(UseBoundCheckInstruction) {
643 __ pop(SSR); //SSR:array FSR: index
644 __ dsll(FSR, FSR, Address::times_8);
645 __ dadd(FSR, SSR, FSR);
646 __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);
648 __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes()); //bound
649 __ dsll(AT, AT, Address::times_8);
650 __ dadd(AT, SSR, AT);
651 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);
653 __ gsldle(FSR, FSR, AT);
654 } else {
655 index_check(SSR, FSR);
656 __ dsll(AT, FSR, Address::times_8);
657 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_LONG), 8)) {
658 __ gsldx(FSR, SSR, AT, arrayOopDesc::base_offset_in_bytes(T_LONG));
659 } else {
660 __ dadd(AT, SSR, AT);
661 __ ld(FSR, AT, arrayOopDesc::base_offset_in_bytes(T_LONG));
662 }
663 }
664 }
666 void TemplateTable::faload() {
667 transition(itos, ftos);
668 if(UseBoundCheckInstruction) {
669 __ pop(SSR); //SSR:array FSR: index
670 __ shl(FSR, 2);
671 __ dadd(FSR, SSR, FSR);
672 __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
674 __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes()); //bound
675 __ shl(AT, 2);
676 __ dadd(AT, SSR, AT);
677 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
679 __ gslwlec1(FSF, FSR, AT);
680 } else {
681 index_check(SSR, FSR);
682 __ shl(FSR, 2);
683 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_FLOAT), 8)) {
684 __ gslwxc1(FSF, SSR, FSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
685 } else {
686 __ dadd(FSR, SSR, FSR);
687 __ lwc1(FSF, FSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
688 }
689 }
690 }
692 void TemplateTable::daload() {
693 transition(itos, dtos);
694 if(UseBoundCheckInstruction) {
695 __ pop(SSR); //SSR:array FSR: index
696 __ dsll(FSR, FSR, 3);
697 __ dadd(FSR, SSR, FSR);
698 __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);
700 __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes()); //bound
701 __ dsll(AT, AT, 3);
702 __ dadd(AT, SSR, AT);
703 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);
705 __ gsldlec1(FSF, FSR, AT);
706 } else {
707 index_check(SSR, FSR);
708 __ dsll(AT, FSR, 3);
709 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_DOUBLE), 8)) {
710 __ gsldxc1(FSF, SSR, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE));
711 } else {
712 __ dadd(AT, SSR, AT);
713 __ ldc1(FSF, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE));
714 }
715 }
716 }
718 void TemplateTable::aaload() {
719 transition(itos, atos);
720 index_check(SSR, FSR);
721 __ dsll(FSR, FSR, UseCompressedOops ? Address::times_4 : Address::times_8);
722 __ dadd(FSR, SSR, FSR);
723 //add for compressedoops
724 __ load_heap_oop(FSR, Address(FSR, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
725 }
727 void TemplateTable::baload() {
728 transition(itos, itos);
729 if(UseBoundCheckInstruction) {
730 __ pop(SSR); //SSR:array FSR:index
731 __ dadd(FSR, SSR, FSR);
732 __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_BYTE)); //base
734 __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes());
735 __ dadd(AT, SSR, AT);
736 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_BYTE)); //bound
738 __ gslble(FSR, FSR, AT);
739 } else {
740 index_check(SSR, FSR);
741 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_BYTE), 8)) {
742 __ gslbx(FSR, SSR, FSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
743 } else {
744 __ dadd(FSR, SSR, FSR);
745 __ lb(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
746 }
747 }
748 }
750 void TemplateTable::caload() {
751 transition(itos, itos);
752 index_check(SSR, FSR);
753 __ dsll(FSR, FSR, Address::times_2);
754 __ dadd(FSR, SSR, FSR);
755 __ lhu(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_CHAR));
756 }
758 // iload followed by caload frequent pair
759 // used register : T2
760 // T2 : index
761 void TemplateTable::fast_icaload() {
762 transition(vtos, itos);
763 // load index out of locals
764 locals_index(T2);
765 __ lw(FSR, T2, 0);
766 index_check(SSR, FSR);
767 __ dsll(FSR, FSR, 1);
768 __ dadd(FSR, SSR, FSR);
769 __ lhu(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_CHAR));
770 }
772 void TemplateTable::saload() {
773 transition(itos, itos);
774 if(UseBoundCheckInstruction) {
775 __ pop(SSR); //SSR:array FSR: index
776 __ dsll(FSR, FSR, Address::times_2);
777 __ dadd(FSR, SSR, FSR);
778 __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_SHORT));
780 __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes()); //bound
781 __ dsll(AT, AT, Address::times_2);
782 __ dadd(AT, SSR, AT);
783 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_SHORT));
785 __ gslhle(FSR, FSR, AT);
786 } else {
787 index_check(SSR, FSR);
788 __ dsll(FSR, FSR, Address::times_2);
789 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_SHORT), 8)) {
790 __ gslhx(FSR, SSR, FSR, arrayOopDesc::base_offset_in_bytes(T_SHORT));
791 } else {
792 __ dadd(FSR, SSR, FSR);
793 __ lh(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_SHORT));
794 }
795 }
796 }
798 void TemplateTable::iload(int n) {
799 transition(vtos, itos);
800 __ lw(FSR, iaddress(n));
801 }
803 void TemplateTable::lload(int n) {
804 transition(vtos, ltos);
805 __ ld(FSR, laddress(n));
806 }
808 void TemplateTable::fload(int n) {
809 transition(vtos, ftos);
810 __ lwc1(FSF, faddress(n));
811 }
813 void TemplateTable::dload(int n) {
814 transition(vtos, dtos);
815 __ ldc1(FSF, laddress(n));
816 }
818 void TemplateTable::aload(int n) {
819 transition(vtos, atos);
820 __ ld(FSR, aaddress(n));
821 }
823 // used register : T2, T3
824 // T2 : bytecode
825 // T3 : folded code
826 void TemplateTable::aload_0() {
827 transition(vtos, atos);
828 // According to bytecode histograms, the pairs:
829 //
830 // _aload_0, _fast_igetfield
831 // _aload_0, _fast_agetfield
832 // _aload_0, _fast_fgetfield
833 //
834 // occur frequently. If RewriteFrequentPairs is set, the (slow)
835 // _aload_0 bytecode checks if the next bytecode is either
836 // _fast_igetfield, _fast_agetfield or _fast_fgetfield and then
837 // rewrites the current bytecode into a pair bytecode; otherwise it
838 // rewrites the current bytecode into _fast_aload_0 that doesn't do
839 // the pair check anymore.
840 //
841 // Note: If the next bytecode is _getfield, the rewrite must be
842 // delayed, otherwise we may miss an opportunity for a pair.
843 //
844 // Also rewrite frequent pairs
845 // aload_0, aload_1
846 // aload_0, iload_1
847 // These bytecodes with a small amount of code are most profitable
848 // to rewrite
849 if (RewriteFrequentPairs) {
850 Label rewrite, done;
851 // get the next bytecode in T2
852 __ lbu(T2, at_bcp(Bytecodes::length_for(Bytecodes::_aload_0)));
854 // do actual aload_0
855 aload(0);
857 // if _getfield then wait with rewrite
858 __ move(AT, Bytecodes::_getfield);
859 __ beq(AT, T2, done);
860 __ delayed()->nop();
862 // if _igetfield then reqrite to _fast_iaccess_0
863 assert(Bytecodes::java_code(Bytecodes::_fast_iaccess_0) ==
864 Bytecodes::_aload_0,
865 "fix bytecode definition");
866 __ move(T3, Bytecodes::_fast_iaccess_0);
867 __ move(AT, Bytecodes::_fast_igetfield);
868 __ beq(AT, T2, rewrite);
869 __ delayed()->nop();
871 // if _agetfield then reqrite to _fast_aaccess_0
872 assert(Bytecodes::java_code(Bytecodes::_fast_aaccess_0) ==
873 Bytecodes::_aload_0,
874 "fix bytecode definition");
875 __ move(T3, Bytecodes::_fast_aaccess_0);
876 __ move(AT, Bytecodes::_fast_agetfield);
877 __ beq(AT, T2, rewrite);
878 __ delayed()->nop();
880 // if _fgetfield then reqrite to _fast_faccess_0
881 assert(Bytecodes::java_code(Bytecodes::_fast_faccess_0) ==
882 Bytecodes::_aload_0,
883 "fix bytecode definition");
884 __ move(T3, Bytecodes::_fast_faccess_0);
885 __ move(AT, Bytecodes::_fast_fgetfield);
886 __ beq(AT, T2, rewrite);
887 __ delayed()->nop();
889 // else rewrite to _fast_aload0
890 assert(Bytecodes::java_code(Bytecodes::_fast_aload_0) ==
891 Bytecodes::_aload_0,
892 "fix bytecode definition");
893 __ move(T3, Bytecodes::_fast_aload_0);
895 // rewrite
896 __ bind(rewrite);
897 patch_bytecode(Bytecodes::_aload_0, T3, T2, false);
899 __ bind(done);
900 } else {
901 aload(0);
902 }
903 }
905 void TemplateTable::istore() {
906 transition(itos, vtos);
907 locals_index(T2);
908 __ sw(FSR, T2, 0);
909 }
911 void TemplateTable::lstore() {
912 transition(ltos, vtos);
913 locals_index(T2);
914 __ sd(FSR, T2, -wordSize);
915 }
917 void TemplateTable::fstore() {
918 transition(ftos, vtos);
919 locals_index(T2);
920 __ swc1(FSF, T2, 0);
921 }
923 void TemplateTable::dstore() {
924 transition(dtos, vtos);
925 locals_index(T2);
926 __ sdc1(FSF, T2, -wordSize);
927 }
929 void TemplateTable::astore() {
930 transition(vtos, vtos);
931 __ pop_ptr(FSR);
932 locals_index(T2);
933 __ sd(FSR, T2, 0);
934 }
936 void TemplateTable::wide_istore() {
937 transition(vtos, vtos);
938 __ pop_i(FSR);
939 locals_index_wide(T2);
940 __ sd(FSR, T2, 0);
941 }
943 void TemplateTable::wide_lstore() {
944 transition(vtos, vtos);
945 __ pop_l(FSR);
946 locals_index_wide(T2);
947 __ sd(FSR, T2, -wordSize);
948 }
950 void TemplateTable::wide_fstore() {
951 wide_istore();
952 }
954 void TemplateTable::wide_dstore() {
955 wide_lstore();
956 }
958 void TemplateTable::wide_astore() {
959 transition(vtos, vtos);
960 __ pop_ptr(FSR);
961 locals_index_wide(T2);
962 __ sd(FSR, T2, 0);
963 }
965 // used register : T2
966 void TemplateTable::iastore() {
967 transition(itos, vtos);
968 __ pop_i(SSR); // T2: array SSR: index
969 if(UseBoundCheckInstruction) {
970 __ pop_ptr(T2);
971 __ dsll(SSR, SSR, Address::times_4);
972 __ dadd(SSR, T2, SSR);
973 __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_INT)); // base
975 __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());
976 __ dsll(AT, AT, Address::times_4);
977 __ dadd(AT, T2, AT);
978 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_INT)); //bound
980 __ gsswle(FSR, SSR, AT);
981 } else {
982 index_check(T2, SSR); // prefer index in ebx
983 __ dsll(SSR, SSR, Address::times_4);
984 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_INT), 8)) {
985 __ gsswx(FSR, T2, SSR, arrayOopDesc::base_offset_in_bytes(T_INT));
986 } else {
987 __ dadd(T2, T2, SSR);
988 __ sw(FSR, T2, arrayOopDesc::base_offset_in_bytes(T_INT));
989 }
990 }
991 }
995 // used register T2, T3
996 void TemplateTable::lastore() {
997 transition(ltos, vtos);
998 __ pop_i (T2);
999 if(UseBoundCheckInstruction) {
1000 __ pop_ptr(T3);
1001 __ dsll(T2, T2, Address::times_8);
1002 __ dadd(T2, T3, T2);
1003 __ addi(T2, T2, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize); // base
1005 __ lw(AT, T3, arrayOopDesc::length_offset_in_bytes());
1006 __ dsll(AT, AT, Address::times_8);
1007 __ dadd(AT, T3, AT);
1008 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize); //bound
1010 __ gssdle(FSR, T2, AT);
1011 } else {
1012 index_check(T3, T2);
1013 __ dsll(T2, T2, Address::times_8);
1014 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_LONG), 8)) {
1015 __ gssdx(FSR, T3, T2, arrayOopDesc::base_offset_in_bytes(T_LONG));
1016 } else {
1017 __ dadd(T3, T3, T2);
1018 __ sd(FSR, T3, arrayOopDesc::base_offset_in_bytes(T_LONG));
1019 }
1020 }
1021 }
1023 // used register T2
1024 void TemplateTable::fastore() {
1025 transition(ftos, vtos);
1026 __ pop_i(SSR);
1027 if(UseBoundCheckInstruction) {
1028 __ pop_ptr(T2);
1029 __ dsll(SSR, SSR, Address::times_4);
1030 __ dadd(SSR, T2, SSR);
1031 __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT)); // base
1033 __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());
1034 __ dsll(AT, AT, Address::times_4);
1035 __ dadd(AT, T2, AT);
1036 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_FLOAT)); //bound
1038 __ gsswlec1(FSF, SSR, AT);
1039 } else {
1040 index_check(T2, SSR);
1041 __ dsll(SSR, SSR, Address::times_4);
1042 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_FLOAT), 8)) {
1043 __ gsswxc1(FSF, T2, SSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
1044 } else {
1045 __ dadd(T2, T2, SSR);
1046 __ swc1(FSF, T2, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
1047 }
1048 }
1049 }
1051 // used register T2, T3
1052 void TemplateTable::dastore() {
1053 transition(dtos, vtos);
1054 __ pop_i (T2);
1055 if(UseBoundCheckInstruction) {
1056 __ pop_ptr(T3);
1057 __ dsll(T2, T2, Address::times_8);
1058 __ dadd(T2, T3, T2);
1059 __ addi(T2, T2, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize); // base
1061 __ lw(AT, T3, arrayOopDesc::length_offset_in_bytes());
1062 __ dsll(AT, AT, Address::times_8);
1063 __ dadd(AT, T3, AT);
1064 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize); //bound
1066 __ gssdlec1(FSF, T2, AT);
1067 } else {
1068 index_check(T3, T2);
1069 __ dsll(T2, T2, Address::times_8);
1070 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_DOUBLE), 8)) {
1071 __ gssdxc1(FSF, T3, T2, arrayOopDesc::base_offset_in_bytes(T_DOUBLE));
1072 } else {
1073 __ daddu(T3, T3, T2);
1074 __ sdc1(FSF, T3, arrayOopDesc::base_offset_in_bytes(T_DOUBLE));
1075 }
1076 }
1077 }
1079 // used register : T2, T3, T8
1080 // T2 : array
1081 // T3 : subklass
1082 // T8 : supklass
1083 void TemplateTable::aastore() {
1084 Label is_null, ok_is_subtype, done;
1085 transition(vtos, vtos);
1086 // stack: ..., array, index, value
1087 __ ld(FSR, at_tos()); // Value
1088 __ lw(SSR, at_tos_p1()); // Index
1089 __ ld(T2, at_tos_p2()); // Array
1091 // index_check(T2, SSR);
1092 index_check_without_pop(T2, SSR);
1093 // do array store check - check for NULL value first
1094 __ beq(FSR, R0, is_null);
1095 __ delayed()->nop();
1097 // Move subklass into T3
1098 //add for compressedoops
1099 __ load_klass(T3, FSR);
1100 // Move superklass into T8
1101 //add for compressedoops
1102 __ load_klass(T8, T2);
1103 __ ld(T8, Address(T8, ObjArrayKlass::element_klass_offset()));
1104 // Compress array+index*4+12 into a single register. T2
1105 __ dsll(AT, SSR, UseCompressedOops? Address::times_4 : Address::times_8);
1106 __ dadd(T2, T2, AT);
1107 __ daddi(T2, T2, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
1109 // Generate subtype check.
1110 // Superklass in T8. Subklass in T3.
1111 __ gen_subtype_check(T8, T3, ok_is_subtype); // <-- Jin
1112 // Come here on failure
1113 // object is at FSR
1114 __ jmp(Interpreter::_throw_ArrayStoreException_entry); // <-- Jin
1115 __ delayed()->nop();
1116 // Come here on success
1117 __ bind(ok_is_subtype);
1118 //replace with do_oop_store->store_heap_oop
1119 __ store_heap_oop(Address(T2, 0), FSR); // <-- Jin
1120 __ store_check(T2);
1121 __ b(done);
1122 __ delayed()->nop();
1124 // Have a NULL in FSR, EDX=T2, SSR=index. Store NULL at ary[idx]
1125 __ bind(is_null);
1126 __ profile_null_seen(T9);
1127 __ dsll(AT, SSR, UseCompressedOops? Address::times_4 : Address::times_8);
1128 __ dadd(T2, T2, AT);
1129 __ store_heap_oop(Address(T2, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), FSR); /* FSR is null here */
1131 __ bind(done);
1132 __ daddi(SP, SP, 3 * Interpreter::stackElementSize);
1133 }
1135 void TemplateTable::bastore() {
1136 transition(itos, vtos);
1137 __ pop_i(SSR);
1138 if(UseBoundCheckInstruction) {
1139 __ pop_ptr(T2);
1140 __ dadd(SSR, T2, SSR);
1141 __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // base
1143 __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());
1144 __ dadd(AT, T2, AT);
1145 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_BYTE)); //bound
1147 __ gssble(FSR, SSR, AT);
1148 } else {
1149 index_check(T2, SSR);
1150 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_BYTE), 8)) {
1151 __ gssbx(FSR, T2, SSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
1152 } else {
1153 __ dadd(SSR, T2, SSR);
1154 __ sb(FSR, SSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
1155 }
1156 }
1157 }
1159 void TemplateTable::castore() {
1160 transition(itos, vtos);
1161 __ pop_i(SSR);
1162 if(UseBoundCheckInstruction) {
1163 __ pop_ptr(T2);
1164 __ dsll(SSR, SSR, Address::times_2);
1165 __ dadd(SSR, T2, SSR);
1166 __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_CHAR)); // base
1168 __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());
1169 __ dsll(AT, AT, Address::times_2);
1170 __ dadd(AT, T2, AT);
1171 __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_CHAR)); //bound
1173 __ gsshle(FSR, SSR, AT);
1174 } else {
1175 index_check(T2, SSR);
1176 __ dsll(SSR, SSR, Address::times_2);
1177 if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_CHAR), 8)) {
1178 __ gsshx(FSR, T2, SSR, arrayOopDesc::base_offset_in_bytes(T_CHAR));
1179 } else {
1180 __ dadd(SSR, T2, SSR);
1181 __ sh(FSR, SSR, arrayOopDesc::base_offset_in_bytes(T_CHAR));
1182 }
1183 }
1184 }
1186 void TemplateTable::sastore() {
1187 castore();
1188 }
1190 void TemplateTable::istore(int n) {
1191 transition(itos, vtos);
1192 __ sw(FSR, iaddress(n));
1193 }
1195 void TemplateTable::lstore(int n) {
1196 transition(ltos, vtos);
1197 __ sd(FSR, laddress(n));
1198 }
1200 void TemplateTable::fstore(int n) {
1201 transition(ftos, vtos);
1202 __ swc1(FSF, faddress(n));
1203 }
1205 void TemplateTable::dstore(int n) {
1206 transition(dtos, vtos);
1207 __ sdc1(FSF, laddress(n));
1208 }
1210 void TemplateTable::astore(int n) {
1211 transition(vtos, vtos);
1212 __ pop_ptr(FSR);
1213 __ sd(FSR, aaddress(n));
1214 }
1216 void TemplateTable::pop() {
1217 transition(vtos, vtos);
1218 __ daddi(SP, SP, Interpreter::stackElementSize);
1219 }
1221 void TemplateTable::pop2() {
1222 transition(vtos, vtos);
1223 __ daddi(SP, SP, 2 * Interpreter::stackElementSize);
1224 }
1226 void TemplateTable::dup() {
1227 transition(vtos, vtos);
1228 // stack: ..., a
1229 __ load_ptr(0, FSR);
1230 __ push_ptr(FSR);
1231 // stack: ..., a, a
1232 }
1234 // blows FSR
1235 void TemplateTable::dup_x1() {
1236 transition(vtos, vtos);
1237 // stack: ..., a, b
1238 __ load_ptr(0, FSR); // load b
1239 __ load_ptr(1, A5); // load a
1240 __ store_ptr(1, FSR); // store b
1241 __ store_ptr(0, A5); // store a
1242 __ push_ptr(FSR); // push b
1243 // stack: ..., b, a, b
1244 }
1246 // blows FSR
1247 void TemplateTable::dup_x2() {
1248 transition(vtos, vtos);
1249 // stack: ..., a, b, c
1250 __ load_ptr(0, FSR); // load c
1251 __ load_ptr(2, A5); // load a
1252 __ store_ptr(2, FSR); // store c in a
1253 __ push_ptr(FSR); // push c
1254 // stack: ..., c, b, c, c
1255 __ load_ptr(2, FSR); // load b
1256 __ store_ptr(2, A5); // store a in b
1257 // stack: ..., c, a, c, c
1258 __ store_ptr(1, FSR); // store b in c
1259 // stack: ..., c, a, b, c
1260 }
1262 // blows FSR
1263 void TemplateTable::dup2() {
1264 transition(vtos, vtos);
1265 // stack: ..., a, b
1266 __ load_ptr(1, FSR); // load a
1267 __ push_ptr(FSR); // push a
1268 __ load_ptr(1, FSR); // load b
1269 __ push_ptr(FSR); // push b
1270 // stack: ..., a, b, a, b
1271 }
1273 // blows FSR
1274 void TemplateTable::dup2_x1() {
1275 transition(vtos, vtos);
1276 // stack: ..., a, b, c
1277 __ load_ptr(0, T2); // load c
1278 __ load_ptr(1, FSR); // load b
1279 __ push_ptr(FSR); // push b
1280 __ push_ptr(T2); // push c
1281 // stack: ..., a, b, c, b, c
1282 __ store_ptr(3, T2); // store c in b
1283 // stack: ..., a, c, c, b, c
1284 __ load_ptr(4, T2); // load a
1285 __ store_ptr(2, T2); // store a in 2nd c
1286 // stack: ..., a, c, a, b, c
1287 __ store_ptr(4, FSR); // store b in a
1288 // stack: ..., b, c, a, b, c
1290 // stack: ..., b, c, a, b, c
1291 }
1293 // blows FSR, SSR
1294 void TemplateTable::dup2_x2() {
1295 transition(vtos, vtos);
1296 // stack: ..., a, b, c, d
1297 // stack: ..., a, b, c, d
1298 __ load_ptr(0, T2); // load d
1299 __ load_ptr(1, FSR); // load c
1300 __ push_ptr(FSR); // push c
1301 __ push_ptr(T2); // push d
1302 // stack: ..., a, b, c, d, c, d
1303 __ load_ptr(4, FSR); // load b
1304 __ store_ptr(2, FSR); // store b in d
1305 __ store_ptr(4, T2); // store d in b
1306 // stack: ..., a, d, c, b, c, d
1307 __ load_ptr(5, T2); // load a
1308 __ load_ptr(3, FSR); // load c
1309 __ store_ptr(3, T2); // store a in c
1310 __ store_ptr(5, FSR); // store c in a
1311 // stack: ..., c, d, a, b, c, d
1313 // stack: ..., c, d, a, b, c, d
1314 }
1316 // blows FSR
1317 void TemplateTable::swap() {
1318 transition(vtos, vtos);
1319 // stack: ..., a, b
1321 __ load_ptr(1, A5); // load a
1322 __ load_ptr(0, FSR); // load b
1323 __ store_ptr(0, A5); // store a in b
1324 __ store_ptr(1, FSR); // store b in a
1326 // stack: ..., b, a
1327 }
1329 void TemplateTable::iop2(Operation op) {
1330 transition(itos, itos);
1332 __ pop_i(SSR);
1333 switch (op) {
1334 case add : __ addu32(FSR, SSR, FSR); break;
1335 case sub : __ subu32(FSR, SSR, FSR); break;
1336 case mul : __ mul(FSR, SSR, FSR); break;
1337 case _and : __ andr(FSR, SSR, FSR); break;
1338 case _or : __ orr(FSR, SSR, FSR); break;
1339 case _xor : __ xorr(FSR, SSR, FSR); break;
1340 case shl : __ sllv(FSR, SSR, FSR); break; // implicit masking of lower 5 bits by Intel shift instr. mips also
1341 case shr : __ srav(FSR, SSR, FSR); break; // implicit masking of lower 5 bits by Intel shift instr. mips also
1342 case ushr : __ srlv(FSR, SSR, FSR); break; // implicit masking of lower 5 bits by Intel shift instr. mips also
1343 default : ShouldNotReachHere();
1344 }
1345 }
1347 // the result stored in FSR, SSR,
1348 // used registers : T2, T3
1349 void TemplateTable::lop2(Operation op) {
1350 transition(ltos, ltos);
1351 __ pop_l(T2);
1353 switch (op) {
1354 case add : __ daddu(FSR, T2, FSR); break;
1355 case sub : __ dsubu(FSR, T2, FSR); break;
1356 case _and: __ andr(FSR, T2, FSR); break;
1357 case _or : __ orr(FSR, T2, FSR); break;
1358 case _xor: __ xorr(FSR, T2, FSR); break;
1359 default : ShouldNotReachHere();
1360 }
1361 }
1363 // java require this bytecode could handle 0x80000000/-1, dont cause a overflow exception,
1364 // the result is 0x80000000
1365 // the godson2 cpu do the same, so we need not handle this specially like x86
1366 void TemplateTable::idiv() {
1367 transition(itos, itos);
1368 Label not_zero;
1370 __ bne(FSR, R0, not_zero);
1371 __ delayed()->nop();
1372 __ jmp(Interpreter::_throw_ArithmeticException_entry);
1373 __ delayed()->nop();
1374 __ bind(not_zero);
1376 __ pop_i(SSR);
1377 if (UseLoongsonISA) {
1378 __ gsdiv(FSR, SSR, FSR);
1379 } else {
1380 __ div(SSR, FSR);
1381 __ mflo(FSR);
1382 }
1383 }
1385 void TemplateTable::irem() {
1386 transition(itos, itos);
1387 Label not_zero;
1388 __ pop_i(SSR);
1389 __ div(SSR, FSR);
1391 __ bne(FSR, R0, not_zero);
1392 __ delayed()->nop();
1393 //__ brk(7);
1394 __ jmp(Interpreter::_throw_ArithmeticException_entry);
1395 __ delayed()->nop();
1397 __ bind(not_zero);
1398 __ mfhi(FSR);
1399 }
1401 void TemplateTable::lmul() {
1402 transition(ltos, ltos);
1403 __ pop_l(T2);
1404 if(UseLoongsonISA){
1405 __ gsdmult(FSR, T2, FSR);
1406 } else {
1407 __ dmult(T2, FSR);
1408 __ mflo(FSR);
1409 }
1410 }
1412 // NOTE: i DONT use the Interpreter::_throw_ArithmeticException_entry
1413 void TemplateTable::ldiv() {
1414 transition(ltos, ltos);
1415 Label normal;
1417 __ bne(FSR, R0, normal);
1418 __ delayed()->nop();
1420 //__ brk(7); //generate FPE
1421 __ jmp(Interpreter::_throw_ArithmeticException_entry);
1422 __ delayed()->nop();
1424 __ bind(normal);
1425 __ pop_l(A2);
1426 if (UseLoongsonISA) {
1427 __ gsddiv(FSR, A2, FSR);
1428 } else {
1429 __ ddiv(A2, FSR);
1430 __ mflo(FSR);
1431 }
1432 }
1434 // NOTE: i DONT use the Interpreter::_throw_ArithmeticException_entry
1435 void TemplateTable::lrem() {
1436 transition(ltos, ltos);
1437 Label normal;
1439 __ bne(FSR, R0, normal);
1440 __ delayed()->nop();
1442 __ jmp(Interpreter::_throw_ArithmeticException_entry);
1443 __ delayed()->nop();
1445 __ bind(normal);
1446 __ pop_l (A2);
1448 if(UseLoongsonISA){
1449 __ gsdmod(FSR, A2, FSR);
1450 } else {
1451 __ ddiv(A2, FSR);
1452 __ mfhi(FSR);
1453 }
1454 }
1456 // result in FSR
1457 // used registers : T0
1458 void TemplateTable::lshl() {
1459 transition(itos, ltos);
1460 __ pop_l(T0);
1461 __ dsllv(FSR, T0, FSR);
1462 }
1464 // used registers : T0
1465 void TemplateTable::lshr() {
1466 transition(itos, ltos);
1467 __ pop_l(T0);
1468 __ dsrav(FSR, T0, FSR);
1469 }
1471 // used registers : T0
1472 void TemplateTable::lushr() {
1473 transition(itos, ltos);
1474 __ pop_l(T0);
1475 __ dsrlv(FSR, T0, FSR);
1476 }
1478 // result in FSF
1479 void TemplateTable::fop2(Operation op) {
1480 transition(ftos, ftos);
1481 switch (op) {
1482 case add:
1483 __ lwc1(FTF, at_sp());
1484 __ add_s(FSF, FTF, FSF);
1485 break;
1486 case sub:
1487 __ lwc1(FTF, at_sp());
1488 __ sub_s(FSF, FTF, FSF);
1489 break;
1490 case mul:
1491 __ lwc1(FTF, at_sp());
1492 __ mul_s(FSF, FTF, FSF);
1493 break;
1494 case div:
1495 __ lwc1(FTF, at_sp());
1496 __ div_s(FSF, FTF, FSF);
1497 break;
1498 case rem:
1499 __ mov_s(F13, FSF);
1500 __ lwc1(F12, at_sp());
1501 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::frem), 2);
1502 break;
1503 default : ShouldNotReachHere();
1504 }
1506 __ daddi(SP, SP, 1 * wordSize);
1507 }
1509 // result in SSF||FSF
1510 // i dont handle the strict flags
1511 void TemplateTable::dop2(Operation op) {
1512 transition(dtos, dtos);
1513 switch (op) {
1514 case add:
1515 __ ldc1(FTF, at_sp());
1516 __ add_d(FSF, FTF, FSF);
1517 break;
1518 case sub:
1519 __ ldc1(FTF, at_sp());
1520 __ sub_d(FSF, FTF, FSF);
1521 break;
1522 case mul:
1523 __ ldc1(FTF, at_sp());
1524 __ mul_d(FSF, FTF, FSF);
1525 break;
1526 case div:
1527 __ ldc1(FTF, at_sp());
1528 __ div_d(FSF, FTF, FSF);
1529 break;
1530 case rem:
1531 __ mov_d(F13, FSF);
1532 __ ldc1(F12, at_sp());
1533 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::drem), 2);
1534 break;
1535 default : ShouldNotReachHere();
1536 }
1538 __ daddi(SP, SP, 2 * wordSize);
1539 }
1541 void TemplateTable::ineg() {
1542 transition(itos, itos);
1543 __ subu32(FSR, R0, FSR);
1544 }
1546 void TemplateTable::lneg() {
1547 transition(ltos, ltos);
1548 __ dsubu(FSR, R0, FSR);
1549 }
1551 void TemplateTable::fneg() {
1552 transition(ftos, ftos);
1553 __ neg_s(FSF, FSF);
1554 }
1556 void TemplateTable::dneg() {
1557 transition(dtos, dtos);
1558 __ neg_d(FSF, FSF);
1559 }
1561 // used registers : T2
1562 void TemplateTable::iinc() {
1563 transition(vtos, vtos);
1564 locals_index(T2);
1565 __ lw(FSR, T2, 0);
1566 __ lb(AT, at_bcp(2)); // get constant
1567 __ daddu(FSR, FSR, AT);
1568 __ sw(FSR, T2, 0);
1569 }
1571 // used register : T2
1572 void TemplateTable::wide_iinc() {
1573 transition(vtos, vtos);
1574 locals_index_wide(T2);
1575 __ get_2_byte_integer_at_bcp(FSR, AT, 4);
1576 __ hswap(FSR);
1577 __ lw(AT, T2, 0);
1578 __ daddu(FSR, AT, FSR);
1579 __ sw(FSR, T2, 0);
1580 }
1582 void TemplateTable::convert() {
1583 // Checking
1584 #ifdef ASSERT
1585 {
1586 TosState tos_in = ilgl;
1587 TosState tos_out = ilgl;
1588 switch (bytecode()) {
1589 case Bytecodes::_i2l: // fall through
1590 case Bytecodes::_i2f: // fall through
1591 case Bytecodes::_i2d: // fall through
1592 case Bytecodes::_i2b: // fall through
1593 case Bytecodes::_i2c: // fall through
1594 case Bytecodes::_i2s: tos_in = itos; break;
1595 case Bytecodes::_l2i: // fall through
1596 case Bytecodes::_l2f: // fall through
1597 case Bytecodes::_l2d: tos_in = ltos; break;
1598 case Bytecodes::_f2i: // fall through
1599 case Bytecodes::_f2l: // fall through
1600 case Bytecodes::_f2d: tos_in = ftos; break;
1601 case Bytecodes::_d2i: // fall through
1602 case Bytecodes::_d2l: // fall through
1603 case Bytecodes::_d2f: tos_in = dtos; break;
1604 default : ShouldNotReachHere();
1605 }
1606 switch (bytecode()) {
1607 case Bytecodes::_l2i: // fall through
1608 case Bytecodes::_f2i: // fall through
1609 case Bytecodes::_d2i: // fall through
1610 case Bytecodes::_i2b: // fall through
1611 case Bytecodes::_i2c: // fall through
1612 case Bytecodes::_i2s: tos_out = itos; break;
1613 case Bytecodes::_i2l: // fall through
1614 case Bytecodes::_f2l: // fall through
1615 case Bytecodes::_d2l: tos_out = ltos; break;
1616 case Bytecodes::_i2f: // fall through
1617 case Bytecodes::_l2f: // fall through
1618 case Bytecodes::_d2f: tos_out = ftos; break;
1619 case Bytecodes::_i2d: // fall through
1620 case Bytecodes::_l2d: // fall through
1621 case Bytecodes::_f2d: tos_out = dtos; break;
1622 default : ShouldNotReachHere();
1623 }
1624 transition(tos_in, tos_out);
1625 }
1626 #endif // ASSERT
1628 // Conversion
1629 // (Note: use pushl(ecx)/popl(ecx) for 1/2-word stack-ptr manipulation)
1630 switch (bytecode()) {
1631 case Bytecodes::_i2l:
1632 __ sll(FSR, FSR, 0);
1633 break;
1634 case Bytecodes::_i2f:
1635 __ mtc1(FSR, FSF);
1636 __ cvt_s_w(FSF, FSF);
1637 break;
1638 case Bytecodes::_i2d:
1639 __ mtc1(FSR, FSF);
1640 __ cvt_d_w(FSF, FSF);
1641 break;
1642 case Bytecodes::_i2b:
1643 __ seb(FSR, FSR);
1644 break;
1645 case Bytecodes::_i2c:
1646 __ andi(FSR, FSR, 0xFFFF); // truncate upper 56 bits
1647 break;
1648 case Bytecodes::_i2s:
1649 __ seh(FSR, FSR);
1650 break;
1651 case Bytecodes::_l2i:
1652 __ sll(FSR, FSR, 0);
1653 break;
1654 case Bytecodes::_l2f:
1655 __ dmtc1(FSR, FSF);
1656 __ cvt_s_l(FSF, FSF);
1657 break;
1658 case Bytecodes::_l2d:
1659 __ dmtc1(FSR, FSF);
1660 __ cvt_d_l(FSF, FSF);
1661 break;
1662 case Bytecodes::_f2i:
1663 {
1664 Label L;
1666 __ trunc_w_s(F12, FSF);
1667 __ move(AT, 0x7fffffff);
1668 __ mfc1(FSR, F12);
1669 __ c_un_s(FSF, FSF); //NaN?
1670 __ movt(FSR, R0);
1672 __ bne(AT, FSR, L);
1673 __ delayed()->lui(T9, 0x8000);
1675 __ mfc1(AT, FSF);
1676 __ andr(AT, AT, T9);
1678 __ movn(FSR, T9, AT);
1680 __ bind(L);
1681 }
1682 break;
1683 case Bytecodes::_f2l:
1684 {
1685 Label L;
1687 __ trunc_l_s(F12, FSF);
1688 __ daddiu(AT, R0, -1);
1689 __ dsrl(AT, AT, 1);
1690 __ dmfc1(FSR, F12);
1691 __ c_un_s(FSF, FSF); //NaN?
1692 __ movt(FSR, R0);
1694 __ bne(AT, FSR, L);
1695 __ delayed()->lui(T9, 0x8000);
1697 __ mfc1(AT, FSF);
1698 __ andr(AT, AT, T9);
1700 __ dsll32(T9, T9, 0);
1701 __ movn(FSR, T9, AT);
1703 __ bind(L);
1704 }
1705 break;
1706 case Bytecodes::_f2d:
1707 __ cvt_d_s(FSF, FSF);
1708 break;
1709 case Bytecodes::_d2i:
1710 {
1711 Label L;
1713 __ trunc_w_d(F12, FSF);
1714 __ move(AT, 0x7fffffff);
1715 __ mfc1(FSR, F12);
1717 __ bne(FSR, AT, L);
1718 __ delayed()->mtc1(R0, F12);
1720 __ cvt_d_w(F12, F12);
1721 __ c_ult_d(FSF, F12);
1722 __ bc1f(L);
1723 __ delayed()->addiu(T9, R0, -1);
1725 __ c_un_d(FSF, FSF); //NaN?
1726 __ subu32(FSR, T9, AT);
1727 __ movt(FSR, R0);
1729 __ bind(L);
1730 }
1731 break;
1732 case Bytecodes::_d2l:
1733 {
1734 Label L;
1736 __ trunc_l_d(F12, FSF);
1737 __ daddiu(AT, R0, -1);
1738 __ dsrl(AT, AT, 1);
1739 __ dmfc1(FSR, F12);
1741 __ bne(FSR, AT, L);
1742 __ delayed()->mtc1(R0, F12);
1744 __ cvt_d_w(F12, F12);
1745 __ c_ult_d(FSF, F12);
1746 __ bc1f(L);
1747 __ delayed()->daddiu(T9, R0, -1);
1749 __ c_un_d(FSF, FSF); //NaN?
1750 __ subu(FSR, T9, AT);
1751 __ movt(FSR, R0);
1753 __ bind(L);
1754 }
1755 break;
1756 case Bytecodes::_d2f:
1757 __ cvt_s_d(FSF, FSF);
1758 break;
1759 default :
1760 ShouldNotReachHere();
1761 }
1762 }
1764 void TemplateTable::lcmp() {
1765 transition(ltos, itos);
1767 Label low, high, done;
1768 __ pop(T0);
1769 __ pop(R0);
1770 __ slt(AT, T0, FSR);
1771 __ bne(AT, R0, low);
1772 __ delayed()->nop();
1774 __ bne(T0, FSR, high);
1775 __ delayed()->nop();
1777 __ li(FSR, (long)0);
1778 __ b(done);
1779 __ delayed()->nop();
1781 __ bind(low);
1782 __ li(FSR, (long)-1);
1783 __ b(done);
1784 __ delayed()->nop();
1786 __ bind(high);
1787 __ li(FSR, (long)1);
1788 __ b(done);
1789 __ delayed()->nop();
1791 __ bind(done);
1792 }
1794 void TemplateTable::float_cmp(bool is_float, int unordered_result) {
1795 Label less, done;
1797 __ move(FSR, R0);
1799 if (is_float) {
1800 __ lwc1(FTF, at_sp());
1801 __ c_eq_s(FTF, FSF);
1802 __ bc1t(done);
1803 __ delayed()->daddi(SP, SP, 1 * wordSize);
1805 if (unordered_result<0)
1806 __ c_ult_s(FTF, FSF);
1807 else
1808 __ c_olt_s(FTF, FSF);
1809 } else {
1810 __ ldc1(FTF, at_sp());
1811 __ c_eq_d(FTF, FSF);
1812 __ bc1t(done);
1813 __ delayed()->daddi(SP, SP, 2 * wordSize);
1815 if (unordered_result<0)
1816 __ c_ult_d(FTF, FSF);
1817 else
1818 __ c_olt_d(FTF, FSF);
1819 }
1820 __ bc1t(less);
1821 __ delayed()->nop();
1822 __ move(FSR, 1);
1823 __ b(done);
1824 __ delayed()->nop();
1825 __ bind(less);
1826 __ move(FSR, -1);
1827 __ bind(done);
1828 }
1831 // used registers : T3, A7, Rnext
1832 // FSR : return bci, this is defined by the vm specification
1833 // T2 : MDO taken count
1834 // T3 : method
1835 // A7 : offset
1836 // Rnext : next bytecode, this is required by dispatch_base
1837 void TemplateTable::branch(bool is_jsr, bool is_wide) {
1838 __ get_method(T3);
1839 __ profile_taken_branch(A7, T2); // only C2 meaningful
1841 #ifndef CORE
1842 const ByteSize be_offset = MethodCounters::backedge_counter_offset() +
1843 InvocationCounter::counter_offset();
1844 const ByteSize inv_offset = MethodCounters::invocation_counter_offset() +
1845 InvocationCounter::counter_offset();
1846 #endif // CORE
1848 // Load up T4 with the branch displacement
1849 if (!is_wide) {
1850 __ lb(A7, BCP, 1);
1851 __ lbu(AT, BCP, 2);
1852 __ dsll(A7, A7, 8);
1853 __ orr(A7, A7, AT);
1854 } else {
1855 __ get_4_byte_integer_at_bcp(A7, AT, 1);
1856 __ swap(A7);
1857 }
1859 // Handle all the JSR stuff here, then exit.
1860 // It's much shorter and cleaner than intermingling with the non-JSR
1861 // normal-branch stuff occuring below.
1862 if (is_jsr) {
1863 // Pre-load the next target bytecode into Rnext
1864 __ dadd(AT, BCP, A7);
1865 __ lbu(Rnext, AT, 0);
1867 // compute return address as bci in FSR
1868 __ daddi(FSR, BCP, (is_wide?5:3) - in_bytes(ConstMethod::codes_offset()));
1869 __ ld(AT, T3, in_bytes(Method::const_offset()));
1870 __ dsub(FSR, FSR, AT);
1871 // Adjust the bcp in BCP by the displacement in A7
1872 __ dadd(BCP, BCP, A7);
1873 // jsr returns atos that is not an oop
1874 // Push return address
1875 __ push_i(FSR);
1876 // jsr returns vtos
1877 __ dispatch_only_noverify(vtos);
1879 return;
1880 }
1882 // Normal (non-jsr) branch handling
1884 // Adjust the bcp in S0 by the displacement in T4
1885 __ dadd(BCP, BCP, A7);
1887 #ifdef CORE
1888 // Pre-load the next target bytecode into EBX
1889 __ lbu(Rnext, BCP, 0);
1890 // continue with the bytecode @ target
1891 __ dispatch_only(vtos);
1892 #else
1893 assert(UseLoopCounter || !UseOnStackReplacement, "on-stack-replacement requires loop counters");
1894 Label backedge_counter_overflow;
1895 Label profile_method;
1896 Label dispatch;
1897 if (UseLoopCounter) {
1898 // increment backedge counter for backward branches
1899 // eax: MDO
1900 // ebx: MDO bumped taken-count
1901 // T3: method
1902 // T4: target offset
1903 // BCP: target bcp
1904 // LVP: locals pointer
1905 __ bgtz(A7, dispatch); // check if forward or backward branch
1906 __ delayed()->nop();
1908 // check if MethodCounters exists
1909 Label has_counters;
1910 __ ld(AT, T3, in_bytes(Method::method_counters_offset())); // use AT as MDO, TEMP
1911 __ bne(AT, R0, has_counters);
1912 __ nop();
1913 __ push(T3);
1914 //__ push(A7);
1915 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::build_method_counters),
1916 T3);
1917 //__ pop(A7);
1918 __ pop(T3);
1919 __ ld(AT, T3, in_bytes(Method::method_counters_offset())); // use AT as MDO, TEMP
1920 __ beq(AT, R0, dispatch);
1921 __ nop();
1922 __ bind(has_counters);
1924 // increment back edge counter
1925 __ ld(T1, T3, in_bytes(Method::method_counters_offset()));
1926 __ lw(T0, T1, in_bytes(be_offset));
1927 __ increment(T0, InvocationCounter::count_increment);
1928 __ sw(T0, T1, in_bytes(be_offset));
1930 // load invocation counter
1931 __ lw(T1, T1, in_bytes(inv_offset));
1932 // buffer bit added, mask no needed
1934 // dadd backedge counter & invocation counter
1935 __ dadd(T1, T1, T0);
1937 if (ProfileInterpreter) {
1938 // Test to see if we should create a method data oop
1939 // T1 : backedge counter & invocation counter
1940 if (Assembler::is_simm16(InvocationCounter::InterpreterProfileLimit)) {
1941 __ slti(AT, T1, InvocationCounter::InterpreterProfileLimit);
1942 } else {
1943 __ li(AT, (long)&InvocationCounter::InterpreterProfileLimit);
1944 __ lw(AT, AT, 0);
1945 __ slt(AT, T1, AT);
1946 }
1948 __ bne(AT, R0, dispatch);
1949 __ delayed()->nop();
1951 // if no method data exists, go to profile method
1952 __ test_method_data_pointer(T1, profile_method);
1954 if (UseOnStackReplacement) {
1955 if (Assembler::is_simm16(InvocationCounter::InterpreterBackwardBranchLimit)) {
1956 __ slti(AT, T2, InvocationCounter::InterpreterBackwardBranchLimit);
1957 } else {
1958 __ li(AT, (long)&InvocationCounter::InterpreterBackwardBranchLimit);
1959 __ lw(AT, AT, 0);
1960 __ slt(AT, T2, AT);
1961 }
1963 __ bne(AT, R0, dispatch);
1964 __ delayed()->nop();
1966 // When ProfileInterpreter is on, the backedge_count comes
1967 // from the methodDataOop, which value does not get reset on
1968 // the call to frequency_counter_overflow().
1969 // To avoid excessive calls to the overflow routine while
1970 // the method is being compiled, dadd a second test to make
1971 // sure the overflow function is called only once every
1972 // overflow_frequency.
1973 const int overflow_frequency = 1024;
1974 __ andi(AT, T2, overflow_frequency-1);
1975 __ beq(AT, R0, backedge_counter_overflow);
1976 __ delayed()->nop();
1977 }
1978 } else {
1979 if (UseOnStackReplacement) {
1980 // check for overflow against eax, which is the sum of the counters
1981 __ li(AT, (long)&InvocationCounter::InterpreterBackwardBranchLimit);
1982 __ lw(AT, AT, 0);
1983 __ slt(AT, T1, AT);
1984 __ beq(AT, R0, backedge_counter_overflow);
1985 __ delayed()->nop();
1986 }
1987 }
1988 __ bind(dispatch);
1989 }
1991 // Pre-load the next target bytecode into Rnext
1992 __ lbu(Rnext, BCP, 0);
1994 // continue with the bytecode @ target
1995 // FSR: return bci for jsr's, unused otherwise
1996 // Rnext: target bytecode
1997 // BCP: target bcp
1998 __ dispatch_only(vtos);
2000 if (UseLoopCounter) {
2001 if (ProfileInterpreter) {
2002 // Out-of-line code to allocate method data oop.
2003 __ bind(profile_method);
2004 __ call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
2005 __ lbu(Rnext, BCP, 0);
2006 __ set_method_data_pointer_for_bcp();
2007 __ b(dispatch);
2008 __ delayed()->nop();
2009 }
2011 if (UseOnStackReplacement) {
2012 // invocation counter overflow
2013 __ bind(backedge_counter_overflow);
2014 __ sub(A7, BCP, A7); // branch bcp
2015 call_VM(NOREG, CAST_FROM_FN_PTR(address,
2016 InterpreterRuntime::frequency_counter_overflow), A7);
2017 __ lbu(Rnext, BCP, 0);
2019 // V0: osr nmethod (osr ok) or NULL (osr not possible)
2020 // V1: osr adapter frame return address
2021 // Rnext: target bytecode
2022 // LVP: locals pointer
2023 // BCP: bcp
2024 __ beq(V0, R0, dispatch);
2025 __ delayed()->nop();
2026 // nmethod may have been invalidated (VM may block upon call_VM return)
2027 __ lw(T3, V0, nmethod::entry_bci_offset());
2028 __ move(AT, InvalidOSREntryBci);
2029 __ beq(AT, T3, dispatch);
2030 __ delayed()->nop();
2031 // We need to prepare to execute the OSR method. First we must
2032 // migrate the locals and monitors off of the stack.
2033 //eax V0: osr nmethod (osr ok) or NULL (osr not possible)
2034 //ebx V1: osr adapter frame return address
2035 //edx Rnext: target bytecode
2036 //edi LVP: locals pointer
2037 //esi BCP: bcp
2038 __ move(BCP, V0);
2039 // const Register thread = ecx;
2040 const Register thread = TREG;
2041 #ifndef OPT_THREAD
2042 __ get_thread(thread);
2043 #endif
2044 call_VM(noreg, CAST_FROM_FN_PTR(address,
2045 SharedRuntime::OSR_migration_begin));
2046 // eax is OSR buffer, move it to expected parameter location
2047 //refer to osrBufferPointer in c1_LIRAssembler_mips.cpp
2048 __ move(T0, V0);
2050 // pop the interpreter frame
2051 __ ld(A7, Address(FP, frame::interpreter_frame_sender_sp_offset * wordSize));
2052 //FIXME, shall we keep the return address on the stack?
2053 __ leave(); // remove frame anchor
2054 __ move(LVP, RA);
2055 __ move(SP, A7);
2057 __ move(AT, -(StackAlignmentInBytes));
2058 __ andr(SP , SP , AT);
2060 // push the (possibly adjusted) return address
2061 //refer to osr_entry in c1_LIRAssembler_mips.cpp
2062 __ ld(AT, BCP, nmethod::osr_entry_point_offset());
2063 __ jr(AT);
2064 __ delayed()->nop();
2065 }
2066 }
2067 #endif // not CORE
2068 }
2071 void TemplateTable::if_0cmp(Condition cc) {
2072 transition(itos, vtos);
2073 // assume branch is more often taken than not (loops use backward branches)
2074 Label not_taken;
2075 switch(cc) {
2076 case not_equal:
2077 __ beq(FSR, R0, not_taken);
2078 break;
2079 case equal:
2080 __ bne(FSR, R0, not_taken);
2081 break;
2082 case less:
2083 __ bgez(FSR, not_taken);
2084 break;
2085 case less_equal:
2086 __ bgtz(FSR, not_taken);
2087 break;
2088 case greater:
2089 __ blez(FSR, not_taken);
2090 break;
2091 case greater_equal:
2092 __ bltz(FSR, not_taken);
2093 break;
2094 }
2095 __ delayed()->nop();
2097 branch(false, false);
2099 __ bind(not_taken);
2100 __ profile_not_taken_branch(FSR);
2101 }
2103 void TemplateTable::if_icmp(Condition cc) {
2104 transition(itos, vtos);
2105 // assume branch is more often taken than not (loops use backward branches)
2106 Label not_taken;
2108 __ pop_i(SSR);
2109 switch(cc) {
2110 case not_equal:
2111 __ beq(SSR, FSR, not_taken);
2112 break;
2113 case equal:
2114 __ bne(SSR, FSR, not_taken);
2115 break;
2116 case less:
2117 __ slt(AT, SSR, FSR);
2118 __ beq(AT, R0, not_taken);
2119 break;
2120 case less_equal:
2121 __ slt(AT, FSR, SSR);
2122 __ bne(AT, R0, not_taken);
2123 break;
2124 case greater:
2125 __ slt(AT, FSR, SSR);
2126 __ beq(AT, R0, not_taken);
2127 break;
2128 case greater_equal:
2129 __ slt(AT, SSR, FSR);
2130 __ bne(AT, R0, not_taken);
2131 break;
2132 }
2133 __ delayed()->nop();
2135 branch(false, false);
2136 __ bind(not_taken);
2137 __ profile_not_taken_branch(FSR);
2138 }
2140 void TemplateTable::if_nullcmp(Condition cc) {
2141 transition(atos, vtos);
2142 // assume branch is more often taken than not (loops use backward branches)
2143 Label not_taken;
2144 switch(cc) {
2145 case not_equal:
2146 __ beq(FSR, R0, not_taken);
2147 break;
2148 case equal:
2149 __ bne(FSR, R0, not_taken);
2150 break;
2151 default:
2152 ShouldNotReachHere();
2153 }
2154 __ delayed()->nop();
2156 branch(false, false);
2157 __ bind(not_taken);
2158 __ profile_not_taken_branch(FSR);
2159 }
2162 void TemplateTable::if_acmp(Condition cc) {
2163 transition(atos, vtos);
2164 // assume branch is more often taken than not (loops use backward branches)
2165 Label not_taken;
2166 // __ lw(SSR, SP, 0);
2167 __ pop_ptr(SSR);
2168 switch(cc) {
2169 case not_equal:
2170 __ beq(SSR, FSR, not_taken);
2171 break;
2172 case equal:
2173 __ bne(SSR, FSR, not_taken);
2174 break;
2175 default:
2176 ShouldNotReachHere();
2177 }
2178 __ delayed()->nop();
2180 branch(false, false);
2182 __ bind(not_taken);
2183 __ profile_not_taken_branch(FSR);
2184 }
2186 // used registers : T1, T2, T3
2187 // T1 : method
2188 // T2 : returb bci
2189 void TemplateTable::ret() {
2190 transition(vtos, vtos);
2192 locals_index(T2);
2193 __ ld(T2, T2, 0);
2194 __ profile_ret(T2, T3);
2196 __ get_method(T1);
2197 __ ld(BCP, T1, in_bytes(Method::const_offset()));
2198 __ dadd(BCP, BCP, T2);
2199 __ daddi(BCP, BCP, in_bytes(ConstMethod::codes_offset()));
2201 __ dispatch_next(vtos);
2202 }
2204 // used registers : T1, T2, T3
2205 // T1 : method
2206 // T2 : returb bci
2207 void TemplateTable::wide_ret() {
2208 transition(vtos, vtos);
2210 locals_index_wide(T2);
2211 __ ld(T2, T2, 0); // get return bci, compute return bcp
2212 __ profile_ret(T2, T3);
2214 __ get_method(T1);
2215 __ ld(BCP, T1, in_bytes(Method::const_offset()));
2216 __ dadd(BCP, BCP, T2);
2217 __ daddi(BCP, BCP, in_bytes(ConstMethod::codes_offset()));
2219 __ dispatch_next(vtos);
2220 }
2222 // used register T2, T3, A7, Rnext
2223 // T2 : bytecode pointer
2224 // T3 : low
2225 // A7 : high
2226 // Rnext : dest bytecode, required by dispatch_base
2227 void TemplateTable::tableswitch() {
2228 Label default_case, continue_execution;
2229 transition(itos, vtos);
2231 // align BCP
2232 __ daddi(T2, BCP, BytesPerInt);
2233 __ li(AT, -BytesPerInt);
2234 __ andr(T2, T2, AT);
2236 // load lo & hi
2237 __ lw(T3, T2, 1 * BytesPerInt);
2238 __ swap(T3);
2239 __ lw(A7, T2, 2 * BytesPerInt);
2240 __ swap(A7);
2242 // check against lo & hi
2243 __ slt(AT, FSR, T3);
2244 __ bne(AT, R0, default_case);
2245 __ delayed()->nop();
2247 __ slt(AT, A7, FSR);
2248 __ bne(AT, R0, default_case);
2249 __ delayed()->nop();
2251 // lookup dispatch offset, in A7 big endian
2252 __ dsub(FSR, FSR, T3);
2253 __ dsll(AT, FSR, Address::times_4);
2254 __ dadd(AT, T2, AT);
2255 __ lw(A7, AT, 3 * BytesPerInt);
2256 __ profile_switch_case(FSR, T9, T3);
2258 __ bind(continue_execution);
2259 __ swap(A7);
2260 __ dadd(BCP, BCP, A7);
2261 __ lbu(Rnext, BCP, 0);
2262 __ dispatch_only(vtos);
2264 // handle default
2265 __ bind(default_case);
2266 __ profile_switch_default(FSR);
2267 __ lw(A7, T2, 0);
2268 __ b(continue_execution);
2269 __ delayed()->nop();
2270 }
2272 void TemplateTable::lookupswitch() {
2273 transition(itos, itos);
2274 __ stop("lookupswitch bytecode should have been rewritten");
2275 }
2277 // used registers : T2, T3, A7, Rnext
2278 // T2 : bytecode pointer
2279 // T3 : pair index
2280 // A7 : offset
2281 // Rnext : dest bytecode
2282 // the data after the opcode is the same as lookupswitch
2283 // see Rewriter::rewrite_method for more information
2284 void TemplateTable::fast_linearswitch() {
2285 transition(itos, vtos);
2286 Label loop_entry, loop, found, continue_execution;
2288 // swap eax so we can avoid swapping the table entries
2289 __ swap(FSR);
2291 // align BCP
2292 __ daddi(T2, BCP, BytesPerInt);
2293 __ li(AT, -BytesPerInt);
2294 __ andr(T2, T2, AT);
2296 // set counter
2297 __ lw(T3, T2, BytesPerInt);
2298 __ swap(T3);
2299 __ b(loop_entry);
2300 __ delayed()->nop();
2302 // table search
2303 __ bind(loop);
2304 // get the entry value
2305 __ dsll(AT, T3, Address::times_8);
2306 __ dadd(AT, T2, AT);
2307 __ lw(AT, AT, 2 * BytesPerInt);
2309 // found?
2310 __ beq(FSR, AT, found);
2311 __ delayed()->nop();
2313 __ bind(loop_entry);
2314 __ bgtz(T3, loop);
2315 __ delayed()->daddiu(T3, T3, -1);
2317 // default case
2318 __ profile_switch_default(FSR);
2319 __ lw(A7, T2, 0);
2320 __ b(continue_execution);
2321 __ delayed()->nop();
2323 // entry found -> get offset
2324 __ bind(found);
2325 __ dsll(AT, T3, Address::times_8);
2326 __ dadd(AT, T2, AT);
2327 __ lw(A7, AT, 3 * BytesPerInt);
2328 __ profile_switch_case(T3, FSR, T2);
2330 // continue execution
2331 __ bind(continue_execution);
2332 __ swap(A7);
2333 __ dadd(BCP, BCP, A7);
2334 __ lbu(Rnext, BCP, 0);
2335 __ dispatch_only(vtos);
2336 }
2338 // used registers : T0, T1, T2, T3, A7, Rnext
2339 // T2 : pairs address(array)
2340 // Rnext : dest bytecode
2341 // the data after the opcode is the same as lookupswitch
2342 // see Rewriter::rewrite_method for more information
2343 void TemplateTable::fast_binaryswitch() {
2344 transition(itos, vtos);
2345 // Implementation using the following core algorithm:
2346 //
2347 // int binary_search(int key, LookupswitchPair* array, int n) {
2348 // // Binary search according to "Methodik des Programmierens" by
2349 // // Edsger W. Dijkstra and W.H.J. Feijen, Addison Wesley Germany 1985.
2350 // int i = 0;
2351 // int j = n;
2352 // while (i+1 < j) {
2353 // // invariant P: 0 <= i < j <= n and (a[i] <= key < a[j] or Q)
2354 // // with Q: for all i: 0 <= i < n: key < a[i]
2355 // // where a stands for the array and assuming that the (inexisting)
2356 // // element a[n] is infinitely big.
2357 // int h = (i + j) >> 1;
2358 // // i < h < j
2359 // if (key < array[h].fast_match()) {
2360 // j = h;
2361 // } else {
2362 // i = h;
2363 // }
2364 // }
2365 // // R: a[i] <= key < a[i+1] or Q
2366 // // (i.e., if key is within array, i is the correct index)
2367 // return i;
2368 // }
2370 // register allocation
2371 const Register array = T2;
2372 const Register i = T3, j = A7;
2373 const Register h = T1;
2374 const Register temp = T0;
2375 const Register key = FSR;
2377 // setup array
2378 __ daddi(array, BCP, 3*BytesPerInt);
2379 __ li(AT, -BytesPerInt);
2380 __ andr(array, array, AT);
2382 // initialize i & j
2383 __ move(i, R0);
2384 __ lw(j, array, - 1 * BytesPerInt);
2385 // Convert j into native byteordering
2386 __ swap(j);
2388 // and start
2389 Label entry;
2390 __ b(entry);
2391 __ delayed()->nop();
2393 // binary search loop
2394 {
2395 Label loop;
2396 __ bind(loop);
2397 // int h = (i + j) >> 1;
2398 __ dadd(h, i, j);
2399 __ dsrl(h, h, 1);
2400 // if (key < array[h].fast_match()) {
2401 // j = h;
2402 // } else {
2403 // i = h;
2404 // }
2405 // Convert array[h].match to native byte-ordering before compare
2406 __ dsll(AT, h, Address::times_8);
2407 __ dadd(AT, array, AT);
2408 __ lw(temp, AT, 0 * BytesPerInt);
2409 __ swap(temp);
2411 {
2412 Label set_i, end_of_if;
2413 __ slt(AT, key, temp);
2414 __ beq(AT, R0, set_i);
2415 __ delayed()->nop();
2417 __ b(end_of_if);
2418 __ delayed(); __ move(j, h);
2420 __ bind(set_i);
2421 __ move(i, h);
2423 __ bind(end_of_if);
2424 }
2425 // while (i+1 < j)
2426 __ bind(entry);
2427 __ daddi(h, i, 1);
2428 __ slt(AT, h, j);
2429 __ bne(AT, R0, loop);
2430 __ delayed()->nop();
2431 }
2433 // end of binary search, result index is i (must check again!)
2434 Label default_case;
2435 // Convert array[i].match to native byte-ordering before compare
2436 __ dsll(AT, i, Address::times_8);
2437 __ dadd(AT, array, AT);
2438 __ lw(temp, AT, 0 * BytesPerInt);
2439 __ swap(temp);
2440 __ bne(key, temp, default_case);
2441 __ delayed()->nop();
2443 // entry found -> j = offset
2444 __ dsll(AT, i, Address::times_8);
2445 __ dadd(AT, array, AT);
2446 __ lw(j, AT, 1 * BytesPerInt);
2447 __ profile_switch_case(i, key, array);
2448 __ swap(j);
2450 __ dadd(BCP, BCP, j);
2451 __ lbu(Rnext, BCP, 0);
2452 __ dispatch_only(vtos);
2454 // default case -> j = default offset
2455 __ bind(default_case);
2456 __ profile_switch_default(i);
2457 __ lw(j, array, - 2 * BytesPerInt);
2458 __ swap(j);
2459 __ dadd(BCP, BCP, j);
2460 __ lbu(Rnext, BCP, 0);
2461 __ dispatch_only(vtos);
2462 }
2464 void TemplateTable::_return(TosState state) {
2465 transition(state, state);
2466 assert(_desc->calls_vm(),
2467 "inconsistent calls_vm information"); // call in remove_activation
2469 if (_desc->bytecode() == Bytecodes::_return_register_finalizer) {
2470 assert(state == vtos, "only valid state");
2471 __ ld(T1, aaddress(0));
2472 __ load_klass(LVP, T1);
2473 __ lw(LVP, LVP, in_bytes(Klass::access_flags_offset()));
2474 __ move(AT, JVM_ACC_HAS_FINALIZER);
2475 __ andr(AT, AT, LVP);//by_css
2476 Label skip_register_finalizer;
2477 __ beq(AT, R0, skip_register_finalizer);
2478 __ delayed()->nop();
2479 __ call_VM(noreg, CAST_FROM_FN_PTR(address,
2480 InterpreterRuntime::register_finalizer), T1);
2481 __ bind(skip_register_finalizer);
2482 }
2483 __ remove_activation(state, T9);
2484 __ sync();
2486 __ jr(T9);
2487 __ delayed()->nop();
2488 }
2490 // ----------------------------------------------------------------------------
2491 // Volatile variables demand their effects be made known to all CPU's
2492 // in order. Store buffers on most chips allow reads & writes to
2493 // reorder; the JMM's ReadAfterWrite.java test fails in -Xint mode
2494 // without some kind of memory barrier (i.e., it's not sufficient that
2495 // the interpreter does not reorder volatile references, the hardware
2496 // also must not reorder them).
2497 //
2498 // According to the new Java Memory Model (JMM):
2499 // (1) All volatiles are serialized wrt to each other. ALSO reads &
2500 // writes act as aquire & release, so:
2501 // (2) A read cannot let unrelated NON-volatile memory refs that
2502 // happen after the read float up to before the read. It's OK for
2503 // non-volatile memory refs that happen before the volatile read to
2504 // float down below it.
2505 // (3) Similar a volatile write cannot let unrelated NON-volatile
2506 // memory refs that happen BEFORE the write float down to after the
2507 // write. It's OK for non-volatile memory refs that happen after the
2508 // volatile write to float up before it.
2509 //
2510 // We only put in barriers around volatile refs (they are expensive),
2511 // not _between_ memory refs (that would require us to track the
2512 // flavor of the previous memory refs). Requirements (2) and (3)
2513 // require some barriers before volatile stores and after volatile
2514 // loads. These nearly cover requirement (1) but miss the
2515 // volatile-store-volatile-load case. This final case is placed after
2516 // volatile-stores although it could just as well go before
2517 // volatile-loads.
2518 //void TemplateTable::volatile_barrier(Assembler::Membar_mask_bits
2519 // order_constraint) {
2520 void TemplateTable::volatile_barrier( ) {
2521 // Helper function to insert a is-volatile test and memory barrier
2522 //if (os::is_MP()) { // Not needed on single CPU
2523 // __ membar(order_constraint);
2524 //}
2525 if( !os::is_MP() ) return; // Not needed on single CPU
2526 __ sync();
2527 }
2529 // we dont shift left 2 bits in get_cache_and_index_at_bcp
2530 // for we always need shift the index we use it. the ConstantPoolCacheEntry
2531 // is 16-byte long, index is the index in
2532 // ConstantPoolCache, so cache + base_offset() + index * 16 is
2533 // the corresponding ConstantPoolCacheEntry
2534 // used registers : T2
2535 // NOTE : the returned index need also shift left 4 to get the address!
2536 void TemplateTable::resolve_cache_and_index(int byte_no,
2537 Register Rcache,
2538 Register index,
2539 size_t index_size) {
2540 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
2541 const Register temp = A1;
2542 assert_different_registers(Rcache, index);
2544 Label resolved;
2545 __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size);
2546 // is resolved?
2547 int i = (int)bytecode();
2548 __ addi(temp, temp, -i);
2549 __ beq(temp, R0, resolved);
2550 __ delayed()->nop();
2551 // resolve first time through
2552 address entry;
2553 switch (bytecode()) {
2554 case Bytecodes::_getstatic : // fall through
2555 case Bytecodes::_putstatic : // fall through
2556 case Bytecodes::_getfield : // fall through
2557 case Bytecodes::_putfield :
2558 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put);
2559 break;
2560 case Bytecodes::_invokevirtual : // fall through
2561 case Bytecodes::_invokespecial : // fall through
2562 case Bytecodes::_invokestatic : // fall through
2563 case Bytecodes::_invokeinterface:
2564 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);
2565 break;
2566 case Bytecodes::_invokehandle:
2567 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle);
2568 break;
2569 case Bytecodes::_invokedynamic:
2570 entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);
2571 break;
2572 default :
2573 fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode())));
2574 break;
2575 }
2577 __ move(temp, i);
2578 __ call_VM(NOREG, entry, temp);
2580 // Update registers with resolved info
2581 __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
2582 __ bind(resolved);
2583 }
2585 // The Rcache and index registers must be set before call
2586 void TemplateTable::load_field_cp_cache_entry(Register obj,
2587 Register cache,
2588 Register index,
2589 Register off,
2590 Register flags,
2591 bool is_static = false) {
2592 assert_different_registers(cache, index, flags, off);
2594 ByteSize cp_base_offset = ConstantPoolCache::base_offset();
2595 // Field offset
2596 __ dsll(AT, index, Address::times_ptr);
2597 __ dadd(AT, cache, AT);
2598 __ ld(off, AT, in_bytes(cp_base_offset + ConstantPoolCacheEntry::f2_offset()));
2599 // Flags
2600 __ ld(flags, AT, in_bytes(cp_base_offset + ConstantPoolCacheEntry::flags_offset()));
2602 // klass overwrite register
2603 if (is_static) {
2604 __ ld(obj, AT, in_bytes(cp_base_offset + ConstantPoolCacheEntry::f1_offset()));
2605 const int mirror_offset = in_bytes(Klass::java_mirror_offset());
2606 __ ld(obj, Address(obj, mirror_offset));
2608 __ verify_oop(obj);
2609 }
2610 }
2612 // get the method, itable_index and flags of the current invoke
2613 void TemplateTable::load_invoke_cp_cache_entry(int byte_no,
2614 Register method,
2615 Register itable_index,
2616 Register flags,
2617 bool is_invokevirtual,
2618 bool is_invokevfinal, /*unused*/
2619 bool is_invokedynamic) {
2620 // setup registers
2621 const Register cache = T3;
2622 const Register index = T1;
2623 assert_different_registers(method, flags);
2624 assert_different_registers(method, cache, index);
2625 assert_different_registers(itable_index, flags);
2626 assert_different_registers(itable_index, cache, index);
2627 assert(is_invokevirtual == (byte_no == f2_byte), "is invokevirtual flag redundant");
2628 // determine constant pool cache field offsets
2629 const int method_offset = in_bytes(
2630 ConstantPoolCache::base_offset() +
2631 ((byte_no == f2_byte)
2632 ? ConstantPoolCacheEntry::f2_offset()
2633 : ConstantPoolCacheEntry::f1_offset()));
2634 const int flags_offset = in_bytes(ConstantPoolCache::base_offset() +
2635 ConstantPoolCacheEntry::flags_offset());
2636 // access constant pool cache fields
2637 const int index_offset = in_bytes(ConstantPoolCache::base_offset() +
2638 ConstantPoolCacheEntry::f2_offset());
2640 size_t index_size = (is_invokedynamic ? sizeof(u4): sizeof(u2));
2641 resolve_cache_and_index(byte_no, cache, index, index_size);
2643 //assert(wordSize == 8, "adjust code below");
2644 // note we shift 4 not 2, for we get is the true inde
2645 // of ConstantPoolCacheEntry, not the shifted 2-bit index as x86 version
2646 __ dsll(AT, index, Address::times_ptr);
2647 __ dadd(AT, cache, AT);
2648 __ ld(method, AT, method_offset);
2650 if (itable_index != NOREG) {
2651 __ ld(itable_index, AT, index_offset);
2652 }
2653 __ ld(flags, AT, flags_offset);
2654 }
2656 // The registers cache and index expected to be set before call.
2657 // Correct values of the cache and index registers are preserved.
2658 void TemplateTable::jvmti_post_field_access(Register cache, Register index,
2659 bool is_static, bool has_tos) {
2660 // do the JVMTI work here to avoid disturbing the register state below
2661 // We use c_rarg registers here because we want to use the register used in
2662 // the call to the VM
2663 if (JvmtiExport::can_post_field_access()) {
2664 // Check to see if a field access watch has been set before we
2665 // take the time to call into the VM.
2666 Label L1;
2667 // kill FSR
2668 Register tmp1 = T2;
2669 Register tmp2 = T1;
2670 Register tmp3 = T3;
2671 assert_different_registers(cache, index, AT);
2672 __ li(AT, (intptr_t)JvmtiExport::get_field_access_count_addr());
2673 __ lw(AT, AT, 0);
2674 __ beq(AT, R0, L1);
2675 __ delayed()->nop();
2677 __ get_cache_and_index_at_bcp(tmp2, tmp3, 1);
2679 // cache entry pointer
2680 __ daddi(tmp2, tmp2, in_bytes(ConstantPoolCache::base_offset()));
2681 __ shl(tmp3, LogBytesPerWord);
2682 __ dadd(tmp2, tmp2, tmp3);
2683 if (is_static) {
2684 __ move(tmp1, R0);
2685 } else {
2686 __ ld(tmp1, SP, 0);
2687 __ verify_oop(tmp1);
2688 }
2689 // tmp1: object pointer or NULL
2690 // tmp2: cache entry pointer
2691 // tmp3: jvalue object on the stack
2692 __ call_VM(NOREG, CAST_FROM_FN_PTR(address,
2693 InterpreterRuntime::post_field_access),
2694 tmp1, tmp2, tmp3);
2695 __ get_cache_and_index_at_bcp(cache, index, 1);
2696 __ bind(L1);
2697 }
2698 }
2700 void TemplateTable::pop_and_check_object(Register r) {
2701 __ pop_ptr(r);
2702 __ null_check(r); // for field access must check obj.
2703 __ verify_oop(r);
2704 }
2706 // used registers : T1, T2, T3, T1
2707 // T1 : flags
2708 // T2 : off
2709 // T3 : obj
2710 // T1 : field address
2711 // The flags 31, 30, 29, 28 together build a 4 bit number 0 to 8 with the
2712 // following mapping to the TosState states:
2713 // btos: 0
2714 // ctos: 1
2715 // stos: 2
2716 // itos: 3
2717 // ltos: 4
2718 // ftos: 5
2719 // dtos: 6
2720 // atos: 7
2721 // vtos: 8
2722 // see ConstantPoolCacheEntry::set_field for more info
2723 void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
2724 transition(vtos, vtos);
2726 const Register cache = T3;
2727 const Register index = T0;
2729 const Register obj = T3;
2730 const Register off = T2;
2731 const Register flags = T1;
2732 resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
2733 jvmti_post_field_access(cache, index, is_static, false);
2734 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
2736 if (!is_static) pop_and_check_object(obj);
2737 __ dadd(index, obj, off);
2740 Label Done, notByte, notInt, notShort, notChar,
2741 notLong, notFloat, notObj, notDouble;
2743 assert(btos == 0, "change code, btos != 0");
2744 __ dsrl(flags, flags, ConstantPoolCacheEntry::tos_state_shift);
2745 __ andi(flags, flags, 0xf);
2746 __ bne(flags, R0, notByte);
2747 __ delayed()->nop();
2749 // btos
2750 __ lb(FSR, index, 0);
2751 __ sd(FSR, SP, - wordSize);
2753 // Rewrite bytecode to be faster
2754 if (!is_static) {
2755 patch_bytecode(Bytecodes::_fast_bgetfield, T3, T2);
2756 }
2757 __ b(Done);
2758 __ delayed()->daddi(SP, SP, - wordSize);
2760 __ bind(notByte);
2761 __ move(AT, itos);
2762 __ bne(flags, AT, notInt);
2763 __ delayed()->nop();
2765 // itos
2766 __ lw(FSR, index, 0);
2767 __ sd(FSR, SP, - wordSize);
2769 // Rewrite bytecode to be faster
2770 if (!is_static) {
2771 // patch_bytecode(Bytecodes::_fast_igetfield, T3, T2);
2772 patch_bytecode(Bytecodes::_fast_igetfield, T3, T2);
2773 }
2774 __ b(Done);
2775 __ delayed()->daddi(SP, SP, - wordSize);
2777 __ bind(notInt);
2778 __ move(AT, atos);
2779 __ bne(flags, AT, notObj);
2780 __ delayed()->nop();
2782 // atos
2783 //add for compressedoops
2784 __ load_heap_oop(FSR, Address(index, 0));
2785 __ sd(FSR, SP, - wordSize);
2787 if (!is_static) {
2788 //patch_bytecode(Bytecodes::_fast_agetfield, T3, T2);
2789 patch_bytecode(Bytecodes::_fast_agetfield, T3, T2);
2790 }
2791 __ b(Done);
2792 __ delayed()->daddi(SP, SP, - wordSize);
2794 __ bind(notObj);
2795 __ move(AT, ctos);
2796 __ bne(flags, AT, notChar);
2797 __ delayed()->nop();
2799 // ctos
2800 __ lhu(FSR, index, 0);
2801 __ sd(FSR, SP, - wordSize);
2803 if (!is_static) {
2804 patch_bytecode(Bytecodes::_fast_cgetfield, T3, T2);
2805 }
2806 __ b(Done);
2807 __ delayed()->daddi(SP, SP, - wordSize);
2809 __ bind(notChar);
2810 __ move(AT, stos);
2811 __ bne(flags, AT, notShort);
2812 __ delayed()->nop();
2814 // stos
2815 __ lh(FSR, index, 0);
2816 __ sd(FSR, SP, - wordSize);
2818 if (!is_static) {
2819 patch_bytecode(Bytecodes::_fast_sgetfield, T3, T2);
2820 }
2821 __ b(Done);
2822 __ delayed()->daddi(SP, SP, - wordSize);
2824 __ bind(notShort);
2825 __ move(AT, ltos);
2826 __ bne(flags, AT, notLong);
2827 __ delayed()->nop();
2829 // FIXME : the load/store should be atomic, we have no simple method to do this in mips32
2830 // ltos
2831 __ ld(FSR, index, 0 * wordSize);
2832 __ sd(FSR, SP, -2 * wordSize);
2833 __ sd(R0, SP, -1 * wordSize);
2835 // Don't rewrite to _fast_lgetfield for potential volatile case.
2836 __ b(Done);
2837 __ delayed()->daddi(SP, SP, - 2 * wordSize);
2839 __ bind(notLong);
2840 __ move(AT, ftos);
2841 __ bne(flags, AT, notFloat);
2842 __ delayed()->nop();
2844 // ftos
2845 __ lwc1(FSF, index, 0);
2846 __ sdc1(FSF, SP, - wordSize);
2848 if (!is_static) {
2849 patch_bytecode(Bytecodes::_fast_fgetfield, T3, T2);
2850 }
2851 __ b(Done);
2852 __ delayed()->daddi(SP, SP, - wordSize);
2854 __ bind(notFloat);
2855 __ move(AT, dtos);
2856 __ bne(flags, AT, notDouble);
2857 __ delayed()->nop();
2859 // dtos
2860 __ ldc1(FSF, index, 0 * wordSize);
2861 __ sdc1(FSF, SP, - 2 * wordSize);
2862 __ sd(R0, SP, - 1 * wordSize);
2864 if (!is_static) {
2865 patch_bytecode(Bytecodes::_fast_dgetfield, T3, T2);
2866 }
2867 __ b(Done);
2868 __ delayed()->daddi(SP, SP, - 2 * wordSize);
2870 __ bind(notDouble);
2872 __ stop("Bad state");
2874 __ bind(Done);
2875 }
2878 void TemplateTable::getfield(int byte_no) {
2879 getfield_or_static(byte_no, false);
2880 }
2882 void TemplateTable::getstatic(int byte_no) {
2883 getfield_or_static(byte_no, true);
2884 }
2886 // The registers cache and index expected to be set before call.
2887 // The function may destroy various registers, just not the cache and index registers.
2888 void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is_static) {
2889 transition(vtos, vtos);
2891 ByteSize cp_base_offset = ConstantPoolCache::base_offset();
2893 if (JvmtiExport::can_post_field_modification()) {
2894 // Check to see if a field modification watch has been set before
2895 // we take the time to call into the VM.
2896 Label L1;
2897 //kill AT, T1, T2, T3, T9
2898 Register tmp1 = T2;
2899 Register tmp2 = T1;
2900 Register tmp3 = T3;
2901 Register tmp4 = T9;
2902 assert_different_registers(cache, index, tmp4);
2904 __ li(AT, JvmtiExport::get_field_modification_count_addr());
2905 __ lw(AT, AT, 0);
2906 __ beq(AT, R0, L1);
2907 __ delayed()->nop();
2909 __ get_cache_and_index_at_bcp(tmp2, tmp4, 1);
2911 if (is_static) {
2912 __ move(tmp1, R0);
2913 } else {
2914 // Life is harder. The stack holds the value on top, followed by
2915 // the object. We don't know the size of the value, though; it
2916 // could be one or two words depending on its type. As a result,
2917 // we must find the type to determine where the object is.
2918 Label two_word, valsize_known;
2919 __ dsll(AT, tmp4, Address::times_8);
2920 __ dadd(AT, tmp2, AT);
2921 __ ld(tmp3, AT, in_bytes(cp_base_offset +
2922 ConstantPoolCacheEntry::flags_offset()));
2923 __ shr(tmp3, ConstantPoolCacheEntry::tos_state_shift);
2925 // Make sure we don't need to mask ecx for tos_state_shift
2926 // after the above shift
2927 ConstantPoolCacheEntry::verify_tos_state_shift();
2928 __ move(tmp1, SP);
2929 __ move(AT, ltos);
2930 __ beq(tmp3, AT, two_word);
2931 __ delayed()->nop();
2932 __ move(AT, dtos);
2933 __ beq(tmp3, AT, two_word);
2934 __ delayed()->nop();
2935 __ b(valsize_known);
2936 __ delayed()->daddi(tmp1, tmp1, Interpreter::expr_offset_in_bytes(1) );
2938 __ bind(two_word);
2939 __ daddi(tmp1, tmp1, Interpreter::expr_offset_in_bytes(2));
2941 __ bind(valsize_known);
2942 // setup object pointer
2943 __ ld(tmp1, tmp1, 0*wordSize);
2944 }
2945 // cache entry pointer
2946 __ daddi(tmp2, tmp2, in_bytes(cp_base_offset));
2947 __ shl(tmp4, LogBytesPerWord);
2948 __ daddu(tmp2, tmp2, tmp4);
2949 // object (tos)
2950 __ move(tmp3, SP);
2951 // tmp1: object pointer set up above (NULL if static)
2952 // tmp2: cache entry pointer
2953 // tmp3: jvalue object on the stack
2954 __ call_VM(NOREG,
2955 CAST_FROM_FN_PTR(address,
2956 InterpreterRuntime::post_field_modification),
2957 tmp1, tmp2, tmp3);
2958 __ get_cache_and_index_at_bcp(cache, index, 1);
2959 __ bind(L1);
2960 }
2961 }
2963 // used registers : T0, T1, T2, T3, T8
2964 // T1 : flags
2965 // T2 : off
2966 // T3 : obj
2967 // T8 : volatile bit
2968 // see ConstantPoolCacheEntry::set_field for more info
2969 void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
2970 transition(vtos, vtos);
2972 const Register cache = T3;
2973 const Register index = T0;
2974 const Register obj = T3;
2975 const Register off = T2;
2976 const Register flags = T1;
2977 const Register bc = T3;
2979 resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
2980 jvmti_post_field_mod(cache, index, is_static);
2981 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
2983 Label notVolatile, Done;
2984 __ move(AT, 1<<ConstantPoolCacheEntry::is_volatile_shift);
2985 __ andr(T8, flags, AT);
2987 Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
2989 assert(btos == 0, "change code, btos != 0");
2990 // btos
2991 __ dsrl(flags, flags, ConstantPoolCacheEntry::tos_state_shift);
2992 __ andi(flags, flags, ConstantPoolCacheEntry::tos_state_mask);
2993 __ bne(flags, R0, notByte);
2994 __ delayed()->nop();
2996 __ pop(btos);
2997 if (!is_static) {
2998 pop_and_check_object(obj);
2999 }
3000 __ dadd(AT, obj, off);
3001 __ sb(FSR, AT, 0);
3003 if (!is_static) {
3004 patch_bytecode(Bytecodes::_fast_bputfield, bc, off, true, byte_no);
3005 }
3006 __ b(Done);
3007 __ delayed()->nop();
3009 __ bind(notByte);
3010 // itos
3011 __ move(AT, itos);
3012 __ bne(flags, AT, notInt);
3013 __ delayed()->nop();
3015 __ pop(itos);
3016 if (!is_static) {
3017 pop_and_check_object(obj);
3018 }
3019 __ dadd(AT, obj, off);
3020 __ sw(FSR, AT, 0);
3022 if (!is_static) {
3023 patch_bytecode(Bytecodes::_fast_iputfield, bc, off, true, byte_no);
3024 }
3025 __ b(Done);
3026 __ delayed()->nop();
3027 __ bind(notInt);
3028 // atos
3029 __ move(AT, atos);
3030 __ bne(flags, AT, notObj);
3031 __ delayed()->nop();
3033 __ pop(atos);
3034 if (!is_static) {
3035 pop_and_check_object(obj);
3036 }
3038 __ dadd(AT, obj, off);
3039 __ store_heap_oop(Address(AT, 0), FSR);
3040 __ store_check(obj);
3042 if (!is_static) {
3043 patch_bytecode(Bytecodes::_fast_aputfield, bc, off, true, byte_no);
3044 }
3045 __ b(Done);
3046 __ delayed()->nop();
3047 __ bind(notObj);
3048 // ctos
3049 __ move(AT, ctos);
3050 __ bne(flags, AT, notChar);
3051 __ delayed()->nop();
3053 __ pop(ctos);
3054 if (!is_static) {
3055 pop_and_check_object(obj);
3056 }
3057 __ dadd(AT, obj, off);
3058 __ sh(FSR, AT, 0);
3059 if (!is_static) {
3060 patch_bytecode(Bytecodes::_fast_cputfield, bc, off, true, byte_no);
3061 }
3062 __ b(Done);
3063 __ delayed()->nop();
3064 __ bind(notChar);
3065 // stos
3066 __ move(AT, stos);
3067 __ bne(flags, AT, notShort);
3068 __ delayed()->nop();
3070 __ pop(stos);
3071 if (!is_static) {
3072 pop_and_check_object(obj);
3073 }
3074 __ dadd(AT, obj, off);
3075 __ sh(FSR, AT, 0);
3076 if (!is_static) {
3077 patch_bytecode(Bytecodes::_fast_sputfield, bc, off, true, byte_no);
3078 }
3079 __ b(Done);
3080 __ delayed()->nop();
3081 __ bind(notShort);
3082 // ltos
3083 __ move(AT, ltos);
3084 __ bne(flags, AT, notLong);
3085 __ delayed()->nop();
3087 // FIXME: there is no simple method to load/store 64-bit data in a atomic operation
3088 // we just ignore the volatile flag.
3089 //Label notVolatileLong;
3090 //__ beq(T1, R0, notVolatileLong);
3091 //__ delayed()->nop();
3093 //addent = 2 * wordSize;
3094 // no need
3095 //__ lw(FSR, SP, 0);
3096 //__ lw(SSR, SP, 1 * wordSize);
3097 //if (!is_static) {
3098 // __ lw(T3, SP, addent);
3099 // addent += 1 * wordSize;
3100 // __ verify_oop(T3);
3101 //}
3103 //__ daddu(AT, T3, T2);
3105 // Replace with real volatile test
3106 // NOTE : we assume that sdc1&ldc1 operate in 32-bit, this is true for Godson2 even in 64-bit kernel
3107 // last modified by yjl 7/12/2005
3108 //__ ldc1(FSF, SP, 0);
3109 //__ sdc1(FSF, AT, 0);
3110 //volatile_barrier();
3112 // Don't rewrite volatile version
3113 //__ b(notVolatile);
3114 //__ delayed()->addiu(SP, SP, addent);
3116 //__ bind(notVolatileLong);
3118 //__ pop(ltos); // overwrites edx
3119 // __ lw(FSR, SP, 0 * wordSize);
3120 // __ lw(SSR, SP, 1 * wordSize);
3121 // __ daddi(SP, SP, 2*wordSize);
3122 __ pop(ltos);
3123 if (!is_static) {
3124 pop_and_check_object(obj);
3125 }
3126 __ dadd(AT, obj, off);
3127 __ sd(FSR, AT, 0);
3128 if (!is_static) {
3129 patch_bytecode(Bytecodes::_fast_lputfield, bc, off, true, byte_no);
3130 }
3131 __ b(notVolatile);
3132 __ delayed()->nop();
3134 __ bind(notLong);
3135 // ftos
3136 __ move(AT, ftos);
3137 __ bne(flags, AT, notFloat);
3138 __ delayed()->nop();
3140 __ pop(ftos);
3141 if (!is_static) {
3142 pop_and_check_object(obj);
3143 }
3144 __ dadd(AT, obj, off);
3145 __ swc1(FSF, AT, 0);
3146 if (!is_static) {
3147 patch_bytecode(Bytecodes::_fast_fputfield, bc, off, true, byte_no);
3148 }
3149 __ b(Done);
3150 __ delayed()->nop();
3151 __ bind(notFloat);
3152 // dtos
3153 __ move(AT, dtos);
3154 __ bne(flags, AT, notDouble);
3155 __ delayed()->nop();
3157 __ pop(dtos);
3158 if (!is_static) {
3159 pop_and_check_object(obj);
3160 }
3161 __ dadd(AT, obj, off);
3162 __ sdc1(FSF, AT, 0);
3163 if (!is_static) {
3164 patch_bytecode(Bytecodes::_fast_dputfield, bc, off, true, byte_no);
3165 }
3167 #ifdef ASSERT
3168 __ b(Done);
3169 __ delayed()->nop();
3171 __ bind(notDouble);
3172 __ stop("Bad state");
3173 #endif
3175 __ bind(Done);
3177 // Check for volatile store
3178 __ beq(T8, R0, notVolatile);
3179 __ delayed()->nop();
3180 volatile_barrier( );
3181 __ bind(notVolatile);
3182 }
3184 void TemplateTable::putfield(int byte_no) {
3185 putfield_or_static(byte_no, false);
3186 }
3188 void TemplateTable::putstatic(int byte_no) {
3189 putfield_or_static(byte_no, true);
3190 }
3192 // used registers : T1, T2, T3
3193 // T1 : cp_entry
3194 // T2 : obj
3195 // T3 : value pointer
3196 void TemplateTable::jvmti_post_fast_field_mod() {
3197 if (JvmtiExport::can_post_field_modification()) {
3198 // Check to see if a field modification watch has been set before
3199 // we take the time to call into the VM.
3200 Label L2;
3201 //kill AT, T1, T2, T3, T9
3202 Register tmp1 = T2;
3203 Register tmp2 = T1;
3204 Register tmp3 = T3;
3205 Register tmp4 = T9;
3206 __ li(AT, JvmtiExport::get_field_modification_count_addr());
3207 __ lw(tmp3, AT, 0);
3208 __ beq(tmp3, R0, L2);
3209 __ delayed()->nop();
3210 __ pop_ptr(tmp1);
3211 __ verify_oop(tmp1);
3212 __ push_ptr(tmp1);
3213 switch (bytecode()) { // load values into the jvalue object
3214 case Bytecodes::_fast_aputfield: __ push_ptr(FSR); break;
3215 case Bytecodes::_fast_bputfield: // fall through
3216 case Bytecodes::_fast_sputfield: // fall through
3217 case Bytecodes::_fast_cputfield: // fall through
3218 case Bytecodes::_fast_iputfield: __ push_i(FSR); break;
3219 case Bytecodes::_fast_dputfield: __ push_d(FSF); break;
3220 case Bytecodes::_fast_fputfield: __ push_f(); break;
3221 case Bytecodes::_fast_lputfield: __ push_l(FSR); break;
3222 default: ShouldNotReachHere();
3223 }
3224 __ move(tmp3, SP);
3225 // access constant pool cache entry
3226 __ get_cache_entry_pointer_at_bcp(tmp2, FSR, 1);
3227 __ verify_oop(tmp1);
3228 // tmp1: object pointer copied above
3229 // tmp2: cache entry pointer
3230 // tmp3: jvalue object on the stack
3231 __ call_VM(NOREG,
3232 CAST_FROM_FN_PTR(address,
3233 InterpreterRuntime::post_field_modification),
3234 tmp1, tmp2, tmp3);
3236 switch (bytecode()) { // restore tos values
3237 case Bytecodes::_fast_aputfield: __ pop_ptr(FSR); break;
3238 case Bytecodes::_fast_bputfield: // fall through
3239 case Bytecodes::_fast_sputfield: // fall through
3240 case Bytecodes::_fast_cputfield: // fall through
3241 case Bytecodes::_fast_iputfield: __ pop_i(FSR); break;
3242 case Bytecodes::_fast_dputfield: __ pop_d(); break;
3243 case Bytecodes::_fast_fputfield: __ pop_f(); break;
3244 case Bytecodes::_fast_lputfield: __ pop_l(FSR); break;
3245 }
3246 __ bind(L2);
3247 }
3248 }
3250 // used registers : T2, T3, T1
3251 // T2 : index & off & field address
3252 // T3 : cache & obj
3253 // T1 : flags
3254 void TemplateTable::fast_storefield(TosState state) {
3255 transition(state, vtos);
3257 ByteSize base = ConstantPoolCache::base_offset();
3259 jvmti_post_fast_field_mod();
3261 // access constant pool cache
3262 __ get_cache_and_index_at_bcp(T3, T2, 1);
3264 // test for volatile with edx but edx is tos register for lputfield.
3265 __ dsll(AT, T2, Address::times_8);
3266 __ dadd(AT, T3, AT);
3267 __ ld(T1, AT, in_bytes(base + ConstantPoolCacheEntry::flags_offset()));
3269 // replace index with field offset from cache entry
3270 __ ld(T2, AT, in_bytes(base + ConstantPoolCacheEntry::f2_offset()));
3272 // Doug Lea believes this is not needed with current Sparcs (TSO) and Intel (PSO).
3273 // volatile_barrier( );
3275 Label notVolatile, Done;
3276 // Check for volatile store
3277 __ move(AT, 1<<ConstantPoolCacheEntry::is_volatile_shift);
3278 __ andr(AT, T1, AT);
3279 __ beq(AT, R0, notVolatile);
3280 __ delayed()->nop();
3283 // Get object from stack
3284 pop_and_check_object(T3);
3286 // field address
3287 __ dadd(T2, T3, T2);
3289 // access field
3290 switch (bytecode()) {
3291 case Bytecodes::_fast_bputfield:
3292 __ sb(FSR, T2, 0);
3293 break;
3294 case Bytecodes::_fast_sputfield: // fall through
3295 case Bytecodes::_fast_cputfield:
3296 __ sh(FSR, T2, 0);
3297 break;
3298 case Bytecodes::_fast_iputfield:
3299 __ sw(FSR, T2, 0);
3300 break;
3301 case Bytecodes::_fast_lputfield:
3302 __ sd(FSR, T2, 0 * wordSize);
3303 break;
3304 case Bytecodes::_fast_fputfield:
3305 __ swc1(FSF, T2, 0);
3306 break;
3307 case Bytecodes::_fast_dputfield:
3308 __ sdc1(FSF, T2, 0 * wordSize);
3309 break;
3310 case Bytecodes::_fast_aputfield:
3311 __ store_heap_oop(Address(T2, 0), FSR);
3312 __ store_check(T3);
3313 break;
3314 default:
3315 ShouldNotReachHere();
3316 }
3318 Label done;
3319 volatile_barrier( );
3320 __ b(done);
3321 __ delayed()->nop();
3323 // Same code as above, but don't need edx to test for volatile.
3324 __ bind(notVolatile);
3325 pop_and_check_object(T3);
3326 //get the field address
3327 __ dadd(T2, T3, T2);
3329 // access field
3330 switch (bytecode()) {
3331 case Bytecodes::_fast_bputfield:
3332 __ sb(FSR, T2, 0);
3333 break;
3334 case Bytecodes::_fast_sputfield: // fall through
3335 case Bytecodes::_fast_cputfield:
3336 __ sh(FSR, T2, 0);
3337 break;
3338 case Bytecodes::_fast_iputfield:
3339 __ sw(FSR, T2, 0);
3340 break;
3341 case Bytecodes::_fast_lputfield:
3342 __ sd(FSR, T2, 0 * wordSize);
3343 break;
3344 case Bytecodes::_fast_fputfield:
3345 __ swc1(FSF, T2, 0);
3346 break;
3347 case Bytecodes::_fast_dputfield:
3348 __ sdc1(FSF, T2, 0 * wordSize);
3349 break;
3350 case Bytecodes::_fast_aputfield:
3351 //add for compressedoops
3352 __ store_heap_oop(Address(T2, 0), FSR);
3353 __ store_check(T3);
3354 break;
3355 default:
3356 ShouldNotReachHere();
3357 }
3358 __ bind(done);
3359 }
3361 // used registers : T2, T3, T1
3362 // T3 : cp_entry & cache
3363 // T2 : index & offset
3364 void TemplateTable::fast_accessfield(TosState state) {
3365 transition(atos, state);
3367 // do the JVMTI work here to avoid disturbing the register state below
3368 if (JvmtiExport::can_post_field_access()) {
3369 // Check to see if a field access watch has been set before we take
3370 // the time to call into the VM.
3371 Label L1;
3372 __ li(AT, (intptr_t)JvmtiExport::get_field_access_count_addr());
3373 __ lw(T3, AT, 0);
3374 __ beq(T3, R0, L1);
3375 __ delayed()->nop();
3376 // access constant pool cache entry
3377 __ get_cache_entry_pointer_at_bcp(T3, T1, 1);
3378 __ move(TSR, FSR);
3379 __ verify_oop(FSR);
3380 // FSR: object pointer copied above
3381 // T3: cache entry pointer
3382 __ call_VM(NOREG,
3383 CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access),
3384 FSR, T3);
3385 __ move(FSR, TSR);
3386 __ bind(L1);
3387 }
3389 // access constant pool cache
3390 __ get_cache_and_index_at_bcp(T3, T2, 1);
3391 // replace index with field offset from cache entry
3392 __ dsll(AT, T2, Address::times_8);
3393 __ dadd(AT, T3, AT);
3394 __ ld(T2, AT, in_bytes(ConstantPoolCache::base_offset()
3395 + ConstantPoolCacheEntry::f2_offset()));
3397 // eax: object
3398 __ verify_oop(FSR);
3399 __ null_check(FSR);
3400 // field addresses
3401 __ dadd(FSR, FSR, T2);
3403 // access field
3404 switch (bytecode()) {
3405 case Bytecodes::_fast_bgetfield:
3406 __ lb(FSR, FSR, 0);
3407 break;
3408 case Bytecodes::_fast_sgetfield:
3409 __ lh(FSR, FSR, 0);
3410 break;
3411 case Bytecodes::_fast_cgetfield:
3412 __ lhu(FSR, FSR, 0);
3413 break;
3414 case Bytecodes::_fast_igetfield:
3415 __ lw(FSR, FSR, 0);
3416 break;
3417 case Bytecodes::_fast_lgetfield:
3418 __ stop("should not be rewritten");
3419 break;
3420 case Bytecodes::_fast_fgetfield:
3421 __ lwc1(FSF, FSR, 0);
3422 break;
3423 case Bytecodes::_fast_dgetfield:
3424 __ ldc1(FSF, FSR, 0);
3425 break;
3426 case Bytecodes::_fast_agetfield:
3427 //add for compressedoops
3428 __ load_heap_oop(FSR, Address(FSR, 0));
3429 __ verify_oop(FSR);
3430 break;
3431 default:
3432 ShouldNotReachHere();
3433 }
3435 // Doug Lea believes this is not needed with current Sparcs(TSO) and Intel(PSO)
3436 // volatile_barrier( );
3437 }
3439 // generator for _fast_iaccess_0, _fast_aaccess_0, _fast_faccess_0
3440 // used registers : T1, T2, T3, T1
3441 // T1 : obj & field address
3442 // T2 : off
3443 // T3 : cache
3444 // T1 : index
3445 void TemplateTable::fast_xaccess(TosState state) {
3446 transition(vtos, state);
3448 // get receiver
3449 __ ld(T1, aaddress(0));
3450 // access constant pool cache
3451 __ get_cache_and_index_at_bcp(T3, T2, 2);
3452 __ dsll(AT, T2, Address::times_8);
3453 __ dadd(AT, T3, AT);
3454 __ ld(T2, AT, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset()));
3456 // make sure exception is reported in correct bcp range (getfield is
3457 // next instruction)
3458 __ daddi(BCP, BCP, 1);
3459 __ null_check(T1);
3460 __ dadd(T1, T1, T2);
3462 if (state == itos) {
3463 __ lw(FSR, T1, 0);
3464 } else if (state == atos) {
3465 __ load_heap_oop(FSR, Address(T1, 0));
3466 __ verify_oop(FSR);
3467 } else if (state == ftos) {
3468 __ lwc1(FSF, T1, 0);
3469 } else {
3470 ShouldNotReachHere();
3471 }
3472 __ daddi(BCP, BCP, -1);
3473 }
3477 //-----------------------------------------------------------------------------
3478 // Calls
3480 void TemplateTable::count_calls(Register method, Register temp) {
3481 // implemented elsewhere
3482 ShouldNotReachHere();
3483 }
3485 // method, index, recv, flags: T1, T2, T3, T1
3486 // byte_no = 2 for _invokevirtual, 1 else
3487 // T0 : return address
3488 // get the method & index of the invoke, and push the return address of
3489 // the invoke(first word in the frame)
3490 // this address is where the return code jmp to.
3491 // NOTE : this method will set T3&T1 as recv&flags
3492 void TemplateTable::prepare_invoke(int byte_no,
3493 Register method, // linked method (or i-klass)
3494 Register index, // itable index, MethodType, etc.
3495 Register recv, // if caller wants to see it
3496 Register flags // if caller wants to test it
3497 ) {
3498 // determine flags
3499 const Bytecodes::Code code = bytecode();
3500 const bool is_invokeinterface = code == Bytecodes::_invokeinterface;
3501 const bool is_invokedynamic = code == Bytecodes::_invokedynamic;
3502 const bool is_invokehandle = code == Bytecodes::_invokehandle;
3503 const bool is_invokevirtual = code == Bytecodes::_invokevirtual;
3504 const bool is_invokespecial = code == Bytecodes::_invokespecial;
3505 const bool load_receiver = (recv != noreg);
3506 const bool save_flags = (flags != noreg);
3507 assert(load_receiver == (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic),"");
3508 assert(save_flags == (is_invokeinterface || is_invokevirtual), "need flags for vfinal");
3509 assert(flags == noreg || flags == T1, "error flags reg.");
3510 assert(recv == noreg || recv == T3, "error recv reg.");
3512 // setup registers & access constant pool cache
3513 if(recv == noreg) recv = T3;
3514 if(flags == noreg) flags = T1;
3515 assert_different_registers(method, index, recv, flags);
3517 // save 'interpreter return address'
3518 __ save_bcp();
3520 load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual, false, is_invokedynamic);
3522 if (is_invokedynamic || is_invokehandle) {
3523 Label L_no_push;
3524 __ move(AT, (1 << ConstantPoolCacheEntry::has_appendix_shift));
3525 __ andr(AT, AT, flags);
3526 __ beq(AT, R0, L_no_push);
3527 __ delayed()->nop();
3528 // Push the appendix as a trailing parameter.
3529 // This must be done before we get the receiver,
3530 // since the parameter_size includes it.
3531 Register tmp = SSR;
3532 __ push(tmp);
3533 __ move(tmp, index);
3534 assert(ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset == 0, "appendix expected at index+0");
3535 __ load_resolved_reference_at_index(index, tmp);
3536 __ pop(tmp);
3537 __ push(index); // push appendix (MethodType, CallSite, etc.)
3538 __ bind(L_no_push);
3539 }
3541 // load receiver if needed (after appendix is pushed so parameter size is correct)
3542 // Note: no return address pushed yet
3543 if (load_receiver) {
3544 __ move(AT, ConstantPoolCacheEntry::parameter_size_mask);
3545 __ andr(recv, flags, AT);
3546 // 2014/07/31 Fu: Since we won't push RA on stack, no_return_pc_pushed_yet should be 0.
3547 const int no_return_pc_pushed_yet = 0; // argument slot correction before we push return address
3548 const int receiver_is_at_end = -1; // back off one slot to get receiver
3549 Address recv_addr = __ argument_address(recv, no_return_pc_pushed_yet + receiver_is_at_end);
3550 __ ld(recv, recv_addr);
3551 __ verify_oop(recv);
3552 }
3553 if(save_flags) {
3554 __ move(BCP, flags);
3555 }
3557 // compute return type
3558 __ dsrl(flags, flags, ConstantPoolCacheEntry::tos_state_shift);
3559 __ andi(flags, flags, 0xf);
3561 // Make sure we don't need to mask flags for tos_state_shift after the above shift
3562 ConstantPoolCacheEntry::verify_tos_state_shift();
3563 // load return address
3564 {
3565 const address table = (address) Interpreter::invoke_return_entry_table_for(code);
3566 __ li(AT, (long)table);
3567 __ dsll(flags, flags, LogBytesPerWord);
3568 __ dadd(AT, AT, flags);
3569 __ ld(RA, AT, 0);
3570 }
3572 if (save_flags) {
3573 __ move(flags, BCP);
3574 __ restore_bcp();
3575 }
3576 }
3578 // used registers : T0, T3, T1, T2
3579 // T3 : recv, this two register using convention is by prepare_invoke
3580 // T1 : flags, klass
3581 // Rmethod : method, index must be Rmethod
3582 void TemplateTable::invokevirtual_helper(Register index,
3583 Register recv,
3584 Register flags) {
3586 assert_different_registers(index, recv, flags, T2);
3588 // Test for an invoke of a final method
3589 Label notFinal;
3590 __ move(AT, (1 << ConstantPoolCacheEntry::is_vfinal_shift));
3591 __ andr(AT, flags, AT);
3592 __ beq(AT, R0, notFinal);
3593 __ delayed()->nop();
3595 Register method = index; // method must be Rmethod
3596 assert(method == Rmethod, "methodOop must be Rmethod for interpreter calling convention");
3598 // do the call - the index is actually the method to call
3599 // the index is indeed methodOop, for this is vfinal,
3600 // see ConstantPoolCacheEntry::set_method for more info
3602 __ verify_oop(method);
3604 // It's final, need a null check here!
3605 __ null_check(recv);
3607 // profile this call
3608 __ profile_final_call(T2);
3610 // 2014/11/24 Fu
3611 // T2: tmp, used for mdp
3612 // method: callee
3613 // T9: tmp
3614 // is_virtual: true
3615 __ profile_arguments_type(T2, method, T9, true);
3617 __ jump_from_interpreted(method, T2);
3619 __ bind(notFinal);
3621 // get receiver klass
3622 __ null_check(recv, oopDesc::klass_offset_in_bytes());
3623 __ load_klass(T2, recv);
3624 __ verify_oop(T2);
3626 // profile this call
3627 __ profile_virtual_call(T2, T0, T1);
3629 // get target methodOop & entry point
3630 const int base = InstanceKlass::vtable_start_offset() * wordSize;
3631 assert(vtableEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
3632 __ dsll(AT, index, Address::times_ptr);
3633 // T2: receiver
3634 __ dadd(AT, T2, AT);
3635 //this is a ualign read
3636 __ ld(method, AT, base + vtableEntry::method_offset_in_bytes());
3637 __ profile_arguments_type(T2, method, T9, true);
3638 __ jump_from_interpreted(method, T2);
3640 }
3642 void TemplateTable::invokevirtual(int byte_no) {
3643 transition(vtos, vtos);
3644 assert(byte_no == f2_byte, "use this argument");
3645 prepare_invoke(byte_no, Rmethod, NOREG, T3, T1);
3646 // now recv & flags in T3, T1
3647 invokevirtual_helper(Rmethod, T3, T1);
3648 }
3650 // T9 : entry
3651 // Rmethod : method
3652 void TemplateTable::invokespecial(int byte_no) {
3653 transition(vtos, vtos);
3654 assert(byte_no == f1_byte, "use this argument");
3655 prepare_invoke(byte_no, Rmethod, NOREG, T3);
3656 // now recv & flags in T3, T1
3657 __ verify_oop(T3);
3658 __ null_check(T3);
3659 __ profile_call(T9);
3661 // 2014/11/24 Fu
3662 // T8: tmp, used for mdp
3663 // Rmethod: callee
3664 // T9: tmp
3665 // is_virtual: false
3666 __ profile_arguments_type(T8, Rmethod, T9, false);
3668 __ jump_from_interpreted(Rmethod, T9);
3669 __ move(T0, T3);//aoqi ?
3670 }
3672 void TemplateTable::invokestatic(int byte_no) {
3673 transition(vtos, vtos);
3674 assert(byte_no == f1_byte, "use this argument");
3675 prepare_invoke(byte_no, Rmethod, NOREG);
3676 __ verify_oop(Rmethod);
3678 __ profile_call(T9);
3680 // 2014/11/24 Fu
3681 // T8: tmp, used for mdp
3682 // Rmethod: callee
3683 // T9: tmp
3684 // is_virtual: false
3685 __ profile_arguments_type(T8, Rmethod, T9, false);
3687 __ jump_from_interpreted(Rmethod, T9);
3688 }
3690 // i have no idea what to do here, now. for future change. FIXME.
3691 void TemplateTable::fast_invokevfinal(int byte_no) {
3692 transition(vtos, vtos);
3693 assert(byte_no == f2_byte, "use this argument");
3694 __ stop("fast_invokevfinal not used on mips64");
3695 }
3697 // used registers : T0, T1, T2, T3, T1, A7
3698 // T0 : itable, vtable, entry
3699 // T1 : interface
3700 // T3 : receiver
3701 // T1 : flags, klass
3702 // Rmethod : index, method, this is required by interpreter_entry
3703 void TemplateTable::invokeinterface(int byte_no) {
3704 transition(vtos, vtos);
3705 //this method will use T1-T4 and T0
3706 assert(byte_no == f1_byte, "use this argument");
3707 prepare_invoke(byte_no, T2, Rmethod, T3, T1);
3708 // T2: Interface
3709 // Rmethod: index
3710 // T3: receiver
3711 // T1: flags
3713 // Special case of invokeinterface called for virtual method of
3714 // java.lang.Object. See cpCacheOop.cpp for details.
3715 // This code isn't produced by javac, but could be produced by
3716 // another compliant java compiler.
3717 Label notMethod;
3718 __ move(AT, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift));
3719 __ andr(AT, T1, AT);
3720 __ beq(AT, R0, notMethod);
3721 __ delayed()->nop();
3723 invokevirtual_helper(Rmethod, T3, T1);
3724 __ bind(notMethod);
3725 // Get receiver klass into T1 - also a null check
3726 //add for compressedoops
3727 __ load_klass(T1, T3);
3728 __ verify_oop(T1);
3730 // profile this call
3731 __ profile_virtual_call(T1, T0, FSR);
3733 // Compute start of first itableOffsetEntry (which is at the end of the vtable)
3734 // TODO: x86 add a new method lookup_interface_method // LEE
3735 const int base = InstanceKlass::vtable_start_offset() * wordSize;
3736 assert(vtableEntry::size() * wordSize == 8, "adjust the scaling in the code below");
3737 __ lw(AT, T1, InstanceKlass::vtable_length_offset() * wordSize);
3738 __ dsll(AT, AT, Address::times_8);
3739 __ dadd(T0, T1, AT);
3740 __ daddi(T0, T0, base);
3741 if (HeapWordsPerLong > 1) {
3742 // Round up to align_object_offset boundary
3743 __ round_to(T0, BytesPerLong);
3744 }
3745 // now T0 is the begin of the itable
3747 Label entry, search, interface_ok;
3749 ///__ jmp(entry);
3750 __ b(entry);
3751 __ delayed()->nop();
3753 __ bind(search);
3754 __ increment(T0, itableOffsetEntry::size() * wordSize);
3756 __ bind(entry);
3758 // Check that the entry is non-null. A null entry means that the receiver
3759 // class doesn't implement the interface, and wasn't the same as the
3760 // receiver class checked when the interface was resolved.
3761 __ ld(AT, T0, itableOffsetEntry::interface_offset_in_bytes());
3762 __ bne(AT, R0, interface_ok);
3763 __ delayed()->nop();
3764 // throw exception
3765 // the call_VM checks for exception, so we should never return here.
3767 //__ pop();//FIXME here,
3768 // pop return address (pushed by prepare_invoke).
3769 // no need now, we just save the value in RA now
3771 __ call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError));
3772 __ should_not_reach_here();
3774 __ bind(interface_ok);
3775 //NOTICE here, no pop as x86 do
3776 __ bne(AT, T2, search);
3777 __ delayed()->nop();
3779 // now we get vtable of the interface
3780 __ ld(T0, T0, itableOffsetEntry::offset_offset_in_bytes());
3781 __ daddu(T0, T1, T0);
3782 assert(itableMethodEntry::size() * wordSize == 8, "adjust the scaling in the code below");
3783 __ dsll(AT, Rmethod, Address::times_8);
3784 __ daddu(AT, T0, AT);
3785 // now we get the method
3786 __ ld(Rmethod, AT, 0);
3787 // Rnext: methodOop to call
3788 // T3: receiver
3789 // Check for abstract method error
3790 // Note: This should be done more efficiently via a throw_abstract_method_error
3791 // interpreter entry point and a conditional jump to it in case of a null
3792 // method.
3793 {
3794 Label L;
3795 __ bne(Rmethod, R0, L);
3796 __ delayed()->nop();
3798 // throw exception
3799 // note: must restore interpreter registers to canonical
3800 // state for exception handling to work correctly!
3801 ///__ popl(ebx); // pop return address (pushed by prepare_invoke)
3802 //__ restore_bcp(); // esi must be correct for exception handler
3803 //(was destroyed)
3804 //__ restore_locals(); // make sure locals pointer
3805 //is correct as well (was destroyed)
3806 ///__ call_VM(noreg, CAST_FROM_FN_PTR(address,
3807 //InterpreterRuntime::throw_AbstractMethodError));
3808 __ call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
3809 // the call_VM checks for exception, so we should never return here.
3810 __ should_not_reach_here();
3811 __ bind(L);
3812 }
3814 // 2014/11/24 Fu
3815 // T8: tmp, used for mdp
3816 // Rmethod: callee
3817 // T9: tmp
3818 // is_virtual: true
3819 __ profile_arguments_type(T8, Rmethod, T9, true);
3821 __ jump_from_interpreted(Rmethod, T9);
3822 }
3825 void TemplateTable::invokehandle(int byte_no) {
3826 transition(vtos, vtos);
3827 assert(byte_no == f1_byte, "use this argument");
3828 const Register T2_method = Rmethod;
3829 const Register FSR_mtype = FSR;
3830 const Register T3_recv = T3;
3832 if (!EnableInvokeDynamic) {
3833 // rewriter does not generate this bytecode
3834 __ should_not_reach_here();
3835 return;
3836 }
3838 prepare_invoke(byte_no, T2_method, FSR_mtype, T3_recv);
3839 //??__ verify_method_ptr(T2_method);
3840 __ verify_oop(T3_recv);
3841 __ null_check(T3_recv);
3843 // rax: MethodType object (from cpool->resolved_references[f1], if necessary)
3844 // rbx: MH.invokeExact_MT method (from f2)
3846 // Note: rax_mtype is already pushed (if necessary) by prepare_invoke
3848 // FIXME: profile the LambdaForm also
3849 __ profile_final_call(T9);
3851 // 2014/11/24 Fu
3852 // T8: tmp, used for mdp
3853 // T2_method: callee
3854 // T9: tmp
3855 // is_virtual: true
3856 __ profile_arguments_type(T8, T2_method, T9, true);
3858 __ jump_from_interpreted(T2_method, T9);
3859 }
3861 void TemplateTable::invokedynamic(int byte_no) {
3862 transition(vtos, vtos);
3863 assert(byte_no == f1_byte, "use this argument");
3865 if (!EnableInvokeDynamic) {
3866 // We should not encounter this bytecode if !EnableInvokeDynamic.
3867 // The verifier will stop it. However, if we get past the verifier,
3868 // this will stop the thread in a reasonable way, without crashing the JVM.
3869 __ call_VM(noreg, CAST_FROM_FN_PTR(address,
3870 InterpreterRuntime::throw_IncompatibleClassChangeError));
3871 // the call_VM checks for exception, so we should never return here.
3872 __ should_not_reach_here();
3873 return;
3874 }
3876 //const Register Rmethod = T2;
3877 const Register T2_callsite = T2;
3879 prepare_invoke(byte_no, Rmethod, T2_callsite);
3881 // rax: CallSite object (from cpool->resolved_references[f1])
3882 // rbx: MH.linkToCallSite method (from f2)
3884 // Note: rax_callsite is already pushed by prepare_invoke
3885 // %%% should make a type profile for any invokedynamic that takes a ref argument
3886 // profile this call
3887 __ profile_call(T9);
3889 // 2014/11/24 Fu
3890 // T8: tmp, used for mdp
3891 // Rmethod: callee
3892 // T9: tmp
3893 // is_virtual: false
3894 __ profile_arguments_type(T8, Rmethod, T9, false);
3896 __ verify_oop(T2_callsite);
3898 __ jump_from_interpreted(Rmethod, T9);
3899 }
3901 //-----------------------------------------------------------------------------
3902 // Allocation
3903 // T1 : tags & buffer end & thread
3904 // T2 : object end
3905 // T3 : klass
3906 // T1 : object size
3907 // A1 : cpool
3908 // A2 : cp index
3909 // return object in FSR
3910 void TemplateTable::_new() {
3911 transition(vtos, atos);
3912 __ get_unsigned_2_byte_index_at_bcp(A2, 1);
3914 Label slow_case;
3915 Label done;
3916 Label initialize_header;
3917 Label initialize_object; // including clearing the fields
3918 Label allocate_shared;
3920 // get InstanceKlass in T3
3921 __ get_cpool_and_tags(A1, T1);
3923 __ dsll(AT, A2, Address::times_8);
3924 if (UseLoongsonISA && Assembler::is_simm(sizeof(ConstantPool), 8)) {
3925 __ gsldx(T3, A1, AT, sizeof(ConstantPool));
3926 } else {
3927 __ dadd(AT, A1, AT);
3928 __ ld(T3, AT, sizeof(ConstantPool));
3929 }
3931 // make sure the class we're about to instantiate has been resolved.
3932 // Note: slow_case does a pop of stack, which is why we loaded class/pushed above
3933 const int tags_offset = Array<u1>::base_offset_in_bytes();
3934 if (UseLoongsonISA && Assembler::is_simm(tags_offset, 8)) {
3935 __ gslbx(AT, T1, A2, tags_offset);
3936 } else {
3937 __ dadd(T1, T1, A2);
3938 __ lb(AT, T1, tags_offset);
3939 }
3940 __ daddiu(AT, AT, - (int)JVM_CONSTANT_Class);
3941 __ bne(AT, R0, slow_case);
3942 //__ delayed()->nop();
3945 // make sure klass is initialized & doesn't have finalizer
3946 // make sure klass is fully initialized
3947 __ lhu(T1, T3, in_bytes(InstanceKlass::init_state_offset()));
3948 __ daddiu(AT, T1, - (int)InstanceKlass::fully_initialized);
3949 __ bne(AT, R0, slow_case);
3950 //__ delayed()->nop();
3952 // has_finalizer
3953 __ lw(T0, T3, in_bytes(Klass::layout_helper_offset()) );
3954 __ andi(AT, T0, Klass::_lh_instance_slow_path_bit);
3955 __ bne(AT, R0, slow_case);
3956 //__ delayed()->nop();
3958 // Allocate the instance
3959 // 1) Try to allocate in the TLAB
3960 // 2) if fail and the object is large allocate in the shared Eden
3961 // 3) if the above fails (or is not applicable), go to a slow case
3962 // (creates a new TLAB, etc.)
3964 const bool allow_shared_alloc =
3965 Universe::heap()->supports_inline_contig_alloc() && !CMSIncrementalMode;
3967 if (UseTLAB) {
3968 #ifndef OPT_THREAD
3969 const Register thread = T8;
3970 __ get_thread(thread);
3971 #else
3972 const Register thread = TREG;
3973 #endif
3974 // get tlab_top
3975 __ ld(FSR, thread, in_bytes(JavaThread::tlab_top_offset()));
3976 // get tlab_end
3977 __ ld(AT, thread, in_bytes(JavaThread::tlab_end_offset()));
3978 __ dadd(T2, FSR, T0);
3979 __ slt(AT, AT, T2);
3980 __ bne(AT, R0, allow_shared_alloc ? allocate_shared : slow_case);
3981 __ delayed()->nop();
3982 __ sd(T2, thread, in_bytes(JavaThread::tlab_top_offset()));
3984 if (ZeroTLAB) {
3985 // the fields have been already cleared
3986 __ beq(R0, R0, initialize_header);
3987 } else {
3988 // initialize both the header and fields
3989 __ beq(R0, R0, initialize_object);
3990 }
3991 __ delayed()->nop();
3992 }
3994 // Allocation in the shared Eden , if allowed
3995 // T0 : instance size in words
3996 if(allow_shared_alloc){
3997 __ bind(allocate_shared);
3999 Label retry;
4000 Address heap_top(T1);
4001 __ set64(T1, (long)Universe::heap()->top_addr());
4002 __ ld(FSR, heap_top);
4004 __ bind(retry);
4005 __ set64(AT, (long)Universe::heap()->end_addr());
4006 __ ld(AT, AT, 0);
4007 __ dadd(T2, FSR, T0);
4008 __ slt(AT, AT, T2);
4009 __ bne(AT, R0, slow_case);
4010 __ delayed()->nop();
4012 // Compare FSR with the top addr, and if still equal, store the new
4013 // top addr in ebx at the address of the top addr pointer. Sets ZF if was
4014 // equal, and clears it otherwise. Use lock prefix for atomicity on MPs.
4015 //
4016 // FSR: object begin
4017 // T2: object end
4018 // T0: instance size in words
4020 // if someone beat us on the allocation, try again, otherwise continue
4021 __ cmpxchg(T2, heap_top, FSR);
4022 __ beq(AT, R0, retry);
4023 __ delayed()->nop();
4024 }
4026 if (UseTLAB || Universe::heap()->supports_inline_contig_alloc()) {
4027 // The object is initialized before the header. If the object size is
4028 // zero, go directly to the header initialization.
4029 __ bind(initialize_object);
4030 __ set64(AT, - sizeof(oopDesc));
4031 __ daddu(T0, T0, AT);
4032 __ beq(T0, R0, initialize_header);
4033 __ delayed()->nop();
4035 // initialize remaining object fields: T0 is a multiple of 2
4036 {
4037 Label loop;
4038 __ dadd(T1, FSR, T0);
4039 __ daddi(T1, T1, -oopSize);
4041 __ bind(loop);
4042 __ sd(R0, T1, sizeof(oopDesc) + 0 * oopSize);
4043 __ bne(T1, FSR, loop); //dont clear header
4044 __ delayed()->daddi(T1, T1, -oopSize);
4045 }
4047 //klass in T3,
4048 // initialize object header only.
4049 __ bind(initialize_header);
4050 if (UseBiasedLocking) {
4051 __ ld(AT, T3, in_bytes(Klass::prototype_header_offset()));
4052 __ sd(AT, FSR, oopDesc::mark_offset_in_bytes ());
4053 } else {
4054 __ set64(AT, (long)markOopDesc::prototype());
4055 __ sd(AT, FSR, oopDesc::mark_offset_in_bytes());
4056 }
4058 __ store_klass_gap(FSR, R0);
4059 __ store_klass(FSR, T3);
4061 {
4062 SkipIfEqual skip_if(_masm, &DTraceAllocProbes, 0);
4063 // Trigger dtrace event for fastpath
4064 __ push(atos);
4065 __ call_VM_leaf(
4066 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc), FSR);
4067 __ pop(atos);
4069 }
4070 __ b(done);
4071 __ delayed()->nop();
4072 }
4074 // slow case
4075 __ bind(slow_case);
4076 call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), A1, A2);
4078 // continue
4079 __ bind(done);
4080 __ sync();
4081 }
4083 void TemplateTable::newarray() {
4084 transition(itos, atos);
4085 __ lbu(A1, at_bcp(1));
4086 //type, count
4087 call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::newarray), A1, FSR);
4088 __ sync();
4089 }
4091 void TemplateTable::anewarray() {
4092 transition(itos, atos);
4093 __ get_2_byte_integer_at_bcp(A2, AT, 1);
4094 __ huswap(A2);
4095 __ get_constant_pool(A1);
4096 // cp, index, count
4097 call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::anewarray), A1, A2, FSR);
4098 __ sync();
4099 }
4101 void TemplateTable::arraylength() {
4102 transition(atos, itos);
4103 __ null_check(FSR, arrayOopDesc::length_offset_in_bytes());
4104 __ lw(FSR, FSR, arrayOopDesc::length_offset_in_bytes());
4105 }
4107 // i use T2 as ebx, T3 as ecx, T1 as edx
4108 // when invoke gen_subtype_check, super in T3, sub in T2, object in FSR(it's always)
4109 // T2 : sub klass
4110 // T3 : cpool
4111 // T3 : super klass
4112 void TemplateTable::checkcast() {
4113 transition(atos, atos);
4114 Label done, is_null, ok_is_subtype, quicked, resolved;
4115 __ beq(FSR, R0, is_null);
4116 __ delayed()->nop();
4118 // Get cpool & tags index
4119 __ get_cpool_and_tags(T3, T1);
4120 __ get_2_byte_integer_at_bcp(T2, AT, 1);
4121 __ huswap(T2);
4123 // See if bytecode has already been quicked
4124 __ dadd(AT, T1, T2);
4125 __ lb(AT, AT, Array<u1>::base_offset_in_bytes());
4126 __ daddiu(AT, AT, - (int)JVM_CONSTANT_Class);
4127 __ beq(AT, R0, quicked);
4128 __ delayed()->nop();
4130 /* 2012/6/2 Jin: In InterpreterRuntime::quicken_io_cc, lots of new classes may be loaded.
4131 * Then, GC will move the object in V0 to another places in heap.
4132 * Therefore, We should never save such an object in register.
4133 * Instead, we should save it in the stack. It can be modified automatically by the GC thread.
4134 * After GC, the object address in FSR is changed to a new place.
4135 */
4136 __ push(atos);
4137 const Register thread = TREG;
4138 #ifndef OPT_THREAD
4139 __ get_thread(thread);
4140 #endif
4141 call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc));
4142 __ get_vm_result_2(T3, thread);
4143 __ pop_ptr(FSR);
4144 __ b(resolved);
4145 __ delayed()->nop();
4147 // klass already in cp, get superklass in T3
4148 __ bind(quicked);
4149 __ dsll(AT, T2, Address::times_8);
4150 __ dadd(AT, T3, AT);
4151 __ ld(T3, AT, sizeof(ConstantPool));
4153 __ bind(resolved);
4155 // get subklass in T2
4156 //add for compressedoops
4157 __ load_klass(T2, FSR);
4158 // Superklass in T3. Subklass in T2.
4159 __ gen_subtype_check(T3, T2, ok_is_subtype);
4161 // Come here on failure
4162 // object is at FSR
4163 __ jmp(Interpreter::_throw_ClassCastException_entry);
4164 __ delayed()->nop();
4166 // Come here on success
4167 __ bind(ok_is_subtype);
4169 // Collect counts on whether this check-cast sees NULLs a lot or not.
4170 if (ProfileInterpreter) {
4171 __ b(done);
4172 __ delayed()->nop();
4173 __ bind(is_null);
4174 __ profile_null_seen(T3);
4175 } else {
4176 __ bind(is_null);
4177 }
4178 __ bind(done);
4179 }
4181 // i use T3 as cpool, T1 as tags, T2 as index
4182 // object always in FSR, superklass in T3, subklass in T2
4183 void TemplateTable::instanceof() {
4184 transition(atos, itos);
4185 Label done, is_null, ok_is_subtype, quicked, resolved;
4187 __ beq(FSR, R0, is_null);
4188 __ delayed()->nop();
4190 // Get cpool & tags index
4191 __ get_cpool_and_tags(T3, T1);
4192 // get index
4193 __ get_2_byte_integer_at_bcp(T2, AT, 1);
4194 __ hswap(T2);
4196 // See if bytecode has already been quicked
4197 // quicked
4198 __ daddu(AT, T1, T2);
4199 __ lb(AT, AT, Array<u1>::base_offset_in_bytes());
4200 __ daddiu(AT, AT, - (int)JVM_CONSTANT_Class);
4201 __ beq(AT, R0, quicked);
4202 __ delayed()->nop();
4204 __ push(atos);
4205 const Register thread = TREG;
4206 #ifndef OPT_THREAD
4207 __ get_thread(thread);
4208 #endif
4209 call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc));
4210 __ get_vm_result_2(T3, thread);
4211 __ pop_ptr(FSR);
4212 __ b(resolved);
4213 __ delayed()->nop();
4215 // get superklass in T3, subklass in T2
4216 __ bind(quicked);
4217 __ dsll(AT, T2, Address::times_8);
4218 __ daddu(AT, T3, AT);
4219 __ ld(T3, AT, sizeof(ConstantPool));
4221 __ bind(resolved);
4222 // get subklass in T2
4223 //add for compressedoops
4224 __ load_klass(T2, FSR);
4226 // Superklass in T3. Subklass in T2.
4227 __ gen_subtype_check(T3, T2, ok_is_subtype);
4228 // Come here on failure
4229 __ b(done);
4230 __ delayed(); __ move(FSR, R0);
4232 // Come here on success
4233 __ bind(ok_is_subtype);
4234 __ move(FSR, 1);
4236 // Collect counts on whether this test sees NULLs a lot or not.
4237 if (ProfileInterpreter) {
4238 __ beq(R0, R0, done);
4239 __ nop();
4240 __ bind(is_null);
4241 __ profile_null_seen(T3);
4242 } else {
4243 __ bind(is_null); // same as 'done'
4244 }
4245 __ bind(done);
4246 // FSR = 0: obj == NULL or obj is not an instanceof the specified klass
4247 // FSR = 1: obj != NULL and obj is an instanceof the specified klass
4248 }
4250 //--------------------------------------------------------
4251 //--------------------------------------------
4252 // Breakpoints
4253 void TemplateTable::_breakpoint() {
4254 // Note: We get here even if we are single stepping..
4255 // jbug inists on setting breakpoints at every bytecode
4256 // even if we are in single step mode.
4258 transition(vtos, vtos);
4260 // get the unpatched byte code
4261 __ get_method(A1);
4262 __ call_VM(NOREG,
4263 CAST_FROM_FN_PTR(address,
4264 InterpreterRuntime::get_original_bytecode_at),
4265 A1, BCP);
4266 __ move(Rnext, V0); // Jin: Rnext will be used in dispatch_only_normal
4268 // post the breakpoint event
4269 __ get_method(A1);
4270 __ call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::_breakpoint), A1, BCP);
4272 // complete the execution of original bytecode
4273 __ dispatch_only_normal(vtos);
4274 }
4276 //-----------------------------------------------------------------------------
4277 // Exceptions
4279 void TemplateTable::athrow() {
4280 transition(atos, vtos);
4281 __ null_check(FSR);
4282 __ jmp(Interpreter::throw_exception_entry());
4283 __ delayed()->nop();
4284 }
4286 //-----------------------------------------------------------------------------
4287 // Synchronization
4288 //
4289 // Note: monitorenter & exit are symmetric routines; which is reflected
4290 // in the assembly code structure as well
4291 //
4292 // Stack layout:
4293 //
4294 // [expressions ] <--- SP = expression stack top
4295 // ..
4296 // [expressions ]
4297 // [monitor entry] <--- monitor block top = expression stack bot
4298 // ..
4299 // [monitor entry]
4300 // [frame data ] <--- monitor block bot
4301 // ...
4302 // [return addr ] <--- FP
4304 // we use T2 as monitor entry pointer, T3 as monitor top pointer, c_rarg0 as free slot pointer
4305 // object always in FSR
4306 void TemplateTable::monitorenter() {
4307 transition(atos, vtos);
4309 // check for NULL object
4310 __ null_check(FSR);
4312 const Address monitor_block_top(FP, frame::interpreter_frame_monitor_block_top_offset
4313 * wordSize);
4314 const int entry_size = (frame::interpreter_frame_monitor_size()* wordSize);
4315 Label allocated;
4317 // initialize entry pointer
4318 __ move(c_rarg0, R0);
4320 // find a free slot in the monitor block (result in edx)
4321 {
4322 Label entry, loop, exit, next;
4323 __ ld(T2, monitor_block_top);
4324 __ b(entry);
4325 __ delayed()->daddi(T3, FP, frame::interpreter_frame_initial_sp_offset * wordSize);
4327 // free slot?
4328 __ bind(loop);
4329 __ ld(AT, T2, BasicObjectLock::obj_offset_in_bytes());
4330 __ bne(AT, R0, next);
4331 __ delayed()->nop();
4332 __ move(c_rarg0, T2);
4334 __ bind(next);
4335 __ beq(FSR, AT, exit);
4336 __ delayed()->nop();
4337 __ daddi(T2, T2, entry_size);
4339 __ bind(entry);
4340 __ bne(T3, T2, loop);
4341 __ delayed()->nop();
4342 __ bind(exit);
4343 }
4345 __ bne(c_rarg0, R0, allocated);
4346 __ delayed()->nop();
4348 // allocate one if there's no free slot
4349 {
4350 Label entry, loop;
4351 // 1. compute new pointers // SP: old expression stack top
4352 __ ld(c_rarg0, monitor_block_top);
4353 __ daddi(SP, SP, - entry_size);
4354 __ daddi(c_rarg0, c_rarg0, - entry_size);
4355 __ sd(c_rarg0, monitor_block_top);
4356 __ b(entry);
4357 __ delayed(); __ move(T3, SP);
4359 // 2. move expression stack contents
4360 __ bind(loop);
4361 __ ld(AT, T3, entry_size);
4362 __ sd(AT, T3, 0);
4363 __ daddi(T3, T3, wordSize);
4364 __ bind(entry);
4365 __ bne(T3, c_rarg0, loop);
4366 __ delayed()->nop();
4367 }
4369 __ bind(allocated);
4370 // Increment bcp to point to the next bytecode,
4371 // so exception handling for async. exceptions work correctly.
4372 // The object has already been poped from the stack, so the
4373 // expression stack looks correct.
4374 __ daddi(BCP, BCP, 1);
4375 __ sd(FSR, c_rarg0, BasicObjectLock::obj_offset_in_bytes());
4376 __ lock_object(c_rarg0);
4377 // check to make sure this monitor doesn't cause stack overflow after locking
4378 __ save_bcp(); // in case of exception
4379 __ generate_stack_overflow_check(0);
4380 // The bcp has already been incremented. Just need to dispatch to next instruction.
4382 __ dispatch_next(vtos);
4383 }
4385 // T2 : top
4386 // c_rarg0 : entry
4387 void TemplateTable::monitorexit() {
4388 transition(atos, vtos);
4390 __ null_check(FSR);
4392 const int entry_size =(frame::interpreter_frame_monitor_size()* wordSize);
4393 Label found;
4395 // find matching slot
4396 {
4397 Label entry, loop;
4398 __ ld(c_rarg0, FP, frame::interpreter_frame_monitor_block_top_offset * wordSize);
4399 __ b(entry);
4400 __ delayed()->daddiu(T2, FP, frame::interpreter_frame_initial_sp_offset * wordSize);
4402 __ bind(loop);
4403 __ ld(AT, c_rarg0, BasicObjectLock::obj_offset_in_bytes());
4404 __ beq(FSR, AT, found);
4405 __ delayed()->nop();
4406 __ daddiu(c_rarg0, c_rarg0, entry_size);
4407 __ bind(entry);
4408 __ bne(T2, c_rarg0, loop);
4409 __ delayed()->nop();
4410 }
4412 // error handling. Unlocking was not block-structured
4413 Label end;
4414 __ call_VM(NOREG, CAST_FROM_FN_PTR(address,
4415 InterpreterRuntime::throw_illegal_monitor_state_exception));
4416 __ should_not_reach_here();
4418 // call run-time routine
4419 // c_rarg0: points to monitor entry
4420 __ bind(found);
4421 __ move(TSR, FSR);
4422 __ unlock_object(c_rarg0);
4423 __ move(FSR, TSR);
4424 __ bind(end);
4425 }
4428 // Wide instructions
4429 void TemplateTable::wide() {
4430 transition(vtos, vtos);
4431 // Note: the esi increment step is part of the individual wide bytecode implementations
4432 __ lbu(Rnext, at_bcp(1));
4433 __ dsll(T9, Rnext, Address::times_8);
4434 __ li(AT, (long)Interpreter::_wentry_point);
4435 __ dadd(AT, T9, AT);
4436 __ ld(T9, AT, 0);
4437 __ jr(T9);
4438 __ delayed()->nop();
4439 }
4442 void TemplateTable::multianewarray() {
4443 transition(vtos, atos);
4444 // last dim is on top of stack; we want address of first one:
4445 // first_addr = last_addr + (ndims - 1) * wordSize
4446 __ lbu(A1, at_bcp(3)); // dimension
4447 __ daddi(A1, A1, -1);
4448 __ dsll(A1, A1, Address::times_8);
4449 __ dadd(A1, SP, A1); // now A1 pointer to the count array on the stack
4450 call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::multianewarray), A1);
4451 __ lbu(AT, at_bcp(3));
4452 __ dsll(AT, AT, Address::times_8);
4453 __ dadd(SP, SP, AT);
4454 __ sync();
4455 }
4456 #endif // !CC_INTERP