/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "gc_interface/collectedHeap.hpp"
#include "opto/machnode.hpp"
#include "opto/regalloc.hpp"
//=============================================================================
// Return the value requested
// result register lookup, corresponding to int_format
}
// input register lookup, corresponding to ext_format
}
// A zero, default, indicates this value is not needed.
// May need to lookup the base register, as done in int_ and ext_format
// Check for PC-Relative displacement
// Return the label
//------------------------------negate-----------------------------------------
// Negate conditional branches. Error for non-branch operands
}
//-----------------------------type--------------------------------------------
}
//------------------------------in_RegMask-------------------------------------
return NULL;
}
//------------------------------dump_spec--------------------------------------
// Print any per-operand special info
#ifndef PRODUCT
#endif
//------------------------------hash-------------------------------------------
// Print any per-operand special info
return 5;
}
//------------------------------cmp--------------------------------------------
// Print any per-operand special info
}
//------------------------------hash-------------------------------------------
// Print any per-operand special info
return _block_num;
}
//------------------------------cmp--------------------------------------------
// Print any per-operand special info
}
//------------------------------hash-------------------------------------------
// Print any per-operand special info
}
//------------------------------cmp--------------------------------------------
// Print any per-operand special info
}
//=============================================================================
//------------------------------MachNode---------------------------------------
//------------------------------emit-------------------------------------------
#ifdef ASSERT
dump();
#endif
}
//------------------------------size-------------------------------------------
// Size of instruction in bytes
// If a virtual was not defined for this specific instruction,
// Call the helper which finds the size by emitting the bits.
}
//------------------------------size-------------------------------------------
// Helper function that computes size by emitting code
// Emit into a trash buffer and count bytes emitted.
return ra_->C->scratch_emit_size(this);
}
//------------------------------hash-------------------------------------------
}
//-----------------------------cmp---------------------------------------------
return 0; // mis-matched operands
return 1; // match
}
// Return an equivalent instruction using memory for cisc_operand position
return NULL;
}
}
//-----------------------------in_RegMask--------------------------------------
// debug info can be anywhere
}
opcnt++; // Bump operand count
}
}
return *rm;
}
//-----------------------------memory_inputs--------------------------------
base = NodeSentinel;
} else {
// It has a unique memory operand. Find its index.
while (--oper_idx >= 0) {
}
if (base_pos >= 0) {
}
if (index_pos >= 0) {
}
}
}
return oper;
}
//-----------------------------get_base_and_disp----------------------------
// Find the memory inputs using our helper function
// Base has been set to NULL
offset = 0;
// Base has been set to NodeSentinel
// There is not a unique memory use here. We will fall to AliasIdxBot.
} else {
// Base may be NULL, even if offset turns out to be != 0
// Now we have collected every part of the ADLC MEMORY_INTER.
// See if it adds up to a base + offset.
// Memory references through narrow oops have a
// funny base so grab the type from the index:
// [R12 + narrow_oop_reg<<3 + offset]
return NULL;
} else {
}
}
}
// In i486.ad, indOffset32X uses base==RegI and disp==RegP,
// this will prevent alias analysis without the following support:
// Lookup the TypePtr used by indOffset32X, a compile-time constant oop,
// Add the offset determined by the "base", or use Type::OffsetBot.
if( adr_type == TYPE_PTR_SENTINAL ) {
if (t_base->isa_intptr_t()) {
}
}
// Use ideal type if it is oop ptr.
}
}
}
}
return base;
}
//---------------------------------adr_type---------------------------------
if( adr_type != TYPE_PTR_SENTINAL ) {
return adr_type; // get_base_and_disp has the answer
}
// Direct addressing modes have no base node, simply an indirect
// offset, which is always to raw memory.
// %%%%% Someday we'd like to allow constant oop offsets which
// would let Intel load from static globals in 1 instruction.
// Currently Intel requires 2 instructions and a register temp.
// NULL base, zero offset means no memory at all (a null pointer!)
if (offset == 0) {
return NULL;
}
// NULL base, any offset means any pointer whatever
}
// %%% make offset be intptr_t
return TypeRawPtr::BOTTOM;
}
// base of -1 with no particular offset means all of memory
// 32-bit unscaled narrow oop can be the base of any address expression
t = t->make_ptr();
}
// We cannot assert that the offset does not look oop-ish here.
// Depending on the heap layout the cardmark base could land
// inside some oopish region. It definitely does for Win2K.
// The sum of cardmark-base plus shift-by-9-oop lands outside
// the oop-ish area but we can't assert for that statically.
return TypeRawPtr::BOTTOM;
}
// be conservative if we do not recognize the type
assert(false, "this path may produce not optimal code");
}
}
//-----------------------------operand_index---------------------------------
}
return skipped;
}
//------------------------------peephole---------------------------------------
// Apply peephole rule(s) to this instruction
MachNode *MachNode::peephole( Block *block, int block_index, PhaseRegAlloc *ra_, int &deleted, Compile* C ) {
return NULL;
}
//------------------------------add_case_label---------------------------------
// Adds the label for the case
}
//------------------------------method_set-------------------------------------
// Set the absolute address of a method
}
//------------------------------rematerialize----------------------------------
// Temps are always rematerializable
if (is_MachTemp()) return true;
if( r < Matcher::_begin_rematerialize ||
r >= Matcher::_end_rematerialize )
return false;
// For 2-address instructions, the input live range is also the output
// live range. Remateralizing does not make progress on the that live range.
if( two_adr() ) return false;
// Check for rematerializing float constants, or not
if( !Matcher::rematerialize_float_constants ) {
return false;
}
// Defining flags - can't spill these! Must remateralize.
if( ideal_reg() == Op_RegFlags )
return true;
// Stretching lots of inputs - don't do it.
if( req() > 2 )
return false;
// Don't remateralize somebody with bound inputs - it stretches a
// fixed register lifetime.
return false;
}
return true;
}
#ifndef PRODUCT
//------------------------------dump_spec--------------------------------------
// Print any per-operand special info
if( t ) {
if( C->alias_type(t)->is_volatile() )
}
}
//------------------------------dump_format------------------------------------
// access to virtual
}
#endif
//=============================================================================
#ifndef PRODUCT
}
#endif
//=============================================================================
// Bind the offset lazily.
// If called from Compile::scratch_emit_size return the
// pre-calculated offset.
// NOTE: If the AD file does some table base offset optimizations
// later the AD file needs to take care of this fact.
}
}
}
//=============================================================================
#ifndef PRODUCT
}
#endif
// only emits entries in the null-pointer exception handler table
}
// Nothing to emit
}
// Nothing to emit
}
}
//=============================================================================
// Try the normal mechanism first
}
// Else use generic type from ideal register set
}
// in(0) might be a narrow MemBar; otherwise we will report TypePtr::BOTTOM
#ifdef ASSERT
#endif
return adr_type;
}
return NULL;
}
#ifndef PRODUCT
switch (_ideal_reg) {
}
}
#endif
//=============================================================================
#ifndef PRODUCT
}
#endif
//=============================================================================
//------------------------------Registers--------------------------------------
}
// most returns and calls are assumed to consume & modify all of memory
// the matcher will copy non-wide adr_types from ideal originals
return _adr_type;
}
//=============================================================================
//------------------------------Registers--------------------------------------
// Values in the domain use the users calling convention, embodied in the
// _in_rms array of RegMasks.
if (SafePointNode::needs_polling_address_input() &&
ideal_Opcode() == Op_SafePoint) {
}
// Values outside the domain represent debug info
}
//=============================================================================
#ifndef PRODUCT
}
#endif
// void return
return false;
}
// find the projection corresponding to the return value
return true;
}
}
return false;
}
//------------------------------Registers--------------------------------------
// Values in the domain use the users calling convention, embodied in the
// _in_rms array of RegMasks.
// Values outside the domain represent debug info
}
//=============================================================================
}
#ifndef PRODUCT
if (_method) {
}
}
#endif
//------------------------------Registers--------------------------------------
// Values in the domain use the users calling convention, embodied in the
// _in_rms array of RegMasks.
// Values outside the domain represent debug info
// If this call is a MethodHandle invoke we have to use a different
// debugmask which does not include the register we use to save the
// SP over MH invokes.
}
//=============================================================================
}
//----------------------------uncommon_trap_request----------------------------
// If this is an uncommon trap, return the request code, else zero.
return CallStaticJavaNode::extract_uncommon_trap_request(this);
}
return 0;
}
#ifndef PRODUCT
// Helper for summarizing uncommon_trap arguments.
if (trap_req != 0) {
trap_req));
}
}
}
}
#endif
//=============================================================================
#ifndef PRODUCT
}
#endif
//=============================================================================
}
#ifndef PRODUCT
}
#endif
//=============================================================================
// A shared JVMState for all HaltNodes. Indicates the start of debug info
// is at TypeFunc::Parms. Only required for SOE register spill handling -
// to indicate where the stack-slot-only debug info inputs begin.
// There is no other JVM state needed here.
return &jvms_for_throw;
}
//=============================================================================
#ifndef PRODUCT
}
#endif // PRODUCT
//=============================================================================
#ifndef PRODUCT
}
#endif // PRODUCT