src/cpu/ppc/vm/sharedRuntime_ppc.cpp

Print this page
rev 5186 : 8024342: PPC64 (part 111): Support for C calling conventions that require 64-bit ints.
Summary: Some platforms, as ppc and s390x/zArch require that 32-bit ints are passed as 64-bit values to C functions. This change adds support to adapt the signature and to issue proper casts to c2-compiled stubs. The functions are used in generate_native_wrapper(). Adapt signature in PhaseIdealLoop::intrinsify_fill().


 717   // Avoid passing C arguments in the wrong stack slots.
 718   assert((SharedRuntime::out_preserve_stack_slots() + stk) * VMRegImpl::stack_slot_size == 112,
 719          "passing C arguments in wrong stack slots");
 720 
 721   // We fill-out regs AND regs2 if an argument must be passed in a
 722   // register AND in a stack slot. If regs2 is NULL in such a
 723   // situation, we bail-out with a fatal error.
 724   for (int i = 0; i < total_args_passed; ++i, ++arg) {
 725     // Initialize regs2 to BAD.
 726     if (regs2 != NULL) regs2[i].set_bad();
 727 
 728     switch(sig_bt[i]) {
 729     case T_BOOLEAN:
 730     case T_CHAR:
 731     case T_BYTE:
 732     case T_SHORT:
 733     case T_INT:
 734       // We must cast ints to longs and use full 64 bit stack slots
 735       // here. We do the cast in GraphKit::gen_stub() and just guard
 736       // here against loosing that change.
 737       Unimplemented(); // TODO: PPC port
 738       /*
 739       assert(SharedRuntime::c_calling_convention_requires_ints_as_longs(),
 740              "argument of type int should be promoted to type long");
 741       */
 742       guarantee(i > 0 && sig_bt[i-1] == T_LONG,
 743                 "argument of type (bt) should have been promoted to type (T_LONG,bt) for bt in "
 744                 "{T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
 745       // Do not count halves.
 746       regs[i].set_bad();
 747       --arg;
 748       break;
 749     case T_LONG:
 750       guarantee(sig_bt[i+1] == T_VOID    ||
 751                 sig_bt[i+1] == T_BOOLEAN || sig_bt[i+1] == T_CHAR  ||
 752                 sig_bt[i+1] == T_BYTE    || sig_bt[i+1] == T_SHORT ||
 753                 sig_bt[i+1] == T_INT,
 754                 "expecting type (T_LONG,half) or type (T_LONG,bt) with bt in {T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
 755     case T_OBJECT:
 756     case T_ARRAY:
 757     case T_ADDRESS:
 758     case T_METADATA:
 759       // Oops are already boxed if required (JNI).
 760       if (put_arg_in_reg(arg)) {
 761         reg = iarg_reg[arg];


 813         }
 814         ++freg;
 815       }
 816 
 817       regs[i].set2(reg);
 818       break;
 819     case T_VOID:
 820       // Do not count halves.
 821       regs[i].set_bad();
 822       --arg;
 823       break;
 824     default:
 825       ShouldNotReachHere();
 826     }
 827   }
 828 
 829   return round_to(stk, 2);
 830 }
 831 #endif // COMPILER2
 832 





 833 static address gen_c2i_adapter(MacroAssembler *masm,
 834                             int total_args_passed,
 835                             int comp_args_on_stack,
 836                             const BasicType *sig_bt,
 837                             const VMRegPair *regs,
 838                             Label& call_interpreter,
 839                             const Register& ientry) {
 840 
 841   address c2i_entrypoint;
 842 
 843   const Register sender_SP = R21_sender_SP; // == R21_tmp1
 844   const Register code      = R22_tmp2;
 845   //const Register ientry  = R23_tmp3;
 846   const Register value_regs[] = { R24_tmp4, R25_tmp5, R26_tmp6 };
 847   const int num_value_regs = sizeof(value_regs) / sizeof(Register);
 848   int value_regs_index = 0;
 849 
 850   const Register return_pc = R27_tmp7;
 851   const Register tmp       = R28_tmp8;
 852 




 717   // Avoid passing C arguments in the wrong stack slots.
 718   assert((SharedRuntime::out_preserve_stack_slots() + stk) * VMRegImpl::stack_slot_size == 112,
 719          "passing C arguments in wrong stack slots");
 720 
 721   // We fill-out regs AND regs2 if an argument must be passed in a
 722   // register AND in a stack slot. If regs2 is NULL in such a
 723   // situation, we bail-out with a fatal error.
 724   for (int i = 0; i < total_args_passed; ++i, ++arg) {
 725     // Initialize regs2 to BAD.
 726     if (regs2 != NULL) regs2[i].set_bad();
 727 
 728     switch(sig_bt[i]) {
 729     case T_BOOLEAN:
 730     case T_CHAR:
 731     case T_BYTE:
 732     case T_SHORT:
 733     case T_INT:
 734       // We must cast ints to longs and use full 64 bit stack slots
 735       // here. We do the cast in GraphKit::gen_stub() and just guard
 736       // here against loosing that change.


 737       assert(SharedRuntime::c_calling_convention_requires_ints_as_longs(),
 738              "argument of type int should be promoted to type long");

 739       guarantee(i > 0 && sig_bt[i-1] == T_LONG,
 740                 "argument of type (bt) should have been promoted to type (T_LONG,bt) for bt in "
 741                 "{T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
 742       // Do not count halves.
 743       regs[i].set_bad();
 744       --arg;
 745       break;
 746     case T_LONG:
 747       guarantee(sig_bt[i+1] == T_VOID    ||
 748                 sig_bt[i+1] == T_BOOLEAN || sig_bt[i+1] == T_CHAR  ||
 749                 sig_bt[i+1] == T_BYTE    || sig_bt[i+1] == T_SHORT ||
 750                 sig_bt[i+1] == T_INT,
 751                 "expecting type (T_LONG,half) or type (T_LONG,bt) with bt in {T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
 752     case T_OBJECT:
 753     case T_ARRAY:
 754     case T_ADDRESS:
 755     case T_METADATA:
 756       // Oops are already boxed if required (JNI).
 757       if (put_arg_in_reg(arg)) {
 758         reg = iarg_reg[arg];


 810         }
 811         ++freg;
 812       }
 813 
 814       regs[i].set2(reg);
 815       break;
 816     case T_VOID:
 817       // Do not count halves.
 818       regs[i].set_bad();
 819       --arg;
 820       break;
 821     default:
 822       ShouldNotReachHere();
 823     }
 824   }
 825 
 826   return round_to(stk, 2);
 827 }
 828 #endif // COMPILER2
 829 
 830 // Do we need to convert ints to longs for c calls?
 831 bool SharedRuntime::c_calling_convention_requires_ints_as_longs() {
 832   return true;
 833 }
 834 
 835 static address gen_c2i_adapter(MacroAssembler *masm,
 836                             int total_args_passed,
 837                             int comp_args_on_stack,
 838                             const BasicType *sig_bt,
 839                             const VMRegPair *regs,
 840                             Label& call_interpreter,
 841                             const Register& ientry) {
 842 
 843   address c2i_entrypoint;
 844 
 845   const Register sender_SP = R21_sender_SP; // == R21_tmp1
 846   const Register code      = R22_tmp2;
 847   //const Register ientry  = R23_tmp3;
 848   const Register value_regs[] = { R24_tmp4, R25_tmp5, R26_tmp6 };
 849   const int num_value_regs = sizeof(value_regs) / sizeof(Register);
 850   int value_regs_index = 0;
 851 
 852   const Register return_pc = R27_tmp7;
 853   const Register tmp       = R28_tmp8;
 854