Path: blob/master/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
41144 views
/*1* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "asm/macroAssembler.hpp"26#include "asm/macroAssembler.inline.hpp"27#include "c1/c1_CodeStubs.hpp"28#include "c1/c1_Compilation.hpp"29#include "c1/c1_LIRAssembler.hpp"30#include "c1/c1_MacroAssembler.hpp"31#include "c1/c1_Runtime1.hpp"32#include "c1/c1_ValueStack.hpp"33#include "ci/ciArrayKlass.hpp"34#include "ci/ciInstance.hpp"35#include "compiler/oopMap.hpp"36#include "gc/shared/collectedHeap.hpp"37#include "gc/shared/gc_globals.hpp"38#include "nativeInst_x86.hpp"39#include "oops/objArrayKlass.hpp"40#include "runtime/frame.inline.hpp"41#include "runtime/safepointMechanism.hpp"42#include "runtime/sharedRuntime.hpp"43#include "runtime/stubRoutines.hpp"44#include "utilities/powerOfTwo.hpp"45#include "vmreg_x86.inline.hpp"464748// These masks are used to provide 128-bit aligned bitmasks to the XMM49// instructions, to allow sign-masking or sign-bit flipping. They allow50// fast versions of NegF/NegD and AbsF/AbsD.5152// Note: 'double' and 'long long' have 32-bits alignment on x86.53static jlong* double_quadword(jlong *adr, jlong lo, jlong hi) {54// Use the expression (adr)&(~0xF) to provide 128-bits aligned address55// of 128-bits operands for SSE instructions.56jlong *operand = (jlong*)(((intptr_t)adr) & ((intptr_t)(~0xF)));57// Store the value to a 128-bits operand.58operand[0] = lo;59operand[1] = hi;60return operand;61}6263// Buffer for 128-bits masks used by SSE instructions.64static jlong fp_signmask_pool[(4+1)*2]; // 4*128bits(data) + 128bits(alignment)6566// Static initialization during VM startup.67static jlong *float_signmask_pool = double_quadword(&fp_signmask_pool[1*2], CONST64(0x7FFFFFFF7FFFFFFF), CONST64(0x7FFFFFFF7FFFFFFF));68static jlong *double_signmask_pool = double_quadword(&fp_signmask_pool[2*2], CONST64(0x7FFFFFFFFFFFFFFF), CONST64(0x7FFFFFFFFFFFFFFF));69static jlong *float_signflip_pool = double_quadword(&fp_signmask_pool[3*2], (jlong)UCONST64(0x8000000080000000), (jlong)UCONST64(0x8000000080000000));70static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], (jlong)UCONST64(0x8000000000000000), (jlong)UCONST64(0x8000000000000000));717273NEEDS_CLEANUP // remove this definitions ?74const Register IC_Klass = rax; // where the IC klass is cached75const Register SYNC_header = rax; // synchronization header76const Register SHIFT_count = rcx; // where count for shift operations must be7778#define __ _masm->798081static void select_different_registers(Register preserve,82Register extra,83Register &tmp1,84Register &tmp2) {85if (tmp1 == preserve) {86assert_different_registers(tmp1, tmp2, extra);87tmp1 = extra;88} else if (tmp2 == preserve) {89assert_different_registers(tmp1, tmp2, extra);90tmp2 = extra;91}92assert_different_registers(preserve, tmp1, tmp2);93}94959697static void select_different_registers(Register preserve,98Register extra,99Register &tmp1,100Register &tmp2,101Register &tmp3) {102if (tmp1 == preserve) {103assert_different_registers(tmp1, tmp2, tmp3, extra);104tmp1 = extra;105} else if (tmp2 == preserve) {106assert_different_registers(tmp1, tmp2, tmp3, extra);107tmp2 = extra;108} else if (tmp3 == preserve) {109assert_different_registers(tmp1, tmp2, tmp3, extra);110tmp3 = extra;111}112assert_different_registers(preserve, tmp1, tmp2, tmp3);113}114115116117bool LIR_Assembler::is_small_constant(LIR_Opr opr) {118if (opr->is_constant()) {119LIR_Const* constant = opr->as_constant_ptr();120switch (constant->type()) {121case T_INT: {122return true;123}124125default:126return false;127}128}129return false;130}131132133LIR_Opr LIR_Assembler::receiverOpr() {134return FrameMap::receiver_opr;135}136137LIR_Opr LIR_Assembler::osrBufferPointer() {138return FrameMap::as_pointer_opr(receiverOpr()->as_register());139}140141//--------------fpu register translations-----------------------142143144address LIR_Assembler::float_constant(float f) {145address const_addr = __ float_constant(f);146if (const_addr == NULL) {147bailout("const section overflow");148return __ code()->consts()->start();149} else {150return const_addr;151}152}153154155address LIR_Assembler::double_constant(double d) {156address const_addr = __ double_constant(d);157if (const_addr == NULL) {158bailout("const section overflow");159return __ code()->consts()->start();160} else {161return const_addr;162}163}164165#ifndef _LP64166void LIR_Assembler::fpop() {167__ fpop();168}169170void LIR_Assembler::fxch(int i) {171__ fxch(i);172}173174void LIR_Assembler::fld(int i) {175__ fld_s(i);176}177178void LIR_Assembler::ffree(int i) {179__ ffree(i);180}181#endif // !_LP64182183void LIR_Assembler::breakpoint() {184__ int3();185}186187void LIR_Assembler::push(LIR_Opr opr) {188if (opr->is_single_cpu()) {189__ push_reg(opr->as_register());190} else if (opr->is_double_cpu()) {191NOT_LP64(__ push_reg(opr->as_register_hi()));192__ push_reg(opr->as_register_lo());193} else if (opr->is_stack()) {194__ push_addr(frame_map()->address_for_slot(opr->single_stack_ix()));195} else if (opr->is_constant()) {196LIR_Const* const_opr = opr->as_constant_ptr();197if (const_opr->type() == T_OBJECT) {198__ push_oop(const_opr->as_jobject());199} else if (const_opr->type() == T_INT) {200__ push_jint(const_opr->as_jint());201} else {202ShouldNotReachHere();203}204205} else {206ShouldNotReachHere();207}208}209210void LIR_Assembler::pop(LIR_Opr opr) {211if (opr->is_single_cpu()) {212__ pop_reg(opr->as_register());213} else {214ShouldNotReachHere();215}216}217218bool LIR_Assembler::is_literal_address(LIR_Address* addr) {219return addr->base()->is_illegal() && addr->index()->is_illegal();220}221222//-------------------------------------------223224Address LIR_Assembler::as_Address(LIR_Address* addr) {225return as_Address(addr, rscratch1);226}227228Address LIR_Assembler::as_Address(LIR_Address* addr, Register tmp) {229if (addr->base()->is_illegal()) {230assert(addr->index()->is_illegal(), "must be illegal too");231AddressLiteral laddr((address)addr->disp(), relocInfo::none);232if (! __ reachable(laddr)) {233__ movptr(tmp, laddr.addr());234Address res(tmp, 0);235return res;236} else {237return __ as_Address(laddr);238}239}240241Register base = addr->base()->as_pointer_register();242243if (addr->index()->is_illegal()) {244return Address( base, addr->disp());245} else if (addr->index()->is_cpu_register()) {246Register index = addr->index()->as_pointer_register();247return Address(base, index, (Address::ScaleFactor) addr->scale(), addr->disp());248} else if (addr->index()->is_constant()) {249intptr_t addr_offset = (addr->index()->as_constant_ptr()->as_jint() << addr->scale()) + addr->disp();250assert(Assembler::is_simm32(addr_offset), "must be");251252return Address(base, addr_offset);253} else {254Unimplemented();255return Address();256}257}258259260Address LIR_Assembler::as_Address_hi(LIR_Address* addr) {261Address base = as_Address(addr);262return Address(base._base, base._index, base._scale, base._disp + BytesPerWord);263}264265266Address LIR_Assembler::as_Address_lo(LIR_Address* addr) {267return as_Address(addr);268}269270271void LIR_Assembler::osr_entry() {272offsets()->set_value(CodeOffsets::OSR_Entry, code_offset());273BlockBegin* osr_entry = compilation()->hir()->osr_entry();274ValueStack* entry_state = osr_entry->state();275int number_of_locks = entry_state->locks_size();276277// we jump here if osr happens with the interpreter278// state set up to continue at the beginning of the279// loop that triggered osr - in particular, we have280// the following registers setup:281//282// rcx: osr buffer283//284285// build frame286ciMethod* m = compilation()->method();287__ build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes());288289// OSR buffer is290//291// locals[nlocals-1..0]292// monitors[0..number_of_locks]293//294// locals is a direct copy of the interpreter frame so in the osr buffer295// so first slot in the local array is the last local from the interpreter296// and last slot is local[0] (receiver) from the interpreter297//298// Similarly with locks. The first lock slot in the osr buffer is the nth lock299// from the interpreter frame, the nth lock slot in the osr buffer is 0th lock300// in the interpreter frame (the method lock if a sync method)301302// Initialize monitors in the compiled activation.303// rcx: pointer to osr buffer304//305// All other registers are dead at this point and the locals will be306// copied into place by code emitted in the IR.307308Register OSR_buf = osrBufferPointer()->as_pointer_register();309{ assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");310int monitor_offset = BytesPerWord * method()->max_locals() +311(BasicObjectLock::size() * BytesPerWord) * (number_of_locks - 1);312// SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in313// the OSR buffer using 2 word entries: first the lock and then314// the oop.315for (int i = 0; i < number_of_locks; i++) {316int slot_offset = monitor_offset - ((i * 2) * BytesPerWord);317#ifdef ASSERT318// verify the interpreter's monitor has a non-null object319{320Label L;321__ cmpptr(Address(OSR_buf, slot_offset + 1*BytesPerWord), (int32_t)NULL_WORD);322__ jcc(Assembler::notZero, L);323__ stop("locked object is NULL");324__ bind(L);325}326#endif327__ movptr(rbx, Address(OSR_buf, slot_offset + 0));328__ movptr(frame_map()->address_for_monitor_lock(i), rbx);329__ movptr(rbx, Address(OSR_buf, slot_offset + 1*BytesPerWord));330__ movptr(frame_map()->address_for_monitor_object(i), rbx);331}332}333}334335336// inline cache check; done before the frame is built.337int LIR_Assembler::check_icache() {338Register receiver = FrameMap::receiver_opr->as_register();339Register ic_klass = IC_Klass;340const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);341const bool do_post_padding = VerifyOops || UseCompressedClassPointers;342if (!do_post_padding) {343// insert some nops so that the verified entry point is aligned on CodeEntryAlignment344__ align(CodeEntryAlignment, __ offset() + ic_cmp_size);345}346int offset = __ offset();347__ inline_cache_check(receiver, IC_Klass);348assert(__ offset() % CodeEntryAlignment == 0 || do_post_padding, "alignment must be correct");349if (do_post_padding) {350// force alignment after the cache check.351// It's been verified to be aligned if !VerifyOops352__ align(CodeEntryAlignment);353}354return offset;355}356357void LIR_Assembler::clinit_barrier(ciMethod* method) {358assert(VM_Version::supports_fast_class_init_checks(), "sanity");359assert(!method->holder()->is_not_initialized(), "initialization should have been started");360361Label L_skip_barrier;362Register klass = rscratch1;363Register thread = LP64_ONLY( r15_thread ) NOT_LP64( noreg );364assert(thread != noreg, "x86_32 not implemented");365366__ mov_metadata(klass, method->holder()->constant_encoding());367__ clinit_barrier(klass, thread, &L_skip_barrier /*L_fast_path*/);368369__ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));370371__ bind(L_skip_barrier);372}373374void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo* info) {375jobject o = NULL;376PatchingStub* patch = new PatchingStub(_masm, patching_id(info));377__ movoop(reg, o);378patching_epilog(patch, lir_patch_normal, reg, info);379}380381void LIR_Assembler::klass2reg_with_patching(Register reg, CodeEmitInfo* info) {382Metadata* o = NULL;383PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_klass_id);384__ mov_metadata(reg, o);385patching_epilog(patch, lir_patch_normal, reg, info);386}387388// This specifies the rsp decrement needed to build the frame389int LIR_Assembler::initial_frame_size_in_bytes() const {390// if rounding, must let FrameMap know!391392// The frame_map records size in slots (32bit word)393394// subtract two words to account for return address and link395return (frame_map()->framesize() - (2*VMRegImpl::slots_per_word)) * VMRegImpl::stack_slot_size;396}397398399int LIR_Assembler::emit_exception_handler() {400// if the last instruction is a call (typically to do a throw which401// is coming at the end after block reordering) the return address402// must still point into the code area in order to avoid assertion403// failures when searching for the corresponding bci => add a nop404// (was bug 5/14/1999 - gri)405__ nop();406407// generate code for exception handler408address handler_base = __ start_a_stub(exception_handler_size());409if (handler_base == NULL) {410// not enough space left for the handler411bailout("exception handler overflow");412return -1;413}414415int offset = code_offset();416417// the exception oop and pc are in rax, and rdx418// no other registers need to be preserved, so invalidate them419__ invalidate_registers(false, true, true, false, true, true);420421// check that there is really an exception422__ verify_not_null_oop(rax);423424// search an exception handler (rax: exception oop, rdx: throwing pc)425__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id)));426__ should_not_reach_here();427guarantee(code_offset() - offset <= exception_handler_size(), "overflow");428__ end_a_stub();429430return offset;431}432433434// Emit the code to remove the frame from the stack in the exception435// unwind path.436int LIR_Assembler::emit_unwind_handler() {437#ifndef PRODUCT438if (CommentedAssembly) {439_masm->block_comment("Unwind handler");440}441#endif442443int offset = code_offset();444445// Fetch the exception from TLS and clear out exception related thread state446Register thread = NOT_LP64(rsi) LP64_ONLY(r15_thread);447NOT_LP64(__ get_thread(rsi));448__ movptr(rax, Address(thread, JavaThread::exception_oop_offset()));449__ movptr(Address(thread, JavaThread::exception_oop_offset()), (intptr_t)NULL_WORD);450__ movptr(Address(thread, JavaThread::exception_pc_offset()), (intptr_t)NULL_WORD);451452__ bind(_unwind_handler_entry);453__ verify_not_null_oop(rax);454if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {455__ mov(rbx, rax); // Preserve the exception (rbx is always callee-saved)456}457458// Preform needed unlocking459MonitorExitStub* stub = NULL;460if (method()->is_synchronized()) {461monitor_address(0, FrameMap::rax_opr);462stub = new MonitorExitStub(FrameMap::rax_opr, true, 0);463__ unlock_object(rdi, rsi, rax, *stub->entry());464__ bind(*stub->continuation());465}466467if (compilation()->env()->dtrace_method_probes()) {468#ifdef _LP64469__ mov(rdi, r15_thread);470__ mov_metadata(rsi, method()->constant_encoding());471#else472__ get_thread(rax);473__ movptr(Address(rsp, 0), rax);474__ mov_metadata(Address(rsp, sizeof(void*)), method()->constant_encoding());475#endif476__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit)));477}478479if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {480__ mov(rax, rbx); // Restore the exception481}482483// remove the activation and dispatch to the unwind handler484__ remove_frame(initial_frame_size_in_bytes());485__ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id)));486487// Emit the slow path assembly488if (stub != NULL) {489stub->emit_code(this);490}491492return offset;493}494495496int LIR_Assembler::emit_deopt_handler() {497// if the last instruction is a call (typically to do a throw which498// is coming at the end after block reordering) the return address499// must still point into the code area in order to avoid assertion500// failures when searching for the corresponding bci => add a nop501// (was bug 5/14/1999 - gri)502__ nop();503504// generate code for exception handler505address handler_base = __ start_a_stub(deopt_handler_size());506if (handler_base == NULL) {507// not enough space left for the handler508bailout("deopt handler overflow");509return -1;510}511512int offset = code_offset();513InternalAddress here(__ pc());514515__ pushptr(here.addr());516__ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));517guarantee(code_offset() - offset <= deopt_handler_size(), "overflow");518__ end_a_stub();519520return offset;521}522523void LIR_Assembler::return_op(LIR_Opr result, C1SafepointPollStub* code_stub) {524assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == rax, "word returns are in rax,");525if (!result->is_illegal() && result->is_float_kind() && !result->is_xmm_register()) {526assert(result->fpu() == 0, "result must already be on TOS");527}528529// Pop the stack before the safepoint code530__ remove_frame(initial_frame_size_in_bytes());531532if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) {533__ reserved_stack_check();534}535536// Note: we do not need to round double result; float result has the right precision537// the poll sets the condition code, but no data registers538539#ifdef _LP64540const Register thread = r15_thread;541#else542const Register thread = rbx;543__ get_thread(thread);544#endif545code_stub->set_safepoint_offset(__ offset());546__ relocate(relocInfo::poll_return_type);547__ safepoint_poll(*code_stub->entry(), thread, true /* at_return */, true /* in_nmethod */);548__ ret(0);549}550551552int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {553guarantee(info != NULL, "Shouldn't be NULL");554int offset = __ offset();555#ifdef _LP64556const Register poll_addr = rscratch1;557__ movptr(poll_addr, Address(r15_thread, JavaThread::polling_page_offset()));558#else559assert(tmp->is_cpu_register(), "needed");560const Register poll_addr = tmp->as_register();561__ get_thread(poll_addr);562__ movptr(poll_addr, Address(poll_addr, in_bytes(JavaThread::polling_page_offset())));563#endif564add_debug_info_for_branch(info);565__ relocate(relocInfo::poll_type);566address pre_pc = __ pc();567__ testl(rax, Address(poll_addr, 0));568address post_pc = __ pc();569guarantee(pointer_delta(post_pc, pre_pc, 1) == 2 LP64_ONLY(+1), "must be exact length");570return offset;571}572573574void LIR_Assembler::move_regs(Register from_reg, Register to_reg) {575if (from_reg != to_reg) __ mov(to_reg, from_reg);576}577578void LIR_Assembler::swap_reg(Register a, Register b) {579__ xchgptr(a, b);580}581582583void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {584assert(src->is_constant(), "should not call otherwise");585assert(dest->is_register(), "should not call otherwise");586LIR_Const* c = src->as_constant_ptr();587588switch (c->type()) {589case T_INT: {590assert(patch_code == lir_patch_none, "no patching handled here");591__ movl(dest->as_register(), c->as_jint());592break;593}594595case T_ADDRESS: {596assert(patch_code == lir_patch_none, "no patching handled here");597__ movptr(dest->as_register(), c->as_jint());598break;599}600601case T_LONG: {602assert(patch_code == lir_patch_none, "no patching handled here");603#ifdef _LP64604__ movptr(dest->as_register_lo(), (intptr_t)c->as_jlong());605#else606__ movptr(dest->as_register_lo(), c->as_jint_lo());607__ movptr(dest->as_register_hi(), c->as_jint_hi());608#endif // _LP64609break;610}611612case T_OBJECT: {613if (patch_code != lir_patch_none) {614jobject2reg_with_patching(dest->as_register(), info);615} else {616__ movoop(dest->as_register(), c->as_jobject());617}618break;619}620621case T_METADATA: {622if (patch_code != lir_patch_none) {623klass2reg_with_patching(dest->as_register(), info);624} else {625__ mov_metadata(dest->as_register(), c->as_metadata());626}627break;628}629630case T_FLOAT: {631if (dest->is_single_xmm()) {632if (LP64_ONLY(UseAVX <= 2 &&) c->is_zero_float()) {633__ xorps(dest->as_xmm_float_reg(), dest->as_xmm_float_reg());634} else {635__ movflt(dest->as_xmm_float_reg(),636InternalAddress(float_constant(c->as_jfloat())));637}638} else {639#ifndef _LP64640assert(dest->is_single_fpu(), "must be");641assert(dest->fpu_regnr() == 0, "dest must be TOS");642if (c->is_zero_float()) {643__ fldz();644} else if (c->is_one_float()) {645__ fld1();646} else {647__ fld_s (InternalAddress(float_constant(c->as_jfloat())));648}649#else650ShouldNotReachHere();651#endif // !_LP64652}653break;654}655656case T_DOUBLE: {657if (dest->is_double_xmm()) {658if (LP64_ONLY(UseAVX <= 2 &&) c->is_zero_double()) {659__ xorpd(dest->as_xmm_double_reg(), dest->as_xmm_double_reg());660} else {661__ movdbl(dest->as_xmm_double_reg(),662InternalAddress(double_constant(c->as_jdouble())));663}664} else {665#ifndef _LP64666assert(dest->is_double_fpu(), "must be");667assert(dest->fpu_regnrLo() == 0, "dest must be TOS");668if (c->is_zero_double()) {669__ fldz();670} else if (c->is_one_double()) {671__ fld1();672} else {673__ fld_d (InternalAddress(double_constant(c->as_jdouble())));674}675#else676ShouldNotReachHere();677#endif // !_LP64678}679break;680}681682default:683ShouldNotReachHere();684}685}686687void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) {688assert(src->is_constant(), "should not call otherwise");689assert(dest->is_stack(), "should not call otherwise");690LIR_Const* c = src->as_constant_ptr();691692switch (c->type()) {693case T_INT: // fall through694case T_FLOAT:695__ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());696break;697698case T_ADDRESS:699__ movptr(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());700break;701702case T_OBJECT:703__ movoop(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jobject());704break;705706case T_LONG: // fall through707case T_DOUBLE:708#ifdef _LP64709__ movptr(frame_map()->address_for_slot(dest->double_stack_ix(),710lo_word_offset_in_bytes), (intptr_t)c->as_jlong_bits());711#else712__ movptr(frame_map()->address_for_slot(dest->double_stack_ix(),713lo_word_offset_in_bytes), c->as_jint_lo_bits());714__ movptr(frame_map()->address_for_slot(dest->double_stack_ix(),715hi_word_offset_in_bytes), c->as_jint_hi_bits());716#endif // _LP64717break;718719default:720ShouldNotReachHere();721}722}723724void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) {725assert(src->is_constant(), "should not call otherwise");726assert(dest->is_address(), "should not call otherwise");727LIR_Const* c = src->as_constant_ptr();728LIR_Address* addr = dest->as_address_ptr();729730int null_check_here = code_offset();731switch (type) {732case T_INT: // fall through733case T_FLOAT:734__ movl(as_Address(addr), c->as_jint_bits());735break;736737case T_ADDRESS:738__ movptr(as_Address(addr), c->as_jint_bits());739break;740741case T_OBJECT: // fall through742case T_ARRAY:743if (c->as_jobject() == NULL) {744if (UseCompressedOops && !wide) {745__ movl(as_Address(addr), (int32_t)NULL_WORD);746} else {747#ifdef _LP64748__ xorptr(rscratch1, rscratch1);749null_check_here = code_offset();750__ movptr(as_Address(addr), rscratch1);751#else752__ movptr(as_Address(addr), NULL_WORD);753#endif754}755} else {756if (is_literal_address(addr)) {757ShouldNotReachHere();758__ movoop(as_Address(addr, noreg), c->as_jobject());759} else {760#ifdef _LP64761__ movoop(rscratch1, c->as_jobject());762if (UseCompressedOops && !wide) {763__ encode_heap_oop(rscratch1);764null_check_here = code_offset();765__ movl(as_Address_lo(addr), rscratch1);766} else {767null_check_here = code_offset();768__ movptr(as_Address_lo(addr), rscratch1);769}770#else771__ movoop(as_Address(addr), c->as_jobject());772#endif773}774}775break;776777case T_LONG: // fall through778case T_DOUBLE:779#ifdef _LP64780if (is_literal_address(addr)) {781ShouldNotReachHere();782__ movptr(as_Address(addr, r15_thread), (intptr_t)c->as_jlong_bits());783} else {784__ movptr(r10, (intptr_t)c->as_jlong_bits());785null_check_here = code_offset();786__ movptr(as_Address_lo(addr), r10);787}788#else789// Always reachable in 32bit so this doesn't produce useless move literal790__ movptr(as_Address_hi(addr), c->as_jint_hi_bits());791__ movptr(as_Address_lo(addr), c->as_jint_lo_bits());792#endif // _LP64793break;794795case T_BOOLEAN: // fall through796case T_BYTE:797__ movb(as_Address(addr), c->as_jint() & 0xFF);798break;799800case T_CHAR: // fall through801case T_SHORT:802__ movw(as_Address(addr), c->as_jint() & 0xFFFF);803break;804805default:806ShouldNotReachHere();807};808809if (info != NULL) {810add_debug_info_for_null_check(null_check_here, info);811}812}813814815void LIR_Assembler::reg2reg(LIR_Opr src, LIR_Opr dest) {816assert(src->is_register(), "should not call otherwise");817assert(dest->is_register(), "should not call otherwise");818819// move between cpu-registers820if (dest->is_single_cpu()) {821#ifdef _LP64822if (src->type() == T_LONG) {823// Can do LONG -> OBJECT824move_regs(src->as_register_lo(), dest->as_register());825return;826}827#endif828assert(src->is_single_cpu(), "must match");829if (src->type() == T_OBJECT) {830__ verify_oop(src->as_register());831}832move_regs(src->as_register(), dest->as_register());833834} else if (dest->is_double_cpu()) {835#ifdef _LP64836if (is_reference_type(src->type())) {837// Surprising to me but we can see move of a long to t_object838__ verify_oop(src->as_register());839move_regs(src->as_register(), dest->as_register_lo());840return;841}842#endif843assert(src->is_double_cpu(), "must match");844Register f_lo = src->as_register_lo();845Register f_hi = src->as_register_hi();846Register t_lo = dest->as_register_lo();847Register t_hi = dest->as_register_hi();848#ifdef _LP64849assert(f_hi == f_lo, "must be same");850assert(t_hi == t_lo, "must be same");851move_regs(f_lo, t_lo);852#else853assert(f_lo != f_hi && t_lo != t_hi, "invalid register allocation");854855856if (f_lo == t_hi && f_hi == t_lo) {857swap_reg(f_lo, f_hi);858} else if (f_hi == t_lo) {859assert(f_lo != t_hi, "overwriting register");860move_regs(f_hi, t_hi);861move_regs(f_lo, t_lo);862} else {863assert(f_hi != t_lo, "overwriting register");864move_regs(f_lo, t_lo);865move_regs(f_hi, t_hi);866}867#endif // LP64868869#ifndef _LP64870// special moves from fpu-register to xmm-register871// necessary for method results872} else if (src->is_single_xmm() && !dest->is_single_xmm()) {873__ movflt(Address(rsp, 0), src->as_xmm_float_reg());874__ fld_s(Address(rsp, 0));875} else if (src->is_double_xmm() && !dest->is_double_xmm()) {876__ movdbl(Address(rsp, 0), src->as_xmm_double_reg());877__ fld_d(Address(rsp, 0));878} else if (dest->is_single_xmm() && !src->is_single_xmm()) {879__ fstp_s(Address(rsp, 0));880__ movflt(dest->as_xmm_float_reg(), Address(rsp, 0));881} else if (dest->is_double_xmm() && !src->is_double_xmm()) {882__ fstp_d(Address(rsp, 0));883__ movdbl(dest->as_xmm_double_reg(), Address(rsp, 0));884#endif // !_LP64885886// move between xmm-registers887} else if (dest->is_single_xmm()) {888assert(src->is_single_xmm(), "must match");889__ movflt(dest->as_xmm_float_reg(), src->as_xmm_float_reg());890} else if (dest->is_double_xmm()) {891assert(src->is_double_xmm(), "must match");892__ movdbl(dest->as_xmm_double_reg(), src->as_xmm_double_reg());893894#ifndef _LP64895// move between fpu-registers (no instruction necessary because of fpu-stack)896} else if (dest->is_single_fpu() || dest->is_double_fpu()) {897assert(src->is_single_fpu() || src->is_double_fpu(), "must match");898assert(src->fpu() == dest->fpu(), "currently should be nothing to do");899#endif // !_LP64900901} else {902ShouldNotReachHere();903}904}905906void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool pop_fpu_stack) {907assert(src->is_register(), "should not call otherwise");908assert(dest->is_stack(), "should not call otherwise");909910if (src->is_single_cpu()) {911Address dst = frame_map()->address_for_slot(dest->single_stack_ix());912if (is_reference_type(type)) {913__ verify_oop(src->as_register());914__ movptr (dst, src->as_register());915} else if (type == T_METADATA || type == T_ADDRESS) {916__ movptr (dst, src->as_register());917} else {918__ movl (dst, src->as_register());919}920921} else if (src->is_double_cpu()) {922Address dstLO = frame_map()->address_for_slot(dest->double_stack_ix(), lo_word_offset_in_bytes);923Address dstHI = frame_map()->address_for_slot(dest->double_stack_ix(), hi_word_offset_in_bytes);924__ movptr (dstLO, src->as_register_lo());925NOT_LP64(__ movptr (dstHI, src->as_register_hi()));926927} else if (src->is_single_xmm()) {928Address dst_addr = frame_map()->address_for_slot(dest->single_stack_ix());929__ movflt(dst_addr, src->as_xmm_float_reg());930931} else if (src->is_double_xmm()) {932Address dst_addr = frame_map()->address_for_slot(dest->double_stack_ix());933__ movdbl(dst_addr, src->as_xmm_double_reg());934935#ifndef _LP64936} else if (src->is_single_fpu()) {937assert(src->fpu_regnr() == 0, "argument must be on TOS");938Address dst_addr = frame_map()->address_for_slot(dest->single_stack_ix());939if (pop_fpu_stack) __ fstp_s (dst_addr);940else __ fst_s (dst_addr);941942} else if (src->is_double_fpu()) {943assert(src->fpu_regnrLo() == 0, "argument must be on TOS");944Address dst_addr = frame_map()->address_for_slot(dest->double_stack_ix());945if (pop_fpu_stack) __ fstp_d (dst_addr);946else __ fst_d (dst_addr);947#endif // !_LP64948949} else {950ShouldNotReachHere();951}952}953954955void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool wide, bool /* unaligned */) {956LIR_Address* to_addr = dest->as_address_ptr();957PatchingStub* patch = NULL;958Register compressed_src = rscratch1;959960if (is_reference_type(type)) {961__ verify_oop(src->as_register());962#ifdef _LP64963if (UseCompressedOops && !wide) {964__ movptr(compressed_src, src->as_register());965__ encode_heap_oop(compressed_src);966if (patch_code != lir_patch_none) {967info->oop_map()->set_narrowoop(compressed_src->as_VMReg());968}969}970#endif971}972973if (patch_code != lir_patch_none) {974patch = new PatchingStub(_masm, PatchingStub::access_field_id);975Address toa = as_Address(to_addr);976assert(toa.disp() != 0, "must have");977}978979int null_check_here = code_offset();980switch (type) {981case T_FLOAT: {982#ifdef _LP64983assert(src->is_single_xmm(), "not a float");984__ movflt(as_Address(to_addr), src->as_xmm_float_reg());985#else986if (src->is_single_xmm()) {987__ movflt(as_Address(to_addr), src->as_xmm_float_reg());988} else {989assert(src->is_single_fpu(), "must be");990assert(src->fpu_regnr() == 0, "argument must be on TOS");991if (pop_fpu_stack) __ fstp_s(as_Address(to_addr));992else __ fst_s (as_Address(to_addr));993}994#endif // _LP64995break;996}997998case T_DOUBLE: {999#ifdef _LP641000assert(src->is_double_xmm(), "not a double");1001__ movdbl(as_Address(to_addr), src->as_xmm_double_reg());1002#else1003if (src->is_double_xmm()) {1004__ movdbl(as_Address(to_addr), src->as_xmm_double_reg());1005} else {1006assert(src->is_double_fpu(), "must be");1007assert(src->fpu_regnrLo() == 0, "argument must be on TOS");1008if (pop_fpu_stack) __ fstp_d(as_Address(to_addr));1009else __ fst_d (as_Address(to_addr));1010}1011#endif // _LP641012break;1013}10141015case T_ARRAY: // fall through1016case T_OBJECT: // fall through1017if (UseCompressedOops && !wide) {1018__ movl(as_Address(to_addr), compressed_src);1019} else {1020__ movptr(as_Address(to_addr), src->as_register());1021}1022break;1023case T_METADATA:1024// We get here to store a method pointer to the stack to pass to1025// a dtrace runtime call. This can't work on 64 bit with1026// compressed klass ptrs: T_METADATA can be a compressed klass1027// ptr or a 64 bit method pointer.1028LP64_ONLY(ShouldNotReachHere());1029__ movptr(as_Address(to_addr), src->as_register());1030break;1031case T_ADDRESS:1032__ movptr(as_Address(to_addr), src->as_register());1033break;1034case T_INT:1035__ movl(as_Address(to_addr), src->as_register());1036break;10371038case T_LONG: {1039Register from_lo = src->as_register_lo();1040Register from_hi = src->as_register_hi();1041#ifdef _LP641042__ movptr(as_Address_lo(to_addr), from_lo);1043#else1044Register base = to_addr->base()->as_register();1045Register index = noreg;1046if (to_addr->index()->is_register()) {1047index = to_addr->index()->as_register();1048}1049if (base == from_lo || index == from_lo) {1050assert(base != from_hi, "can't be");1051assert(index == noreg || (index != base && index != from_hi), "can't handle this");1052__ movl(as_Address_hi(to_addr), from_hi);1053if (patch != NULL) {1054patching_epilog(patch, lir_patch_high, base, info);1055patch = new PatchingStub(_masm, PatchingStub::access_field_id);1056patch_code = lir_patch_low;1057}1058__ movl(as_Address_lo(to_addr), from_lo);1059} else {1060assert(index == noreg || (index != base && index != from_lo), "can't handle this");1061__ movl(as_Address_lo(to_addr), from_lo);1062if (patch != NULL) {1063patching_epilog(patch, lir_patch_low, base, info);1064patch = new PatchingStub(_masm, PatchingStub::access_field_id);1065patch_code = lir_patch_high;1066}1067__ movl(as_Address_hi(to_addr), from_hi);1068}1069#endif // _LP641070break;1071}10721073case T_BYTE: // fall through1074case T_BOOLEAN: {1075Register src_reg = src->as_register();1076Address dst_addr = as_Address(to_addr);1077assert(VM_Version::is_P6() || src_reg->has_byte_register(), "must use byte registers if not P6");1078__ movb(dst_addr, src_reg);1079break;1080}10811082case T_CHAR: // fall through1083case T_SHORT:1084__ movw(as_Address(to_addr), src->as_register());1085break;10861087default:1088ShouldNotReachHere();1089}1090if (info != NULL) {1091add_debug_info_for_null_check(null_check_here, info);1092}10931094if (patch_code != lir_patch_none) {1095patching_epilog(patch, patch_code, to_addr->base()->as_register(), info);1096}1097}109810991100void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) {1101assert(src->is_stack(), "should not call otherwise");1102assert(dest->is_register(), "should not call otherwise");11031104if (dest->is_single_cpu()) {1105if (is_reference_type(type)) {1106__ movptr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()));1107__ verify_oop(dest->as_register());1108} else if (type == T_METADATA || type == T_ADDRESS) {1109__ movptr(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()));1110} else {1111__ movl(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()));1112}11131114} else if (dest->is_double_cpu()) {1115Address src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix(), lo_word_offset_in_bytes);1116Address src_addr_HI = frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes);1117__ movptr(dest->as_register_lo(), src_addr_LO);1118NOT_LP64(__ movptr(dest->as_register_hi(), src_addr_HI));11191120} else if (dest->is_single_xmm()) {1121Address src_addr = frame_map()->address_for_slot(src->single_stack_ix());1122__ movflt(dest->as_xmm_float_reg(), src_addr);11231124} else if (dest->is_double_xmm()) {1125Address src_addr = frame_map()->address_for_slot(src->double_stack_ix());1126__ movdbl(dest->as_xmm_double_reg(), src_addr);11271128#ifndef _LP641129} else if (dest->is_single_fpu()) {1130assert(dest->fpu_regnr() == 0, "dest must be TOS");1131Address src_addr = frame_map()->address_for_slot(src->single_stack_ix());1132__ fld_s(src_addr);11331134} else if (dest->is_double_fpu()) {1135assert(dest->fpu_regnrLo() == 0, "dest must be TOS");1136Address src_addr = frame_map()->address_for_slot(src->double_stack_ix());1137__ fld_d(src_addr);1138#endif // _LP6411391140} else {1141ShouldNotReachHere();1142}1143}114411451146void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) {1147if (src->is_single_stack()) {1148if (is_reference_type(type)) {1149__ pushptr(frame_map()->address_for_slot(src ->single_stack_ix()));1150__ popptr (frame_map()->address_for_slot(dest->single_stack_ix()));1151} else {1152#ifndef _LP641153__ pushl(frame_map()->address_for_slot(src ->single_stack_ix()));1154__ popl (frame_map()->address_for_slot(dest->single_stack_ix()));1155#else1156//no pushl on 64bits1157__ movl(rscratch1, frame_map()->address_for_slot(src ->single_stack_ix()));1158__ movl(frame_map()->address_for_slot(dest->single_stack_ix()), rscratch1);1159#endif1160}11611162} else if (src->is_double_stack()) {1163#ifdef _LP641164__ pushptr(frame_map()->address_for_slot(src ->double_stack_ix()));1165__ popptr (frame_map()->address_for_slot(dest->double_stack_ix()));1166#else1167__ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 0));1168// push and pop the part at src + wordSize, adding wordSize for the previous push1169__ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 2 * wordSize));1170__ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 2 * wordSize));1171__ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 0));1172#endif // _LP6411731174} else {1175ShouldNotReachHere();1176}1177}117811791180void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool /* unaligned */) {1181assert(src->is_address(), "should not call otherwise");1182assert(dest->is_register(), "should not call otherwise");11831184LIR_Address* addr = src->as_address_ptr();1185Address from_addr = as_Address(addr);1186Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);11871188if (addr->base()->type() == T_OBJECT) {1189__ verify_oop(addr->base()->as_pointer_register());1190}11911192switch (type) {1193case T_BOOLEAN: // fall through1194case T_BYTE: // fall through1195case T_CHAR: // fall through1196case T_SHORT:1197if (!VM_Version::is_P6() && !from_addr.uses(dest->as_register())) {1198// on pre P6 processors we may get partial register stalls1199// so blow away the value of to_rinfo before loading a1200// partial word into it. Do it here so that it precedes1201// the potential patch point below.1202__ xorptr(dest->as_register(), dest->as_register());1203}1204break;1205default:1206break;1207}12081209PatchingStub* patch = NULL;1210if (patch_code != lir_patch_none) {1211patch = new PatchingStub(_masm, PatchingStub::access_field_id);1212assert(from_addr.disp() != 0, "must have");1213}1214if (info != NULL) {1215add_debug_info_for_null_check_here(info);1216}12171218switch (type) {1219case T_FLOAT: {1220if (dest->is_single_xmm()) {1221__ movflt(dest->as_xmm_float_reg(), from_addr);1222} else {1223#ifndef _LP641224assert(dest->is_single_fpu(), "must be");1225assert(dest->fpu_regnr() == 0, "dest must be TOS");1226__ fld_s(from_addr);1227#else1228ShouldNotReachHere();1229#endif // !LP641230}1231break;1232}12331234case T_DOUBLE: {1235if (dest->is_double_xmm()) {1236__ movdbl(dest->as_xmm_double_reg(), from_addr);1237} else {1238#ifndef _LP641239assert(dest->is_double_fpu(), "must be");1240assert(dest->fpu_regnrLo() == 0, "dest must be TOS");1241__ fld_d(from_addr);1242#else1243ShouldNotReachHere();1244#endif // !LP641245}1246break;1247}12481249case T_OBJECT: // fall through1250case T_ARRAY: // fall through1251if (UseCompressedOops && !wide) {1252__ movl(dest->as_register(), from_addr);1253} else {1254__ movptr(dest->as_register(), from_addr);1255}1256break;12571258case T_ADDRESS:1259if (UseCompressedClassPointers && addr->disp() == oopDesc::klass_offset_in_bytes()) {1260__ movl(dest->as_register(), from_addr);1261} else {1262__ movptr(dest->as_register(), from_addr);1263}1264break;1265case T_INT:1266__ movl(dest->as_register(), from_addr);1267break;12681269case T_LONG: {1270Register to_lo = dest->as_register_lo();1271Register to_hi = dest->as_register_hi();1272#ifdef _LP641273__ movptr(to_lo, as_Address_lo(addr));1274#else1275Register base = addr->base()->as_register();1276Register index = noreg;1277if (addr->index()->is_register()) {1278index = addr->index()->as_register();1279}1280if ((base == to_lo && index == to_hi) ||1281(base == to_hi && index == to_lo)) {1282// addresses with 2 registers are only formed as a result of1283// array access so this code will never have to deal with1284// patches or null checks.1285assert(info == NULL && patch == NULL, "must be");1286__ lea(to_hi, as_Address(addr));1287__ movl(to_lo, Address(to_hi, 0));1288__ movl(to_hi, Address(to_hi, BytesPerWord));1289} else if (base == to_lo || index == to_lo) {1290assert(base != to_hi, "can't be");1291assert(index == noreg || (index != base && index != to_hi), "can't handle this");1292__ movl(to_hi, as_Address_hi(addr));1293if (patch != NULL) {1294patching_epilog(patch, lir_patch_high, base, info);1295patch = new PatchingStub(_masm, PatchingStub::access_field_id);1296patch_code = lir_patch_low;1297}1298__ movl(to_lo, as_Address_lo(addr));1299} else {1300assert(index == noreg || (index != base && index != to_lo), "can't handle this");1301__ movl(to_lo, as_Address_lo(addr));1302if (patch != NULL) {1303patching_epilog(patch, lir_patch_low, base, info);1304patch = new PatchingStub(_masm, PatchingStub::access_field_id);1305patch_code = lir_patch_high;1306}1307__ movl(to_hi, as_Address_hi(addr));1308}1309#endif // _LP641310break;1311}13121313case T_BOOLEAN: // fall through1314case T_BYTE: {1315Register dest_reg = dest->as_register();1316assert(VM_Version::is_P6() || dest_reg->has_byte_register(), "must use byte registers if not P6");1317if (VM_Version::is_P6() || from_addr.uses(dest_reg)) {1318__ movsbl(dest_reg, from_addr);1319} else {1320__ movb(dest_reg, from_addr);1321__ shll(dest_reg, 24);1322__ sarl(dest_reg, 24);1323}1324break;1325}13261327case T_CHAR: {1328Register dest_reg = dest->as_register();1329assert(VM_Version::is_P6() || dest_reg->has_byte_register(), "must use byte registers if not P6");1330if (VM_Version::is_P6() || from_addr.uses(dest_reg)) {1331__ movzwl(dest_reg, from_addr);1332} else {1333__ movw(dest_reg, from_addr);1334}1335break;1336}13371338case T_SHORT: {1339Register dest_reg = dest->as_register();1340if (VM_Version::is_P6() || from_addr.uses(dest_reg)) {1341__ movswl(dest_reg, from_addr);1342} else {1343__ movw(dest_reg, from_addr);1344__ shll(dest_reg, 16);1345__ sarl(dest_reg, 16);1346}1347break;1348}13491350default:1351ShouldNotReachHere();1352}13531354if (patch != NULL) {1355patching_epilog(patch, patch_code, addr->base()->as_register(), info);1356}13571358if (is_reference_type(type)) {1359#ifdef _LP641360if (UseCompressedOops && !wide) {1361__ decode_heap_oop(dest->as_register());1362}1363#endif13641365// Load barrier has not yet been applied, so ZGC can't verify the oop here1366if (!UseZGC) {1367__ verify_oop(dest->as_register());1368}1369} else if (type == T_ADDRESS && addr->disp() == oopDesc::klass_offset_in_bytes()) {1370#ifdef _LP641371if (UseCompressedClassPointers) {1372__ decode_klass_not_null(dest->as_register(), tmp_load_klass);1373}1374#endif1375}1376}137713781379NEEDS_CLEANUP; // This could be static?1380Address::ScaleFactor LIR_Assembler::array_element_size(BasicType type) const {1381int elem_size = type2aelembytes(type);1382switch (elem_size) {1383case 1: return Address::times_1;1384case 2: return Address::times_2;1385case 4: return Address::times_4;1386case 8: return Address::times_8;1387}1388ShouldNotReachHere();1389return Address::no_scale;1390}139113921393void LIR_Assembler::emit_op3(LIR_Op3* op) {1394switch (op->code()) {1395case lir_idiv:1396case lir_irem:1397arithmetic_idiv(op->code(),1398op->in_opr1(),1399op->in_opr2(),1400op->in_opr3(),1401op->result_opr(),1402op->info());1403break;1404case lir_fmad:1405__ fmad(op->result_opr()->as_xmm_double_reg(),1406op->in_opr1()->as_xmm_double_reg(),1407op->in_opr2()->as_xmm_double_reg(),1408op->in_opr3()->as_xmm_double_reg());1409break;1410case lir_fmaf:1411__ fmaf(op->result_opr()->as_xmm_float_reg(),1412op->in_opr1()->as_xmm_float_reg(),1413op->in_opr2()->as_xmm_float_reg(),1414op->in_opr3()->as_xmm_float_reg());1415break;1416default: ShouldNotReachHere(); break;1417}1418}14191420void LIR_Assembler::emit_opBranch(LIR_OpBranch* op) {1421#ifdef ASSERT1422assert(op->block() == NULL || op->block()->label() == op->label(), "wrong label");1423if (op->block() != NULL) _branch_target_blocks.append(op->block());1424if (op->ublock() != NULL) _branch_target_blocks.append(op->ublock());1425#endif14261427if (op->cond() == lir_cond_always) {1428if (op->info() != NULL) add_debug_info_for_branch(op->info());1429__ jmp (*(op->label()));1430} else {1431Assembler::Condition acond = Assembler::zero;1432if (op->code() == lir_cond_float_branch) {1433assert(op->ublock() != NULL, "must have unordered successor");1434__ jcc(Assembler::parity, *(op->ublock()->label()));1435switch(op->cond()) {1436case lir_cond_equal: acond = Assembler::equal; break;1437case lir_cond_notEqual: acond = Assembler::notEqual; break;1438case lir_cond_less: acond = Assembler::below; break;1439case lir_cond_lessEqual: acond = Assembler::belowEqual; break;1440case lir_cond_greaterEqual: acond = Assembler::aboveEqual; break;1441case lir_cond_greater: acond = Assembler::above; break;1442default: ShouldNotReachHere();1443}1444} else {1445switch (op->cond()) {1446case lir_cond_equal: acond = Assembler::equal; break;1447case lir_cond_notEqual: acond = Assembler::notEqual; break;1448case lir_cond_less: acond = Assembler::less; break;1449case lir_cond_lessEqual: acond = Assembler::lessEqual; break;1450case lir_cond_greaterEqual: acond = Assembler::greaterEqual;break;1451case lir_cond_greater: acond = Assembler::greater; break;1452case lir_cond_belowEqual: acond = Assembler::belowEqual; break;1453case lir_cond_aboveEqual: acond = Assembler::aboveEqual; break;1454default: ShouldNotReachHere();1455}1456}1457__ jcc(acond,*(op->label()));1458}1459}14601461void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) {1462LIR_Opr src = op->in_opr();1463LIR_Opr dest = op->result_opr();14641465switch (op->bytecode()) {1466case Bytecodes::_i2l:1467#ifdef _LP641468__ movl2ptr(dest->as_register_lo(), src->as_register());1469#else1470move_regs(src->as_register(), dest->as_register_lo());1471move_regs(src->as_register(), dest->as_register_hi());1472__ sarl(dest->as_register_hi(), 31);1473#endif // LP641474break;14751476case Bytecodes::_l2i:1477#ifdef _LP641478__ movl(dest->as_register(), src->as_register_lo());1479#else1480move_regs(src->as_register_lo(), dest->as_register());1481#endif1482break;14831484case Bytecodes::_i2b:1485move_regs(src->as_register(), dest->as_register());1486__ sign_extend_byte(dest->as_register());1487break;14881489case Bytecodes::_i2c:1490move_regs(src->as_register(), dest->as_register());1491__ andl(dest->as_register(), 0xFFFF);1492break;14931494case Bytecodes::_i2s:1495move_regs(src->as_register(), dest->as_register());1496__ sign_extend_short(dest->as_register());1497break;149814991500#ifdef _LP641501case Bytecodes::_f2d:1502__ cvtss2sd(dest->as_xmm_double_reg(), src->as_xmm_float_reg());1503break;15041505case Bytecodes::_d2f:1506__ cvtsd2ss(dest->as_xmm_float_reg(), src->as_xmm_double_reg());1507break;15081509case Bytecodes::_i2f:1510__ cvtsi2ssl(dest->as_xmm_float_reg(), src->as_register());1511break;15121513case Bytecodes::_i2d:1514__ cvtsi2sdl(dest->as_xmm_double_reg(), src->as_register());1515break;15161517case Bytecodes::_l2f:1518__ cvtsi2ssq(dest->as_xmm_float_reg(), src->as_register_lo());1519break;15201521case Bytecodes::_l2d:1522__ cvtsi2sdq(dest->as_xmm_double_reg(), src->as_register_lo());1523break;15241525case Bytecodes::_f2i:1526__ convert_f2i(dest->as_register(), src->as_xmm_float_reg());1527break;15281529case Bytecodes::_d2i:1530__ convert_d2i(dest->as_register(), src->as_xmm_double_reg());1531break;15321533case Bytecodes::_f2l:1534__ convert_f2l(dest->as_register_lo(), src->as_xmm_float_reg());1535break;15361537case Bytecodes::_d2l:1538__ convert_d2l(dest->as_register_lo(), src->as_xmm_double_reg());1539break;1540#else1541case Bytecodes::_f2d:1542case Bytecodes::_d2f:1543if (dest->is_single_xmm()) {1544__ cvtsd2ss(dest->as_xmm_float_reg(), src->as_xmm_double_reg());1545} else if (dest->is_double_xmm()) {1546__ cvtss2sd(dest->as_xmm_double_reg(), src->as_xmm_float_reg());1547} else {1548assert(src->fpu() == dest->fpu(), "register must be equal");1549// do nothing (float result is rounded later through spilling)1550}1551break;15521553case Bytecodes::_i2f:1554case Bytecodes::_i2d:1555if (dest->is_single_xmm()) {1556__ cvtsi2ssl(dest->as_xmm_float_reg(), src->as_register());1557} else if (dest->is_double_xmm()) {1558__ cvtsi2sdl(dest->as_xmm_double_reg(), src->as_register());1559} else {1560assert(dest->fpu() == 0, "result must be on TOS");1561__ movl(Address(rsp, 0), src->as_register());1562__ fild_s(Address(rsp, 0));1563}1564break;15651566case Bytecodes::_l2f:1567case Bytecodes::_l2d:1568assert(!dest->is_xmm_register(), "result in xmm register not supported (no SSE instruction present)");1569assert(dest->fpu() == 0, "result must be on TOS");1570__ movptr(Address(rsp, 0), src->as_register_lo());1571__ movl(Address(rsp, BytesPerWord), src->as_register_hi());1572__ fild_d(Address(rsp, 0));1573// float result is rounded later through spilling1574break;15751576case Bytecodes::_f2i:1577case Bytecodes::_d2i:1578if (src->is_single_xmm()) {1579__ cvttss2sil(dest->as_register(), src->as_xmm_float_reg());1580} else if (src->is_double_xmm()) {1581__ cvttsd2sil(dest->as_register(), src->as_xmm_double_reg());1582} else {1583assert(src->fpu() == 0, "input must be on TOS");1584__ fldcw(ExternalAddress(StubRoutines::x86::addr_fpu_cntrl_wrd_trunc()));1585__ fist_s(Address(rsp, 0));1586__ movl(dest->as_register(), Address(rsp, 0));1587__ fldcw(ExternalAddress(StubRoutines::x86::addr_fpu_cntrl_wrd_std()));1588}1589// IA32 conversion instructions do not match JLS for overflow, underflow and NaN -> fixup in stub1590assert(op->stub() != NULL, "stub required");1591__ cmpl(dest->as_register(), 0x80000000);1592__ jcc(Assembler::equal, *op->stub()->entry());1593__ bind(*op->stub()->continuation());1594break;15951596case Bytecodes::_f2l:1597case Bytecodes::_d2l:1598assert(!src->is_xmm_register(), "input in xmm register not supported (no SSE instruction present)");1599assert(src->fpu() == 0, "input must be on TOS");1600assert(dest == FrameMap::long0_opr, "runtime stub places result in these registers");16011602// instruction sequence too long to inline it here1603{1604__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::fpu2long_stub_id)));1605}1606break;1607#endif // _LP6416081609default: ShouldNotReachHere();1610}1611}16121613void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) {1614if (op->init_check()) {1615add_debug_info_for_null_check_here(op->stub()->info());1616__ cmpb(Address(op->klass()->as_register(),1617InstanceKlass::init_state_offset()),1618InstanceKlass::fully_initialized);1619__ jcc(Assembler::notEqual, *op->stub()->entry());1620}1621__ allocate_object(op->obj()->as_register(),1622op->tmp1()->as_register(),1623op->tmp2()->as_register(),1624op->header_size(),1625op->object_size(),1626op->klass()->as_register(),1627*op->stub()->entry());1628__ bind(*op->stub()->continuation());1629}16301631void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {1632Register len = op->len()->as_register();1633LP64_ONLY( __ movslq(len, len); )16341635if (UseSlowPath ||1636(!UseFastNewObjectArray && is_reference_type(op->type())) ||1637(!UseFastNewTypeArray && !is_reference_type(op->type()))) {1638__ jmp(*op->stub()->entry());1639} else {1640Register tmp1 = op->tmp1()->as_register();1641Register tmp2 = op->tmp2()->as_register();1642Register tmp3 = op->tmp3()->as_register();1643if (len == tmp1) {1644tmp1 = tmp3;1645} else if (len == tmp2) {1646tmp2 = tmp3;1647} else if (len == tmp3) {1648// everything is ok1649} else {1650__ mov(tmp3, len);1651}1652__ allocate_array(op->obj()->as_register(),1653len,1654tmp1,1655tmp2,1656arrayOopDesc::header_size(op->type()),1657array_element_size(op->type()),1658op->klass()->as_register(),1659*op->stub()->entry());1660}1661__ bind(*op->stub()->continuation());1662}16631664void LIR_Assembler::type_profile_helper(Register mdo,1665ciMethodData *md, ciProfileData *data,1666Register recv, Label* update_done) {1667for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) {1668Label next_test;1669// See if the receiver is receiver[n].1670__ cmpptr(recv, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i))));1671__ jccb(Assembler::notEqual, next_test);1672Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)));1673__ addptr(data_addr, DataLayout::counter_increment);1674__ jmp(*update_done);1675__ bind(next_test);1676}16771678// Didn't find receiver; find next empty slot and fill it in1679for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) {1680Label next_test;1681Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)));1682__ cmpptr(recv_addr, (intptr_t)NULL_WORD);1683__ jccb(Assembler::notEqual, next_test);1684__ movptr(recv_addr, recv);1685__ movptr(Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))), DataLayout::counter_increment);1686__ jmp(*update_done);1687__ bind(next_test);1688}1689}16901691void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) {1692// we always need a stub for the failure case.1693CodeStub* stub = op->stub();1694Register obj = op->object()->as_register();1695Register k_RInfo = op->tmp1()->as_register();1696Register klass_RInfo = op->tmp2()->as_register();1697Register dst = op->result_opr()->as_register();1698ciKlass* k = op->klass();1699Register Rtmp1 = noreg;1700Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);17011702// check if it needs to be profiled1703ciMethodData* md = NULL;1704ciProfileData* data = NULL;17051706if (op->should_profile()) {1707ciMethod* method = op->profiled_method();1708assert(method != NULL, "Should have method");1709int bci = op->profiled_bci();1710md = method->method_data_or_null();1711assert(md != NULL, "Sanity");1712data = md->bci_to_data(bci);1713assert(data != NULL, "need data for type check");1714assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");1715}1716Label profile_cast_success, profile_cast_failure;1717Label *success_target = op->should_profile() ? &profile_cast_success : success;1718Label *failure_target = op->should_profile() ? &profile_cast_failure : failure;17191720if (obj == k_RInfo) {1721k_RInfo = dst;1722} else if (obj == klass_RInfo) {1723klass_RInfo = dst;1724}1725if (k->is_loaded() && !UseCompressedClassPointers) {1726select_different_registers(obj, dst, k_RInfo, klass_RInfo);1727} else {1728Rtmp1 = op->tmp3()->as_register();1729select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1);1730}17311732assert_different_registers(obj, k_RInfo, klass_RInfo);17331734__ cmpptr(obj, (int32_t)NULL_WORD);1735if (op->should_profile()) {1736Label not_null;1737__ jccb(Assembler::notEqual, not_null);1738// Object is null; update MDO and exit1739Register mdo = klass_RInfo;1740__ mov_metadata(mdo, md->constant_encoding());1741Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()));1742int header_bits = BitData::null_seen_byte_constant();1743__ orb(data_addr, header_bits);1744__ jmp(*obj_is_null);1745__ bind(not_null);1746} else {1747__ jcc(Assembler::equal, *obj_is_null);1748}17491750if (!k->is_loaded()) {1751klass2reg_with_patching(k_RInfo, op->info_for_patch());1752} else {1753#ifdef _LP641754__ mov_metadata(k_RInfo, k->constant_encoding());1755#endif // _LP641756}1757__ verify_oop(obj);17581759if (op->fast_check()) {1760// get object class1761// not a safepoint as obj null check happens earlier1762#ifdef _LP641763if (UseCompressedClassPointers) {1764__ load_klass(Rtmp1, obj, tmp_load_klass);1765__ cmpptr(k_RInfo, Rtmp1);1766} else {1767__ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));1768}1769#else1770if (k->is_loaded()) {1771__ cmpklass(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding());1772} else {1773__ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));1774}1775#endif1776__ jcc(Assembler::notEqual, *failure_target);1777// successful cast, fall through to profile or jump1778} else {1779// get object class1780// not a safepoint as obj null check happens earlier1781__ load_klass(klass_RInfo, obj, tmp_load_klass);1782if (k->is_loaded()) {1783// See if we get an immediate positive hit1784#ifdef _LP641785__ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset()));1786#else1787__ cmpklass(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding());1788#endif // _LP641789if ((juint)in_bytes(Klass::secondary_super_cache_offset()) != k->super_check_offset()) {1790__ jcc(Assembler::notEqual, *failure_target);1791// successful cast, fall through to profile or jump1792} else {1793// See if we get an immediate positive hit1794__ jcc(Assembler::equal, *success_target);1795// check for self1796#ifdef _LP641797__ cmpptr(klass_RInfo, k_RInfo);1798#else1799__ cmpklass(klass_RInfo, k->constant_encoding());1800#endif // _LP641801__ jcc(Assembler::equal, *success_target);18021803__ push(klass_RInfo);1804#ifdef _LP641805__ push(k_RInfo);1806#else1807__ pushklass(k->constant_encoding());1808#endif // _LP641809__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));1810__ pop(klass_RInfo);1811__ pop(klass_RInfo);1812// result is a boolean1813__ cmpl(klass_RInfo, 0);1814__ jcc(Assembler::equal, *failure_target);1815// successful cast, fall through to profile or jump1816}1817} else {1818// perform the fast part of the checking logic1819__ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL);1820// call out-of-line instance of __ check_klass_subtype_slow_path(...):1821__ push(klass_RInfo);1822__ push(k_RInfo);1823__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));1824__ pop(klass_RInfo);1825__ pop(k_RInfo);1826// result is a boolean1827__ cmpl(k_RInfo, 0);1828__ jcc(Assembler::equal, *failure_target);1829// successful cast, fall through to profile or jump1830}1831}1832if (op->should_profile()) {1833Register mdo = klass_RInfo, recv = k_RInfo;1834__ bind(profile_cast_success);1835__ mov_metadata(mdo, md->constant_encoding());1836__ load_klass(recv, obj, tmp_load_klass);1837type_profile_helper(mdo, md, data, recv, success);1838__ jmp(*success);18391840__ bind(profile_cast_failure);1841__ mov_metadata(mdo, md->constant_encoding());1842Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));1843__ subptr(counter_addr, DataLayout::counter_increment);1844__ jmp(*failure);1845}1846__ jmp(*success);1847}184818491850void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {1851Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);1852LIR_Code code = op->code();1853if (code == lir_store_check) {1854Register value = op->object()->as_register();1855Register array = op->array()->as_register();1856Register k_RInfo = op->tmp1()->as_register();1857Register klass_RInfo = op->tmp2()->as_register();1858Register Rtmp1 = op->tmp3()->as_register();18591860CodeStub* stub = op->stub();18611862// check if it needs to be profiled1863ciMethodData* md = NULL;1864ciProfileData* data = NULL;18651866if (op->should_profile()) {1867ciMethod* method = op->profiled_method();1868assert(method != NULL, "Should have method");1869int bci = op->profiled_bci();1870md = method->method_data_or_null();1871assert(md != NULL, "Sanity");1872data = md->bci_to_data(bci);1873assert(data != NULL, "need data for type check");1874assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");1875}1876Label profile_cast_success, profile_cast_failure, done;1877Label *success_target = op->should_profile() ? &profile_cast_success : &done;1878Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry();18791880__ cmpptr(value, (int32_t)NULL_WORD);1881if (op->should_profile()) {1882Label not_null;1883__ jccb(Assembler::notEqual, not_null);1884// Object is null; update MDO and exit1885Register mdo = klass_RInfo;1886__ mov_metadata(mdo, md->constant_encoding());1887Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()));1888int header_bits = BitData::null_seen_byte_constant();1889__ orb(data_addr, header_bits);1890__ jmp(done);1891__ bind(not_null);1892} else {1893__ jcc(Assembler::equal, done);1894}18951896add_debug_info_for_null_check_here(op->info_for_exception());1897__ load_klass(k_RInfo, array, tmp_load_klass);1898__ load_klass(klass_RInfo, value, tmp_load_klass);18991900// get instance klass (it's already uncompressed)1901__ movptr(k_RInfo, Address(k_RInfo, ObjArrayKlass::element_klass_offset()));1902// perform the fast part of the checking logic1903__ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL);1904// call out-of-line instance of __ check_klass_subtype_slow_path(...):1905__ push(klass_RInfo);1906__ push(k_RInfo);1907__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));1908__ pop(klass_RInfo);1909__ pop(k_RInfo);1910// result is a boolean1911__ cmpl(k_RInfo, 0);1912__ jcc(Assembler::equal, *failure_target);1913// fall through to the success case19141915if (op->should_profile()) {1916Register mdo = klass_RInfo, recv = k_RInfo;1917__ bind(profile_cast_success);1918__ mov_metadata(mdo, md->constant_encoding());1919__ load_klass(recv, value, tmp_load_klass);1920type_profile_helper(mdo, md, data, recv, &done);1921__ jmpb(done);19221923__ bind(profile_cast_failure);1924__ mov_metadata(mdo, md->constant_encoding());1925Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));1926__ subptr(counter_addr, DataLayout::counter_increment);1927__ jmp(*stub->entry());1928}19291930__ bind(done);1931} else1932if (code == lir_checkcast) {1933Register obj = op->object()->as_register();1934Register dst = op->result_opr()->as_register();1935Label success;1936emit_typecheck_helper(op, &success, op->stub()->entry(), &success);1937__ bind(success);1938if (dst != obj) {1939__ mov(dst, obj);1940}1941} else1942if (code == lir_instanceof) {1943Register obj = op->object()->as_register();1944Register dst = op->result_opr()->as_register();1945Label success, failure, done;1946emit_typecheck_helper(op, &success, &failure, &failure);1947__ bind(failure);1948__ xorptr(dst, dst);1949__ jmpb(done);1950__ bind(success);1951__ movptr(dst, 1);1952__ bind(done);1953} else {1954ShouldNotReachHere();1955}19561957}195819591960void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) {1961if (LP64_ONLY(false &&) op->code() == lir_cas_long && VM_Version::supports_cx8()) {1962assert(op->cmp_value()->as_register_lo() == rax, "wrong register");1963assert(op->cmp_value()->as_register_hi() == rdx, "wrong register");1964assert(op->new_value()->as_register_lo() == rbx, "wrong register");1965assert(op->new_value()->as_register_hi() == rcx, "wrong register");1966Register addr = op->addr()->as_register();1967__ lock();1968NOT_LP64(__ cmpxchg8(Address(addr, 0)));19691970} else if (op->code() == lir_cas_int || op->code() == lir_cas_obj ) {1971NOT_LP64(assert(op->addr()->is_single_cpu(), "must be single");)1972Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo());1973Register newval = op->new_value()->as_register();1974Register cmpval = op->cmp_value()->as_register();1975assert(cmpval == rax, "wrong register");1976assert(newval != NULL, "new val must be register");1977assert(cmpval != newval, "cmp and new values must be in different registers");1978assert(cmpval != addr, "cmp and addr must be in different registers");1979assert(newval != addr, "new value and addr must be in different registers");19801981if ( op->code() == lir_cas_obj) {1982#ifdef _LP641983if (UseCompressedOops) {1984__ encode_heap_oop(cmpval);1985__ mov(rscratch1, newval);1986__ encode_heap_oop(rscratch1);1987__ lock();1988// cmpval (rax) is implicitly used by this instruction1989__ cmpxchgl(rscratch1, Address(addr, 0));1990} else1991#endif1992{1993__ lock();1994__ cmpxchgptr(newval, Address(addr, 0));1995}1996} else {1997assert(op->code() == lir_cas_int, "lir_cas_int expected");1998__ lock();1999__ cmpxchgl(newval, Address(addr, 0));2000}2001#ifdef _LP642002} else if (op->code() == lir_cas_long) {2003Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo());2004Register newval = op->new_value()->as_register_lo();2005Register cmpval = op->cmp_value()->as_register_lo();2006assert(cmpval == rax, "wrong register");2007assert(newval != NULL, "new val must be register");2008assert(cmpval != newval, "cmp and new values must be in different registers");2009assert(cmpval != addr, "cmp and addr must be in different registers");2010assert(newval != addr, "new value and addr must be in different registers");2011__ lock();2012__ cmpxchgq(newval, Address(addr, 0));2013#endif // _LP642014} else {2015Unimplemented();2016}2017}20182019void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type) {2020Assembler::Condition acond, ncond;2021switch (condition) {2022case lir_cond_equal: acond = Assembler::equal; ncond = Assembler::notEqual; break;2023case lir_cond_notEqual: acond = Assembler::notEqual; ncond = Assembler::equal; break;2024case lir_cond_less: acond = Assembler::less; ncond = Assembler::greaterEqual; break;2025case lir_cond_lessEqual: acond = Assembler::lessEqual; ncond = Assembler::greater; break;2026case lir_cond_greaterEqual: acond = Assembler::greaterEqual; ncond = Assembler::less; break;2027case lir_cond_greater: acond = Assembler::greater; ncond = Assembler::lessEqual; break;2028case lir_cond_belowEqual: acond = Assembler::belowEqual; ncond = Assembler::above; break;2029case lir_cond_aboveEqual: acond = Assembler::aboveEqual; ncond = Assembler::below; break;2030default: acond = Assembler::equal; ncond = Assembler::notEqual;2031ShouldNotReachHere();2032}20332034if (opr1->is_cpu_register()) {2035reg2reg(opr1, result);2036} else if (opr1->is_stack()) {2037stack2reg(opr1, result, result->type());2038} else if (opr1->is_constant()) {2039const2reg(opr1, result, lir_patch_none, NULL);2040} else {2041ShouldNotReachHere();2042}20432044if (VM_Version::supports_cmov() && !opr2->is_constant()) {2045// optimized version that does not require a branch2046if (opr2->is_single_cpu()) {2047assert(opr2->cpu_regnr() != result->cpu_regnr(), "opr2 already overwritten by previous move");2048__ cmov(ncond, result->as_register(), opr2->as_register());2049} else if (opr2->is_double_cpu()) {2050assert(opr2->cpu_regnrLo() != result->cpu_regnrLo() && opr2->cpu_regnrLo() != result->cpu_regnrHi(), "opr2 already overwritten by previous move");2051assert(opr2->cpu_regnrHi() != result->cpu_regnrLo() && opr2->cpu_regnrHi() != result->cpu_regnrHi(), "opr2 already overwritten by previous move");2052__ cmovptr(ncond, result->as_register_lo(), opr2->as_register_lo());2053NOT_LP64(__ cmovptr(ncond, result->as_register_hi(), opr2->as_register_hi());)2054} else if (opr2->is_single_stack()) {2055__ cmovl(ncond, result->as_register(), frame_map()->address_for_slot(opr2->single_stack_ix()));2056} else if (opr2->is_double_stack()) {2057__ cmovptr(ncond, result->as_register_lo(), frame_map()->address_for_slot(opr2->double_stack_ix(), lo_word_offset_in_bytes));2058NOT_LP64(__ cmovptr(ncond, result->as_register_hi(), frame_map()->address_for_slot(opr2->double_stack_ix(), hi_word_offset_in_bytes));)2059} else {2060ShouldNotReachHere();2061}20622063} else {2064Label skip;2065__ jcc (acond, skip);2066if (opr2->is_cpu_register()) {2067reg2reg(opr2, result);2068} else if (opr2->is_stack()) {2069stack2reg(opr2, result, result->type());2070} else if (opr2->is_constant()) {2071const2reg(opr2, result, lir_patch_none, NULL);2072} else {2073ShouldNotReachHere();2074}2075__ bind(skip);2076}2077}207820792080void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info, bool pop_fpu_stack) {2081assert(info == NULL, "should never be used, idiv/irem and ldiv/lrem not handled by this method");20822083if (left->is_single_cpu()) {2084assert(left == dest, "left and dest must be equal");2085Register lreg = left->as_register();20862087if (right->is_single_cpu()) {2088// cpu register - cpu register2089Register rreg = right->as_register();2090switch (code) {2091case lir_add: __ addl (lreg, rreg); break;2092case lir_sub: __ subl (lreg, rreg); break;2093case lir_mul: __ imull(lreg, rreg); break;2094default: ShouldNotReachHere();2095}20962097} else if (right->is_stack()) {2098// cpu register - stack2099Address raddr = frame_map()->address_for_slot(right->single_stack_ix());2100switch (code) {2101case lir_add: __ addl(lreg, raddr); break;2102case lir_sub: __ subl(lreg, raddr); break;2103default: ShouldNotReachHere();2104}21052106} else if (right->is_constant()) {2107// cpu register - constant2108jint c = right->as_constant_ptr()->as_jint();2109switch (code) {2110case lir_add: {2111__ incrementl(lreg, c);2112break;2113}2114case lir_sub: {2115__ decrementl(lreg, c);2116break;2117}2118default: ShouldNotReachHere();2119}21202121} else {2122ShouldNotReachHere();2123}21242125} else if (left->is_double_cpu()) {2126assert(left == dest, "left and dest must be equal");2127Register lreg_lo = left->as_register_lo();2128Register lreg_hi = left->as_register_hi();21292130if (right->is_double_cpu()) {2131// cpu register - cpu register2132Register rreg_lo = right->as_register_lo();2133Register rreg_hi = right->as_register_hi();2134NOT_LP64(assert_different_registers(lreg_lo, lreg_hi, rreg_lo, rreg_hi));2135LP64_ONLY(assert_different_registers(lreg_lo, rreg_lo));2136switch (code) {2137case lir_add:2138__ addptr(lreg_lo, rreg_lo);2139NOT_LP64(__ adcl(lreg_hi, rreg_hi));2140break;2141case lir_sub:2142__ subptr(lreg_lo, rreg_lo);2143NOT_LP64(__ sbbl(lreg_hi, rreg_hi));2144break;2145case lir_mul:2146#ifdef _LP642147__ imulq(lreg_lo, rreg_lo);2148#else2149assert(lreg_lo == rax && lreg_hi == rdx, "must be");2150__ imull(lreg_hi, rreg_lo);2151__ imull(rreg_hi, lreg_lo);2152__ addl (rreg_hi, lreg_hi);2153__ mull (rreg_lo);2154__ addl (lreg_hi, rreg_hi);2155#endif // _LP642156break;2157default:2158ShouldNotReachHere();2159}21602161} else if (right->is_constant()) {2162// cpu register - constant2163#ifdef _LP642164jlong c = right->as_constant_ptr()->as_jlong_bits();2165__ movptr(r10, (intptr_t) c);2166switch (code) {2167case lir_add:2168__ addptr(lreg_lo, r10);2169break;2170case lir_sub:2171__ subptr(lreg_lo, r10);2172break;2173default:2174ShouldNotReachHere();2175}2176#else2177jint c_lo = right->as_constant_ptr()->as_jint_lo();2178jint c_hi = right->as_constant_ptr()->as_jint_hi();2179switch (code) {2180case lir_add:2181__ addptr(lreg_lo, c_lo);2182__ adcl(lreg_hi, c_hi);2183break;2184case lir_sub:2185__ subptr(lreg_lo, c_lo);2186__ sbbl(lreg_hi, c_hi);2187break;2188default:2189ShouldNotReachHere();2190}2191#endif // _LP6421922193} else {2194ShouldNotReachHere();2195}21962197} else if (left->is_single_xmm()) {2198assert(left == dest, "left and dest must be equal");2199XMMRegister lreg = left->as_xmm_float_reg();22002201if (right->is_single_xmm()) {2202XMMRegister rreg = right->as_xmm_float_reg();2203switch (code) {2204case lir_add: __ addss(lreg, rreg); break;2205case lir_sub: __ subss(lreg, rreg); break;2206case lir_mul: __ mulss(lreg, rreg); break;2207case lir_div: __ divss(lreg, rreg); break;2208default: ShouldNotReachHere();2209}2210} else {2211Address raddr;2212if (right->is_single_stack()) {2213raddr = frame_map()->address_for_slot(right->single_stack_ix());2214} else if (right->is_constant()) {2215// hack for now2216raddr = __ as_Address(InternalAddress(float_constant(right->as_jfloat())));2217} else {2218ShouldNotReachHere();2219}2220switch (code) {2221case lir_add: __ addss(lreg, raddr); break;2222case lir_sub: __ subss(lreg, raddr); break;2223case lir_mul: __ mulss(lreg, raddr); break;2224case lir_div: __ divss(lreg, raddr); break;2225default: ShouldNotReachHere();2226}2227}22282229} else if (left->is_double_xmm()) {2230assert(left == dest, "left and dest must be equal");22312232XMMRegister lreg = left->as_xmm_double_reg();2233if (right->is_double_xmm()) {2234XMMRegister rreg = right->as_xmm_double_reg();2235switch (code) {2236case lir_add: __ addsd(lreg, rreg); break;2237case lir_sub: __ subsd(lreg, rreg); break;2238case lir_mul: __ mulsd(lreg, rreg); break;2239case lir_div: __ divsd(lreg, rreg); break;2240default: ShouldNotReachHere();2241}2242} else {2243Address raddr;2244if (right->is_double_stack()) {2245raddr = frame_map()->address_for_slot(right->double_stack_ix());2246} else if (right->is_constant()) {2247// hack for now2248raddr = __ as_Address(InternalAddress(double_constant(right->as_jdouble())));2249} else {2250ShouldNotReachHere();2251}2252switch (code) {2253case lir_add: __ addsd(lreg, raddr); break;2254case lir_sub: __ subsd(lreg, raddr); break;2255case lir_mul: __ mulsd(lreg, raddr); break;2256case lir_div: __ divsd(lreg, raddr); break;2257default: ShouldNotReachHere();2258}2259}22602261#ifndef _LP642262} else if (left->is_single_fpu()) {2263assert(dest->is_single_fpu(), "fpu stack allocation required");22642265if (right->is_single_fpu()) {2266arith_fpu_implementation(code, left->fpu_regnr(), right->fpu_regnr(), dest->fpu_regnr(), pop_fpu_stack);22672268} else {2269assert(left->fpu_regnr() == 0, "left must be on TOS");2270assert(dest->fpu_regnr() == 0, "dest must be on TOS");22712272Address raddr;2273if (right->is_single_stack()) {2274raddr = frame_map()->address_for_slot(right->single_stack_ix());2275} else if (right->is_constant()) {2276address const_addr = float_constant(right->as_jfloat());2277assert(const_addr != NULL, "incorrect float/double constant maintainance");2278// hack for now2279raddr = __ as_Address(InternalAddress(const_addr));2280} else {2281ShouldNotReachHere();2282}22832284switch (code) {2285case lir_add: __ fadd_s(raddr); break;2286case lir_sub: __ fsub_s(raddr); break;2287case lir_mul: __ fmul_s(raddr); break;2288case lir_div: __ fdiv_s(raddr); break;2289default: ShouldNotReachHere();2290}2291}22922293} else if (left->is_double_fpu()) {2294assert(dest->is_double_fpu(), "fpu stack allocation required");22952296if (code == lir_mul || code == lir_div) {2297// Double values require special handling for strictfp mul/div on x862298__ fld_x(ExternalAddress(StubRoutines::x86::addr_fpu_subnormal_bias1()));2299__ fmulp(left->fpu_regnrLo() + 1);2300}23012302if (right->is_double_fpu()) {2303arith_fpu_implementation(code, left->fpu_regnrLo(), right->fpu_regnrLo(), dest->fpu_regnrLo(), pop_fpu_stack);23042305} else {2306assert(left->fpu_regnrLo() == 0, "left must be on TOS");2307assert(dest->fpu_regnrLo() == 0, "dest must be on TOS");23082309Address raddr;2310if (right->is_double_stack()) {2311raddr = frame_map()->address_for_slot(right->double_stack_ix());2312} else if (right->is_constant()) {2313// hack for now2314raddr = __ as_Address(InternalAddress(double_constant(right->as_jdouble())));2315} else {2316ShouldNotReachHere();2317}23182319switch (code) {2320case lir_add: __ fadd_d(raddr); break;2321case lir_sub: __ fsub_d(raddr); break;2322case lir_mul: __ fmul_d(raddr); break;2323case lir_div: __ fdiv_d(raddr); break;2324default: ShouldNotReachHere();2325}2326}23272328if (code == lir_mul || code == lir_div) {2329// Double values require special handling for strictfp mul/div on x862330__ fld_x(ExternalAddress(StubRoutines::x86::addr_fpu_subnormal_bias2()));2331__ fmulp(dest->fpu_regnrLo() + 1);2332}2333#endif // !_LP6423342335} else if (left->is_single_stack() || left->is_address()) {2336assert(left == dest, "left and dest must be equal");23372338Address laddr;2339if (left->is_single_stack()) {2340laddr = frame_map()->address_for_slot(left->single_stack_ix());2341} else if (left->is_address()) {2342laddr = as_Address(left->as_address_ptr());2343} else {2344ShouldNotReachHere();2345}23462347if (right->is_single_cpu()) {2348Register rreg = right->as_register();2349switch (code) {2350case lir_add: __ addl(laddr, rreg); break;2351case lir_sub: __ subl(laddr, rreg); break;2352default: ShouldNotReachHere();2353}2354} else if (right->is_constant()) {2355jint c = right->as_constant_ptr()->as_jint();2356switch (code) {2357case lir_add: {2358__ incrementl(laddr, c);2359break;2360}2361case lir_sub: {2362__ decrementl(laddr, c);2363break;2364}2365default: ShouldNotReachHere();2366}2367} else {2368ShouldNotReachHere();2369}23702371} else {2372ShouldNotReachHere();2373}2374}23752376#ifndef _LP642377void LIR_Assembler::arith_fpu_implementation(LIR_Code code, int left_index, int right_index, int dest_index, bool pop_fpu_stack) {2378assert(pop_fpu_stack || (left_index == dest_index || right_index == dest_index), "invalid LIR");2379assert(!pop_fpu_stack || (left_index - 1 == dest_index || right_index - 1 == dest_index), "invalid LIR");2380assert(left_index == 0 || right_index == 0, "either must be on top of stack");23812382bool left_is_tos = (left_index == 0);2383bool dest_is_tos = (dest_index == 0);2384int non_tos_index = (left_is_tos ? right_index : left_index);23852386switch (code) {2387case lir_add:2388if (pop_fpu_stack) __ faddp(non_tos_index);2389else if (dest_is_tos) __ fadd (non_tos_index);2390else __ fadda(non_tos_index);2391break;23922393case lir_sub:2394if (left_is_tos) {2395if (pop_fpu_stack) __ fsubrp(non_tos_index);2396else if (dest_is_tos) __ fsub (non_tos_index);2397else __ fsubra(non_tos_index);2398} else {2399if (pop_fpu_stack) __ fsubp (non_tos_index);2400else if (dest_is_tos) __ fsubr (non_tos_index);2401else __ fsuba (non_tos_index);2402}2403break;24042405case lir_mul:2406if (pop_fpu_stack) __ fmulp(non_tos_index);2407else if (dest_is_tos) __ fmul (non_tos_index);2408else __ fmula(non_tos_index);2409break;24102411case lir_div:2412if (left_is_tos) {2413if (pop_fpu_stack) __ fdivrp(non_tos_index);2414else if (dest_is_tos) __ fdiv (non_tos_index);2415else __ fdivra(non_tos_index);2416} else {2417if (pop_fpu_stack) __ fdivp (non_tos_index);2418else if (dest_is_tos) __ fdivr (non_tos_index);2419else __ fdiva (non_tos_index);2420}2421break;24222423case lir_rem:2424assert(left_is_tos && dest_is_tos && right_index == 1, "must be guaranteed by FPU stack allocation");2425__ fremr(noreg);2426break;24272428default:2429ShouldNotReachHere();2430}2431}2432#endif // _LP64243324342435void LIR_Assembler::intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr tmp, LIR_Opr dest, LIR_Op* op) {2436if (value->is_double_xmm()) {2437switch(code) {2438case lir_abs :2439{2440#ifdef _LP642441if (UseAVX > 2 && !VM_Version::supports_avx512vl()) {2442assert(tmp->is_valid(), "need temporary");2443__ vpandn(dest->as_xmm_double_reg(), tmp->as_xmm_double_reg(), value->as_xmm_double_reg(), 2);2444} else2445#endif2446{2447if (dest->as_xmm_double_reg() != value->as_xmm_double_reg()) {2448__ movdbl(dest->as_xmm_double_reg(), value->as_xmm_double_reg());2449}2450assert(!tmp->is_valid(), "do not need temporary");2451__ andpd(dest->as_xmm_double_reg(),2452ExternalAddress((address)double_signmask_pool));2453}2454}2455break;24562457case lir_sqrt: __ sqrtsd(dest->as_xmm_double_reg(), value->as_xmm_double_reg()); break;2458// all other intrinsics are not available in the SSE instruction set, so FPU is used2459default : ShouldNotReachHere();2460}24612462#ifndef _LP642463} else if (value->is_double_fpu()) {2464assert(value->fpu_regnrLo() == 0 && dest->fpu_regnrLo() == 0, "both must be on TOS");2465switch(code) {2466case lir_abs : __ fabs() ; break;2467case lir_sqrt : __ fsqrt(); break;2468default : ShouldNotReachHere();2469}2470#endif // !_LP642471} else {2472Unimplemented();2473}2474}24752476void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst) {2477// assert(left->destroys_register(), "check");2478if (left->is_single_cpu()) {2479Register reg = left->as_register();2480if (right->is_constant()) {2481int val = right->as_constant_ptr()->as_jint();2482switch (code) {2483case lir_logic_and: __ andl (reg, val); break;2484case lir_logic_or: __ orl (reg, val); break;2485case lir_logic_xor: __ xorl (reg, val); break;2486default: ShouldNotReachHere();2487}2488} else if (right->is_stack()) {2489// added support for stack operands2490Address raddr = frame_map()->address_for_slot(right->single_stack_ix());2491switch (code) {2492case lir_logic_and: __ andl (reg, raddr); break;2493case lir_logic_or: __ orl (reg, raddr); break;2494case lir_logic_xor: __ xorl (reg, raddr); break;2495default: ShouldNotReachHere();2496}2497} else {2498Register rright = right->as_register();2499switch (code) {2500case lir_logic_and: __ andptr (reg, rright); break;2501case lir_logic_or : __ orptr (reg, rright); break;2502case lir_logic_xor: __ xorptr (reg, rright); break;2503default: ShouldNotReachHere();2504}2505}2506move_regs(reg, dst->as_register());2507} else {2508Register l_lo = left->as_register_lo();2509Register l_hi = left->as_register_hi();2510if (right->is_constant()) {2511#ifdef _LP642512__ mov64(rscratch1, right->as_constant_ptr()->as_jlong());2513switch (code) {2514case lir_logic_and:2515__ andq(l_lo, rscratch1);2516break;2517case lir_logic_or:2518__ orq(l_lo, rscratch1);2519break;2520case lir_logic_xor:2521__ xorq(l_lo, rscratch1);2522break;2523default: ShouldNotReachHere();2524}2525#else2526int r_lo = right->as_constant_ptr()->as_jint_lo();2527int r_hi = right->as_constant_ptr()->as_jint_hi();2528switch (code) {2529case lir_logic_and:2530__ andl(l_lo, r_lo);2531__ andl(l_hi, r_hi);2532break;2533case lir_logic_or:2534__ orl(l_lo, r_lo);2535__ orl(l_hi, r_hi);2536break;2537case lir_logic_xor:2538__ xorl(l_lo, r_lo);2539__ xorl(l_hi, r_hi);2540break;2541default: ShouldNotReachHere();2542}2543#endif // _LP642544} else {2545#ifdef _LP642546Register r_lo;2547if (is_reference_type(right->type())) {2548r_lo = right->as_register();2549} else {2550r_lo = right->as_register_lo();2551}2552#else2553Register r_lo = right->as_register_lo();2554Register r_hi = right->as_register_hi();2555assert(l_lo != r_hi, "overwriting registers");2556#endif2557switch (code) {2558case lir_logic_and:2559__ andptr(l_lo, r_lo);2560NOT_LP64(__ andptr(l_hi, r_hi);)2561break;2562case lir_logic_or:2563__ orptr(l_lo, r_lo);2564NOT_LP64(__ orptr(l_hi, r_hi);)2565break;2566case lir_logic_xor:2567__ xorptr(l_lo, r_lo);2568NOT_LP64(__ xorptr(l_hi, r_hi);)2569break;2570default: ShouldNotReachHere();2571}2572}25732574Register dst_lo = dst->as_register_lo();2575Register dst_hi = dst->as_register_hi();25762577#ifdef _LP642578move_regs(l_lo, dst_lo);2579#else2580if (dst_lo == l_hi) {2581assert(dst_hi != l_lo, "overwriting registers");2582move_regs(l_hi, dst_hi);2583move_regs(l_lo, dst_lo);2584} else {2585assert(dst_lo != l_hi, "overwriting registers");2586move_regs(l_lo, dst_lo);2587move_regs(l_hi, dst_hi);2588}2589#endif // _LP642590}2591}259225932594// we assume that rax, and rdx can be overwritten2595void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info) {25962597assert(left->is_single_cpu(), "left must be register");2598assert(right->is_single_cpu() || right->is_constant(), "right must be register or constant");2599assert(result->is_single_cpu(), "result must be register");26002601// assert(left->destroys_register(), "check");2602// assert(right->destroys_register(), "check");26032604Register lreg = left->as_register();2605Register dreg = result->as_register();26062607if (right->is_constant()) {2608jint divisor = right->as_constant_ptr()->as_jint();2609assert(divisor > 0 && is_power_of_2(divisor), "must be");2610if (code == lir_idiv) {2611assert(lreg == rax, "must be rax,");2612assert(temp->as_register() == rdx, "tmp register must be rdx");2613__ cdql(); // sign extend into rdx:rax2614if (divisor == 2) {2615__ subl(lreg, rdx);2616} else {2617__ andl(rdx, divisor - 1);2618__ addl(lreg, rdx);2619}2620__ sarl(lreg, log2i_exact(divisor));2621move_regs(lreg, dreg);2622} else if (code == lir_irem) {2623Label done;2624__ mov(dreg, lreg);2625__ andl(dreg, 0x80000000 | (divisor - 1));2626__ jcc(Assembler::positive, done);2627__ decrement(dreg);2628__ orl(dreg, ~(divisor - 1));2629__ increment(dreg);2630__ bind(done);2631} else {2632ShouldNotReachHere();2633}2634} else {2635Register rreg = right->as_register();2636assert(lreg == rax, "left register must be rax,");2637assert(rreg != rdx, "right register must not be rdx");2638assert(temp->as_register() == rdx, "tmp register must be rdx");26392640move_regs(lreg, rax);26412642int idivl_offset = __ corrected_idivl(rreg);2643if (ImplicitDiv0Checks) {2644add_debug_info_for_div0(idivl_offset, info);2645}2646if (code == lir_irem) {2647move_regs(rdx, dreg); // result is in rdx2648} else {2649move_regs(rax, dreg);2650}2651}2652}265326542655void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Op2* op) {2656if (opr1->is_single_cpu()) {2657Register reg1 = opr1->as_register();2658if (opr2->is_single_cpu()) {2659// cpu register - cpu register2660if (is_reference_type(opr1->type())) {2661__ cmpoop(reg1, opr2->as_register());2662} else {2663assert(!is_reference_type(opr2->type()), "cmp int, oop?");2664__ cmpl(reg1, opr2->as_register());2665}2666} else if (opr2->is_stack()) {2667// cpu register - stack2668if (is_reference_type(opr1->type())) {2669__ cmpoop(reg1, frame_map()->address_for_slot(opr2->single_stack_ix()));2670} else {2671__ cmpl(reg1, frame_map()->address_for_slot(opr2->single_stack_ix()));2672}2673} else if (opr2->is_constant()) {2674// cpu register - constant2675LIR_Const* c = opr2->as_constant_ptr();2676if (c->type() == T_INT) {2677__ cmpl(reg1, c->as_jint());2678} else if (c->type() == T_METADATA) {2679// All we need for now is a comparison with NULL for equality.2680assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "oops");2681Metadata* m = c->as_metadata();2682if (m == NULL) {2683__ cmpptr(reg1, (int32_t)0);2684} else {2685ShouldNotReachHere();2686}2687} else if (is_reference_type(c->type())) {2688// In 64bit oops are single register2689jobject o = c->as_jobject();2690if (o == NULL) {2691__ cmpptr(reg1, (int32_t)NULL_WORD);2692} else {2693__ cmpoop(reg1, o);2694}2695} else {2696fatal("unexpected type: %s", basictype_to_str(c->type()));2697}2698// cpu register - address2699} else if (opr2->is_address()) {2700if (op->info() != NULL) {2701add_debug_info_for_null_check_here(op->info());2702}2703__ cmpl(reg1, as_Address(opr2->as_address_ptr()));2704} else {2705ShouldNotReachHere();2706}27072708} else if(opr1->is_double_cpu()) {2709Register xlo = opr1->as_register_lo();2710Register xhi = opr1->as_register_hi();2711if (opr2->is_double_cpu()) {2712#ifdef _LP642713__ cmpptr(xlo, opr2->as_register_lo());2714#else2715// cpu register - cpu register2716Register ylo = opr2->as_register_lo();2717Register yhi = opr2->as_register_hi();2718__ subl(xlo, ylo);2719__ sbbl(xhi, yhi);2720if (condition == lir_cond_equal || condition == lir_cond_notEqual) {2721__ orl(xhi, xlo);2722}2723#endif // _LP642724} else if (opr2->is_constant()) {2725// cpu register - constant 02726assert(opr2->as_jlong() == (jlong)0, "only handles zero");2727#ifdef _LP642728__ cmpptr(xlo, (int32_t)opr2->as_jlong());2729#else2730assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "only handles equals case");2731__ orl(xhi, xlo);2732#endif // _LP642733} else {2734ShouldNotReachHere();2735}27362737} else if (opr1->is_single_xmm()) {2738XMMRegister reg1 = opr1->as_xmm_float_reg();2739if (opr2->is_single_xmm()) {2740// xmm register - xmm register2741__ ucomiss(reg1, opr2->as_xmm_float_reg());2742} else if (opr2->is_stack()) {2743// xmm register - stack2744__ ucomiss(reg1, frame_map()->address_for_slot(opr2->single_stack_ix()));2745} else if (opr2->is_constant()) {2746// xmm register - constant2747__ ucomiss(reg1, InternalAddress(float_constant(opr2->as_jfloat())));2748} else if (opr2->is_address()) {2749// xmm register - address2750if (op->info() != NULL) {2751add_debug_info_for_null_check_here(op->info());2752}2753__ ucomiss(reg1, as_Address(opr2->as_address_ptr()));2754} else {2755ShouldNotReachHere();2756}27572758} else if (opr1->is_double_xmm()) {2759XMMRegister reg1 = opr1->as_xmm_double_reg();2760if (opr2->is_double_xmm()) {2761// xmm register - xmm register2762__ ucomisd(reg1, opr2->as_xmm_double_reg());2763} else if (opr2->is_stack()) {2764// xmm register - stack2765__ ucomisd(reg1, frame_map()->address_for_slot(opr2->double_stack_ix()));2766} else if (opr2->is_constant()) {2767// xmm register - constant2768__ ucomisd(reg1, InternalAddress(double_constant(opr2->as_jdouble())));2769} else if (opr2->is_address()) {2770// xmm register - address2771if (op->info() != NULL) {2772add_debug_info_for_null_check_here(op->info());2773}2774__ ucomisd(reg1, as_Address(opr2->pointer()->as_address()));2775} else {2776ShouldNotReachHere();2777}27782779#ifndef _LP642780} else if(opr1->is_single_fpu() || opr1->is_double_fpu()) {2781assert(opr1->is_fpu_register() && opr1->fpu() == 0, "currently left-hand side must be on TOS (relax this restriction)");2782assert(opr2->is_fpu_register(), "both must be registers");2783__ fcmp(noreg, opr2->fpu(), op->fpu_pop_count() > 0, op->fpu_pop_count() > 1);2784#endif // LP6427852786} else if (opr1->is_address() && opr2->is_constant()) {2787LIR_Const* c = opr2->as_constant_ptr();2788#ifdef _LP642789if (is_reference_type(c->type())) {2790assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "need to reverse");2791__ movoop(rscratch1, c->as_jobject());2792}2793#endif // LP642794if (op->info() != NULL) {2795add_debug_info_for_null_check_here(op->info());2796}2797// special case: address - constant2798LIR_Address* addr = opr1->as_address_ptr();2799if (c->type() == T_INT) {2800__ cmpl(as_Address(addr), c->as_jint());2801} else if (is_reference_type(c->type())) {2802#ifdef _LP642803// %%% Make this explode if addr isn't reachable until we figure out a2804// better strategy by giving noreg as the temp for as_Address2805__ cmpoop(rscratch1, as_Address(addr, noreg));2806#else2807__ cmpoop(as_Address(addr), c->as_jobject());2808#endif // _LP642809} else {2810ShouldNotReachHere();2811}28122813} else {2814ShouldNotReachHere();2815}2816}28172818void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst, LIR_Op2* op) {2819if (code == lir_cmp_fd2i || code == lir_ucmp_fd2i) {2820if (left->is_single_xmm()) {2821assert(right->is_single_xmm(), "must match");2822__ cmpss2int(left->as_xmm_float_reg(), right->as_xmm_float_reg(), dst->as_register(), code == lir_ucmp_fd2i);2823} else if (left->is_double_xmm()) {2824assert(right->is_double_xmm(), "must match");2825__ cmpsd2int(left->as_xmm_double_reg(), right->as_xmm_double_reg(), dst->as_register(), code == lir_ucmp_fd2i);28262827} else {2828#ifdef _LP642829ShouldNotReachHere();2830#else2831assert(left->is_single_fpu() || left->is_double_fpu(), "must be");2832assert(right->is_single_fpu() || right->is_double_fpu(), "must match");28332834assert(left->fpu() == 0, "left must be on TOS");2835__ fcmp2int(dst->as_register(), code == lir_ucmp_fd2i, right->fpu(),2836op->fpu_pop_count() > 0, op->fpu_pop_count() > 1);2837#endif // LP642838}2839} else {2840assert(code == lir_cmp_l2i, "check");2841#ifdef _LP642842Label done;2843Register dest = dst->as_register();2844__ cmpptr(left->as_register_lo(), right->as_register_lo());2845__ movl(dest, -1);2846__ jccb(Assembler::less, done);2847__ set_byte_if_not_zero(dest);2848__ movzbl(dest, dest);2849__ bind(done);2850#else2851__ lcmp2int(left->as_register_hi(),2852left->as_register_lo(),2853right->as_register_hi(),2854right->as_register_lo());2855move_regs(left->as_register_hi(), dst->as_register());2856#endif // _LP642857}2858}285928602861void LIR_Assembler::align_call(LIR_Code code) {2862// make sure that the displacement word of the call ends up word aligned2863int offset = __ offset();2864switch (code) {2865case lir_static_call:2866case lir_optvirtual_call:2867case lir_dynamic_call:2868offset += NativeCall::displacement_offset;2869break;2870case lir_icvirtual_call:2871offset += NativeCall::displacement_offset + NativeMovConstReg::instruction_size;2872break;2873default: ShouldNotReachHere();2874}2875__ align(BytesPerWord, offset);2876}287728782879void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) {2880assert((__ offset() + NativeCall::displacement_offset) % BytesPerWord == 0,2881"must be aligned");2882__ call(AddressLiteral(op->addr(), rtype));2883add_call_info(code_offset(), op->info());2884}288528862887void LIR_Assembler::ic_call(LIR_OpJavaCall* op) {2888__ ic_call(op->addr());2889add_call_info(code_offset(), op->info());2890assert((__ offset() - NativeCall::instruction_size + NativeCall::displacement_offset) % BytesPerWord == 0,2891"must be aligned");2892}289328942895void LIR_Assembler::emit_static_call_stub() {2896address call_pc = __ pc();2897address stub = __ start_a_stub(call_stub_size());2898if (stub == NULL) {2899bailout("static call stub overflow");2900return;2901}29022903int start = __ offset();29042905// make sure that the displacement word of the call ends up word aligned2906__ align(BytesPerWord, __ offset() + NativeMovConstReg::instruction_size + NativeCall::displacement_offset);2907__ relocate(static_stub_Relocation::spec(call_pc));2908__ mov_metadata(rbx, (Metadata*)NULL);2909// must be set to -1 at code generation time2910assert(((__ offset() + 1) % BytesPerWord) == 0, "must be aligned");2911// On 64bit this will die since it will take a movq & jmp, must be only a jmp2912__ jump(RuntimeAddress(__ pc()));29132914assert(__ offset() - start <= call_stub_size(), "stub too big");2915__ end_a_stub();2916}291729182919void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) {2920assert(exceptionOop->as_register() == rax, "must match");2921assert(exceptionPC->as_register() == rdx, "must match");29222923// exception object is not added to oop map by LinearScan2924// (LinearScan assumes that no oops are in fixed registers)2925info->add_register_oop(exceptionOop);2926Runtime1::StubID unwind_id;29272928// get current pc information2929// pc is only needed if the method has an exception handler, the unwind code does not need it.2930int pc_for_athrow_offset = __ offset();2931InternalAddress pc_for_athrow(__ pc());2932__ lea(exceptionPC->as_register(), pc_for_athrow);2933add_call_info(pc_for_athrow_offset, info); // for exception handler29342935__ verify_not_null_oop(rax);2936// search an exception handler (rax: exception oop, rdx: throwing pc)2937if (compilation()->has_fpu_code()) {2938unwind_id = Runtime1::handle_exception_id;2939} else {2940unwind_id = Runtime1::handle_exception_nofpu_id;2941}2942__ call(RuntimeAddress(Runtime1::entry_for(unwind_id)));29432944// enough room for two byte trap2945__ nop();2946}294729482949void LIR_Assembler::unwind_op(LIR_Opr exceptionOop) {2950assert(exceptionOop->as_register() == rax, "must match");29512952__ jmp(_unwind_handler_entry);2953}295429552956void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) {29572958// optimized version for linear scan:2959// * count must be already in ECX (guaranteed by LinearScan)2960// * left and dest must be equal2961// * tmp must be unused2962assert(count->as_register() == SHIFT_count, "count must be in ECX");2963assert(left == dest, "left and dest must be equal");2964assert(tmp->is_illegal(), "wasting a register if tmp is allocated");29652966if (left->is_single_cpu()) {2967Register value = left->as_register();2968assert(value != SHIFT_count, "left cannot be ECX");29692970switch (code) {2971case lir_shl: __ shll(value); break;2972case lir_shr: __ sarl(value); break;2973case lir_ushr: __ shrl(value); break;2974default: ShouldNotReachHere();2975}2976} else if (left->is_double_cpu()) {2977Register lo = left->as_register_lo();2978Register hi = left->as_register_hi();2979assert(lo != SHIFT_count && hi != SHIFT_count, "left cannot be ECX");2980#ifdef _LP642981switch (code) {2982case lir_shl: __ shlptr(lo); break;2983case lir_shr: __ sarptr(lo); break;2984case lir_ushr: __ shrptr(lo); break;2985default: ShouldNotReachHere();2986}2987#else29882989switch (code) {2990case lir_shl: __ lshl(hi, lo); break;2991case lir_shr: __ lshr(hi, lo, true); break;2992case lir_ushr: __ lshr(hi, lo, false); break;2993default: ShouldNotReachHere();2994}2995#endif // LP642996} else {2997ShouldNotReachHere();2998}2999}300030013002void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, jint count, LIR_Opr dest) {3003if (dest->is_single_cpu()) {3004// first move left into dest so that left is not destroyed by the shift3005Register value = dest->as_register();3006count = count & 0x1F; // Java spec30073008move_regs(left->as_register(), value);3009switch (code) {3010case lir_shl: __ shll(value, count); break;3011case lir_shr: __ sarl(value, count); break;3012case lir_ushr: __ shrl(value, count); break;3013default: ShouldNotReachHere();3014}3015} else if (dest->is_double_cpu()) {3016#ifndef _LP643017Unimplemented();3018#else3019// first move left into dest so that left is not destroyed by the shift3020Register value = dest->as_register_lo();3021count = count & 0x1F; // Java spec30223023move_regs(left->as_register_lo(), value);3024switch (code) {3025case lir_shl: __ shlptr(value, count); break;3026case lir_shr: __ sarptr(value, count); break;3027case lir_ushr: __ shrptr(value, count); break;3028default: ShouldNotReachHere();3029}3030#endif // _LP643031} else {3032ShouldNotReachHere();3033}3034}303530363037void LIR_Assembler::store_parameter(Register r, int offset_from_rsp_in_words) {3038assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp");3039int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord;3040assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset");3041__ movptr (Address(rsp, offset_from_rsp_in_bytes), r);3042}304330443045void LIR_Assembler::store_parameter(jint c, int offset_from_rsp_in_words) {3046assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp");3047int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord;3048assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset");3049__ movptr (Address(rsp, offset_from_rsp_in_bytes), c);3050}305130523053void LIR_Assembler::store_parameter(jobject o, int offset_from_rsp_in_words) {3054assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp");3055int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord;3056assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset");3057__ movoop (Address(rsp, offset_from_rsp_in_bytes), o);3058}305930603061void LIR_Assembler::store_parameter(Metadata* m, int offset_from_rsp_in_words) {3062assert(offset_from_rsp_in_words >= 0, "invalid offset from rsp");3063int offset_from_rsp_in_bytes = offset_from_rsp_in_words * BytesPerWord;3064assert(offset_from_rsp_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset");3065__ mov_metadata(Address(rsp, offset_from_rsp_in_bytes), m);3066}306730683069// This code replaces a call to arraycopy; no exception may3070// be thrown in this code, they must be thrown in the System.arraycopy3071// activation frame; we could save some checks if this would not be the case3072void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {3073ciArrayKlass* default_type = op->expected_type();3074Register src = op->src()->as_register();3075Register dst = op->dst()->as_register();3076Register src_pos = op->src_pos()->as_register();3077Register dst_pos = op->dst_pos()->as_register();3078Register length = op->length()->as_register();3079Register tmp = op->tmp()->as_register();3080Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);30813082CodeStub* stub = op->stub();3083int flags = op->flags();3084BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL;3085if (is_reference_type(basic_type)) basic_type = T_OBJECT;30863087// if we don't know anything, just go through the generic arraycopy3088if (default_type == NULL) {3089// save outgoing arguments on stack in case call to System.arraycopy is needed3090// HACK ALERT. This code used to push the parameters in a hardwired fashion3091// for interpreter calling conventions. Now we have to do it in new style conventions.3092// For the moment until C1 gets the new register allocator I just force all the3093// args to the right place (except the register args) and then on the back side3094// reload the register args properly if we go slow path. Yuck30953096// These are proper for the calling convention3097store_parameter(length, 2);3098store_parameter(dst_pos, 1);3099store_parameter(dst, 0);31003101// these are just temporary placements until we need to reload3102store_parameter(src_pos, 3);3103store_parameter(src, 4);3104NOT_LP64(assert(src == rcx && src_pos == rdx, "mismatch in calling convention");)31053106address copyfunc_addr = StubRoutines::generic_arraycopy();3107assert(copyfunc_addr != NULL, "generic arraycopy stub required");31083109// pass arguments: may push as this is not a safepoint; SP must be fix at each safepoint3110#ifdef _LP643111// The arguments are in java calling convention so we can trivially shift them to C3112// convention3113assert_different_registers(c_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4);3114__ mov(c_rarg0, j_rarg0);3115assert_different_registers(c_rarg1, j_rarg2, j_rarg3, j_rarg4);3116__ mov(c_rarg1, j_rarg1);3117assert_different_registers(c_rarg2, j_rarg3, j_rarg4);3118__ mov(c_rarg2, j_rarg2);3119assert_different_registers(c_rarg3, j_rarg4);3120__ mov(c_rarg3, j_rarg3);3121#ifdef _WIN643122// Allocate abi space for args but be sure to keep stack aligned3123__ subptr(rsp, 6*wordSize);3124store_parameter(j_rarg4, 4);3125#ifndef PRODUCT3126if (PrintC1Statistics) {3127__ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));3128}3129#endif3130__ call(RuntimeAddress(copyfunc_addr));3131__ addptr(rsp, 6*wordSize);3132#else3133__ mov(c_rarg4, j_rarg4);3134#ifndef PRODUCT3135if (PrintC1Statistics) {3136__ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));3137}3138#endif3139__ call(RuntimeAddress(copyfunc_addr));3140#endif // _WIN643141#else3142__ push(length);3143__ push(dst_pos);3144__ push(dst);3145__ push(src_pos);3146__ push(src);31473148#ifndef PRODUCT3149if (PrintC1Statistics) {3150__ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));3151}3152#endif3153__ call_VM_leaf(copyfunc_addr, 5); // removes pushed parameter from the stack31543155#endif // _LP6431563157__ cmpl(rax, 0);3158__ jcc(Assembler::equal, *stub->continuation());31593160__ mov(tmp, rax);3161__ xorl(tmp, -1);31623163// Reload values from the stack so they are where the stub3164// expects them.3165__ movptr (dst, Address(rsp, 0*BytesPerWord));3166__ movptr (dst_pos, Address(rsp, 1*BytesPerWord));3167__ movptr (length, Address(rsp, 2*BytesPerWord));3168__ movptr (src_pos, Address(rsp, 3*BytesPerWord));3169__ movptr (src, Address(rsp, 4*BytesPerWord));31703171__ subl(length, tmp);3172__ addl(src_pos, tmp);3173__ addl(dst_pos, tmp);3174__ jmp(*stub->entry());31753176__ bind(*stub->continuation());3177return;3178}31793180assert(default_type != NULL && default_type->is_array_klass() && default_type->is_loaded(), "must be true at this point");31813182int elem_size = type2aelembytes(basic_type);3183Address::ScaleFactor scale;31843185switch (elem_size) {3186case 1 :3187scale = Address::times_1;3188break;3189case 2 :3190scale = Address::times_2;3191break;3192case 4 :3193scale = Address::times_4;3194break;3195case 8 :3196scale = Address::times_8;3197break;3198default:3199scale = Address::no_scale;3200ShouldNotReachHere();3201}32023203Address src_length_addr = Address(src, arrayOopDesc::length_offset_in_bytes());3204Address dst_length_addr = Address(dst, arrayOopDesc::length_offset_in_bytes());3205Address src_klass_addr = Address(src, oopDesc::klass_offset_in_bytes());3206Address dst_klass_addr = Address(dst, oopDesc::klass_offset_in_bytes());32073208// length and pos's are all sign extended at this point on 64bit32093210// test for NULL3211if (flags & LIR_OpArrayCopy::src_null_check) {3212__ testptr(src, src);3213__ jcc(Assembler::zero, *stub->entry());3214}3215if (flags & LIR_OpArrayCopy::dst_null_check) {3216__ testptr(dst, dst);3217__ jcc(Assembler::zero, *stub->entry());3218}32193220// If the compiler was not able to prove that exact type of the source or the destination3221// of the arraycopy is an array type, check at runtime if the source or the destination is3222// an instance type.3223if (flags & LIR_OpArrayCopy::type_check) {3224if (!(flags & LIR_OpArrayCopy::dst_objarray)) {3225__ load_klass(tmp, dst, tmp_load_klass);3226__ cmpl(Address(tmp, in_bytes(Klass::layout_helper_offset())), Klass::_lh_neutral_value);3227__ jcc(Assembler::greaterEqual, *stub->entry());3228}32293230if (!(flags & LIR_OpArrayCopy::src_objarray)) {3231__ load_klass(tmp, src, tmp_load_klass);3232__ cmpl(Address(tmp, in_bytes(Klass::layout_helper_offset())), Klass::_lh_neutral_value);3233__ jcc(Assembler::greaterEqual, *stub->entry());3234}3235}32363237// check if negative3238if (flags & LIR_OpArrayCopy::src_pos_positive_check) {3239__ testl(src_pos, src_pos);3240__ jcc(Assembler::less, *stub->entry());3241}3242if (flags & LIR_OpArrayCopy::dst_pos_positive_check) {3243__ testl(dst_pos, dst_pos);3244__ jcc(Assembler::less, *stub->entry());3245}32463247if (flags & LIR_OpArrayCopy::src_range_check) {3248__ lea(tmp, Address(src_pos, length, Address::times_1, 0));3249__ cmpl(tmp, src_length_addr);3250__ jcc(Assembler::above, *stub->entry());3251}3252if (flags & LIR_OpArrayCopy::dst_range_check) {3253__ lea(tmp, Address(dst_pos, length, Address::times_1, 0));3254__ cmpl(tmp, dst_length_addr);3255__ jcc(Assembler::above, *stub->entry());3256}32573258if (flags & LIR_OpArrayCopy::length_positive_check) {3259__ testl(length, length);3260__ jcc(Assembler::less, *stub->entry());3261}32623263#ifdef _LP643264__ movl2ptr(src_pos, src_pos); //higher 32bits must be null3265__ movl2ptr(dst_pos, dst_pos); //higher 32bits must be null3266#endif32673268if (flags & LIR_OpArrayCopy::type_check) {3269// We don't know the array types are compatible3270if (basic_type != T_OBJECT) {3271// Simple test for basic type arrays3272if (UseCompressedClassPointers) {3273__ movl(tmp, src_klass_addr);3274__ cmpl(tmp, dst_klass_addr);3275} else {3276__ movptr(tmp, src_klass_addr);3277__ cmpptr(tmp, dst_klass_addr);3278}3279__ jcc(Assembler::notEqual, *stub->entry());3280} else {3281// For object arrays, if src is a sub class of dst then we can3282// safely do the copy.3283Label cont, slow;32843285__ push(src);3286__ push(dst);32873288__ load_klass(src, src, tmp_load_klass);3289__ load_klass(dst, dst, tmp_load_klass);32903291__ check_klass_subtype_fast_path(src, dst, tmp, &cont, &slow, NULL);32923293__ push(src);3294__ push(dst);3295__ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));3296__ pop(dst);3297__ pop(src);32983299__ cmpl(src, 0);3300__ jcc(Assembler::notEqual, cont);33013302__ bind(slow);3303__ pop(dst);3304__ pop(src);33053306address copyfunc_addr = StubRoutines::checkcast_arraycopy();3307if (copyfunc_addr != NULL) { // use stub if available3308// src is not a sub class of dst so we have to do a3309// per-element check.33103311int mask = LIR_OpArrayCopy::src_objarray|LIR_OpArrayCopy::dst_objarray;3312if ((flags & mask) != mask) {3313// Check that at least both of them object arrays.3314assert(flags & mask, "one of the two should be known to be an object array");33153316if (!(flags & LIR_OpArrayCopy::src_objarray)) {3317__ load_klass(tmp, src, tmp_load_klass);3318} else if (!(flags & LIR_OpArrayCopy::dst_objarray)) {3319__ load_klass(tmp, dst, tmp_load_klass);3320}3321int lh_offset = in_bytes(Klass::layout_helper_offset());3322Address klass_lh_addr(tmp, lh_offset);3323jint objArray_lh = Klass::array_layout_helper(T_OBJECT);3324__ cmpl(klass_lh_addr, objArray_lh);3325__ jcc(Assembler::notEqual, *stub->entry());3326}33273328// Spill because stubs can use any register they like and it's3329// easier to restore just those that we care about.3330store_parameter(dst, 0);3331store_parameter(dst_pos, 1);3332store_parameter(length, 2);3333store_parameter(src_pos, 3);3334store_parameter(src, 4);33353336#ifndef _LP643337__ movptr(tmp, dst_klass_addr);3338__ movptr(tmp, Address(tmp, ObjArrayKlass::element_klass_offset()));3339__ push(tmp);3340__ movl(tmp, Address(tmp, Klass::super_check_offset_offset()));3341__ push(tmp);3342__ push(length);3343__ lea(tmp, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));3344__ push(tmp);3345__ lea(tmp, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));3346__ push(tmp);33473348__ call_VM_leaf(copyfunc_addr, 5);3349#else3350__ movl2ptr(length, length); //higher 32bits must be null33513352__ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));3353assert_different_registers(c_rarg0, dst, dst_pos, length);3354__ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));3355assert_different_registers(c_rarg1, dst, length);33563357__ mov(c_rarg2, length);3358assert_different_registers(c_rarg2, dst);33593360#ifdef _WIN643361// Allocate abi space for args but be sure to keep stack aligned3362__ subptr(rsp, 6*wordSize);3363__ load_klass(c_rarg3, dst, tmp_load_klass);3364__ movptr(c_rarg3, Address(c_rarg3, ObjArrayKlass::element_klass_offset()));3365store_parameter(c_rarg3, 4);3366__ movl(c_rarg3, Address(c_rarg3, Klass::super_check_offset_offset()));3367__ call(RuntimeAddress(copyfunc_addr));3368__ addptr(rsp, 6*wordSize);3369#else3370__ load_klass(c_rarg4, dst, tmp_load_klass);3371__ movptr(c_rarg4, Address(c_rarg4, ObjArrayKlass::element_klass_offset()));3372__ movl(c_rarg3, Address(c_rarg4, Klass::super_check_offset_offset()));3373__ call(RuntimeAddress(copyfunc_addr));3374#endif33753376#endif33773378#ifndef PRODUCT3379if (PrintC1Statistics) {3380Label failed;3381__ testl(rax, rax);3382__ jcc(Assembler::notZero, failed);3383__ incrementl(ExternalAddress((address)&Runtime1::_arraycopy_checkcast_cnt));3384__ bind(failed);3385}3386#endif33873388__ testl(rax, rax);3389__ jcc(Assembler::zero, *stub->continuation());33903391#ifndef PRODUCT3392if (PrintC1Statistics) {3393__ incrementl(ExternalAddress((address)&Runtime1::_arraycopy_checkcast_attempt_cnt));3394}3395#endif33963397__ mov(tmp, rax);33983399__ xorl(tmp, -1);34003401// Restore previously spilled arguments3402__ movptr (dst, Address(rsp, 0*BytesPerWord));3403__ movptr (dst_pos, Address(rsp, 1*BytesPerWord));3404__ movptr (length, Address(rsp, 2*BytesPerWord));3405__ movptr (src_pos, Address(rsp, 3*BytesPerWord));3406__ movptr (src, Address(rsp, 4*BytesPerWord));340734083409__ subl(length, tmp);3410__ addl(src_pos, tmp);3411__ addl(dst_pos, tmp);3412}34133414__ jmp(*stub->entry());34153416__ bind(cont);3417__ pop(dst);3418__ pop(src);3419}3420}34213422#ifdef ASSERT3423if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) {3424// Sanity check the known type with the incoming class. For the3425// primitive case the types must match exactly with src.klass and3426// dst.klass each exactly matching the default type. For the3427// object array case, if no type check is needed then either the3428// dst type is exactly the expected type and the src type is a3429// subtype which we can't check or src is the same array as dst3430// but not necessarily exactly of type default_type.3431Label known_ok, halt;3432__ mov_metadata(tmp, default_type->constant_encoding());3433#ifdef _LP643434if (UseCompressedClassPointers) {3435__ encode_klass_not_null(tmp, rscratch1);3436}3437#endif34383439if (basic_type != T_OBJECT) {34403441if (UseCompressedClassPointers) __ cmpl(tmp, dst_klass_addr);3442else __ cmpptr(tmp, dst_klass_addr);3443__ jcc(Assembler::notEqual, halt);3444if (UseCompressedClassPointers) __ cmpl(tmp, src_klass_addr);3445else __ cmpptr(tmp, src_klass_addr);3446__ jcc(Assembler::equal, known_ok);3447} else {3448if (UseCompressedClassPointers) __ cmpl(tmp, dst_klass_addr);3449else __ cmpptr(tmp, dst_klass_addr);3450__ jcc(Assembler::equal, known_ok);3451__ cmpptr(src, dst);3452__ jcc(Assembler::equal, known_ok);3453}3454__ bind(halt);3455__ stop("incorrect type information in arraycopy");3456__ bind(known_ok);3457}3458#endif34593460#ifndef PRODUCT3461if (PrintC1Statistics) {3462__ incrementl(ExternalAddress(Runtime1::arraycopy_count_address(basic_type)));3463}3464#endif34653466#ifdef _LP643467assert_different_registers(c_rarg0, dst, dst_pos, length);3468__ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));3469assert_different_registers(c_rarg1, length);3470__ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));3471__ mov(c_rarg2, length);34723473#else3474__ lea(tmp, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));3475store_parameter(tmp, 0);3476__ lea(tmp, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type)));3477store_parameter(tmp, 1);3478store_parameter(length, 2);3479#endif // _LP6434803481bool disjoint = (flags & LIR_OpArrayCopy::overlapping) == 0;3482bool aligned = (flags & LIR_OpArrayCopy::unaligned) == 0;3483const char *name;3484address entry = StubRoutines::select_arraycopy_function(basic_type, aligned, disjoint, name, false);3485__ call_VM_leaf(entry, 0);34863487__ bind(*stub->continuation());3488}34893490void LIR_Assembler::emit_updatecrc32(LIR_OpUpdateCRC32* op) {3491assert(op->crc()->is_single_cpu(), "crc must be register");3492assert(op->val()->is_single_cpu(), "byte value must be register");3493assert(op->result_opr()->is_single_cpu(), "result must be register");3494Register crc = op->crc()->as_register();3495Register val = op->val()->as_register();3496Register res = op->result_opr()->as_register();34973498assert_different_registers(val, crc, res);34993500__ lea(res, ExternalAddress(StubRoutines::crc_table_addr()));3501__ notl(crc); // ~crc3502__ update_byte_crc32(crc, val, res);3503__ notl(crc); // ~crc3504__ mov(res, crc);3505}35063507void LIR_Assembler::emit_lock(LIR_OpLock* op) {3508Register obj = op->obj_opr()->as_register(); // may not be an oop3509Register hdr = op->hdr_opr()->as_register();3510Register lock = op->lock_opr()->as_register();3511if (!UseFastLocking) {3512__ jmp(*op->stub()->entry());3513} else if (op->code() == lir_lock) {3514Register scratch = noreg;3515if (UseBiasedLocking) {3516scratch = op->scratch_opr()->as_register();3517}3518assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");3519// add debug info for NullPointerException only if one is possible3520int null_check_offset = __ lock_object(hdr, obj, lock, scratch, *op->stub()->entry());3521if (op->info() != NULL) {3522add_debug_info_for_null_check(null_check_offset, op->info());3523}3524// done3525} else if (op->code() == lir_unlock) {3526assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");3527__ unlock_object(hdr, obj, lock, *op->stub()->entry());3528} else {3529Unimplemented();3530}3531__ bind(*op->stub()->continuation());3532}353335343535void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {3536ciMethod* method = op->profiled_method();3537int bci = op->profiled_bci();3538ciMethod* callee = op->profiled_callee();3539Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);35403541// Update counter for all call types3542ciMethodData* md = method->method_data_or_null();3543assert(md != NULL, "Sanity");3544ciProfileData* data = md->bci_to_data(bci);3545assert(data != NULL && data->is_CounterData(), "need CounterData for calls");3546assert(op->mdo()->is_single_cpu(), "mdo must be allocated");3547Register mdo = op->mdo()->as_register();3548__ mov_metadata(mdo, md->constant_encoding());3549Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));3550// Perform additional virtual call profiling for invokevirtual and3551// invokeinterface bytecodes3552if (op->should_profile_receiver_type()) {3553assert(op->recv()->is_single_cpu(), "recv must be allocated");3554Register recv = op->recv()->as_register();3555assert_different_registers(mdo, recv);3556assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls");3557ciKlass* known_klass = op->known_holder();3558if (C1OptimizeVirtualCallProfiling && known_klass != NULL) {3559// We know the type that will be seen at this call site; we can3560// statically update the MethodData* rather than needing to do3561// dynamic tests on the receiver type35623563// NOTE: we should probably put a lock around this search to3564// avoid collisions by concurrent compilations3565ciVirtualCallData* vc_data = (ciVirtualCallData*) data;3566uint i;3567for (i = 0; i < VirtualCallData::row_limit(); i++) {3568ciKlass* receiver = vc_data->receiver(i);3569if (known_klass->equals(receiver)) {3570Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));3571__ addptr(data_addr, DataLayout::counter_increment);3572return;3573}3574}35753576// Receiver type not found in profile data; select an empty slot35773578// Note that this is less efficient than it should be because it3579// always does a write to the receiver part of the3580// VirtualCallData rather than just the first time3581for (i = 0; i < VirtualCallData::row_limit(); i++) {3582ciKlass* receiver = vc_data->receiver(i);3583if (receiver == NULL) {3584Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)));3585__ mov_metadata(recv_addr, known_klass->constant_encoding());3586Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));3587__ addptr(data_addr, DataLayout::counter_increment);3588return;3589}3590}3591} else {3592__ load_klass(recv, recv, tmp_load_klass);3593Label update_done;3594type_profile_helper(mdo, md, data, recv, &update_done);3595// Receiver did not match any saved receiver and there is no empty row for it.3596// Increment total counter to indicate polymorphic case.3597__ addptr(counter_addr, DataLayout::counter_increment);35983599__ bind(update_done);3600}3601} else {3602// Static call3603__ addptr(counter_addr, DataLayout::counter_increment);3604}3605}36063607void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {3608Register obj = op->obj()->as_register();3609Register tmp = op->tmp()->as_pointer_register();3610Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);3611Address mdo_addr = as_Address(op->mdp()->as_address_ptr());3612ciKlass* exact_klass = op->exact_klass();3613intptr_t current_klass = op->current_klass();3614bool not_null = op->not_null();3615bool no_conflict = op->no_conflict();36163617Label update, next, none;36183619bool do_null = !not_null;3620bool exact_klass_set = exact_klass != NULL && ciTypeEntries::valid_ciklass(current_klass) == exact_klass;3621bool do_update = !TypeEntries::is_type_unknown(current_klass) && !exact_klass_set;36223623assert(do_null || do_update, "why are we here?");3624assert(!TypeEntries::was_null_seen(current_klass) || do_update, "why are we here?");36253626__ verify_oop(obj);36273628if (tmp != obj) {3629__ mov(tmp, obj);3630}3631if (do_null) {3632__ testptr(tmp, tmp);3633__ jccb(Assembler::notZero, update);3634if (!TypeEntries::was_null_seen(current_klass)) {3635__ orptr(mdo_addr, TypeEntries::null_seen);3636}3637if (do_update) {3638#ifndef ASSERT3639__ jmpb(next);3640}3641#else3642__ jmp(next);3643}3644} else {3645__ testptr(tmp, tmp);3646__ jcc(Assembler::notZero, update);3647__ stop("unexpect null obj");3648#endif3649}36503651__ bind(update);36523653if (do_update) {3654#ifdef ASSERT3655if (exact_klass != NULL) {3656Label ok;3657__ load_klass(tmp, tmp, tmp_load_klass);3658__ push(tmp);3659__ mov_metadata(tmp, exact_klass->constant_encoding());3660__ cmpptr(tmp, Address(rsp, 0));3661__ jcc(Assembler::equal, ok);3662__ stop("exact klass and actual klass differ");3663__ bind(ok);3664__ pop(tmp);3665}3666#endif3667if (!no_conflict) {3668if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) {3669if (exact_klass != NULL) {3670__ mov_metadata(tmp, exact_klass->constant_encoding());3671} else {3672__ load_klass(tmp, tmp, tmp_load_klass);3673}36743675__ xorptr(tmp, mdo_addr);3676__ testptr(tmp, TypeEntries::type_klass_mask);3677// klass seen before, nothing to do. The unknown bit may have been3678// set already but no need to check.3679__ jccb(Assembler::zero, next);36803681__ testptr(tmp, TypeEntries::type_unknown);3682__ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.36833684if (TypeEntries::is_type_none(current_klass)) {3685__ cmpptr(mdo_addr, 0);3686__ jccb(Assembler::equal, none);3687__ cmpptr(mdo_addr, TypeEntries::null_seen);3688__ jccb(Assembler::equal, none);3689// There is a chance that the checks above (re-reading profiling3690// data from memory) fail if another thread has just set the3691// profiling to this obj's klass3692__ xorptr(tmp, mdo_addr);3693__ testptr(tmp, TypeEntries::type_klass_mask);3694__ jccb(Assembler::zero, next);3695}3696} else {3697assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&3698ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only");36993700__ movptr(tmp, mdo_addr);3701__ testptr(tmp, TypeEntries::type_unknown);3702__ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.3703}37043705// different than before. Cannot keep accurate profile.3706__ orptr(mdo_addr, TypeEntries::type_unknown);37073708if (TypeEntries::is_type_none(current_klass)) {3709__ jmpb(next);37103711__ bind(none);3712// first time here. Set profile type.3713__ movptr(mdo_addr, tmp);3714}3715} else {3716// There's a single possible klass at this profile point3717assert(exact_klass != NULL, "should be");3718if (TypeEntries::is_type_none(current_klass)) {3719__ mov_metadata(tmp, exact_klass->constant_encoding());3720__ xorptr(tmp, mdo_addr);3721__ testptr(tmp, TypeEntries::type_klass_mask);3722#ifdef ASSERT3723__ jcc(Assembler::zero, next);37243725{3726Label ok;3727__ push(tmp);3728__ cmpptr(mdo_addr, 0);3729__ jcc(Assembler::equal, ok);3730__ cmpptr(mdo_addr, TypeEntries::null_seen);3731__ jcc(Assembler::equal, ok);3732// may have been set by another thread3733__ mov_metadata(tmp, exact_klass->constant_encoding());3734__ xorptr(tmp, mdo_addr);3735__ testptr(tmp, TypeEntries::type_mask);3736__ jcc(Assembler::zero, ok);37373738__ stop("unexpected profiling mismatch");3739__ bind(ok);3740__ pop(tmp);3741}3742#else3743__ jccb(Assembler::zero, next);3744#endif3745// first time here. Set profile type.3746__ movptr(mdo_addr, tmp);3747} else {3748assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&3749ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");37503751__ movptr(tmp, mdo_addr);3752__ testptr(tmp, TypeEntries::type_unknown);3753__ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.37543755__ orptr(mdo_addr, TypeEntries::type_unknown);3756}3757}37583759__ bind(next);3760}3761}37623763void LIR_Assembler::emit_delay(LIR_OpDelay*) {3764Unimplemented();3765}376637673768void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) {3769__ lea(dst->as_register(), frame_map()->address_for_monitor_lock(monitor_no));3770}377137723773void LIR_Assembler::align_backward_branch_target() {3774__ align(BytesPerWord);3775}377637773778void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest, LIR_Opr tmp) {3779if (left->is_single_cpu()) {3780__ negl(left->as_register());3781move_regs(left->as_register(), dest->as_register());37823783} else if (left->is_double_cpu()) {3784Register lo = left->as_register_lo();3785#ifdef _LP643786Register dst = dest->as_register_lo();3787__ movptr(dst, lo);3788__ negptr(dst);3789#else3790Register hi = left->as_register_hi();3791__ lneg(hi, lo);3792if (dest->as_register_lo() == hi) {3793assert(dest->as_register_hi() != lo, "destroying register");3794move_regs(hi, dest->as_register_hi());3795move_regs(lo, dest->as_register_lo());3796} else {3797move_regs(lo, dest->as_register_lo());3798move_regs(hi, dest->as_register_hi());3799}3800#endif // _LP6438013802} else if (dest->is_single_xmm()) {3803#ifdef _LP643804if (UseAVX > 2 && !VM_Version::supports_avx512vl()) {3805assert(tmp->is_valid(), "need temporary");3806assert_different_registers(left->as_xmm_float_reg(), tmp->as_xmm_float_reg());3807__ vpxor(dest->as_xmm_float_reg(), tmp->as_xmm_float_reg(), left->as_xmm_float_reg(), 2);3808}3809else3810#endif3811{3812assert(!tmp->is_valid(), "do not need temporary");3813if (left->as_xmm_float_reg() != dest->as_xmm_float_reg()) {3814__ movflt(dest->as_xmm_float_reg(), left->as_xmm_float_reg());3815}3816__ xorps(dest->as_xmm_float_reg(),3817ExternalAddress((address)float_signflip_pool));3818}3819} else if (dest->is_double_xmm()) {3820#ifdef _LP643821if (UseAVX > 2 && !VM_Version::supports_avx512vl()) {3822assert(tmp->is_valid(), "need temporary");3823assert_different_registers(left->as_xmm_double_reg(), tmp->as_xmm_double_reg());3824__ vpxor(dest->as_xmm_double_reg(), tmp->as_xmm_double_reg(), left->as_xmm_double_reg(), 2);3825}3826else3827#endif3828{3829assert(!tmp->is_valid(), "do not need temporary");3830if (left->as_xmm_double_reg() != dest->as_xmm_double_reg()) {3831__ movdbl(dest->as_xmm_double_reg(), left->as_xmm_double_reg());3832}3833__ xorpd(dest->as_xmm_double_reg(),3834ExternalAddress((address)double_signflip_pool));3835}3836#ifndef _LP643837} else if (left->is_single_fpu() || left->is_double_fpu()) {3838assert(left->fpu() == 0, "arg must be on TOS");3839assert(dest->fpu() == 0, "dest must be TOS");3840__ fchs();3841#endif // !_LP6438423843} else {3844ShouldNotReachHere();3845}3846}384738483849void LIR_Assembler::leal(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {3850assert(src->is_address(), "must be an address");3851assert(dest->is_register(), "must be a register");38523853PatchingStub* patch = NULL;3854if (patch_code != lir_patch_none) {3855patch = new PatchingStub(_masm, PatchingStub::access_field_id);3856}38573858Register reg = dest->as_pointer_register();3859LIR_Address* addr = src->as_address_ptr();3860__ lea(reg, as_Address(addr));38613862if (patch != NULL) {3863patching_epilog(patch, patch_code, addr->base()->as_register(), info);3864}3865}3866386738683869void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) {3870assert(!tmp->is_valid(), "don't need temporary");3871__ call(RuntimeAddress(dest));3872if (info != NULL) {3873add_call_info_here(info);3874}3875}387638773878void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) {3879assert(type == T_LONG, "only for volatile long fields");38803881if (info != NULL) {3882add_debug_info_for_null_check_here(info);3883}38843885if (src->is_double_xmm()) {3886if (dest->is_double_cpu()) {3887#ifdef _LP643888__ movdq(dest->as_register_lo(), src->as_xmm_double_reg());3889#else3890__ movdl(dest->as_register_lo(), src->as_xmm_double_reg());3891__ psrlq(src->as_xmm_double_reg(), 32);3892__ movdl(dest->as_register_hi(), src->as_xmm_double_reg());3893#endif // _LP643894} else if (dest->is_double_stack()) {3895__ movdbl(frame_map()->address_for_slot(dest->double_stack_ix()), src->as_xmm_double_reg());3896} else if (dest->is_address()) {3897__ movdbl(as_Address(dest->as_address_ptr()), src->as_xmm_double_reg());3898} else {3899ShouldNotReachHere();3900}39013902} else if (dest->is_double_xmm()) {3903if (src->is_double_stack()) {3904__ movdbl(dest->as_xmm_double_reg(), frame_map()->address_for_slot(src->double_stack_ix()));3905} else if (src->is_address()) {3906__ movdbl(dest->as_xmm_double_reg(), as_Address(src->as_address_ptr()));3907} else {3908ShouldNotReachHere();3909}39103911#ifndef _LP643912} else if (src->is_double_fpu()) {3913assert(src->fpu_regnrLo() == 0, "must be TOS");3914if (dest->is_double_stack()) {3915__ fistp_d(frame_map()->address_for_slot(dest->double_stack_ix()));3916} else if (dest->is_address()) {3917__ fistp_d(as_Address(dest->as_address_ptr()));3918} else {3919ShouldNotReachHere();3920}39213922} else if (dest->is_double_fpu()) {3923assert(dest->fpu_regnrLo() == 0, "must be TOS");3924if (src->is_double_stack()) {3925__ fild_d(frame_map()->address_for_slot(src->double_stack_ix()));3926} else if (src->is_address()) {3927__ fild_d(as_Address(src->as_address_ptr()));3928} else {3929ShouldNotReachHere();3930}3931#endif // !_LP6439323933} else {3934ShouldNotReachHere();3935}3936}39373938#ifdef ASSERT3939// emit run-time assertion3940void LIR_Assembler::emit_assert(LIR_OpAssert* op) {3941assert(op->code() == lir_assert, "must be");39423943if (op->in_opr1()->is_valid()) {3944assert(op->in_opr2()->is_valid(), "both operands must be valid");3945comp_op(op->condition(), op->in_opr1(), op->in_opr2(), op);3946} else {3947assert(op->in_opr2()->is_illegal(), "both operands must be illegal");3948assert(op->condition() == lir_cond_always, "no other conditions allowed");3949}39503951Label ok;3952if (op->condition() != lir_cond_always) {3953Assembler::Condition acond = Assembler::zero;3954switch (op->condition()) {3955case lir_cond_equal: acond = Assembler::equal; break;3956case lir_cond_notEqual: acond = Assembler::notEqual; break;3957case lir_cond_less: acond = Assembler::less; break;3958case lir_cond_lessEqual: acond = Assembler::lessEqual; break;3959case lir_cond_greaterEqual: acond = Assembler::greaterEqual;break;3960case lir_cond_greater: acond = Assembler::greater; break;3961case lir_cond_belowEqual: acond = Assembler::belowEqual; break;3962case lir_cond_aboveEqual: acond = Assembler::aboveEqual; break;3963default: ShouldNotReachHere();3964}3965__ jcc(acond, ok);3966}3967if (op->halt()) {3968const char* str = __ code_string(op->msg());3969__ stop(str);3970} else {3971breakpoint();3972}3973__ bind(ok);3974}3975#endif39763977void LIR_Assembler::membar() {3978// QQQ sparc TSO uses this,3979__ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad));3980}39813982void LIR_Assembler::membar_acquire() {3983// No x86 machines currently require load fences3984}39853986void LIR_Assembler::membar_release() {3987// No x86 machines currently require store fences3988}39893990void LIR_Assembler::membar_loadload() {3991// no-op3992//__ membar(Assembler::Membar_mask_bits(Assembler::loadload));3993}39943995void LIR_Assembler::membar_storestore() {3996// no-op3997//__ membar(Assembler::Membar_mask_bits(Assembler::storestore));3998}39994000void LIR_Assembler::membar_loadstore() {4001// no-op4002//__ membar(Assembler::Membar_mask_bits(Assembler::loadstore));4003}40044005void LIR_Assembler::membar_storeload() {4006__ membar(Assembler::Membar_mask_bits(Assembler::StoreLoad));4007}40084009void LIR_Assembler::on_spin_wait() {4010__ pause ();4011}40124013void LIR_Assembler::get_thread(LIR_Opr result_reg) {4014assert(result_reg->is_register(), "check");4015#ifdef _LP644016// __ get_thread(result_reg->as_register_lo());4017__ mov(result_reg->as_register(), r15_thread);4018#else4019__ get_thread(result_reg->as_register());4020#endif // _LP644021}402240234024void LIR_Assembler::peephole(LIR_List*) {4025// do nothing for now4026}40274028void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp) {4029assert(data == dest, "xchg/xadd uses only 2 operands");40304031if (data->type() == T_INT) {4032if (code == lir_xadd) {4033__ lock();4034__ xaddl(as_Address(src->as_address_ptr()), data->as_register());4035} else {4036__ xchgl(data->as_register(), as_Address(src->as_address_ptr()));4037}4038} else if (data->is_oop()) {4039assert (code == lir_xchg, "xadd for oops");4040Register obj = data->as_register();4041#ifdef _LP644042if (UseCompressedOops) {4043__ encode_heap_oop(obj);4044__ xchgl(obj, as_Address(src->as_address_ptr()));4045__ decode_heap_oop(obj);4046} else {4047__ xchgptr(obj, as_Address(src->as_address_ptr()));4048}4049#else4050__ xchgl(obj, as_Address(src->as_address_ptr()));4051#endif4052} else if (data->type() == T_LONG) {4053#ifdef _LP644054assert(data->as_register_lo() == data->as_register_hi(), "should be a single register");4055if (code == lir_xadd) {4056__ lock();4057__ xaddq(as_Address(src->as_address_ptr()), data->as_register_lo());4058} else {4059__ xchgq(data->as_register_lo(), as_Address(src->as_address_ptr()));4060}4061#else4062ShouldNotReachHere();4063#endif4064} else {4065ShouldNotReachHere();4066}4067}40684069#undef __407040714072