428 #endif // AARCH64
429 }
430
431
432 void TemplateTable::bipush() {
433 transition(vtos, itos);
434 __ ldrsb(R0_tos, at_bcp(1));
435 }
436
437
438 void TemplateTable::sipush() {
439 transition(vtos, itos);
440 __ ldrsb(R0_tmp, at_bcp(1));
441 __ ldrb(R1_tmp, at_bcp(2));
442 __ orr(R0_tos, R1_tmp, AsmOperand(R0_tmp, lsl, BitsPerByte));
443 }
444
445
446 void TemplateTable::ldc(bool wide) {
447 transition(vtos, vtos);
448 Label fastCase, Done;
449
450 const Register Rindex = R1_tmp;
451 const Register Rcpool = R2_tmp;
452 const Register Rtags = R3_tmp;
453 const Register RtagType = R3_tmp;
454
455 if (wide) {
456 __ get_unsigned_2_byte_index_at_bcp(Rindex, 1);
457 } else {
458 __ ldrb(Rindex, at_bcp(1));
459 }
460 __ get_cpool_and_tags(Rcpool, Rtags);
461
462 const int base_offset = ConstantPool::header_size() * wordSize;
463 const int tags_offset = Array<u1>::base_offset_in_bytes();
464
465 // get const type
466 __ add(Rtemp, Rtags, tags_offset);
467 #ifdef AARCH64
468 __ add(Rtemp, Rtemp, Rindex);
480 #ifdef AARCH64
481 __ mov(Rtemp, JVM_CONSTANT_UnresolvedClassInError); // this constant does not fit into 5-bit immediate constraint
482 __ cond_cmp(RtagType, Rtemp, ne);
483 #else
484 __ cond_cmp(RtagType, JVM_CONSTANT_UnresolvedClassInError, ne);
485 #endif // AARCH64
486
487 // resolved class - need to call vm to get java mirror of the class
488 __ cond_cmp(RtagType, JVM_CONSTANT_Class, ne);
489
490 __ b(fastCase, ne);
491
492 // slow case - call runtime
493 __ mov(R1, wide);
494 call_VM(R0_tos, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), R1);
495 __ push(atos);
496 __ b(Done);
497
498 // int, float, String
499 __ bind(fastCase);
500 #ifdef ASSERT
501 { Label L;
502 __ cmp(RtagType, JVM_CONSTANT_Integer);
503 __ cond_cmp(RtagType, JVM_CONSTANT_Float, ne);
504 __ b(L, eq);
505 __ stop("unexpected tag type in ldc");
506 __ bind(L);
507 }
508 #endif // ASSERT
509 // itos, ftos
510 __ add(Rtemp, Rcpool, AsmOperand(Rindex, lsl, LogBytesPerWord));
511 __ ldr_u32(R0_tos, Address(Rtemp, base_offset));
512
513 // floats and ints are placed on stack in the same way, so
514 // we can use push(itos) to transfer float value without VFP
515 __ push(itos);
516 __ bind(Done);
517 }
518
519 // Fast path for caching oop constants.
520 void TemplateTable::fast_aldc(bool wide) {
521 transition(vtos, atos);
522 int index_size = wide ? sizeof(u2) : sizeof(u1);
523 Label resolved;
524
525 // We are resolved if the resolved reference cache entry contains a
526 // non-null object (CallSite, etc.)
527 assert_different_registers(R0_tos, R2_tmp);
528 __ get_index_at_bcp(R2_tmp, 1, R0_tos, index_size);
529 __ load_resolved_reference_at_index(R0_tos, R2_tmp);
530 __ cbnz(R0_tos, resolved);
531
532 address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);
533
534 // first time invocation - must resolve first
535 __ mov(R1, (int)bytecode());
536 __ call_VM(R0_tos, entry, R1);
537 __ bind(resolved);
538
539 if (VerifyOops) {
540 __ verify_oop(R0_tos);
541 }
542 }
543
544 void TemplateTable::ldc2_w() {
545 transition(vtos, vtos);
546 const Register Rtags = R2_tmp;
547 const Register Rindex = R3_tmp;
548 const Register Rcpool = R4_tmp;
549 const Register Rbase = R5_tmp;
550
551 __ get_unsigned_2_byte_index_at_bcp(Rindex, 1);
552
553 __ get_cpool_and_tags(Rcpool, Rtags);
554 const int base_offset = ConstantPool::header_size() * wordSize;
555 const int tags_offset = Array<u1>::base_offset_in_bytes();
556
557 __ add(Rbase, Rcpool, AsmOperand(Rindex, lsl, LogBytesPerWord));
558
559 #ifdef __ABI_HARD__
560 Label Long, exit;
561 // get type from tags
562 __ add(Rtemp, Rtags, tags_offset);
563 __ ldrb(Rtemp, Address(Rtemp, Rindex));
564 __ cmp(Rtemp, JVM_CONSTANT_Double);
565 __ b(Long, ne);
566 __ ldr_double(D0_tos, Address(Rbase, base_offset));
567
568 __ push(dtos);
569 __ b(exit);
570 __ bind(Long);
571 #endif
572
573 #ifdef AARCH64
574 __ ldr(R0_tos, Address(Rbase, base_offset));
575 #else
576 __ ldr(R0_tos_lo, Address(Rbase, base_offset + 0 * wordSize));
577 __ ldr(R1_tos_hi, Address(Rbase, base_offset + 1 * wordSize));
578 #endif // AARCH64
579 __ push(ltos);
580
581 #ifdef __ABI_HARD__
582 __ bind(exit);
583 #endif
584 }
585
586
587 void TemplateTable::locals_index(Register reg, int offset) {
588 __ ldrb(reg, at_bcp(offset));
589 }
590
591 void TemplateTable::iload() {
592 iload_internal();
593 }
594
595 void TemplateTable::nofast_iload() {
596 iload_internal(may_not_rewrite);
597 }
598
599 void TemplateTable::iload_internal(RewriteControl rc) {
600 transition(vtos, itos);
601
602 if ((rc == may_rewrite) && __ rewrite_frequent_pairs()) {
603 Label rewrite, done;
|
428 #endif // AARCH64
429 }
430
431
432 void TemplateTable::bipush() {
433 transition(vtos, itos);
434 __ ldrsb(R0_tos, at_bcp(1));
435 }
436
437
438 void TemplateTable::sipush() {
439 transition(vtos, itos);
440 __ ldrsb(R0_tmp, at_bcp(1));
441 __ ldrb(R1_tmp, at_bcp(2));
442 __ orr(R0_tos, R1_tmp, AsmOperand(R0_tmp, lsl, BitsPerByte));
443 }
444
445
446 void TemplateTable::ldc(bool wide) {
447 transition(vtos, vtos);
448 Label fastCase, Condy, Done;
449
450 const Register Rindex = R1_tmp;
451 const Register Rcpool = R2_tmp;
452 const Register Rtags = R3_tmp;
453 const Register RtagType = R3_tmp;
454
455 if (wide) {
456 __ get_unsigned_2_byte_index_at_bcp(Rindex, 1);
457 } else {
458 __ ldrb(Rindex, at_bcp(1));
459 }
460 __ get_cpool_and_tags(Rcpool, Rtags);
461
462 const int base_offset = ConstantPool::header_size() * wordSize;
463 const int tags_offset = Array<u1>::base_offset_in_bytes();
464
465 // get const type
466 __ add(Rtemp, Rtags, tags_offset);
467 #ifdef AARCH64
468 __ add(Rtemp, Rtemp, Rindex);
480 #ifdef AARCH64
481 __ mov(Rtemp, JVM_CONSTANT_UnresolvedClassInError); // this constant does not fit into 5-bit immediate constraint
482 __ cond_cmp(RtagType, Rtemp, ne);
483 #else
484 __ cond_cmp(RtagType, JVM_CONSTANT_UnresolvedClassInError, ne);
485 #endif // AARCH64
486
487 // resolved class - need to call vm to get java mirror of the class
488 __ cond_cmp(RtagType, JVM_CONSTANT_Class, ne);
489
490 __ b(fastCase, ne);
491
492 // slow case - call runtime
493 __ mov(R1, wide);
494 call_VM(R0_tos, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), R1);
495 __ push(atos);
496 __ b(Done);
497
498 // int, float, String
499 __ bind(fastCase);
500
501 __ cmp(RtagType, JVM_CONSTANT_Integer);
502 __ cond_cmp(RtagType, JVM_CONSTANT_Float, ne);
503 __ b(Condy, ne);
504
505 // itos, ftos
506 __ add(Rtemp, Rcpool, AsmOperand(Rindex, lsl, LogBytesPerWord));
507 __ ldr_u32(R0_tos, Address(Rtemp, base_offset));
508
509 // floats and ints are placed on stack in the same way, so
510 // we can use push(itos) to transfer float value without VFP
511 __ push(itos);
512 __ b(Done);
513
514 __ bind(Condy);
515 condy_helper(Done);
516
517 __ bind(Done);
518 }
519
520 // Fast path for caching oop constants.
521 void TemplateTable::fast_aldc(bool wide) {
522 transition(vtos, atos);
523 int index_size = wide ? sizeof(u2) : sizeof(u1);
524 Label resolved;
525
526 // We are resolved if the resolved reference cache entry contains a
527 // non-null object (CallSite, etc.)
528 assert_different_registers(R0_tos, R2_tmp);
529 __ get_index_at_bcp(R2_tmp, 1, R0_tos, index_size);
530 __ load_resolved_reference_at_index(R0_tos, R2_tmp);
531 __ cbnz(R0_tos, resolved);
532
533 address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);
534
535 // first time invocation - must resolve first
536 __ mov(R1, (int)bytecode());
537 __ call_VM(R0_tos, entry, R1);
538 __ bind(resolved);
539
540 { // Check for the null sentinel.
541 // If we just called the VM, that already did the mapping for us,
542 // but it's harmless to retry.
543 Label notNull;
544 Register result = R0;
545 Register tmp = R1;
546 Register rarg = R2;
547
548 // Stash null_sentinel address to get its value later
549 __ mov_slow(rarg, (uintptr_t)Universe::the_null_sentinel_addr());
550 __ ldr(tmp, Address(rarg));
551 __ cmp(result, tmp);
552 __ b(notNull, ne);
553 __ mov(result, 0); // NULL object reference
554 __ bind(notNull);
555 }
556
557 if (VerifyOops) {
558 __ verify_oop(R0_tos);
559 }
560 }
561
562 void TemplateTable::ldc2_w() {
563 transition(vtos, vtos);
564 const Register Rtags = R2_tmp;
565 const Register Rindex = R3_tmp;
566 const Register Rcpool = R4_tmp;
567 const Register Rbase = R5_tmp;
568
569 __ get_unsigned_2_byte_index_at_bcp(Rindex, 1);
570
571 __ get_cpool_and_tags(Rcpool, Rtags);
572 const int base_offset = ConstantPool::header_size() * wordSize;
573 const int tags_offset = Array<u1>::base_offset_in_bytes();
574
575 __ add(Rbase, Rcpool, AsmOperand(Rindex, lsl, LogBytesPerWord));
576
577 Label Condy, exit;
578 #ifdef __ABI_HARD__
579 Label Long;
580 // get type from tags
581 __ add(Rtemp, Rtags, tags_offset);
582 __ ldrb(Rtemp, Address(Rtemp, Rindex));
583 __ cmp(Rtemp, JVM_CONSTANT_Double);
584 __ b(Long, ne);
585 __ ldr_double(D0_tos, Address(Rbase, base_offset));
586
587 __ push(dtos);
588 __ b(exit);
589 __ bind(Long);
590 #endif
591
592 __ cmp(Rtemp, JVM_CONSTANT_Long);
593 __ b(Condy, ne);
594 #ifdef AARCH64
595 __ ldr(R0_tos, Address(Rbase, base_offset));
596 #else
597 __ ldr(R0_tos_lo, Address(Rbase, base_offset + 0 * wordSize));
598 __ ldr(R1_tos_hi, Address(Rbase, base_offset + 1 * wordSize));
599 #endif // AARCH64
600 __ push(ltos);
601 __ b(exit);
602
603 __ bind(Condy);
604 condy_helper(exit);
605
606 __ bind(exit);
607 }
608
609
610 void TemplateTable::condy_helper(Label& Done)
611 {
612 Register obj = R0_tmp;
613 Register rtmp = R1_tmp;
614 Register flags = R2_tmp;
615 Register off = R3_tmp;
616
617 __ mov(R1, (int) bytecode());
618 __ call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc), R1);
619 __ get_vm_result_2(flags, rtmp);
620
621 // VMr = obj = base address to find primitive value to push
622 // VMr2 = flags = (tos, off) using format of CPCE::_flags
623 __ mov(off, flags);
624
625 #ifdef AARCH64
626 __ andr(off, off, (unsigned)ConstantPoolCacheEntry::field_index_mask);
627 #else
628 __ logical_shift_left( off, off, 32 - ConstantPoolCacheEntry::field_index_bits);
629 __ logical_shift_right(off, off, 32 - ConstantPoolCacheEntry::field_index_bits);
630 #endif
631
632 const Address field(obj, off);
633
634 __ logical_shift_right(flags, flags, ConstantPoolCacheEntry::tos_state_shift);
635
636 switch (bytecode()) {
637 case Bytecodes::_ldc:
638 case Bytecodes::_ldc_w:
639 {
640 // tos in (itos, ftos, stos, btos, ctos, ztos)
641 Label notIntFloat, notShort, notByte, notChar, notBool;
642 __ cmp(flags, itos);
643 __ cond_cmp(flags, ftos, ne);
644 __ b(notIntFloat, ne);
645 __ ldr(R0, field);
646 __ push(itos);
647 __ b(Done);
648
649 __ bind(notIntFloat);
650 __ cmp(flags, stos);
651 __ b(notShort, ne);
652 __ ldrsh(R0, field);
653 __ push(stos);
654 __ b(Done);
655
656 __ bind(notShort);
657 __ cmp(flags, btos);
658 __ b(notByte, ne);
659 __ ldrsb(R0, field);
660 __ push(btos);
661 __ b(Done);
662
663 __ bind(notByte);
664 __ cmp(flags, ctos);
665 __ b(notChar, ne);
666 __ ldrh(R0, field);
667 __ push(ctos);
668 __ b(Done);
669
670 __ bind(notChar);
671 __ cmp(flags, ztos);
672 __ b(notBool, ne);
673 __ ldrsb(R0, field);
674 __ push(ztos);
675 __ b(Done);
676
677 __ bind(notBool);
678 break;
679 }
680
681 case Bytecodes::_ldc2_w:
682 {
683 Label notLongDouble;
684 __ cmp(flags, ltos);
685 __ cond_cmp(flags, dtos, ne);
686 __ b(notLongDouble, ne);
687
688 #ifdef AARCH64
689 __ ldr(R0_tos, field);
690 #else
691 __ add(rtmp, obj, wordSize);
692 __ ldr(R0_tos_lo, Address(obj, off));
693 __ ldr(R1_tos_hi, Address(rtmp, off));
694 #endif
695 __ push(ltos);
696 __ b(Done);
697
698 __ bind(notLongDouble);
699
700 break;
701 }
702
703 default:
704 ShouldNotReachHere();
705 }
706
707 __ stop("bad ldc/condy");
708 }
709
710
711 void TemplateTable::locals_index(Register reg, int offset) {
712 __ ldrb(reg, at_bcp(offset));
713 }
714
715 void TemplateTable::iload() {
716 iload_internal();
717 }
718
719 void TemplateTable::nofast_iload() {
720 iload_internal(may_not_rewrite);
721 }
722
723 void TemplateTable::iload_internal(RewriteControl rc) {
724 transition(vtos, itos);
725
726 if ((rc == may_rewrite) && __ rewrite_frequent_pairs()) {
727 Label rewrite, done;
|