mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-21 19:08:31 +00:00
7011627: C1: call_RT must support targets that don't fit in wdisp30
Make both compilers emit near and far calls when necessary. Reviewed-by: never, kvn, phh
This commit is contained in:
parent
4912ef0e5d
commit
18619a6ed6
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -823,15 +823,23 @@ class Assembler : public AbstractAssembler {
|
||||
};
|
||||
|
||||
// test if x is within signed immediate range for nbits
|
||||
static bool is_simm(int x, int nbits) { return -( 1 << nbits-1 ) <= x && x < ( 1 << nbits-1 ); }
|
||||
static bool is_simm(intptr_t x, int nbits) { return -( intptr_t(1) << nbits-1 ) <= x && x < ( intptr_t(1) << nbits-1 ); }
|
||||
|
||||
// test if -4096 <= x <= 4095
|
||||
static bool is_simm13(int x) { return is_simm(x, 13); }
|
||||
static bool is_simm13(intptr_t x) { return is_simm(x, 13); }
|
||||
|
||||
static bool is_in_wdisp_range(address a, address b, int nbits) {
|
||||
intptr_t d = intptr_t(b) - intptr_t(a);
|
||||
return is_simm(d, nbits + 2);
|
||||
}
|
||||
|
||||
// test if label is in simm16 range in words (wdisp16).
|
||||
bool is_in_wdisp16_range(Label& L) {
|
||||
intptr_t d = intptr_t(pc()) - intptr_t(target(L));
|
||||
return is_simm(d, 18);
|
||||
return is_in_wdisp_range(target(L), pc(), 16);
|
||||
}
|
||||
// test if the distance between two addresses fits in simm30 range in words
|
||||
static bool is_in_wdisp30_range(address a, address b) {
|
||||
return is_in_wdisp_range(a, b, 30);
|
||||
}
|
||||
|
||||
enum ASIs { // page 72, v9
|
||||
@ -1843,6 +1851,8 @@ class MacroAssembler: public Assembler {
|
||||
inline void jmp( Register s1, Register s2 );
|
||||
inline void jmp( Register s1, int simm13a, RelocationHolder const& rspec = RelocationHolder() );
|
||||
|
||||
// Check if the call target is out of wdisp30 range (relative to the code cache)
|
||||
static inline bool is_far_target(address d);
|
||||
inline void call( address d, relocInfo::relocType rt = relocInfo::runtime_call_type );
|
||||
inline void call( Label& L, relocInfo::relocType rt = relocInfo::runtime_call_type );
|
||||
inline void callr( Register s1, Register s2 );
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -588,10 +588,13 @@ inline void MacroAssembler::fbp( Condition c, bool a, CC cc, Predict p, Label& L
|
||||
inline void MacroAssembler::jmp( Register s1, Register s2 ) { jmpl( s1, s2, G0 ); }
|
||||
inline void MacroAssembler::jmp( Register s1, int simm13a, RelocationHolder const& rspec ) { jmpl( s1, simm13a, G0, rspec); }
|
||||
|
||||
inline bool MacroAssembler::is_far_target(address d) {
|
||||
return !is_in_wdisp30_range(d, CodeCache::low_bound()) || !is_in_wdisp30_range(d, CodeCache::high_bound());
|
||||
}
|
||||
|
||||
// Call with a check to see if we need to deal with the added
|
||||
// expense of relocation and if we overflow the displacement
|
||||
// of the quick call instruction./
|
||||
// Check to see if we have to deal with relocations
|
||||
// of the quick call instruction.
|
||||
inline void MacroAssembler::call( address d, relocInfo::relocType rt ) {
|
||||
#ifdef _LP64
|
||||
intptr_t disp;
|
||||
@ -603,14 +606,12 @@ inline void MacroAssembler::call( address d, relocInfo::relocType rt ) {
|
||||
|
||||
// Is this address within range of the call instruction?
|
||||
// If not, use the expensive instruction sequence
|
||||
disp = (intptr_t)d - (intptr_t)pc();
|
||||
if ( disp != (intptr_t)(int32_t)disp ) {
|
||||
if (is_far_target(d)) {
|
||||
relocate(rt);
|
||||
AddressLiteral dest(d);
|
||||
jumpl_to(dest, O7, O7);
|
||||
}
|
||||
else {
|
||||
Assembler::call( d, rt );
|
||||
} else {
|
||||
Assembler::call(d, rt);
|
||||
}
|
||||
#else
|
||||
Assembler::call( d, rt );
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
//
|
||||
// This code is free software; you can redistribute it and/or modify it
|
||||
@ -575,7 +575,11 @@ int MachCallDynamicJavaNode::ret_addr_offset() {
|
||||
|
||||
int MachCallRuntimeNode::ret_addr_offset() {
|
||||
#ifdef _LP64
|
||||
return NativeFarCall::instruction_size; // farcall; delay slot
|
||||
if (MacroAssembler::is_far_target(entry_point())) {
|
||||
return NativeFarCall::instruction_size;
|
||||
} else {
|
||||
return NativeCall::instruction_size;
|
||||
}
|
||||
#else
|
||||
return NativeCall::instruction_size; // call; delay slot
|
||||
#endif
|
||||
@ -941,7 +945,7 @@ void emit_form3_mem_reg(CodeBuffer &cbuf, const MachNode* n, int primary, int te
|
||||
#endif
|
||||
}
|
||||
|
||||
void emit_call_reloc(CodeBuffer &cbuf, intptr_t entry_point, relocInfo::relocType rtype, bool preserve_g2 = false, bool force_far_call = false) {
|
||||
void emit_call_reloc(CodeBuffer &cbuf, intptr_t entry_point, relocInfo::relocType rtype, bool preserve_g2 = false) {
|
||||
// The method which records debug information at every safepoint
|
||||
// expects the call to be the first instruction in the snippet as
|
||||
// it creates a PcDesc structure which tracks the offset of a call
|
||||
@ -963,20 +967,7 @@ void emit_call_reloc(CodeBuffer &cbuf, intptr_t entry_point, relocInfo::relocTyp
|
||||
int startpos = __ offset();
|
||||
#endif /* ASSERT */
|
||||
|
||||
#ifdef _LP64
|
||||
// Calls to the runtime or native may not be reachable from compiled code,
|
||||
// so we generate the far call sequence on 64 bit sparc.
|
||||
// This code sequence is relocatable to any address, even on LP64.
|
||||
if ( force_far_call ) {
|
||||
__ relocate(rtype);
|
||||
AddressLiteral dest(entry_point);
|
||||
__ jumpl_to(dest, O7, O7);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
__ call((address)entry_point, rtype);
|
||||
}
|
||||
__ call((address)entry_point, rtype);
|
||||
|
||||
if (preserve_g2) __ delayed()->mov(G2, L7);
|
||||
else __ delayed()->nop();
|
||||
@ -2507,7 +2498,7 @@ encode %{
|
||||
// CALL directly to the runtime
|
||||
// The user of this is responsible for ensuring that R_L7 is empty (killed).
|
||||
emit_call_reloc(cbuf, $meth$$method, relocInfo::runtime_call_type,
|
||||
/*preserve_g2=*/true, /*force far call*/true);
|
||||
/*preserve_g2=*/true);
|
||||
%}
|
||||
|
||||
enc_class preserve_SP %{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user