0N/A/*
3932N/A * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1472N/A * or visit www.oracle.com if you need additional information or have any
1472N/A * questions.
0N/A *
0N/A */
0N/A
1879N/A#ifndef SHARE_VM_C1_C1_LIR_HPP
1879N/A#define SHARE_VM_C1_C1_LIR_HPP
1879N/A
1879N/A#include "c1/c1_ValueType.hpp"
3932N/A#include "oops/methodOop.hpp"
1879N/A
0N/Aclass BlockBegin;
0N/Aclass BlockList;
0N/Aclass LIR_Assembler;
0N/Aclass CodeEmitInfo;
0N/Aclass CodeStub;
0N/Aclass CodeStubList;
0N/Aclass ArrayCopyStub;
0N/Aclass LIR_Op;
0N/Aclass ciType;
0N/Aclass ValueType;
0N/Aclass LIR_OpVisitState;
0N/Aclass FpuStackSim;
0N/A
0N/A//---------------------------------------------------------------------
0N/A// LIR Operands
0N/A// LIR_OprDesc
0N/A// LIR_OprPtr
0N/A// LIR_Const
0N/A// LIR_Address
0N/A//---------------------------------------------------------------------
0N/Aclass LIR_OprDesc;
0N/Aclass LIR_OprPtr;
0N/Aclass LIR_Const;
0N/Aclass LIR_Address;
0N/Aclass LIR_OprVisitor;
0N/A
0N/A
0N/Atypedef LIR_OprDesc* LIR_Opr;
0N/Atypedef int RegNr;
0N/A
0N/Adefine_array(LIR_OprArray, LIR_Opr)
0N/Adefine_stack(LIR_OprList, LIR_OprArray)
0N/A
0N/Adefine_array(LIR_OprRefArray, LIR_Opr*)
0N/Adefine_stack(LIR_OprRefList, LIR_OprRefArray)
0N/A
0N/Adefine_array(CodeEmitInfoArray, CodeEmitInfo*)
0N/Adefine_stack(CodeEmitInfoList, CodeEmitInfoArray)
0N/A
0N/Adefine_array(LIR_OpArray, LIR_Op*)
0N/Adefine_stack(LIR_OpList, LIR_OpArray)
0N/A
0N/A// define LIR_OprPtr early so LIR_OprDesc can refer to it
0N/Aclass LIR_OprPtr: public CompilationResourceObj {
0N/A public:
0N/A bool is_oop_pointer() const { return (type() == T_OBJECT); }
0N/A bool is_float_kind() const { BasicType t = type(); return (t == T_FLOAT) || (t == T_DOUBLE); }
0N/A
0N/A virtual LIR_Const* as_constant() { return NULL; }
0N/A virtual LIR_Address* as_address() { return NULL; }
0N/A virtual BasicType type() const = 0;
0N/A virtual void print_value_on(outputStream* out) const = 0;
0N/A};
0N/A
0N/A
0N/A
0N/A// LIR constants
0N/Aclass LIR_Const: public LIR_OprPtr {
0N/A private:
0N/A JavaValue _value;
0N/A
0N/A void type_check(BasicType t) const { assert(type() == t, "type check"); }
0N/A void type_check(BasicType t1, BasicType t2) const { assert(type() == t1 || type() == t2, "type check"); }
1297N/A void type_check(BasicType t1, BasicType t2, BasicType t3) const { assert(type() == t1 || type() == t2 || type() == t3, "type check"); }
0N/A
0N/A public:
1297N/A LIR_Const(jint i, bool is_address=false) { _value.set_type(is_address?T_ADDRESS:T_INT); _value.set_jint(i); }
0N/A LIR_Const(jlong l) { _value.set_type(T_LONG); _value.set_jlong(l); }
0N/A LIR_Const(jfloat f) { _value.set_type(T_FLOAT); _value.set_jfloat(f); }
0N/A LIR_Const(jdouble d) { _value.set_type(T_DOUBLE); _value.set_jdouble(d); }
0N/A LIR_Const(jobject o) { _value.set_type(T_OBJECT); _value.set_jobject(o); }
0N/A LIR_Const(void* p) {
0N/A#ifdef _LP64
0N/A assert(sizeof(jlong) >= sizeof(p), "too small");;
0N/A _value.set_type(T_LONG); _value.set_jlong((jlong)p);
0N/A#else
0N/A assert(sizeof(jint) >= sizeof(p), "too small");;
0N/A _value.set_type(T_INT); _value.set_jint((jint)p);
0N/A#endif
0N/A }
0N/A
0N/A virtual BasicType type() const { return _value.get_type(); }
0N/A virtual LIR_Const* as_constant() { return this; }
0N/A
1297N/A jint as_jint() const { type_check(T_INT, T_ADDRESS); return _value.get_jint(); }
0N/A jlong as_jlong() const { type_check(T_LONG ); return _value.get_jlong(); }
0N/A jfloat as_jfloat() const { type_check(T_FLOAT ); return _value.get_jfloat(); }
0N/A jdouble as_jdouble() const { type_check(T_DOUBLE); return _value.get_jdouble(); }
0N/A jobject as_jobject() const { type_check(T_OBJECT); return _value.get_jobject(); }
0N/A jint as_jint_lo() const { type_check(T_LONG ); return low(_value.get_jlong()); }
0N/A jint as_jint_hi() const { type_check(T_LONG ); return high(_value.get_jlong()); }
0N/A
0N/A#ifdef _LP64
0N/A address as_pointer() const { type_check(T_LONG ); return (address)_value.get_jlong(); }
0N/A#else
0N/A address as_pointer() const { type_check(T_INT ); return (address)_value.get_jint(); }
0N/A#endif
0N/A
0N/A
1297N/A jint as_jint_bits() const { type_check(T_FLOAT, T_INT, T_ADDRESS); return _value.get_jint(); }
0N/A jint as_jint_lo_bits() const {
0N/A if (type() == T_DOUBLE) {
0N/A return low(jlong_cast(_value.get_jdouble()));
0N/A } else {
0N/A return as_jint_lo();
0N/A }
0N/A }
0N/A jint as_jint_hi_bits() const {
0N/A if (type() == T_DOUBLE) {
0N/A return high(jlong_cast(_value.get_jdouble()));
0N/A } else {
0N/A return as_jint_hi();
0N/A }
0N/A }
304N/A jlong as_jlong_bits() const {
304N/A if (type() == T_DOUBLE) {
304N/A return jlong_cast(_value.get_jdouble());
304N/A } else {
304N/A return as_jlong();
304N/A }
304N/A }
0N/A
0N/A virtual void print_value_on(outputStream* out) const PRODUCT_RETURN;
0N/A
0N/A
0N/A bool is_zero_float() {
0N/A jfloat f = as_jfloat();
0N/A jfloat ok = 0.0f;
0N/A return jint_cast(f) == jint_cast(ok);
0N/A }
0N/A
0N/A bool is_one_float() {
0N/A jfloat f = as_jfloat();
0N/A return !g_isnan(f) && g_isfinite(f) && f == 1.0;
0N/A }
0N/A
0N/A bool is_zero_double() {
0N/A jdouble d = as_jdouble();
0N/A jdouble ok = 0.0;
0N/A return jlong_cast(d) == jlong_cast(ok);
0N/A }
0N/A
0N/A bool is_one_double() {
0N/A jdouble d = as_jdouble();
0N/A return !g_isnan(d) && g_isfinite(d) && d == 1.0;
0N/A }
0N/A};
0N/A
0N/A
0N/A//---------------------LIR Operand descriptor------------------------------------
0N/A//
0N/A// The class LIR_OprDesc represents a LIR instruction operand;
0N/A// it can be a register (ALU/FPU), stack location or a constant;
0N/A// Constants and addresses are represented as resource area allocated
0N/A// structures (see above).
0N/A// Registers and stack locations are inlined into the this pointer
0N/A// (see value function).
0N/A
0N/Aclass LIR_OprDesc: public CompilationResourceObj {
0N/A public:
0N/A // value structure:
0N/A // data opr-type opr-kind
0N/A // +--------------+-------+-------+
0N/A // [max...........|7 6 5 4|3 2 1 0]
0N/A // ^
0N/A // is_pointer bit
0N/A //
0N/A // lowest bit cleared, means it is a structure pointer
0N/A // we need 4 bits to represent types
0N/A
0N/A private:
0N/A friend class LIR_OprFact;
0N/A
0N/A // Conversion
0N/A intptr_t value() const { return (intptr_t) this; }
0N/A
0N/A bool check_value_mask(intptr_t mask, intptr_t masked_value) const {
0N/A return (value() & mask) == masked_value;
0N/A }
0N/A
0N/A enum OprKind {
0N/A pointer_value = 0
0N/A , stack_value = 1
0N/A , cpu_register = 3
0N/A , fpu_register = 5
0N/A , illegal_value = 7
0N/A };
0N/A
0N/A enum OprBits {
0N/A pointer_bits = 1
0N/A , kind_bits = 3
0N/A , type_bits = 4
0N/A , size_bits = 2
0N/A , destroys_bits = 1
0N/A , virtual_bits = 1
0N/A , is_xmm_bits = 1
0N/A , last_use_bits = 1
0N/A , is_fpu_stack_offset_bits = 1 // used in assertion checking on x86 for FPU stack slot allocation
0N/A , non_data_bits = kind_bits + type_bits + size_bits + destroys_bits + last_use_bits +
0N/A is_fpu_stack_offset_bits + virtual_bits + is_xmm_bits
0N/A , data_bits = BitsPerInt - non_data_bits
0N/A , reg_bits = data_bits / 2 // for two registers in one value encoding
0N/A };
0N/A
0N/A enum OprShift {
0N/A kind_shift = 0
0N/A , type_shift = kind_shift + kind_bits
0N/A , size_shift = type_shift + type_bits
0N/A , destroys_shift = size_shift + size_bits
0N/A , last_use_shift = destroys_shift + destroys_bits
0N/A , is_fpu_stack_offset_shift = last_use_shift + last_use_bits
0N/A , virtual_shift = is_fpu_stack_offset_shift + is_fpu_stack_offset_bits
0N/A , is_xmm_shift = virtual_shift + virtual_bits
0N/A , data_shift = is_xmm_shift + is_xmm_bits
0N/A , reg1_shift = data_shift
0N/A , reg2_shift = data_shift + reg_bits
0N/A
0N/A };
0N/A
0N/A enum OprSize {
0N/A single_size = 0 << size_shift
0N/A , double_size = 1 << size_shift
0N/A };
0N/A
0N/A enum OprMask {
0N/A kind_mask = right_n_bits(kind_bits)
0N/A , type_mask = right_n_bits(type_bits) << type_shift
0N/A , size_mask = right_n_bits(size_bits) << size_shift
0N/A , last_use_mask = right_n_bits(last_use_bits) << last_use_shift
0N/A , is_fpu_stack_offset_mask = right_n_bits(is_fpu_stack_offset_bits) << is_fpu_stack_offset_shift
0N/A , virtual_mask = right_n_bits(virtual_bits) << virtual_shift
0N/A , is_xmm_mask = right_n_bits(is_xmm_bits) << is_xmm_shift
0N/A , pointer_mask = right_n_bits(pointer_bits)
0N/A , lower_reg_mask = right_n_bits(reg_bits)
0N/A , no_type_mask = (int)(~(type_mask | last_use_mask | is_fpu_stack_offset_mask))
0N/A };
0N/A
0N/A uintptr_t data() const { return value() >> data_shift; }
0N/A int lo_reg_half() const { return data() & lower_reg_mask; }
0N/A int hi_reg_half() const { return (data() >> reg_bits) & lower_reg_mask; }
0N/A OprKind kind_field() const { return (OprKind)(value() & kind_mask); }
0N/A OprSize size_field() const { return (OprSize)(value() & size_mask); }
0N/A
0N/A static char type_char(BasicType t);
0N/A
0N/A public:
0N/A enum {
0N/A vreg_base = ConcreteRegisterImpl::number_of_registers,
0N/A vreg_max = (1 << data_bits) - 1
0N/A };
0N/A
0N/A static inline LIR_Opr illegalOpr();
0N/A
0N/A enum OprType {
0N/A unknown_type = 0 << type_shift // means: not set (catch uninitialized types)
0N/A , int_type = 1 << type_shift
0N/A , long_type = 2 << type_shift
0N/A , object_type = 3 << type_shift
1736N/A , address_type = 4 << type_shift
0N/A , float_type = 5 << type_shift
0N/A , double_type = 6 << type_shift
0N/A };
0N/A friend OprType as_OprType(BasicType t);
0N/A friend BasicType as_BasicType(OprType t);
0N/A
0N/A OprType type_field_valid() const { assert(is_register() || is_stack(), "should not be called otherwise"); return (OprType)(value() & type_mask); }
0N/A OprType type_field() const { return is_illegal() ? unknown_type : (OprType)(value() & type_mask); }
0N/A
0N/A static OprSize size_for(BasicType t) {
0N/A switch (t) {
0N/A case T_LONG:
0N/A case T_DOUBLE:
0N/A return double_size;
0N/A break;
0N/A
0N/A case T_FLOAT:
0N/A case T_BOOLEAN:
0N/A case T_CHAR:
0N/A case T_BYTE:
0N/A case T_SHORT:
0N/A case T_INT:
1736N/A case T_ADDRESS:
0N/A case T_OBJECT:
0N/A case T_ARRAY:
0N/A return single_size;
0N/A break;
0N/A
0N/A default:
0N/A ShouldNotReachHere();
304N/A return single_size;
0N/A }
0N/A }
0N/A
0N/A
0N/A void validate_type() const PRODUCT_RETURN;
0N/A
0N/A BasicType type() const {
0N/A if (is_pointer()) {
0N/A return pointer()->type();
0N/A }
0N/A return as_BasicType(type_field());
0N/A }
0N/A
0N/A
0N/A ValueType* value_type() const { return as_ValueType(type()); }
0N/A
0N/A char type_char() const { return type_char((is_pointer()) ? pointer()->type() : type()); }
0N/A
0N/A bool is_equal(LIR_Opr opr) const { return this == opr; }
0N/A // checks whether types are same
0N/A bool is_same_type(LIR_Opr opr) const {
0N/A assert(type_field() != unknown_type &&
0N/A opr->type_field() != unknown_type, "shouldn't see unknown_type");
0N/A return type_field() == opr->type_field();
0N/A }
0N/A bool is_same_register(LIR_Opr opr) {
0N/A return (is_register() && opr->is_register() &&
0N/A kind_field() == opr->kind_field() &&
0N/A (value() & no_type_mask) == (opr->value() & no_type_mask));
0N/A }
0N/A
0N/A bool is_pointer() const { return check_value_mask(pointer_mask, pointer_value); }
0N/A bool is_illegal() const { return kind_field() == illegal_value; }
0N/A bool is_valid() const { return kind_field() != illegal_value; }
0N/A
0N/A bool is_register() const { return is_cpu_register() || is_fpu_register(); }
0N/A bool is_virtual() const { return is_virtual_cpu() || is_virtual_fpu(); }
0N/A
0N/A bool is_constant() const { return is_pointer() && pointer()->as_constant() != NULL; }
0N/A bool is_address() const { return is_pointer() && pointer()->as_address() != NULL; }
0N/A
0N/A bool is_float_kind() const { return is_pointer() ? pointer()->is_float_kind() : (kind_field() == fpu_register); }
0N/A bool is_oop() const;
0N/A
0N/A // semantic for fpu- and xmm-registers:
0N/A // * is_float and is_double return true for xmm_registers
0N/A // (so is_single_fpu and is_single_xmm are true)
0N/A // * So you must always check for is_???_xmm prior to is_???_fpu to
0N/A // distinguish between fpu- and xmm-registers
0N/A
0N/A bool is_stack() const { validate_type(); return check_value_mask(kind_mask, stack_value); }
0N/A bool is_single_stack() const { validate_type(); return check_value_mask(kind_mask | size_mask, stack_value | single_size); }
0N/A bool is_double_stack() const { validate_type(); return check_value_mask(kind_mask | size_mask, stack_value | double_size); }
0N/A
0N/A bool is_cpu_register() const { validate_type(); return check_value_mask(kind_mask, cpu_register); }
0N/A bool is_virtual_cpu() const { validate_type(); return check_value_mask(kind_mask | virtual_mask, cpu_register | virtual_mask); }
0N/A bool is_fixed_cpu() const { validate_type(); return check_value_mask(kind_mask | virtual_mask, cpu_register); }
0N/A bool is_single_cpu() const { validate_type(); return check_value_mask(kind_mask | size_mask, cpu_register | single_size); }
0N/A bool is_double_cpu() const { validate_type(); return check_value_mask(kind_mask | size_mask, cpu_register | double_size); }
0N/A
0N/A bool is_fpu_register() const { validate_type(); return check_value_mask(kind_mask, fpu_register); }
0N/A bool is_virtual_fpu() const { validate_type(); return check_value_mask(kind_mask | virtual_mask, fpu_register | virtual_mask); }
0N/A bool is_fixed_fpu() const { validate_type(); return check_value_mask(kind_mask | virtual_mask, fpu_register); }
0N/A bool is_single_fpu() const { validate_type(); return check_value_mask(kind_mask | size_mask, fpu_register | single_size); }
0N/A bool is_double_fpu() const { validate_type(); return check_value_mask(kind_mask | size_mask, fpu_register | double_size); }
0N/A
0N/A bool is_xmm_register() const { validate_type(); return check_value_mask(kind_mask | is_xmm_mask, fpu_register | is_xmm_mask); }
0N/A bool is_single_xmm() const { validate_type(); return check_value_mask(kind_mask | size_mask | is_xmm_mask, fpu_register | single_size | is_xmm_mask); }
0N/A bool is_double_xmm() const { validate_type(); return check_value_mask(kind_mask | size_mask | is_xmm_mask, fpu_register | double_size | is_xmm_mask); }
0N/A
0N/A // fast accessor functions for special bits that do not work for pointers
0N/A // (in this functions, the check for is_pointer() is omitted)
0N/A bool is_single_word() const { assert(is_register() || is_stack(), "type check"); return check_value_mask(size_mask, single_size); }
0N/A bool is_double_word() const { assert(is_register() || is_stack(), "type check"); return check_value_mask(size_mask, double_size); }
0N/A bool is_virtual_register() const { assert(is_register(), "type check"); return check_value_mask(virtual_mask, virtual_mask); }
0N/A bool is_oop_register() const { assert(is_register() || is_stack(), "type check"); return type_field_valid() == object_type; }
0N/A BasicType type_register() const { assert(is_register() || is_stack(), "type check"); return as_BasicType(type_field_valid()); }
0N/A
0N/A bool is_last_use() const { assert(is_register(), "only works for registers"); return (value() & last_use_mask) != 0; }
0N/A bool is_fpu_stack_offset() const { assert(is_register(), "only works for registers"); return (value() & is_fpu_stack_offset_mask) != 0; }
0N/A LIR_Opr make_last_use() { assert(is_register(), "only works for registers"); return (LIR_Opr)(value() | last_use_mask); }
0N/A LIR_Opr make_fpu_stack_offset() { assert(is_register(), "only works for registers"); return (LIR_Opr)(value() | is_fpu_stack_offset_mask); }
0N/A
0N/A
0N/A int single_stack_ix() const { assert(is_single_stack() && !is_virtual(), "type check"); return (int)data(); }
0N/A int double_stack_ix() const { assert(is_double_stack() && !is_virtual(), "type check"); return (int)data(); }
0N/A RegNr cpu_regnr() const { assert(is_single_cpu() && !is_virtual(), "type check"); return (RegNr)data(); }
0N/A RegNr cpu_regnrLo() const { assert(is_double_cpu() && !is_virtual(), "type check"); return (RegNr)lo_reg_half(); }
0N/A RegNr cpu_regnrHi() const { assert(is_double_cpu() && !is_virtual(), "type check"); return (RegNr)hi_reg_half(); }
0N/A RegNr fpu_regnr() const { assert(is_single_fpu() && !is_virtual(), "type check"); return (RegNr)data(); }
0N/A RegNr fpu_regnrLo() const { assert(is_double_fpu() && !is_virtual(), "type check"); return (RegNr)lo_reg_half(); }
0N/A RegNr fpu_regnrHi() const { assert(is_double_fpu() && !is_virtual(), "type check"); return (RegNr)hi_reg_half(); }
0N/A RegNr xmm_regnr() const { assert(is_single_xmm() && !is_virtual(), "type check"); return (RegNr)data(); }
0N/A RegNr xmm_regnrLo() const { assert(is_double_xmm() && !is_virtual(), "type check"); return (RegNr)lo_reg_half(); }
0N/A RegNr xmm_regnrHi() const { assert(is_double_xmm() && !is_virtual(), "type check"); return (RegNr)hi_reg_half(); }
0N/A int vreg_number() const { assert(is_virtual(), "type check"); return (RegNr)data(); }
0N/A
0N/A LIR_OprPtr* pointer() const { assert(is_pointer(), "type check"); return (LIR_OprPtr*)this; }
0N/A LIR_Const* as_constant_ptr() const { return pointer()->as_constant(); }
0N/A LIR_Address* as_address_ptr() const { return pointer()->as_address(); }
0N/A
0N/A Register as_register() const;
0N/A Register as_register_lo() const;
0N/A Register as_register_hi() const;
0N/A
0N/A Register as_pointer_register() {
0N/A#ifdef _LP64
0N/A if (is_double_cpu()) {
0N/A assert(as_register_lo() == as_register_hi(), "should be a single register");
0N/A return as_register_lo();
0N/A }
0N/A#endif
0N/A return as_register();
0N/A }
0N/A
304N/A#ifdef X86
0N/A XMMRegister as_xmm_float_reg() const;
0N/A XMMRegister as_xmm_double_reg() const;
0N/A // for compatibility with RInfo
0N/A int fpu () const { return lo_reg_half(); }
304N/A#endif // X86
1601N/A#if defined(SPARC) || defined(ARM) || defined(PPC)
0N/A FloatRegister as_float_reg () const;
0N/A FloatRegister as_double_reg () const;
0N/A#endif
0N/A
0N/A jint as_jint() const { return as_constant_ptr()->as_jint(); }
0N/A jlong as_jlong() const { return as_constant_ptr()->as_jlong(); }
0N/A jfloat as_jfloat() const { return as_constant_ptr()->as_jfloat(); }
0N/A jdouble as_jdouble() const { return as_constant_ptr()->as_jdouble(); }
0N/A jobject as_jobject() const { return as_constant_ptr()->as_jobject(); }
0N/A
0N/A void print() const PRODUCT_RETURN;
0N/A void print(outputStream* out) const PRODUCT_RETURN;
0N/A};
0N/A
0N/A
0N/Ainline LIR_OprDesc::OprType as_OprType(BasicType type) {
0N/A switch (type) {
0N/A case T_INT: return LIR_OprDesc::int_type;
0N/A case T_LONG: return LIR_OprDesc::long_type;
0N/A case T_FLOAT: return LIR_OprDesc::float_type;
0N/A case T_DOUBLE: return LIR_OprDesc::double_type;
0N/A case T_OBJECT:
0N/A case T_ARRAY: return LIR_OprDesc::object_type;
1736N/A case T_ADDRESS: return LIR_OprDesc::address_type;
0N/A case T_ILLEGAL: // fall through
0N/A default: ShouldNotReachHere(); return LIR_OprDesc::unknown_type;
0N/A }
0N/A}
0N/A
0N/Ainline BasicType as_BasicType(LIR_OprDesc::OprType t) {
0N/A switch (t) {
0N/A case LIR_OprDesc::int_type: return T_INT;
0N/A case LIR_OprDesc::long_type: return T_LONG;
0N/A case LIR_OprDesc::float_type: return T_FLOAT;
0N/A case LIR_OprDesc::double_type: return T_DOUBLE;
0N/A case LIR_OprDesc::object_type: return T_OBJECT;
1736N/A case LIR_OprDesc::address_type: return T_ADDRESS;
0N/A case LIR_OprDesc::unknown_type: // fall through
0N/A default: ShouldNotReachHere(); return T_ILLEGAL;
0N/A }
0N/A}
0N/A
0N/A
0N/A// LIR_Address
0N/Aclass LIR_Address: public LIR_OprPtr {
0N/A friend class LIR_OpVisitState;
0N/A
0N/A public:
0N/A // NOTE: currently these must be the log2 of the scale factor (and
0N/A // must also be equivalent to the ScaleFactor enum in
0N/A // assembler_i486.hpp)
0N/A enum Scale {
0N/A times_1 = 0,
0N/A times_2 = 1,
0N/A times_4 = 2,
0N/A times_8 = 3
0N/A };
0N/A
0N/A private:
0N/A LIR_Opr _base;
0N/A LIR_Opr _index;
0N/A Scale _scale;
0N/A intx _disp;
0N/A BasicType _type;
0N/A
0N/A public:
0N/A LIR_Address(LIR_Opr base, LIR_Opr index, BasicType type):
0N/A _base(base)
0N/A , _index(index)
0N/A , _scale(times_1)
0N/A , _type(type)
0N/A , _disp(0) { verify(); }
0N/A
1492N/A LIR_Address(LIR_Opr base, intx disp, BasicType type):
0N/A _base(base)
0N/A , _index(LIR_OprDesc::illegalOpr())
0N/A , _scale(times_1)
0N/A , _type(type)
0N/A , _disp(disp) { verify(); }
0N/A
1492N/A LIR_Address(LIR_Opr base, BasicType type):
1492N/A _base(base)
1492N/A , _index(LIR_OprDesc::illegalOpr())
1492N/A , _scale(times_1)
1492N/A , _type(type)
1492N/A , _disp(0) { verify(); }
1492N/A
1601N/A#if defined(X86) || defined(ARM)
1492N/A LIR_Address(LIR_Opr base, LIR_Opr index, Scale scale, intx disp, BasicType type):
0N/A _base(base)
0N/A , _index(index)
0N/A , _scale(scale)
0N/A , _type(type)
0N/A , _disp(disp) { verify(); }
1601N/A#endif // X86 || ARM
0N/A
0N/A LIR_Opr base() const { return _base; }
0N/A LIR_Opr index() const { return _index; }
0N/A Scale scale() const { return _scale; }
0N/A intx disp() const { return _disp; }
0N/A
0N/A bool equals(LIR_Address* other) const { return base() == other->base() && index() == other->index() && disp() == other->disp() && scale() == other->scale(); }
0N/A
0N/A virtual LIR_Address* as_address() { return this; }
0N/A virtual BasicType type() const { return _type; }
0N/A virtual void print_value_on(outputStream* out) const PRODUCT_RETURN;
0N/A
0N/A void verify() const PRODUCT_RETURN;
0N/A
0N/A static Scale scale(BasicType type);
0N/A};
0N/A
0N/A
0N/A// operand factory
0N/Aclass LIR_OprFact: public AllStatic {
0N/A public:
0N/A
0N/A static LIR_Opr illegalOpr;
0N/A
1736N/A static LIR_Opr single_cpu(int reg) {
1736N/A return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) |
1736N/A LIR_OprDesc::int_type |
1736N/A LIR_OprDesc::cpu_register |
1736N/A LIR_OprDesc::single_size);
1736N/A }
1736N/A static LIR_Opr single_cpu_oop(int reg) {
1736N/A return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) |
1736N/A LIR_OprDesc::object_type |
1736N/A LIR_OprDesc::cpu_register |
1736N/A LIR_OprDesc::single_size);
1736N/A }
1736N/A static LIR_Opr single_cpu_address(int reg) {
1736N/A return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) |
1736N/A LIR_OprDesc::address_type |
1736N/A LIR_OprDesc::cpu_register |
1736N/A LIR_OprDesc::single_size);
1736N/A }
304N/A static LIR_Opr double_cpu(int reg1, int reg2) {
304N/A LP64_ONLY(assert(reg1 == reg2, "must be identical"));
304N/A return (LIR_Opr)(intptr_t)((reg1 << LIR_OprDesc::reg1_shift) |
304N/A (reg2 << LIR_OprDesc::reg2_shift) |
304N/A LIR_OprDesc::long_type |
304N/A LIR_OprDesc::cpu_register |
304N/A LIR_OprDesc::double_size);
304N/A }
0N/A
304N/A static LIR_Opr single_fpu(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) |
304N/A LIR_OprDesc::float_type |
304N/A LIR_OprDesc::fpu_register |
304N/A LIR_OprDesc::single_size); }
1601N/A#if defined(ARM)
1601N/A static LIR_Opr double_fpu(int reg1, int reg2) { return (LIR_Opr)((reg1 << LIR_OprDesc::reg1_shift) | (reg2 << LIR_OprDesc::reg2_shift) | LIR_OprDesc::double_type | LIR_OprDesc::fpu_register | LIR_OprDesc::double_size); }
1601N/A static LIR_Opr single_softfp(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) | LIR_OprDesc::float_type | LIR_OprDesc::cpu_register | LIR_OprDesc::single_size); }
1601N/A static LIR_Opr double_softfp(int reg1, int reg2) { return (LIR_Opr)((reg1 << LIR_OprDesc::reg1_shift) | (reg2 << LIR_OprDesc::reg2_shift) | LIR_OprDesc::double_type | LIR_OprDesc::cpu_register | LIR_OprDesc::double_size); }
1601N/A#endif
0N/A#ifdef SPARC
304N/A static LIR_Opr double_fpu(int reg1, int reg2) { return (LIR_Opr)(intptr_t)((reg1 << LIR_OprDesc::reg1_shift) |
304N/A (reg2 << LIR_OprDesc::reg2_shift) |
304N/A LIR_OprDesc::double_type |
304N/A LIR_OprDesc::fpu_register |
304N/A LIR_OprDesc::double_size); }
0N/A#endif
304N/A#ifdef X86
304N/A static LIR_Opr double_fpu(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) |
304N/A (reg << LIR_OprDesc::reg2_shift) |
304N/A LIR_OprDesc::double_type |
304N/A LIR_OprDesc::fpu_register |
304N/A LIR_OprDesc::double_size); }
304N/A
304N/A static LIR_Opr single_xmm(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) |
304N/A LIR_OprDesc::float_type |
304N/A LIR_OprDesc::fpu_register |
304N/A LIR_OprDesc::single_size |
304N/A LIR_OprDesc::is_xmm_mask); }
304N/A static LIR_Opr double_xmm(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) |
304N/A (reg << LIR_OprDesc::reg2_shift) |
304N/A LIR_OprDesc::double_type |
304N/A LIR_OprDesc::fpu_register |
304N/A LIR_OprDesc::double_size |
304N/A LIR_OprDesc::is_xmm_mask); }
304N/A#endif // X86
1601N/A#ifdef PPC
1601N/A static LIR_Opr double_fpu(int reg) { return (LIR_Opr)(intptr_t)((reg << LIR_OprDesc::reg1_shift) |
1601N/A (reg << LIR_OprDesc::reg2_shift) |
1601N/A LIR_OprDesc::double_type |
1601N/A LIR_OprDesc::fpu_register |
1601N/A LIR_OprDesc::double_size); }
1601N/A static LIR_Opr single_softfp(int reg) { return (LIR_Opr)((reg << LIR_OprDesc::reg1_shift) |
1601N/A LIR_OprDesc::float_type |
1601N/A LIR_OprDesc::cpu_register |
1601N/A LIR_OprDesc::single_size); }
1601N/A static LIR_Opr double_softfp(int reg1, int reg2) { return (LIR_Opr)((reg2 << LIR_OprDesc::reg1_shift) |
1601N/A (reg1 << LIR_OprDesc::reg2_shift) |
1601N/A LIR_OprDesc::double_type |
1601N/A LIR_OprDesc::cpu_register |
1601N/A LIR_OprDesc::double_size); }
1601N/A#endif // PPC
0N/A
0N/A static LIR_Opr virtual_register(int index, BasicType type) {
0N/A LIR_Opr res;
0N/A switch (type) {
0N/A case T_OBJECT: // fall through
304N/A case T_ARRAY:
304N/A res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
304N/A LIR_OprDesc::object_type |
304N/A LIR_OprDesc::cpu_register |
304N/A LIR_OprDesc::single_size |
304N/A LIR_OprDesc::virtual_mask);
304N/A break;
304N/A
304N/A case T_INT:
304N/A res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
304N/A LIR_OprDesc::int_type |
304N/A LIR_OprDesc::cpu_register |
304N/A LIR_OprDesc::single_size |
304N/A LIR_OprDesc::virtual_mask);
304N/A break;
304N/A
1736N/A case T_ADDRESS:
1736N/A res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
1736N/A LIR_OprDesc::address_type |
1736N/A LIR_OprDesc::cpu_register |
1736N/A LIR_OprDesc::single_size |
1736N/A LIR_OprDesc::virtual_mask);
1736N/A break;
1736N/A
304N/A case T_LONG:
304N/A res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
304N/A LIR_OprDesc::long_type |
304N/A LIR_OprDesc::cpu_register |
304N/A LIR_OprDesc::double_size |
304N/A LIR_OprDesc::virtual_mask);
304N/A break;
304N/A
1601N/A#ifdef __SOFTFP__
1601N/A case T_FLOAT:
1601N/A res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
1601N/A LIR_OprDesc::float_type |
1601N/A LIR_OprDesc::cpu_register |
1601N/A LIR_OprDesc::single_size |
1601N/A LIR_OprDesc::virtual_mask);
1601N/A break;
1601N/A case T_DOUBLE:
1601N/A res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
1601N/A LIR_OprDesc::double_type |
1601N/A LIR_OprDesc::cpu_register |
1601N/A LIR_OprDesc::double_size |
1601N/A LIR_OprDesc::virtual_mask);
1601N/A break;
1601N/A#else // __SOFTFP__
304N/A case T_FLOAT:
304N/A res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
304N/A LIR_OprDesc::float_type |
304N/A LIR_OprDesc::fpu_register |
304N/A LIR_OprDesc::single_size |
304N/A LIR_OprDesc::virtual_mask);
304N/A break;
304N/A
304N/A case
304N/A T_DOUBLE: res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
304N/A LIR_OprDesc::double_type |
304N/A LIR_OprDesc::fpu_register |
304N/A LIR_OprDesc::double_size |
304N/A LIR_OprDesc::virtual_mask);
304N/A break;
1601N/A#endif // __SOFTFP__
0N/A default: ShouldNotReachHere(); res = illegalOpr;
0N/A }
0N/A
0N/A#ifdef ASSERT
0N/A res->validate_type();
0N/A assert(res->vreg_number() == index, "conversion check");
0N/A assert(index >= LIR_OprDesc::vreg_base, "must start at vreg_base");
0N/A assert(index <= (max_jint >> LIR_OprDesc::data_shift), "index is too big");
0N/A
0N/A // old-style calculation; check if old and new method are equal
0N/A LIR_OprDesc::OprType t = as_OprType(type);
1601N/A#ifdef __SOFTFP__
1601N/A LIR_Opr old_res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
1601N/A t |
1601N/A LIR_OprDesc::cpu_register |
1601N/A LIR_OprDesc::size_for(type) | LIR_OprDesc::virtual_mask);
1601N/A#else // __SOFTFP__
304N/A LIR_Opr old_res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) | t |
304N/A ((type == T_FLOAT || type == T_DOUBLE) ? LIR_OprDesc::fpu_register : LIR_OprDesc::cpu_register) |
0N/A LIR_OprDesc::size_for(type) | LIR_OprDesc::virtual_mask);
0N/A assert(res == old_res, "old and new method not equal");
1601N/A#endif // __SOFTFP__
1601N/A#endif // ASSERT
0N/A
0N/A return res;
0N/A }
0N/A
0N/A // 'index' is computed by FrameMap::local_stack_pos(index); do not use other parameters as
0N/A // the index is platform independent; a double stack useing indeces 2 and 3 has always
0N/A // index 2.
0N/A static LIR_Opr stack(int index, BasicType type) {
0N/A LIR_Opr res;
0N/A switch (type) {
0N/A case T_OBJECT: // fall through
304N/A case T_ARRAY:
304N/A res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
304N/A LIR_OprDesc::object_type |
304N/A LIR_OprDesc::stack_value |
304N/A LIR_OprDesc::single_size);
304N/A break;
304N/A
304N/A case T_INT:
304N/A res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
304N/A LIR_OprDesc::int_type |
304N/A LIR_OprDesc::stack_value |
304N/A LIR_OprDesc::single_size);
304N/A break;
304N/A
1736N/A case T_ADDRESS:
1736N/A res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
1736N/A LIR_OprDesc::address_type |
1736N/A LIR_OprDesc::stack_value |
1736N/A LIR_OprDesc::single_size);
1736N/A break;
1736N/A
304N/A case T_LONG:
304N/A res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
304N/A LIR_OprDesc::long_type |
304N/A LIR_OprDesc::stack_value |
304N/A LIR_OprDesc::double_size);
304N/A break;
304N/A
304N/A case T_FLOAT:
304N/A res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
304N/A LIR_OprDesc::float_type |
304N/A LIR_OprDesc::stack_value |
304N/A LIR_OprDesc::single_size);
304N/A break;
304N/A case T_DOUBLE:
304N/A res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
304N/A LIR_OprDesc::double_type |
304N/A LIR_OprDesc::stack_value |
304N/A LIR_OprDesc::double_size);
304N/A break;
0N/A
0N/A default: ShouldNotReachHere(); res = illegalOpr;
0N/A }
0N/A
0N/A#ifdef ASSERT
0N/A assert(index >= 0, "index must be positive");
0N/A assert(index <= (max_jint >> LIR_OprDesc::data_shift), "index is too big");
0N/A
304N/A LIR_Opr old_res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
304N/A LIR_OprDesc::stack_value |
304N/A as_OprType(type) |
304N/A LIR_OprDesc::size_for(type));
0N/A assert(res == old_res, "old and new method not equal");
0N/A#endif
0N/A
0N/A return res;
0N/A }
0N/A
0N/A static LIR_Opr intConst(jint i) { return (LIR_Opr)(new LIR_Const(i)); }
0N/A static LIR_Opr longConst(jlong l) { return (LIR_Opr)(new LIR_Const(l)); }
0N/A static LIR_Opr floatConst(jfloat f) { return (LIR_Opr)(new LIR_Const(f)); }
0N/A static LIR_Opr doubleConst(jdouble d) { return (LIR_Opr)(new LIR_Const(d)); }
0N/A static LIR_Opr oopConst(jobject o) { return (LIR_Opr)(new LIR_Const(o)); }
0N/A static LIR_Opr address(LIR_Address* a) { return (LIR_Opr)a; }
0N/A static LIR_Opr intptrConst(void* p) { return (LIR_Opr)(new LIR_Const(p)); }
0N/A static LIR_Opr intptrConst(intptr_t v) { return (LIR_Opr)(new LIR_Const((void*)v)); }
0N/A static LIR_Opr illegal() { return (LIR_Opr)-1; }
1297N/A static LIR_Opr addressConst(jint i) { return (LIR_Opr)(new LIR_Const(i, true)); }
0N/A
0N/A static LIR_Opr value_type(ValueType* type);
0N/A static LIR_Opr dummy_value_type(ValueType* type);
0N/A};
0N/A
0N/A
0N/A//-------------------------------------------------------------------------------
0N/A// LIR Instructions
0N/A//-------------------------------------------------------------------------------
0N/A//
0N/A// Note:
0N/A// - every instruction has a result operand
0N/A// - every instruction has an CodeEmitInfo operand (can be revisited later)
0N/A// - every instruction has a LIR_OpCode operand
0N/A// - LIR_OpN, means an instruction that has N input operands
0N/A//
0N/A// class hierarchy:
0N/A//
0N/Aclass LIR_Op;
0N/Aclass LIR_Op0;
0N/Aclass LIR_OpLabel;
0N/Aclass LIR_Op1;
0N/Aclass LIR_OpBranch;
0N/Aclass LIR_OpConvert;
0N/Aclass LIR_OpAllocObj;
0N/Aclass LIR_OpRoundFP;
0N/Aclass LIR_Op2;
0N/Aclass LIR_OpDelay;
0N/Aclass LIR_Op3;
0N/Aclass LIR_OpAllocArray;
0N/Aclass LIR_OpCall;
0N/Aclass LIR_OpJavaCall;
0N/Aclass LIR_OpRTCall;
0N/Aclass LIR_OpArrayCopy;
0N/Aclass LIR_OpLock;
0N/Aclass LIR_OpTypeCheck;
0N/Aclass LIR_OpCompareAndSwap;
0N/Aclass LIR_OpProfileCall;
0N/A
0N/A
0N/A// LIR operation codes
0N/Aenum LIR_Code {
0N/A lir_none
0N/A , begin_op0
0N/A , lir_word_align
0N/A , lir_label
0N/A , lir_nop
0N/A , Error!

 

There was an error!

null

java.lang.NullPointerException