src/share/vm/opto/generateOptoStub.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().

*** 44,53 **** --- 44,57 ---- int is_fancy_jump, bool pass_tls, bool return_pc) { ResourceMark rm; + // Do we need to convert ints to longs for c calls? + const bool convert_ints_to_longs = + SharedRuntime::c_calling_convention_requires_ints_as_longs(); + const TypeTuple *jdomain = C->tf()->domain(); const TypeTuple *jrange = C->tf()->range(); // The procedure start StartNode* start = new (C) StartNode(root(), jdomain);
*** 115,126 **** // Compute signature for C call. Varies from the Java signature! const Type **fields = TypeTuple::fields(2*parm_cnt+2); uint cnt = TypeFunc::Parms; // The C routines gets the base of thread-local storage passed in as an // extra argument. Not all calls need it, but its cheap to add here. ! for( ; cnt<parm_cnt; cnt++ ) ! fields[cnt] = jdomain->field_at(cnt); fields[cnt++] = TypeRawPtr::BOTTOM; // Thread-local storage // Also pass in the caller's PC, if asked for. if( return_pc ) fields[cnt++] = TypeRawPtr::BOTTOM; // Return PC --- 119,138 ---- // Compute signature for C call. Varies from the Java signature! const Type **fields = TypeTuple::fields(2*parm_cnt+2); uint cnt = TypeFunc::Parms; // The C routines gets the base of thread-local storage passed in as an // extra argument. Not all calls need it, but its cheap to add here. ! for (uint pcnt = cnt; pcnt < parm_cnt; pcnt++, cnt++) { ! // Convert ints to longs if required. ! if (convert_ints_to_longs && jdomain->field_at(pcnt)->isa_int()) { ! fields[cnt++] = TypeLong::LONG; ! fields[cnt] = Type::HALF; // must add an additional half for a long ! } else { ! fields[cnt] = jdomain->field_at(pcnt); ! } ! } ! fields[cnt++] = TypeRawPtr::BOTTOM; // Thread-local storage // Also pass in the caller's PC, if asked for. if( return_pc ) fields[cnt++] = TypeRawPtr::BOTTOM; // Return PC
*** 167,182 **** call->jvms()->set_bci(0); call->jvms()->set_offsets(cnt); // Set fixed predefined input arguments cnt = 0; ! for( i=0; i<TypeFunc::Parms; i++ ) ! call->init_req( cnt++, map()->in(i) ); // A little too aggressive on the parm copy; return address is not an input call->set_req(TypeFunc::ReturnAdr, top()); ! for( ; i<parm_cnt; i++ ) // Regular input arguments ! call->init_req( cnt++, map()->in(i) ); call->init_req( cnt++, thread ); if( return_pc ) // Return PC, if asked for call->init_req( cnt++, returnadr() ); _gvn.transform_no_reclaim(call); --- 179,202 ---- call->jvms()->set_bci(0); call->jvms()->set_offsets(cnt); // Set fixed predefined input arguments cnt = 0; ! for (i = 0; i < TypeFunc::Parms; i++) ! call->init_req(cnt++, map()->in(i)); // A little too aggressive on the parm copy; return address is not an input call->set_req(TypeFunc::ReturnAdr, top()); ! for (; i < parm_cnt; i++) { // Regular input arguments ! // Convert ints to longs if required. ! if (convert_ints_to_longs && jdomain->field_at(i)->isa_int()) { ! Node* int_as_long = _gvn.transform(new (C) ConvI2LNode(map()->in(i))); ! call->init_req(cnt++, int_as_long); // long ! call->init_req(cnt++, top()); // half ! } else { ! call->init_req(cnt++, map()->in(i)); ! } ! } call->init_req( cnt++, thread ); if( return_pc ) // Return PC, if asked for call->init_req( cnt++, returnadr() ); _gvn.transform_no_reclaim(call);