sharedRuntime_sparc.cpp (727:6b2273dd6fa9) | sharedRuntime_sparc.cpp (1006:dcf03e02b020) |
---|---|
1/* 2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * --- 526 unchanged lines hidden (view full) --- 535 } 536 } 537 538 // retun the amount of stack space these arguments will need. 539 return stk_reg_pairs; 540 541} 542 | 1/* 2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * --- 526 unchanged lines hidden (view full) --- 535 } 536 } 537 538 // retun the amount of stack space these arguments will need. 539 return stk_reg_pairs; 540 541} 542 |
543// Helper class mostly to avoid passing masm everywhere, and handle store 544// displacement overflow logic for LP64 | 543// Helper class mostly to avoid passing masm everywhere, and handle 544// store displacement overflow logic. |
545class AdapterGenerator { 546 MacroAssembler *masm; | 545class AdapterGenerator { 546 MacroAssembler *masm; |
547#ifdef _LP64 | |
548 Register Rdisp; 549 void set_Rdisp(Register r) { Rdisp = r; } | 547 Register Rdisp; 548 void set_Rdisp(Register r) { Rdisp = r; } |
550#endif // _LP64 | |
551 552 void patch_callers_callsite(); 553 void tag_c2i_arg(frame::Tag t, Register base, int st_off, Register scratch); 554 555 // base+st_off points to top of argument 556 int arg_offset(const int st_off) { return st_off + Interpreter::value_offset_in_bytes(); } 557 int next_arg_offset(const int st_off) { 558 return st_off - Interpreter::stackElementSize() + Interpreter::value_offset_in_bytes(); 559 } 560 | 549 550 void patch_callers_callsite(); 551 void tag_c2i_arg(frame::Tag t, Register base, int st_off, Register scratch); 552 553 // base+st_off points to top of argument 554 int arg_offset(const int st_off) { return st_off + Interpreter::value_offset_in_bytes(); } 555 int next_arg_offset(const int st_off) { 556 return st_off - Interpreter::stackElementSize() + Interpreter::value_offset_in_bytes(); 557 } 558 |
561#ifdef _LP64 562 // On _LP64 argument slot values are loaded first into a register 563 // because they might not fit into displacement. 564 Register arg_slot(const int st_off); 565 Register next_arg_slot(const int st_off); 566#else 567 int arg_slot(const int st_off) { return arg_offset(st_off); } 568 int next_arg_slot(const int st_off) { return next_arg_offset(st_off); } 569#endif // _LP64 | 559 int tag_offset(const int st_off) { return st_off + Interpreter::tag_offset_in_bytes(); } 560 int next_tag_offset(const int st_off) { 561 return st_off - Interpreter::stackElementSize() + Interpreter::tag_offset_in_bytes(); 562 } |
570 | 563 |
564 // Argument slot values may be loaded first into a register because 565 // they might not fit into displacement. 566 RegisterOrConstant arg_slot(const int st_off); 567 RegisterOrConstant next_arg_slot(const int st_off); 568 569 RegisterOrConstant tag_slot(const int st_off); 570 RegisterOrConstant next_tag_slot(const int st_off); 571 |
|
571 // Stores long into offset pointed to by base 572 void store_c2i_long(Register r, Register base, 573 const int st_off, bool is_stack); 574 void store_c2i_object(Register r, Register base, 575 const int st_off); 576 void store_c2i_int(Register r, Register base, 577 const int st_off); 578 void store_c2i_double(VMReg r_2, --- 72 unchanged lines hidden (view full) --- 651 652 __ restore(); // Restore args 653 __ bind(L); 654} 655 656void AdapterGenerator::tag_c2i_arg(frame::Tag t, Register base, int st_off, 657 Register scratch) { 658 if (TaggedStackInterpreter) { | 572 // Stores long into offset pointed to by base 573 void store_c2i_long(Register r, Register base, 574 const int st_off, bool is_stack); 575 void store_c2i_object(Register r, Register base, 576 const int st_off); 577 void store_c2i_int(Register r, Register base, 578 const int st_off); 579 void store_c2i_double(VMReg r_2, --- 72 unchanged lines hidden (view full) --- 652 653 __ restore(); // Restore args 654 __ bind(L); 655} 656 657void AdapterGenerator::tag_c2i_arg(frame::Tag t, Register base, int st_off, 658 Register scratch) { 659 if (TaggedStackInterpreter) { |
659 int tag_off = st_off + Interpreter::tag_offset_in_bytes(); 660#ifdef _LP64 661 Register tag_slot = Rdisp; 662 __ set(tag_off, tag_slot); 663#else 664 int tag_slot = tag_off; 665#endif // _LP64 | 660 RegisterOrConstant slot = tag_slot(st_off); |
666 // have to store zero because local slots can be reused (rats!) 667 if (t == frame::TagValue) { | 661 // have to store zero because local slots can be reused (rats!) 662 if (t == frame::TagValue) { |
668 __ st_ptr(G0, base, tag_slot); | 663 __ st_ptr(G0, base, slot); |
669 } else if (t == frame::TagCategory2) { | 664 } else if (t == frame::TagCategory2) { |
670 __ st_ptr(G0, base, tag_slot); 671 int next_tag_off = st_off - Interpreter::stackElementSize() + 672 Interpreter::tag_offset_in_bytes(); 673#ifdef _LP64 674 __ set(next_tag_off, tag_slot); 675#else 676 tag_slot = next_tag_off; 677#endif // _LP64 678 __ st_ptr(G0, base, tag_slot); | 665 __ st_ptr(G0, base, slot); 666 __ st_ptr(G0, base, next_tag_slot(st_off)); |
679 } else { 680 __ mov(t, scratch); | 667 } else { 668 __ mov(t, scratch); |
681 __ st_ptr(scratch, base, tag_slot); | 669 __ st_ptr(scratch, base, slot); |
682 } 683 } 684} 685 | 670 } 671 } 672} 673 |
686#ifdef _LP64 687Register AdapterGenerator::arg_slot(const int st_off) { 688 __ set( arg_offset(st_off), Rdisp); 689 return Rdisp; | 674 675RegisterOrConstant AdapterGenerator::arg_slot(const int st_off) { 676 RegisterOrConstant roc(arg_offset(st_off)); 677 return __ ensure_simm13_or_reg(roc, Rdisp); |
690} 691 | 678} 679 |
692Register AdapterGenerator::next_arg_slot(const int st_off){ 693 __ set( next_arg_offset(st_off), Rdisp); 694 return Rdisp; | 680RegisterOrConstant AdapterGenerator::next_arg_slot(const int st_off) { 681 RegisterOrConstant roc(next_arg_offset(st_off)); 682 return __ ensure_simm13_or_reg(roc, Rdisp); |
695} | 683} |
696#endif // _LP64 | |
697 | 684 |
685 686RegisterOrConstant AdapterGenerator::tag_slot(const int st_off) { 687 RegisterOrConstant roc(tag_offset(st_off)); 688 return __ ensure_simm13_or_reg(roc, Rdisp); 689} 690 691RegisterOrConstant AdapterGenerator::next_tag_slot(const int st_off) { 692 RegisterOrConstant roc(next_tag_offset(st_off)); 693 return __ ensure_simm13_or_reg(roc, Rdisp); 694} 695 696 |
|
698// Stores long into offset pointed to by base 699void AdapterGenerator::store_c2i_long(Register r, Register base, 700 const int st_off, bool is_stack) { 701#ifdef _LP64 702 // In V9, longs are given 2 64-bit slots in the interpreter, but the 703 // data is passed in only 1 slot. 704 __ stx(r, base, next_arg_slot(st_off)); 705#else --- 341 unchanged lines hidden (view full) --- 1047 } 1048 1049 // Pick up 0, 1 or 2 words from Lesp+offset. Assume mis-aligned in the 1050 // 32-bit build and aligned in the 64-bit build. Look for the obvious 1051 // ldx/lddf optimizations. 1052 1053 // Load in argument order going down. 1054 const int ld_off = (total_args_passed-i)*Interpreter::stackElementSize(); | 697// Stores long into offset pointed to by base 698void AdapterGenerator::store_c2i_long(Register r, Register base, 699 const int st_off, bool is_stack) { 700#ifdef _LP64 701 // In V9, longs are given 2 64-bit slots in the interpreter, but the 702 // data is passed in only 1 slot. 703 __ stx(r, base, next_arg_slot(st_off)); 704#else --- 341 unchanged lines hidden (view full) --- 1046 } 1047 1048 // Pick up 0, 1 or 2 words from Lesp+offset. Assume mis-aligned in the 1049 // 32-bit build and aligned in the 64-bit build. Look for the obvious 1050 // ldx/lddf optimizations. 1051 1052 // Load in argument order going down. 1053 const int ld_off = (total_args_passed-i)*Interpreter::stackElementSize(); |
1055#ifdef _LP64 | |
1056 set_Rdisp(G1_scratch); | 1054 set_Rdisp(G1_scratch); |
1057#endif // _LP64 | |
1058 1059 VMReg r_1 = regs[i].first(); 1060 VMReg r_2 = regs[i].second(); 1061 if (!r_1->is_valid()) { 1062 assert(!r_2->is_valid(), ""); 1063 continue; 1064 } 1065 if (r_1->is_stack()) { // Pretend stack targets are loaded into F8/F9 1066 r_1 = F8->as_VMReg(); // as part of the load/store shuffle 1067 if (r_2->is_valid()) r_2 = r_1->next(); 1068 } 1069 if (r_1->is_Register()) { // Register argument 1070 Register r = r_1->as_Register()->after_restore(); 1071 if (!r_2->is_valid()) { 1072 __ ld(Gargs, arg_slot(ld_off), r); 1073 } else { 1074#ifdef _LP64 1075 // In V9, longs are given 2 64-bit slots in the interpreter, but the 1076 // data is passed in only 1 slot. | 1055 1056 VMReg r_1 = regs[i].first(); 1057 VMReg r_2 = regs[i].second(); 1058 if (!r_1->is_valid()) { 1059 assert(!r_2->is_valid(), ""); 1060 continue; 1061 } 1062 if (r_1->is_stack()) { // Pretend stack targets are loaded into F8/F9 1063 r_1 = F8->as_VMReg(); // as part of the load/store shuffle 1064 if (r_2->is_valid()) r_2 = r_1->next(); 1065 } 1066 if (r_1->is_Register()) { // Register argument 1067 Register r = r_1->as_Register()->after_restore(); 1068 if (!r_2->is_valid()) { 1069 __ ld(Gargs, arg_slot(ld_off), r); 1070 } else { 1071#ifdef _LP64 1072 // In V9, longs are given 2 64-bit slots in the interpreter, but the 1073 // data is passed in only 1 slot. |
1077 Register slot = (sig_bt[i]==T_LONG) ? | 1074 RegisterOrConstant slot = (sig_bt[i] == T_LONG) ? |
1078 next_arg_slot(ld_off) : arg_slot(ld_off); 1079 __ ldx(Gargs, slot, r); 1080#else 1081 // Need to load a 64-bit value into G1/G4, but G1/G4 is being used in the 1082 // stack shuffle. Load the first 2 longs into G1/G4 later. 1083#endif 1084 } 1085 } else { 1086 assert(r_1->is_FloatRegister(), ""); 1087 if (!r_2->is_valid()) { 1088 __ ldf(FloatRegisterImpl::S, Gargs, arg_slot(ld_off), r_1->as_FloatRegister()); 1089 } else { 1090#ifdef _LP64 1091 // In V9, doubles are given 2 64-bit slots in the interpreter, but the 1092 // data is passed in only 1 slot. This code also handles longs that 1093 // are passed on the stack, but need a stack-to-stack move through a 1094 // spare float register. | 1075 next_arg_slot(ld_off) : arg_slot(ld_off); 1076 __ ldx(Gargs, slot, r); 1077#else 1078 // Need to load a 64-bit value into G1/G4, but G1/G4 is being used in the 1079 // stack shuffle. Load the first 2 longs into G1/G4 later. 1080#endif 1081 } 1082 } else { 1083 assert(r_1->is_FloatRegister(), ""); 1084 if (!r_2->is_valid()) { 1085 __ ldf(FloatRegisterImpl::S, Gargs, arg_slot(ld_off), r_1->as_FloatRegister()); 1086 } else { 1087#ifdef _LP64 1088 // In V9, doubles are given 2 64-bit slots in the interpreter, but the 1089 // data is passed in only 1 slot. This code also handles longs that 1090 // are passed on the stack, but need a stack-to-stack move through a 1091 // spare float register. |
1095 Register slot = (sig_bt[i]==T_LONG || sig_bt[i] == T_DOUBLE) ? | 1092 RegisterOrConstant slot = (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) ? |
1096 next_arg_slot(ld_off) : arg_slot(ld_off); 1097 __ ldf(FloatRegisterImpl::D, Gargs, slot, r_1->as_FloatRegister()); 1098#else 1099 // Need to marshal 64-bit value from misaligned Lesp loads 1100 __ ldf(FloatRegisterImpl::S, Gargs, next_arg_slot(ld_off), r_1->as_FloatRegister()); 1101 __ ldf(FloatRegisterImpl::S, Gargs, arg_slot(ld_off), r_2->as_FloatRegister()); 1102#endif 1103 } 1104 } 1105 // Was the argument really intended to be on the stack, but was loaded 1106 // into F8/F9? 1107 if (regs[i].first()->is_stack()) { 1108 assert(r_1->as_FloatRegister() == F8, "fix this code"); 1109 // Convert stack slot to an SP offset 1110 int st_off = reg2offset(regs[i].first()) + STACK_BIAS; 1111 // Store down the shuffled stack word. Target address _is_ aligned. | 1093 next_arg_slot(ld_off) : arg_slot(ld_off); 1094 __ ldf(FloatRegisterImpl::D, Gargs, slot, r_1->as_FloatRegister()); 1095#else 1096 // Need to marshal 64-bit value from misaligned Lesp loads 1097 __ ldf(FloatRegisterImpl::S, Gargs, next_arg_slot(ld_off), r_1->as_FloatRegister()); 1098 __ ldf(FloatRegisterImpl::S, Gargs, arg_slot(ld_off), r_2->as_FloatRegister()); 1099#endif 1100 } 1101 } 1102 // Was the argument really intended to be on the stack, but was loaded 1103 // into F8/F9? 1104 if (regs[i].first()->is_stack()) { 1105 assert(r_1->as_FloatRegister() == F8, "fix this code"); 1106 // Convert stack slot to an SP offset 1107 int st_off = reg2offset(regs[i].first()) + STACK_BIAS; 1108 // Store down the shuffled stack word. Target address _is_ aligned. |
1112 if (!r_2->is_valid()) __ stf(FloatRegisterImpl::S, r_1->as_FloatRegister(), SP, st_off); 1113 else __ stf(FloatRegisterImpl::D, r_1->as_FloatRegister(), SP, st_off); | 1109 RegisterOrConstant slot = __ ensure_simm13_or_reg(st_off, Rdisp); 1110 if (!r_2->is_valid()) __ stf(FloatRegisterImpl::S, r_1->as_FloatRegister(), SP, slot); 1111 else __ stf(FloatRegisterImpl::D, r_1->as_FloatRegister(), SP, slot); |
1114 } 1115 } 1116 bool made_space = false; 1117#ifndef _LP64 1118 // May need to pick up a few long args in G1/G4 1119 bool g4_crushed = false; 1120 bool g3_crushed = false; 1121 for (int i=0; i<total_args_passed; i++) { --- 2636 unchanged lines hidden --- | 1112 } 1113 } 1114 bool made_space = false; 1115#ifndef _LP64 1116 // May need to pick up a few long args in G1/G4 1117 bool g4_crushed = false; 1118 bool g3_crushed = false; 1119 for (int i=0; i<total_args_passed; i++) { --- 2636 unchanged lines hidden --- |