src/cpu/ppc/vm/sharedRuntime_ppc.cpp

Print this page
rev 5190 : 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 used by the compiler as 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];


 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 
 853   assert_different_registers(sender_SP, code, ientry, return_pc, tmp);
 854 
 855   // Adapter needs TOP_IJAVA_FRAME_ABI.
 856   const int adapter_size = frame::top_ijava_frame_abi_size +
 857                            round_to(total_args_passed * wordSize, frame::alignment_in_bytes);
 858 
 859 
 860   // regular (verified) c2i entry point
 861   c2i_entrypoint = __ pc();
 862 
 863   // Does compiled code exists? If yes, patch the caller's callsite.
 864   __ ld(code, method_(code));
 865   __ cmpdi(CCR0, code, 0);
 866   __ ld(ientry, method_(interpreter_entry)); // preloaded
 867   __ beq(CCR0, call_interpreter);
 868 
 869 
 870   // Patch caller's callsite, method_(code) was not NULL which means that
 871   // compiled code exists.
 872   __ mflr(return_pc);
 873   __ std(return_pc, _abi(lr), R1_SP);
 874   RegisterSaver::push_frame_and_save_argument_registers(masm, tmp, adapter_size, total_args_passed, regs);
 875 
 876   __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite), R19_method, return_pc);
 877 
 878   RegisterSaver::restore_argument_registers_and_pop_frame(masm, adapter_size, total_args_passed, regs);
 879   __ ld(return_pc, _abi(lr), R1_SP);




 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(CCallingConventionRequiresIntsAsLongs,


 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];


 836                             const Register& ientry) {
 837 
 838   address c2i_entrypoint;
 839 
 840   const Register sender_SP = R21_sender_SP; // == R21_tmp1
 841   const Register code      = R22_tmp2;
 842   //const Register ientry  = R23_tmp3;
 843   const Register value_regs[] = { R24_tmp4, R25_tmp5, R26_tmp6 };
 844   const int num_value_regs = sizeof(value_regs) / sizeof(Register);
 845   int value_regs_index = 0;
 846 
 847   const Register return_pc = R27_tmp7;
 848   const Register tmp       = R28_tmp8;
 849 
 850   assert_different_registers(sender_SP, code, ientry, return_pc, tmp);
 851 
 852   // Adapter needs TOP_IJAVA_FRAME_ABI.
 853   const int adapter_size = frame::top_ijava_frame_abi_size +
 854                            round_to(total_args_passed * wordSize, frame::alignment_in_bytes);
 855 

 856   // regular (verified) c2i entry point
 857   c2i_entrypoint = __ pc();
 858 
 859   // Does compiled code exists? If yes, patch the caller's callsite.
 860   __ ld(code, method_(code));
 861   __ cmpdi(CCR0, code, 0);
 862   __ ld(ientry, method_(interpreter_entry)); // preloaded
 863   __ beq(CCR0, call_interpreter);
 864 
 865 
 866   // Patch caller's callsite, method_(code) was not NULL which means that
 867   // compiled code exists.
 868   __ mflr(return_pc);
 869   __ std(return_pc, _abi(lr), R1_SP);
 870   RegisterSaver::push_frame_and_save_argument_registers(masm, tmp, adapter_size, total_args_passed, regs);
 871 
 872   __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite), R19_method, return_pc);
 873 
 874   RegisterSaver::restore_argument_registers_and_pop_frame(masm, adapter_size, total_args_passed, regs);
 875   __ ld(return_pc, _abi(lr), R1_SP);