c1_LIRAssembler_sparc.cpp revision 1977
2702N/A * or visit www.oracle.com if you need additional information or have any
2702N/A#include "precompiled.hpp"
2702N/A#include "c1/c1_Compilation.hpp"
2702N/A#include "c1/c1_LIRAssembler.hpp"
2702N/A#include "c1/c1_MacroAssembler.hpp"
2702N/A#include "c1/c1_Runtime1.hpp"
2702N/A#include "c1/c1_ValueStack.hpp"
2702N/A#include "ci/ciArrayKlass.hpp"
2702N/A#include "ci/ciInstance.hpp"
2702N/A#include "gc_interface/collectedHeap.hpp"
2702N/A#include "memory/barrierSet.hpp"
2702N/A#include "memory/cardTableModRefBS.hpp"
2702N/A#include "nativeInst_sparc.hpp"
2702N/A#include "oops/objArrayKlass.hpp"
2702N/A#include "runtime/sharedRuntime.hpp"
2702N/A case lir_null_check:
2702N/A if (VerifyOops) {
2702N/A if (UseCompressedOops) {
2702N/A if (dst->is_address() && !dst->is_stack() && (dst->type() == T_OBJECT || dst->type() == T_ARRAY)) return false;
2702N/A if (src->is_address() && !src->is_stack() && (src->type() == T_OBJECT || src->type() == T_ARRAY)) return false;
// On-stack-replacement entry sequence (interpreter frame layout described in interpreter_sparc.cpp):
for (int i = 0; i < number_of_locks; i++) {
#ifdef ASSERT
Label L;
// This is the fast version of java.lang.String.compare; it has not
void LIR_Assembler::emit_string_compare(LIR_Opr left, LIR_Opr right, LIR_Opr dst, CodeEmitInfo* info) {
// Get a pointer to the first character of string0 in tmp0 and get string0.count in str0
// Get a pointer to the first character of string1 in tmp1 and get string1.count in str1
// Also, get string0.count-string1.count in o7 and get the condition code set
if (!GenerateSynchronizationCode) return;
if (UseFastLocking) {
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
return offset;
#ifndef PRODUCT
if (CommentedAssembly) {
__ call(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), relocInfo::runtime_call_type);
return offset;
return offset;
if (o == NULL) {
#ifdef ASSERT
case lir_cond_less: acond = (is_unordered ? Assembler::f_unorderedOrLess : Assembler::f_less); break;
case lir_cond_greater: acond = (is_unordered ? Assembler::f_unorderedOrGreater : Assembler::f_greater); break;
case lir_cond_lessEqual: acond = (is_unordered ? Assembler::f_unorderedOrLessOrEqual : Assembler::f_lessOrEqual); break;
case lir_cond_greaterEqual: acond = (is_unordered ? Assembler::f_unorderedOrGreaterOrEqual: Assembler::f_greaterOrEqual); break;
default : ShouldNotReachHere();
default: ShouldNotReachHere();
#ifdef _LP64
switch(code) {
#ifdef _LP64
Label L;
#ifdef _LP64
int shift = (code == Bytecodes::_i2b) ? (BitsPerInt - T_BYTE_aelem_bytes * BitsPerByte) : (BitsPerInt - BitsPerShort);
default: ShouldNotReachHere();
int LIR_Assembler::store(LIR_Opr from_reg, Register base, int offset, BasicType type, bool wide, bool unaligned) {
int store_offset;
switch (type) {
case T_LONG :
#ifdef _LP64
case T_ADDRESS:
case T_OBJECT:
case T_DOUBLE:
default : ShouldNotReachHere();
return store_offset;
int LIR_Assembler::store(LIR_Opr from_reg, Register base, Register disp, BasicType type, bool wide) {
switch (type) {
case T_LONG :
#ifdef _LP64
case T_ADDRESS:
case T_OBJECT:
default : ShouldNotReachHere();
return store_offset;
int LIR_Assembler::load(Register base, int offset, LIR_Opr to_reg, BasicType type, bool wide, bool unaligned) {
int load_offset;
switch(type) {
case T_LONG :
if (!unaligned) {
#ifdef _LP64
#ifdef _LP64
case T_OBJECT:
case T_DOUBLE:
default : ShouldNotReachHere();
return load_offset;
switch(type) {
case T_OBJECT:
case T_LONG :
#ifdef _LP64
default : ShouldNotReachHere();
return load_offset;
switch (c->type()) {
case T_INT:
case T_FLOAT: {
if (value == 0) {
case T_ADDRESS: {
if (value == 0) {
case T_OBJECT: {
case T_LONG:
case T_DOUBLE: {
if (value_lo == 0) {
if (value_hi == 0) {
void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) {
switch (c->type()) {
case T_INT:
case T_FLOAT:
case T_ADDRESS: {
if (value == 0) {
case T_LONG:
case T_DOUBLE: {
if (value_lo == 0) {
if (value_hi == 0) {
case T_OBJECT: {
void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
switch (c->type()) {
case T_INT:
case T_ADDRESS:
case T_LONG:
#ifdef _LP64
#ifdef _LP64
case T_OBJECT:
case T_FLOAT:
case T_DOUBLE:
#ifdef _LP64
switch (type) {
case T_INT:
case T_FLOAT: {
case T_OBJECT: {
case T_LONG:
case T_DOUBLE: {
if (needs_patching) {
if (needs_patching) {
#ifdef _LP64
#ifdef _LP64
if (needs_patching) {
if (needs_patching) {
int offset;
#ifdef ASSERT
return offset;
case T_INT:
case T_OBJECT:
#ifdef _LP64
#ifdef _LP64
void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst, LIR_Op2* op){
__ float_cmp(true, is_unordered_less ? -1 : 1, left->as_float_reg(), right->as_float_reg(), dst->as_register());
__ float_cmp(false, is_unordered_less ? -1 : 1, left->as_double_reg(), right->as_double_reg(), dst->as_register());
#ifdef _LP64
void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type) {
switch (condition) {
default: ShouldNotReachHere();
#ifdef _LP64
void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info, bool pop_fpu_stack) {
w = FloatRegisterImpl::S;
w = FloatRegisterImpl::D;
switch (code) {
default: ShouldNotReachHere();
#ifdef _LP64
switch (code) {
case lir_add:
case lir_sub:
default: ShouldNotReachHere();
switch (code) {
case lir_add:
case lir_sub:
default: ShouldNotReachHere();
switch (code) {
default: ShouldNotReachHere();
switch (code) {
default: ShouldNotReachHere();
switch (code) {
default: ShouldNotReachHere();
void LIR_Assembler::intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr thread, LIR_Opr dest, LIR_Op* op) {
switch (code) {
case lir_sin:
case lir_tan:
case lir_cos: {
case lir_sqrt: {
case lir_abs: {
switch (code) {
default: ShouldNotReachHere();
int simm13 = (int)c;
switch (code) {
case lir_logic_and:
#ifndef _LP64
case lir_logic_or:
#ifndef _LP64
case lir_logic_xor:
#ifndef _LP64
default: ShouldNotReachHere();
switch (code) {
case lir_logic_and: __ and3 (left->as_register(), right->as_register(), dest->as_register()); break;
case lir_logic_xor: __ xor3 (left->as_register(), right->as_register(), dest->as_register()); break;
default: ShouldNotReachHere();
#ifdef _LP64
switch (code) {
default: ShouldNotReachHere();
switch (code) {
case lir_logic_and:
case lir_logic_or:
case lir_logic_xor:
default: ShouldNotReachHere();
switch (elem_size) {
BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL;
if (UseCompressedOops) {
#ifdef ASSERT
if (UseCompressedOops) {
if (shift == 0) {
if (shift == 0) {
if (shift == 0) {
void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) {
#ifdef _LP64
switch (code) {
default: ShouldNotReachHere();
switch (code) {
default: ShouldNotReachHere();
#ifdef _LP64
switch (code) {
case lir_shl: __ sllx (left->as_register_lo(), count->as_register(), dest->as_register_lo()); break;
case lir_shr: __ srax (left->as_register_lo(), count->as_register(), dest->as_register_lo()); break;
case lir_ushr: __ srlx (left->as_register_lo(), count->as_register(), dest->as_register_lo()); break;
default: ShouldNotReachHere();
switch (code) {
case lir_shl: __ lshl (left->as_register_hi(), left->as_register_lo(), count->as_register(), dest->as_register_hi(), dest->as_register_lo(), G3_scratch); break;
case lir_shr: __ lshr (left->as_register_hi(), left->as_register_lo(), count->as_register(), dest->as_register_hi(), dest->as_register_lo(), G3_scratch); break;
case lir_ushr: __ lushr (left->as_register_hi(), left->as_register_lo(), count->as_register(), dest->as_register_hi(), dest->as_register_lo(), G3_scratch); break;
default: ShouldNotReachHere();
#ifdef _LP64
switch (code) {
default: ShouldNotReachHere();
switch (code) {
default: ShouldNotReachHere();
switch (code) {
default: ShouldNotReachHere();
if (UseSlowPath ||
uint i;
if (!Assembler::is_simm13(md->byte_offset_of_slot(data, DataLayout::header_offset()) + data->size_in_bytes())) {
void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) {
int mdo_offset_bias = 0;
if (mdo_offset_bias > 0) {
Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias);
if (k->is_loaded()) {
bool need_slow_path = true;
if (k->is_loaded()) {
need_slow_path = false;
if (need_slow_path) {
if (mdo_offset_bias > 0) {
if (mdo_offset_bias > 0) {
Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);
int mdo_offset_bias = 0;
if (mdo_offset_bias > 0) {
Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias);
__ ld_ptr(Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)), k_RInfo);
__ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target, failure_target, NULL);
if (mdo_offset_bias > 0) {
if (mdo_offset_bias > 0) {
Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);
#ifdef _LP64
if (UseCompressedOops) {
if (UseFastLocking) {
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
if (UseFastLocking) {
assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
#ifdef _LP64
int mdo_offset_bias = 0;
Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);
uint i;
#ifdef ASSERT
if (call_info) {
if (VerifyStackAtCalls) {
#ifdef _LP64
#ifdef ASSERT
void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) {
#ifdef _LP64
assert(addr->index()->is_illegal() && addr->scale() == LIR_Address::times_1 && Assembler::is_simm13(addr->disp()), "can't handle complex addresses yet");
case lir_cond_float_branch:
case lir_branch: {
#ifndef PRODUCT
if (LIRTracePeephole) {
if (!delay_op) {
case lir_static_call:
case lir_virtual_call:
case lir_icvirtual_call:
case lir_optvirtual_call:
case lir_dynamic_call: {
#ifndef PRODUCT
if (LIRTracePeephole) {
call = new LIR_OpJavaCall(op->code(), callop->method(), callop->receiver(), FrameMap::g1_long_single_opr,
call = new LIR_OpJavaCall(op->code(), callop->method(), callop->receiver(), FrameMap::g1_long_single_opr,
inst->insert_before(i + 1, new LIR_Op1(lir_unpack64, FrameMap::g1_long_single_opr, callop->result_opr(),