/*
* 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.
*
*/
#ifndef SHARE_VM_C1_C1_LIRGENERATOR_HPP
#define SHARE_VM_C1_C1_LIRGENERATOR_HPP
#include "c1/c1_Instruction.hpp"
#include "c1/c1_LIR.hpp"
#include "ci/ciMethodData.hpp"
// The classes responsible for code emission and register allocation
class LIRGenerator;
class LIREmitter;
class Invoke;
class SwitchRange;
class LIRItem;
private:
int _low_key;
int _high_key;
public:
SwitchRange(int start_key, BlockBegin* sux): _low_key(start_key), _high_key(start_key), _sux(sux) {}
};
class ResolveNode;
// Node objects form a directed graph of LIR_Opr
// Edges between Nodes represent moves from one Node to its destinations
private:
public:
, _assigned(false)
, _visited(false)
, _start_node(false) {};
// accessors
// modifiers
};
// This is shared state to be used by the PhiResolver so the operand
// arrays don't have to be reallocated for reach resolution.
friend class PhiResolver;
private:
public:
PhiResolverState() {}
};
// class used to move value of phi operand to phi function
private:
// access to shared state arrays
return _gen;
}
public:
~PhiResolver();
};
// only the classes below belong in the same file
private:
return this;
}
#ifdef ASSERT
return _lir;
}
#endif
return _lir;
}
// a simple cache of constants used within a block
friend class PhiResolver;
// unified bailout support
// register allocation
// get a constant into a register and get track of what register was used
// Given an immediate value, return an operand usable in logical ops.
x->set_operand(opr);
if (opr->is_virtual()) {
}
}
friend class LIRItem;
// code emission
void do_ArithmeticOp_Long (ArithmeticOp* x);
void do_ArithmeticOp_Int (ArithmeticOp* x);
void do_ArithmeticOp_FPU (ArithmeticOp* x);
// platform dependent
void do_RegisterFinalizer(Intrinsic* x);
void do_isInstance(Intrinsic* x);
void do_getClass(Intrinsic* x);
void do_currentThread(Intrinsic* x);
void do_MathIntrinsic(Intrinsic* x);
void do_ArrayCopy(Intrinsic* x);
void do_NIOCheckIndex(Intrinsic* x);
void do_FPIntrinsics(Intrinsic* x);
void do_Reference_get(Intrinsic* x);
LIR_Opr call_runtime(BasicTypeArray* signature, LIRItemList* args, address entry, ValueType* result_type, CodeEmitInfo* info);
LIR_Opr call_runtime(BasicTypeArray* signature, LIR_OprList* args, address entry, ValueType* result_type, CodeEmitInfo* info);
// convenience functions
LIR_Opr call_runtime(Value arg1, Value arg2, address entry, ValueType* result_type, CodeEmitInfo* info);
// GC Barriers
// generic interface
// specific implementations
// pre barriers
// post barriers
// volatile field operations are never patchable because a klass
// must be loaded to know it's volatile which means that the offset
// it always known as well.
void put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data, BasicType type, bool is_volatile);
void get_Object_unsafe(LIR_Opr dest, LIR_Opr src, LIR_Opr offset, BasicType type, bool is_volatile);
// is_strictfp is only needed for mul and div (and only generates different code on i486)
void arithmetic_op(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp, CodeEmitInfo* info = NULL);
// machine dependent. returns true if it emitted code for the multiply
// this loads the length and compares against the index
void array_range_check (LIR_Opr array, LIR_Opr index, CodeEmitInfo* null_check_info, CodeEmitInfo* range_check_info);
// For java.nio.Buffer.checkIndex
void arithmetic_op_int (Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, LIR_Opr tmp);
void arithmetic_op_long (Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, CodeEmitInfo* info = NULL);
void arithmetic_op_fpu (Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp = LIR_OprFact::illegalOpr);
void monitor_enter (LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no, CodeEmitInfo* info_for_exception, CodeEmitInfo* info);
void new_instance (LIR_Opr dst, ciInstanceKlass* klass, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info);
// machine dependent
void cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, int disp, BasicType type, CodeEmitInfo* info);
void cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, LIR_Opr disp, BasicType type, CodeEmitInfo* info);
// returns a LIR_Address to address an array location. May also
// emit some code as part of address calculation. If
// needs_card_mark is true then compute the full address for use by
// both the store and the card mark.
int disp,
}
LIR_Address* emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, BasicType type, bool needs_card_mark);
// the helper for generate_address
// machine preferences and characteristics
bool can_inline_as_constant(Value i) const;
bool can_inline_as_constant(LIR_Const* c) const;
if (compilation()->count_invocations()) {
}
}
if (compilation()->count_backedges()) {
}
}
// allocates a virtual register for this instruction if
// one isn't already allocated. Only for Phi and Local.
// returns a register suitable for doing pointer math
#ifdef _LP64
return new_register(T_LONG);
#else
return new_register(T_INT);
#endif
}
switch (cond) {
};
return l;
}
#ifdef __SOFTFP__
void do_soft_float_compare(If *x);
#endif // __SOFTFP__
void init();
#ifdef TRACE_HAVE_INTRINSICS
void do_ThreadIDIntrinsic(Intrinsic* x);
void do_ClassIDIntrinsic(Intrinsic* x);
#endif
public:
// Flags that can be set on vregs
enum VregFlag {
must_start_in_memory = 0 // needs to be assigned a memory location at beginning, but may then be loaded in a register
};
init();
}
// for virtual registers, maps them back to Phi's or Local's
// statics
static LIR_Opr exceptionOopOpr();
static LIR_Opr exceptionPcOpr();
static LIR_Opr shiftCountOpr();
// returns a register suitable for saving the thread in a
// call_runtime_leaf if one is needed.
// visitor functionality
virtual void do_Constant (Constant* x);
virtual void do_LoadField (LoadField* x);
virtual void do_StoreField (StoreField* x);
virtual void do_ArrayLength (ArrayLength* x);
virtual void do_LoadIndexed (LoadIndexed* x);
virtual void do_StoreIndexed (StoreIndexed* x);
virtual void do_NegateOp (NegateOp* x);
virtual void do_ArithmeticOp (ArithmeticOp* x);
virtual void do_ShiftOp (ShiftOp* x);
virtual void do_LogicOp (LogicOp* x);
virtual void do_CompareOp (CompareOp* x);
virtual void do_Convert (Convert* x);
virtual void do_NullCheck (NullCheck* x);
virtual void do_TypeCast (TypeCast* x);
virtual void do_NewInstance (NewInstance* x);
virtual void do_NewTypeArray (NewTypeArray* x);
virtual void do_NewObjectArray (NewObjectArray* x);
virtual void do_NewMultiArray (NewMultiArray* x);
virtual void do_CheckCast (CheckCast* x);
virtual void do_InstanceOf (InstanceOf* x);
virtual void do_MonitorEnter (MonitorEnter* x);
virtual void do_MonitorExit (MonitorExit* x);
virtual void do_Intrinsic (Intrinsic* x);
virtual void do_BlockBegin (BlockBegin* x);
virtual void do_IfInstanceOf (IfInstanceOf* x);
virtual void do_TableSwitch (TableSwitch* x);
virtual void do_LookupSwitch (LookupSwitch* x);
virtual void do_OsrEntry (OsrEntry* x);
virtual void do_ExceptionObject(ExceptionObject* x);
virtual void do_RoundFP (RoundFP* x);
virtual void do_UnsafeGetRaw (UnsafeGetRaw* x);
virtual void do_UnsafePutRaw (UnsafePutRaw* x);
virtual void do_UnsafeGetObject(UnsafeGetObject* x);
virtual void do_UnsafePutObject(UnsafePutObject* x);
virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x);
virtual void do_UnsafePrefetchRead (UnsafePrefetchRead* x);
virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
virtual void do_ProfileCall (ProfileCall* x);
virtual void do_ProfileInvoke (ProfileInvoke* x);
virtual void do_RuntimeCall (RuntimeCall* x);
};
private:
bool _destroys_register;
public:
_destroys_register = false;
}
_destroys_register = false;
}
}
}
"shouldn't use set_destroys_register with physical regsiters");
if (_new_result->is_illegal()) {
}
return _new_result;
} else {
return _result;
}
return _result;
}
void load_item();
void load_byte_item();
void load_nonconstant();
// load any values which can't be expressed as part of a single store instruction
void dont_load_item() {
// do nothing
}
void set_destroys_register() {
_destroys_register = true;
}
ciObject* get_jobject_constant() const;
jint get_jint_constant() const;
jlong get_jlong_constant() const;
jfloat get_jfloat_constant() const;
jdouble get_jdouble_constant() const;
jint get_address_constant() const;
};
#endif // SHARE_VM_C1_C1_LIRGENERATOR_HPP