Path: blob/master/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp
40930 views
/*1* Copyright (c) 2008, 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.inline.hpp"26#include "c1/c1_Compilation.hpp"27#include "c1/c1_LIRAssembler.hpp"28#include "c1/c1_MacroAssembler.hpp"29#include "c1/c1_Runtime1.hpp"30#include "c1/c1_ValueStack.hpp"31#include "ci/ciArrayKlass.hpp"32#include "ci/ciInstance.hpp"33#include "gc/shared/collectedHeap.hpp"34#include "memory/universe.hpp"35#include "nativeInst_arm.hpp"36#include "oops/objArrayKlass.hpp"37#include "runtime/frame.inline.hpp"38#include "runtime/sharedRuntime.hpp"39#include "runtime/stubRoutines.hpp"40#include "utilities/powerOfTwo.hpp"41#include "vmreg_arm.inline.hpp"4243#define __ _masm->4445// Note: Rtemp usage is this file should not impact C2 and should be46// correct as long as it is not implicitly used in lower layers (the47// arm [macro]assembler) and used with care in the other C1 specific48// files.4950bool LIR_Assembler::is_small_constant(LIR_Opr opr) {51ShouldNotCallThis(); // Not used on ARM52return false;53}545556LIR_Opr LIR_Assembler::receiverOpr() {57// The first register in Java calling conventions58return FrameMap::R0_oop_opr;59}6061LIR_Opr LIR_Assembler::osrBufferPointer() {62return FrameMap::as_pointer_opr(R0);63}6465#ifndef PRODUCT66void LIR_Assembler::verify_reserved_argument_area_size(int args_count) {67assert(args_count * wordSize <= frame_map()->reserved_argument_area_size(), "not enough space for arguments");68}69#endif // !PRODUCT7071void LIR_Assembler::store_parameter(jint c, int offset_from_sp_in_words) {72assert(offset_from_sp_in_words >= 0, "invalid offset from sp");73int offset_from_sp_in_bytes = offset_from_sp_in_words * BytesPerWord;74assert(offset_from_sp_in_bytes < frame_map()->reserved_argument_area_size(), "not enough space");75__ mov_slow(Rtemp, c);76__ str(Rtemp, Address(SP, offset_from_sp_in_bytes));77}7879void LIR_Assembler::store_parameter(Metadata* m, int offset_from_sp_in_words) {80assert(offset_from_sp_in_words >= 0, "invalid offset from sp");81int offset_from_sp_in_bytes = offset_from_sp_in_words * BytesPerWord;82assert(offset_from_sp_in_bytes < frame_map()->reserved_argument_area_size(), "not enough space");83__ mov_metadata(Rtemp, m);84__ str(Rtemp, Address(SP, offset_from_sp_in_bytes));85}8687//--------------fpu register translations-----------------------888990void LIR_Assembler::breakpoint() {91__ breakpoint();92}9394void LIR_Assembler::push(LIR_Opr opr) {95Unimplemented();96}9798void LIR_Assembler::pop(LIR_Opr opr) {99Unimplemented();100}101102//-------------------------------------------103Address LIR_Assembler::as_Address(LIR_Address* addr) {104Register base = addr->base()->as_pointer_register();105106107if (addr->index()->is_illegal() || addr->index()->is_constant()) {108int offset = addr->disp();109if (addr->index()->is_constant()) {110offset += addr->index()->as_constant_ptr()->as_jint() << addr->scale();111}112113if ((offset <= -4096) || (offset >= 4096)) {114BAILOUT_("offset not in range", Address(base));115}116117return Address(base, offset);118119} else {120assert(addr->disp() == 0, "can't have both");121int scale = addr->scale();122123assert(addr->index()->is_single_cpu(), "should be");124return scale >= 0 ? Address(base, addr->index()->as_register(), lsl, scale) :125Address(base, addr->index()->as_register(), lsr, -scale);126}127}128129Address LIR_Assembler::as_Address_hi(LIR_Address* addr) {130Address base = as_Address(addr);131assert(base.index() == noreg, "must be");132if (base.disp() + BytesPerWord >= 4096) { BAILOUT_("offset not in range", Address(base.base(),0)); }133return Address(base.base(), base.disp() + BytesPerWord);134}135136Address LIR_Assembler::as_Address_lo(LIR_Address* addr) {137return as_Address(addr);138}139140141void LIR_Assembler::osr_entry() {142offsets()->set_value(CodeOffsets::OSR_Entry, code_offset());143BlockBegin* osr_entry = compilation()->hir()->osr_entry();144ValueStack* entry_state = osr_entry->end()->state();145int number_of_locks = entry_state->locks_size();146147__ build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes());148Register OSR_buf = osrBufferPointer()->as_pointer_register();149150assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");151int monitor_offset = (method()->max_locals() + 2 * (number_of_locks - 1)) * BytesPerWord;152for (int i = 0; i < number_of_locks; i++) {153int slot_offset = monitor_offset - (i * 2 * BytesPerWord);154__ ldr(R1, Address(OSR_buf, slot_offset + 0*BytesPerWord));155__ ldr(R2, Address(OSR_buf, slot_offset + 1*BytesPerWord));156__ str(R1, frame_map()->address_for_monitor_lock(i));157__ str(R2, frame_map()->address_for_monitor_object(i));158}159}160161162int LIR_Assembler::check_icache() {163Register receiver = LIR_Assembler::receiverOpr()->as_register();164int offset = __ offset();165__ inline_cache_check(receiver, Ricklass);166return offset;167}168169void LIR_Assembler::clinit_barrier(ciMethod* method) {170ShouldNotReachHere(); // not implemented171}172173void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo* info) {174jobject o = (jobject)Universe::non_oop_word();175int index = __ oop_recorder()->allocate_oop_index(o);176177PatchingStub* patch = new PatchingStub(_masm, patching_id(info), index);178179__ patchable_mov_oop(reg, o, index);180patching_epilog(patch, lir_patch_normal, reg, info);181}182183184void LIR_Assembler::klass2reg_with_patching(Register reg, CodeEmitInfo* info) {185Metadata* o = (Metadata*)Universe::non_oop_word();186int index = __ oop_recorder()->allocate_metadata_index(o);187PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_klass_id, index);188189__ patchable_mov_metadata(reg, o, index);190patching_epilog(patch, lir_patch_normal, reg, info);191}192193194int LIR_Assembler::initial_frame_size_in_bytes() const {195// Subtracts two words to account for return address and link196return frame_map()->framesize()*VMRegImpl::stack_slot_size - 2*wordSize;197}198199200int LIR_Assembler::emit_exception_handler() {201// TODO: ARM202__ nop(); // See comments in other ports203204address handler_base = __ start_a_stub(exception_handler_size());205if (handler_base == NULL) {206bailout("exception handler overflow");207return -1;208}209210int offset = code_offset();211212// check that there is really an exception213__ verify_not_null_oop(Rexception_obj);214215__ call(Runtime1::entry_for(Runtime1::handle_exception_from_callee_id), relocInfo::runtime_call_type);216__ should_not_reach_here();217218assert(code_offset() - offset <= exception_handler_size(), "overflow");219__ end_a_stub();220221return offset;222}223224// Emit the code to remove the frame from the stack in the exception225// unwind path.226int LIR_Assembler::emit_unwind_handler() {227#ifndef PRODUCT228if (CommentedAssembly) {229_masm->block_comment("Unwind handler");230}231#endif232233int offset = code_offset();234235// Fetch the exception from TLS and clear out exception related thread state236Register zero = __ zero_register(Rtemp);237__ ldr(Rexception_obj, Address(Rthread, JavaThread::exception_oop_offset()));238__ str(zero, Address(Rthread, JavaThread::exception_oop_offset()));239__ str(zero, Address(Rthread, JavaThread::exception_pc_offset()));240241__ bind(_unwind_handler_entry);242__ verify_not_null_oop(Rexception_obj);243244// Preform needed unlocking245MonitorExitStub* stub = NULL;246if (method()->is_synchronized()) {247monitor_address(0, FrameMap::R0_opr);248stub = new MonitorExitStub(FrameMap::R0_opr, true, 0);249__ unlock_object(R2, R1, R0, Rtemp, *stub->entry());250__ bind(*stub->continuation());251}252253// remove the activation and dispatch to the unwind handler254__ remove_frame(initial_frame_size_in_bytes()); // restores FP and LR255__ jump(Runtime1::entry_for(Runtime1::unwind_exception_id), relocInfo::runtime_call_type, Rtemp);256257// Emit the slow path assembly258if (stub != NULL) {259stub->emit_code(this);260}261262return offset;263}264265266int LIR_Assembler::emit_deopt_handler() {267address handler_base = __ start_a_stub(deopt_handler_size());268if (handler_base == NULL) {269bailout("deopt handler overflow");270return -1;271}272273int offset = code_offset();274275__ mov_relative_address(LR, __ pc());276__ push(LR); // stub expects LR to be saved277__ jump(SharedRuntime::deopt_blob()->unpack(), relocInfo::runtime_call_type, noreg);278279assert(code_offset() - offset <= deopt_handler_size(), "overflow");280__ end_a_stub();281282return offset;283}284285286void LIR_Assembler::return_op(LIR_Opr result, C1SafepointPollStub* code_stub) {287// Pop the frame before safepoint polling288__ remove_frame(initial_frame_size_in_bytes());289__ read_polling_page(Rtemp, relocInfo::poll_return_type);290__ ret();291}292293int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {294295int offset = __ offset();296__ get_polling_page(Rtemp);297__ relocate(relocInfo::poll_type);298add_debug_info_for_branch(info); // help pc_desc_at to find correct scope for current PC299__ ldr(Rtemp, Address(Rtemp));300301return offset;302}303304305void LIR_Assembler::move_regs(Register from_reg, Register to_reg) {306if (from_reg != to_reg) {307__ mov(to_reg, from_reg);308}309}310311void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {312assert(src->is_constant() && dest->is_register(), "must be");313LIR_Const* c = src->as_constant_ptr();314315switch (c->type()) {316case T_ADDRESS:317case T_INT:318assert(patch_code == lir_patch_none, "no patching handled here");319__ mov_slow(dest->as_register(), c->as_jint());320break;321322case T_LONG:323assert(patch_code == lir_patch_none, "no patching handled here");324__ mov_slow(dest->as_register_lo(), c->as_jint_lo());325__ mov_slow(dest->as_register_hi(), c->as_jint_hi());326break;327328case T_OBJECT:329if (patch_code == lir_patch_none) {330__ mov_oop(dest->as_register(), c->as_jobject());331} else {332jobject2reg_with_patching(dest->as_register(), info);333}334break;335336case T_METADATA:337if (patch_code == lir_patch_none) {338__ mov_metadata(dest->as_register(), c->as_metadata());339} else {340klass2reg_with_patching(dest->as_register(), info);341}342break;343344case T_FLOAT:345if (dest->is_single_fpu()) {346__ mov_float(dest->as_float_reg(), c->as_jfloat());347} else {348// Simple getters can return float constant directly into r0349__ mov_slow(dest->as_register(), c->as_jint_bits());350}351break;352353case T_DOUBLE:354if (dest->is_double_fpu()) {355__ mov_double(dest->as_double_reg(), c->as_jdouble());356} else {357// Simple getters can return double constant directly into r1r0358__ mov_slow(dest->as_register_lo(), c->as_jint_lo_bits());359__ mov_slow(dest->as_register_hi(), c->as_jint_hi_bits());360}361break;362363default:364ShouldNotReachHere();365}366}367368void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) {369assert(src->is_constant(), "must be");370assert(dest->is_stack(), "must be");371LIR_Const* c = src->as_constant_ptr();372373switch (c->type()) {374case T_INT: // fall through375case T_FLOAT:376__ mov_slow(Rtemp, c->as_jint_bits());377__ str_32(Rtemp, frame_map()->address_for_slot(dest->single_stack_ix()));378break;379380case T_ADDRESS:381__ mov_slow(Rtemp, c->as_jint());382__ str(Rtemp, frame_map()->address_for_slot(dest->single_stack_ix()));383break;384385case T_OBJECT:386__ mov_oop(Rtemp, c->as_jobject());387__ str(Rtemp, frame_map()->address_for_slot(dest->single_stack_ix()));388break;389390case T_LONG: // fall through391case T_DOUBLE:392__ mov_slow(Rtemp, c->as_jint_lo_bits());393__ str(Rtemp, frame_map()->address_for_slot(dest->double_stack_ix(), lo_word_offset_in_bytes));394if (c->as_jint_hi_bits() != c->as_jint_lo_bits()) {395__ mov_slow(Rtemp, c->as_jint_hi_bits());396}397__ str(Rtemp, frame_map()->address_for_slot(dest->double_stack_ix(), hi_word_offset_in_bytes));398break;399400default:401ShouldNotReachHere();402}403}404405void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type,406CodeEmitInfo* info, bool wide) {407assert((src->as_constant_ptr()->type() == T_OBJECT && src->as_constant_ptr()->as_jobject() == NULL),"cannot handle otherwise");408__ mov(Rtemp, 0);409410int null_check_offset = code_offset();411__ str(Rtemp, as_Address(dest->as_address_ptr()));412413if (info != NULL) {414assert(false, "arm32 didn't support this before, investigate if bug");415add_debug_info_for_null_check(null_check_offset, info);416}417}418419void LIR_Assembler::reg2reg(LIR_Opr src, LIR_Opr dest) {420assert(src->is_register() && dest->is_register(), "must be");421422if (src->is_single_cpu()) {423if (dest->is_single_cpu()) {424move_regs(src->as_register(), dest->as_register());425} else if (dest->is_single_fpu()) {426__ fmsr(dest->as_float_reg(), src->as_register());427} else {428ShouldNotReachHere();429}430} else if (src->is_double_cpu()) {431if (dest->is_double_cpu()) {432__ long_move(dest->as_register_lo(), dest->as_register_hi(), src->as_register_lo(), src->as_register_hi());433} else {434__ fmdrr(dest->as_double_reg(), src->as_register_lo(), src->as_register_hi());435}436} else if (src->is_single_fpu()) {437if (dest->is_single_fpu()) {438__ mov_float(dest->as_float_reg(), src->as_float_reg());439} else if (dest->is_single_cpu()) {440__ mov_fpr2gpr_float(dest->as_register(), src->as_float_reg());441} else {442ShouldNotReachHere();443}444} else if (src->is_double_fpu()) {445if (dest->is_double_fpu()) {446__ mov_double(dest->as_double_reg(), src->as_double_reg());447} else if (dest->is_double_cpu()) {448__ fmrrd(dest->as_register_lo(), dest->as_register_hi(), src->as_double_reg());449} else {450ShouldNotReachHere();451}452} else {453ShouldNotReachHere();454}455}456457void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool pop_fpu_stack) {458assert(src->is_register(), "should not call otherwise");459assert(dest->is_stack(), "should not call otherwise");460461Address addr = dest->is_single_word() ?462frame_map()->address_for_slot(dest->single_stack_ix()) :463frame_map()->address_for_slot(dest->double_stack_ix());464465assert(lo_word_offset_in_bytes == 0 && hi_word_offset_in_bytes == 4, "little ending");466if (src->is_single_fpu() || src->is_double_fpu()) {467if (addr.disp() >= 1024) { BAILOUT("Too exotic case to handle here"); }468}469470if (src->is_single_cpu()) {471switch (type) {472case T_OBJECT:473case T_ARRAY: __ verify_oop(src->as_register()); // fall through474case T_ADDRESS:475case T_METADATA: __ str(src->as_register(), addr); break;476case T_FLOAT: // used in intBitsToFloat intrinsic implementation, fall through477case T_INT: __ str_32(src->as_register(), addr); break;478default:479ShouldNotReachHere();480}481} else if (src->is_double_cpu()) {482__ str(src->as_register_lo(), addr);483__ str(src->as_register_hi(), frame_map()->address_for_slot(dest->double_stack_ix(), hi_word_offset_in_bytes));484} else if (src->is_single_fpu()) {485__ str_float(src->as_float_reg(), addr);486} else if (src->is_double_fpu()) {487__ str_double(src->as_double_reg(), addr);488} else {489ShouldNotReachHere();490}491}492493494void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type,495LIR_PatchCode patch_code, CodeEmitInfo* info,496bool pop_fpu_stack, bool wide,497bool unaligned) {498LIR_Address* to_addr = dest->as_address_ptr();499Register base_reg = to_addr->base()->as_pointer_register();500const bool needs_patching = (patch_code != lir_patch_none);501502PatchingStub* patch = NULL;503if (needs_patching) {504patch = new PatchingStub(_masm, PatchingStub::access_field_id);505}506507int null_check_offset = code_offset();508509switch (type) {510case T_ARRAY:511case T_OBJECT:512if (UseCompressedOops && !wide) {513ShouldNotReachHere();514} else {515__ str(src->as_register(), as_Address(to_addr));516}517break;518519case T_ADDRESS:520__ str(src->as_pointer_register(), as_Address(to_addr));521break;522523case T_BYTE:524case T_BOOLEAN:525__ strb(src->as_register(), as_Address(to_addr));526break;527528case T_CHAR:529case T_SHORT:530__ strh(src->as_register(), as_Address(to_addr));531break;532533case T_INT:534#ifdef __SOFTFP__535case T_FLOAT:536#endif // __SOFTFP__537__ str_32(src->as_register(), as_Address(to_addr));538break;539540541#ifdef __SOFTFP__542case T_DOUBLE:543#endif // __SOFTFP__544case T_LONG: {545Register from_lo = src->as_register_lo();546Register from_hi = src->as_register_hi();547if (to_addr->index()->is_register()) {548assert(to_addr->scale() == LIR_Address::times_1,"Unexpected scaled register");549assert(to_addr->disp() == 0, "Not yet supporting both");550__ add(Rtemp, base_reg, to_addr->index()->as_register());551base_reg = Rtemp;552__ str(from_lo, Address(Rtemp));553if (patch != NULL) {554__ nop(); // see comment before patching_epilog for 2nd str555patching_epilog(patch, lir_patch_low, base_reg, info);556patch = new PatchingStub(_masm, PatchingStub::access_field_id);557patch_code = lir_patch_high;558}559__ str(from_hi, Address(Rtemp, BytesPerWord));560} else if (base_reg == from_lo) {561__ str(from_hi, as_Address_hi(to_addr));562if (patch != NULL) {563__ nop(); // see comment before patching_epilog for 2nd str564patching_epilog(patch, lir_patch_high, base_reg, info);565patch = new PatchingStub(_masm, PatchingStub::access_field_id);566patch_code = lir_patch_low;567}568__ str(from_lo, as_Address_lo(to_addr));569} else {570__ str(from_lo, as_Address_lo(to_addr));571if (patch != NULL) {572__ nop(); // see comment before patching_epilog for 2nd str573patching_epilog(patch, lir_patch_low, base_reg, info);574patch = new PatchingStub(_masm, PatchingStub::access_field_id);575patch_code = lir_patch_high;576}577__ str(from_hi, as_Address_hi(to_addr));578}579break;580}581582#ifndef __SOFTFP__583case T_FLOAT:584if (to_addr->index()->is_register()) {585assert(to_addr->scale() == LIR_Address::times_1,"Unexpected scaled register");586__ add(Rtemp, base_reg, to_addr->index()->as_register());587if ((to_addr->disp() <= -4096) || (to_addr->disp() >= 4096)) { BAILOUT("offset not in range"); }588__ fsts(src->as_float_reg(), Address(Rtemp, to_addr->disp()));589} else {590__ fsts(src->as_float_reg(), as_Address(to_addr));591}592break;593594case T_DOUBLE:595if (to_addr->index()->is_register()) {596assert(to_addr->scale() == LIR_Address::times_1,"Unexpected scaled register");597__ add(Rtemp, base_reg, to_addr->index()->as_register());598if ((to_addr->disp() <= -4096) || (to_addr->disp() >= 4096)) { BAILOUT("offset not in range"); }599__ fstd(src->as_double_reg(), Address(Rtemp, to_addr->disp()));600} else {601__ fstd(src->as_double_reg(), as_Address(to_addr));602}603break;604#endif // __SOFTFP__605606607default:608ShouldNotReachHere();609}610611if (info != NULL) {612add_debug_info_for_null_check(null_check_offset, info);613}614615if (patch != NULL) {616// Offset embedded into LDR/STR instruction may appear not enough617// to address a field. So, provide a space for one more instruction618// that will deal with larger offsets.619__ nop();620patching_epilog(patch, patch_code, base_reg, info);621}622}623624625void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) {626assert(src->is_stack(), "should not call otherwise");627assert(dest->is_register(), "should not call otherwise");628629Address addr = src->is_single_word() ?630frame_map()->address_for_slot(src->single_stack_ix()) :631frame_map()->address_for_slot(src->double_stack_ix());632633assert(lo_word_offset_in_bytes == 0 && hi_word_offset_in_bytes == 4, "little ending");634if (dest->is_single_fpu() || dest->is_double_fpu()) {635if (addr.disp() >= 1024) { BAILOUT("Too exotic case to handle here"); }636}637638if (dest->is_single_cpu()) {639switch (type) {640case T_OBJECT:641case T_ARRAY:642case T_ADDRESS:643case T_METADATA: __ ldr(dest->as_register(), addr); break;644case T_FLOAT: // used in floatToRawIntBits intrinsic implemenation645case T_INT: __ ldr_u32(dest->as_register(), addr); break;646default:647ShouldNotReachHere();648}649if ((type == T_OBJECT) || (type == T_ARRAY)) {650__ verify_oop(dest->as_register());651}652} else if (dest->is_double_cpu()) {653__ ldr(dest->as_register_lo(), addr);654__ ldr(dest->as_register_hi(), frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes));655} else if (dest->is_single_fpu()) {656__ ldr_float(dest->as_float_reg(), addr);657} else if (dest->is_double_fpu()) {658__ ldr_double(dest->as_double_reg(), addr);659} else {660ShouldNotReachHere();661}662}663664665void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) {666if (src->is_single_stack()) {667switch (src->type()) {668case T_OBJECT:669case T_ARRAY:670case T_ADDRESS:671case T_METADATA:672__ ldr(Rtemp, frame_map()->address_for_slot(src->single_stack_ix()));673__ str(Rtemp, frame_map()->address_for_slot(dest->single_stack_ix()));674break;675676case T_INT:677case T_FLOAT:678__ ldr_u32(Rtemp, frame_map()->address_for_slot(src->single_stack_ix()));679__ str_32(Rtemp, frame_map()->address_for_slot(dest->single_stack_ix()));680break;681682default:683ShouldNotReachHere();684}685} else {686assert(src->is_double_stack(), "must be");687__ ldr(Rtemp, frame_map()->address_for_slot(src->double_stack_ix(), lo_word_offset_in_bytes));688__ str(Rtemp, frame_map()->address_for_slot(dest->double_stack_ix(), lo_word_offset_in_bytes));689__ ldr(Rtemp, frame_map()->address_for_slot(src->double_stack_ix(), hi_word_offset_in_bytes));690__ str(Rtemp, frame_map()->address_for_slot(dest->double_stack_ix(), hi_word_offset_in_bytes));691}692}693694695void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type,696LIR_PatchCode patch_code, CodeEmitInfo* info,697bool wide, bool unaligned) {698assert(src->is_address(), "should not call otherwise");699assert(dest->is_register(), "should not call otherwise");700LIR_Address* addr = src->as_address_ptr();701702Register base_reg = addr->base()->as_pointer_register();703704PatchingStub* patch = NULL;705if (patch_code != lir_patch_none) {706patch = new PatchingStub(_masm, PatchingStub::access_field_id);707}708if (info != NULL) {709add_debug_info_for_null_check_here(info);710}711712switch (type) {713case T_OBJECT: // fall through714case T_ARRAY:715if (UseCompressedOops && !wide) {716__ ldr_u32(dest->as_register(), as_Address(addr));717} else {718__ ldr(dest->as_register(), as_Address(addr));719}720break;721722case T_ADDRESS:723if (UseCompressedClassPointers && addr->disp() == oopDesc::klass_offset_in_bytes()) {724__ ldr_u32(dest->as_pointer_register(), as_Address(addr));725} else {726__ ldr(dest->as_pointer_register(), as_Address(addr));727}728break;729730case T_INT:731#ifdef __SOFTFP__732case T_FLOAT:733#endif // __SOFTFP__734__ ldr(dest->as_pointer_register(), as_Address(addr));735break;736737case T_BOOLEAN:738__ ldrb(dest->as_register(), as_Address(addr));739break;740741case T_BYTE:742__ ldrsb(dest->as_register(), as_Address(addr));743break;744745case T_CHAR:746__ ldrh(dest->as_register(), as_Address(addr));747break;748749case T_SHORT:750__ ldrsh(dest->as_register(), as_Address(addr));751break;752753754#ifdef __SOFTFP__755case T_DOUBLE:756#endif // __SOFTFP__757case T_LONG: {758Register to_lo = dest->as_register_lo();759Register to_hi = dest->as_register_hi();760if (addr->index()->is_register()) {761assert(addr->scale() == LIR_Address::times_1,"Unexpected scaled register");762assert(addr->disp() == 0, "Not yet supporting both");763__ add(Rtemp, base_reg, addr->index()->as_register());764base_reg = Rtemp;765__ ldr(to_lo, Address(Rtemp));766if (patch != NULL) {767__ nop(); // see comment before patching_epilog for 2nd ldr768patching_epilog(patch, lir_patch_low, base_reg, info);769patch = new PatchingStub(_masm, PatchingStub::access_field_id);770patch_code = lir_patch_high;771}772__ ldr(to_hi, Address(Rtemp, BytesPerWord));773} else if (base_reg == to_lo) {774__ ldr(to_hi, as_Address_hi(addr));775if (patch != NULL) {776__ nop(); // see comment before patching_epilog for 2nd ldr777patching_epilog(patch, lir_patch_high, base_reg, info);778patch = new PatchingStub(_masm, PatchingStub::access_field_id);779patch_code = lir_patch_low;780}781__ ldr(to_lo, as_Address_lo(addr));782} else {783__ ldr(to_lo, as_Address_lo(addr));784if (patch != NULL) {785__ nop(); // see comment before patching_epilog for 2nd ldr786patching_epilog(patch, lir_patch_low, base_reg, info);787patch = new PatchingStub(_masm, PatchingStub::access_field_id);788patch_code = lir_patch_high;789}790__ ldr(to_hi, as_Address_hi(addr));791}792break;793}794795#ifndef __SOFTFP__796case T_FLOAT:797if (addr->index()->is_register()) {798assert(addr->scale() == LIR_Address::times_1,"Unexpected scaled register");799__ add(Rtemp, base_reg, addr->index()->as_register());800if ((addr->disp() <= -4096) || (addr->disp() >= 4096)) { BAILOUT("offset not in range"); }801__ flds(dest->as_float_reg(), Address(Rtemp, addr->disp()));802} else {803__ flds(dest->as_float_reg(), as_Address(addr));804}805break;806807case T_DOUBLE:808if (addr->index()->is_register()) {809assert(addr->scale() == LIR_Address::times_1,"Unexpected scaled register");810__ add(Rtemp, base_reg, addr->index()->as_register());811if ((addr->disp() <= -4096) || (addr->disp() >= 4096)) { BAILOUT("offset not in range"); }812__ fldd(dest->as_double_reg(), Address(Rtemp, addr->disp()));813} else {814__ fldd(dest->as_double_reg(), as_Address(addr));815}816break;817#endif // __SOFTFP__818819820default:821ShouldNotReachHere();822}823824if (patch != NULL) {825// Offset embedded into LDR/STR instruction may appear not enough826// to address a field. So, provide a space for one more instruction827// that will deal with larger offsets.828__ nop();829patching_epilog(patch, patch_code, base_reg, info);830}831832}833834835void LIR_Assembler::emit_op3(LIR_Op3* op) {836bool is_32 = op->result_opr()->is_single_cpu();837838if (op->code() == lir_idiv && op->in_opr2()->is_constant() && is_32) {839int c = op->in_opr2()->as_constant_ptr()->as_jint();840assert(is_power_of_2(c), "non power-of-2 constant should be put in a register");841842Register left = op->in_opr1()->as_register();843Register dest = op->result_opr()->as_register();844if (c == 1) {845__ mov(dest, left);846} else if (c == 2) {847__ add_32(dest, left, AsmOperand(left, lsr, 31));848__ asr_32(dest, dest, 1);849} else if (c != (int) 0x80000000) {850int power = log2i_exact(c);851__ asr_32(Rtemp, left, 31);852__ add_32(dest, left, AsmOperand(Rtemp, lsr, 32-power)); // dest = left + (left < 0 ? 2^power - 1 : 0);853__ asr_32(dest, dest, power); // dest = dest >>> power;854} else {855// x/0x80000000 is a special case, since dividend is a power of two, but is negative.856// The only possible result values are 0 and 1, with 1 only for dividend == divisor == 0x80000000.857__ cmp_32(left, c);858__ mov(dest, 0, ne);859__ mov(dest, 1, eq);860}861} else {862assert(op->code() == lir_idiv || op->code() == lir_irem, "unexpected op3");863__ call(StubRoutines::Arm::idiv_irem_entry(), relocInfo::runtime_call_type);864add_debug_info_for_div0_here(op->info());865}866}867868869void LIR_Assembler::emit_opBranch(LIR_OpBranch* op) {870#ifdef ASSERT871assert(op->block() == NULL || op->block()->label() == op->label(), "wrong label");872if (op->block() != NULL) _branch_target_blocks.append(op->block());873if (op->ublock() != NULL) _branch_target_blocks.append(op->ublock());874assert(op->info() == NULL, "CodeEmitInfo?");875#endif // ASSERT876877#ifdef __SOFTFP__878assert (op->code() != lir_cond_float_branch, "this should be impossible");879#else880if (op->code() == lir_cond_float_branch) {881__ fmstat();882__ b(*(op->ublock()->label()), vs);883}884#endif // __SOFTFP__885886AsmCondition acond = al;887switch (op->cond()) {888case lir_cond_equal: acond = eq; break;889case lir_cond_notEqual: acond = ne; break;890case lir_cond_less: acond = lt; break;891case lir_cond_lessEqual: acond = le; break;892case lir_cond_greaterEqual: acond = ge; break;893case lir_cond_greater: acond = gt; break;894case lir_cond_aboveEqual: acond = hs; break;895case lir_cond_belowEqual: acond = ls; break;896default: assert(op->cond() == lir_cond_always, "must be");897}898__ b(*(op->label()), acond);899}900901902void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) {903LIR_Opr src = op->in_opr();904LIR_Opr dest = op->result_opr();905906switch (op->bytecode()) {907case Bytecodes::_i2l:908move_regs(src->as_register(), dest->as_register_lo());909__ mov(dest->as_register_hi(), AsmOperand(src->as_register(), asr, 31));910break;911case Bytecodes::_l2i:912move_regs(src->as_register_lo(), dest->as_register());913break;914case Bytecodes::_i2b:915__ sign_extend(dest->as_register(), src->as_register(), 8);916break;917case Bytecodes::_i2s:918__ sign_extend(dest->as_register(), src->as_register(), 16);919break;920case Bytecodes::_i2c:921__ zero_extend(dest->as_register(), src->as_register(), 16);922break;923case Bytecodes::_f2d:924__ convert_f2d(dest->as_double_reg(), src->as_float_reg());925break;926case Bytecodes::_d2f:927__ convert_d2f(dest->as_float_reg(), src->as_double_reg());928break;929case Bytecodes::_i2f:930__ fmsr(Stemp, src->as_register());931__ fsitos(dest->as_float_reg(), Stemp);932break;933case Bytecodes::_i2d:934__ fmsr(Stemp, src->as_register());935__ fsitod(dest->as_double_reg(), Stemp);936break;937case Bytecodes::_f2i:938__ ftosizs(Stemp, src->as_float_reg());939__ fmrs(dest->as_register(), Stemp);940break;941case Bytecodes::_d2i:942__ ftosizd(Stemp, src->as_double_reg());943__ fmrs(dest->as_register(), Stemp);944break;945default:946ShouldNotReachHere();947}948}949950951void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) {952if (op->init_check()) {953Register tmp = op->tmp1()->as_register();954__ ldrb(tmp, Address(op->klass()->as_register(), InstanceKlass::init_state_offset()));955add_debug_info_for_null_check_here(op->stub()->info());956__ cmp(tmp, InstanceKlass::fully_initialized);957__ b(*op->stub()->entry(), ne);958}959__ allocate_object(op->obj()->as_register(),960op->tmp1()->as_register(),961op->tmp2()->as_register(),962op->tmp3()->as_register(),963op->header_size(),964op->object_size(),965op->klass()->as_register(),966*op->stub()->entry());967__ bind(*op->stub()->continuation());968}969970void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {971if (UseSlowPath ||972(!UseFastNewObjectArray && (op->type() == T_OBJECT || op->type() == T_ARRAY)) ||973(!UseFastNewTypeArray && (op->type() != T_OBJECT && op->type() != T_ARRAY))) {974__ b(*op->stub()->entry());975} else {976__ allocate_array(op->obj()->as_register(),977op->len()->as_register(),978op->tmp1()->as_register(),979op->tmp2()->as_register(),980op->tmp3()->as_register(),981arrayOopDesc::header_size(op->type()),982type2aelembytes(op->type()),983op->klass()->as_register(),984*op->stub()->entry());985}986__ bind(*op->stub()->continuation());987}988989void LIR_Assembler::type_profile_helper(Register mdo, int mdo_offset_bias,990ciMethodData *md, ciProfileData *data,991Register recv, Register tmp1, Label* update_done) {992assert_different_registers(mdo, recv, tmp1);993uint i;994for (i = 0; i < VirtualCallData::row_limit(); i++) {995Label next_test;996// See if the receiver is receiver[n].997Address receiver_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) -998mdo_offset_bias);999__ ldr(tmp1, receiver_addr);1000__ verify_klass_ptr(tmp1);1001__ cmp(recv, tmp1);1002__ b(next_test, ne);1003Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) -1004mdo_offset_bias);1005__ ldr(tmp1, data_addr);1006__ add(tmp1, tmp1, DataLayout::counter_increment);1007__ str(tmp1, data_addr);1008__ b(*update_done);1009__ bind(next_test);1010}10111012// Didn't find receiver; find next empty slot and fill it in1013for (i = 0; i < VirtualCallData::row_limit(); i++) {1014Label next_test;1015Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)) -1016mdo_offset_bias);1017__ ldr(tmp1, recv_addr);1018__ cbnz(tmp1, next_test);1019__ str(recv, recv_addr);1020__ mov(tmp1, DataLayout::counter_increment);1021__ str(tmp1, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)) -1022mdo_offset_bias));1023__ b(*update_done);1024__ bind(next_test);1025}1026}10271028void LIR_Assembler::setup_md_access(ciMethod* method, int bci,1029ciMethodData*& md, ciProfileData*& data, int& mdo_offset_bias) {1030md = method->method_data_or_null();1031assert(md != NULL, "Sanity");1032data = md->bci_to_data(bci);1033assert(data != NULL, "need data for checkcast");1034assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");1035if (md->byte_offset_of_slot(data, DataLayout::header_offset()) + data->size_in_bytes() >= 4096) {1036// The offset is large so bias the mdo by the base of the slot so1037// that the ldr can use an immediate offset to reference the slots of the data1038mdo_offset_bias = md->byte_offset_of_slot(data, DataLayout::header_offset());1039}1040}10411042// On 32-bit ARM, code before this helper should test obj for null (ZF should be set if obj is null).1043void LIR_Assembler::typecheck_profile_helper1(ciMethod* method, int bci,1044ciMethodData*& md, ciProfileData*& data, int& mdo_offset_bias,1045Register obj, Register mdo, Register data_val, Label* obj_is_null) {1046assert(method != NULL, "Should have method");1047assert_different_registers(obj, mdo, data_val);1048setup_md_access(method, bci, md, data, mdo_offset_bias);1049Label not_null;1050__ b(not_null, ne);1051__ mov_metadata(mdo, md->constant_encoding());1052if (mdo_offset_bias > 0) {1053__ mov_slow(data_val, mdo_offset_bias);1054__ add(mdo, mdo, data_val);1055}1056Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias);1057__ ldrb(data_val, flags_addr);1058__ orr(data_val, data_val, (uint)BitData::null_seen_byte_constant());1059__ strb(data_val, flags_addr);1060__ b(*obj_is_null);1061__ bind(not_null);1062}10631064void LIR_Assembler::typecheck_profile_helper2(ciMethodData* md, ciProfileData* data, int mdo_offset_bias,1065Register mdo, Register recv, Register value, Register tmp1,1066Label* profile_cast_success, Label* profile_cast_failure,1067Label* success, Label* failure) {1068assert_different_registers(mdo, value, tmp1);1069__ bind(*profile_cast_success);1070__ mov_metadata(mdo, md->constant_encoding());1071if (mdo_offset_bias > 0) {1072__ mov_slow(tmp1, mdo_offset_bias);1073__ add(mdo, mdo, tmp1);1074}1075__ load_klass(recv, value);1076type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success);1077__ b(*success);1078// Cast failure case1079__ bind(*profile_cast_failure);1080__ mov_metadata(mdo, md->constant_encoding());1081if (mdo_offset_bias > 0) {1082__ mov_slow(tmp1, mdo_offset_bias);1083__ add(mdo, mdo, tmp1);1084}1085Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);1086__ ldr(tmp1, data_addr);1087__ sub(tmp1, tmp1, DataLayout::counter_increment);1088__ str(tmp1, data_addr);1089__ b(*failure);1090}10911092// Sets `res` to true, if `cond` holds.1093static void set_instanceof_result(MacroAssembler* _masm, Register res, AsmCondition cond) {1094__ mov(res, 1, cond);1095}109610971098void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {1099// TODO: ARM - can be more effective with one more register1100switch (op->code()) {1101case lir_store_check: {1102CodeStub* stub = op->stub();1103Register value = op->object()->as_register();1104Register array = op->array()->as_register();1105Register klass_RInfo = op->tmp1()->as_register();1106Register k_RInfo = op->tmp2()->as_register();1107assert_different_registers(klass_RInfo, k_RInfo, Rtemp);1108if (op->should_profile()) {1109assert_different_registers(value, klass_RInfo, k_RInfo, Rtemp);1110}11111112// check if it needs to be profiled1113ciMethodData* md;1114ciProfileData* data;1115int mdo_offset_bias = 0;1116Label profile_cast_success, profile_cast_failure, done;1117Label *success_target = op->should_profile() ? &profile_cast_success : &done;1118Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry();11191120if (op->should_profile()) {1121__ cmp(value, 0);1122typecheck_profile_helper1(op->profiled_method(), op->profiled_bci(), md, data, mdo_offset_bias, value, k_RInfo, Rtemp, &done);1123} else {1124__ cbz(value, done);1125}1126assert_different_registers(k_RInfo, value);1127add_debug_info_for_null_check_here(op->info_for_exception());1128__ load_klass(k_RInfo, array);1129__ load_klass(klass_RInfo, value);1130__ ldr(k_RInfo, Address(k_RInfo, ObjArrayKlass::element_klass_offset()));1131__ ldr_u32(Rtemp, Address(k_RInfo, Klass::super_check_offset_offset()));1132// check for immediate positive hit1133__ ldr(Rtemp, Address(klass_RInfo, Rtemp));1134__ cmp(klass_RInfo, k_RInfo);1135__ cond_cmp(Rtemp, k_RInfo, ne);1136__ b(*success_target, eq);1137// check for immediate negative hit1138__ ldr_u32(Rtemp, Address(k_RInfo, Klass::super_check_offset_offset()));1139__ cmp(Rtemp, in_bytes(Klass::secondary_super_cache_offset()));1140__ b(*failure_target, ne);1141// slow case1142assert(klass_RInfo == R0 && k_RInfo == R1, "runtime call setup");1143__ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);1144__ cbz(R0, *failure_target);1145if (op->should_profile()) {1146Register mdo = klass_RInfo, recv = k_RInfo, tmp1 = Rtemp;1147if (mdo == value) {1148mdo = k_RInfo;1149recv = klass_RInfo;1150}1151typecheck_profile_helper2(md, data, mdo_offset_bias, mdo, recv, value, tmp1,1152&profile_cast_success, &profile_cast_failure,1153&done, stub->entry());1154}1155__ bind(done);1156break;1157}11581159case lir_checkcast: {1160CodeStub* stub = op->stub();1161Register obj = op->object()->as_register();1162Register res = op->result_opr()->as_register();1163Register klass_RInfo = op->tmp1()->as_register();1164Register k_RInfo = op->tmp2()->as_register();1165ciKlass* k = op->klass();1166assert_different_registers(res, k_RInfo, klass_RInfo, Rtemp);11671168if (stub->is_simple_exception_stub()) {1169// TODO: ARM - Late binding is used to prevent confusion of register allocator1170assert(stub->is_exception_throw_stub(), "must be");1171((SimpleExceptionStub*)stub)->set_obj(op->result_opr());1172}1173ciMethodData* md;1174ciProfileData* data;1175int mdo_offset_bias = 0;11761177Label done;11781179Label profile_cast_failure, profile_cast_success;1180Label *failure_target = op->should_profile() ? &profile_cast_failure : op->stub()->entry();1181Label *success_target = op->should_profile() ? &profile_cast_success : &done;118211831184__ movs(res, obj);1185if (op->should_profile()) {1186typecheck_profile_helper1(op->profiled_method(), op->profiled_bci(), md, data, mdo_offset_bias, res, klass_RInfo, Rtemp, &done);1187} else {1188__ b(done, eq);1189}1190if (k->is_loaded()) {1191__ mov_metadata(k_RInfo, k->constant_encoding());1192} else if (k_RInfo != obj) {1193klass2reg_with_patching(k_RInfo, op->info_for_patch());1194__ movs(res, obj);1195} else {1196// Patching doesn't update "res" register after GC, so do patching first1197klass2reg_with_patching(Rtemp, op->info_for_patch());1198__ movs(res, obj);1199__ mov(k_RInfo, Rtemp);1200}1201__ load_klass(klass_RInfo, res, ne);12021203if (op->fast_check()) {1204__ cmp(klass_RInfo, k_RInfo, ne);1205__ b(*failure_target, ne);1206} else if (k->is_loaded()) {1207__ b(*success_target, eq);1208__ ldr(Rtemp, Address(klass_RInfo, k->super_check_offset()));1209if (in_bytes(Klass::secondary_super_cache_offset()) != (int) k->super_check_offset()) {1210__ cmp(Rtemp, k_RInfo);1211__ b(*failure_target, ne);1212} else {1213__ cmp(klass_RInfo, k_RInfo);1214__ cmp(Rtemp, k_RInfo, ne);1215__ b(*success_target, eq);1216assert(klass_RInfo == R0 && k_RInfo == R1, "runtime call setup");1217__ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);1218__ cbz(R0, *failure_target);1219}1220} else {1221__ ldr_u32(Rtemp, Address(k_RInfo, Klass::super_check_offset_offset()));1222__ b(*success_target, eq);1223// check for immediate positive hit1224__ ldr(Rtemp, Address(klass_RInfo, Rtemp));1225__ cmp(klass_RInfo, k_RInfo);1226__ cmp(Rtemp, k_RInfo, ne);1227__ b(*success_target, eq);1228// check for immediate negative hit1229__ ldr_u32(Rtemp, Address(k_RInfo, Klass::super_check_offset_offset()));1230__ cmp(Rtemp, in_bytes(Klass::secondary_super_cache_offset()));1231__ b(*failure_target, ne);1232// slow case1233assert(klass_RInfo == R0 && k_RInfo == R1, "runtime call setup");1234__ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);1235__ cbz(R0, *failure_target);1236}12371238if (op->should_profile()) {1239Register mdo = klass_RInfo, recv = k_RInfo, tmp1 = Rtemp;1240typecheck_profile_helper2(md, data, mdo_offset_bias, mdo, recv, res, tmp1,1241&profile_cast_success, &profile_cast_failure,1242&done, stub->entry());1243}1244__ bind(done);1245break;1246}12471248case lir_instanceof: {1249Register obj = op->object()->as_register();1250Register res = op->result_opr()->as_register();1251Register klass_RInfo = op->tmp1()->as_register();1252Register k_RInfo = op->tmp2()->as_register();1253ciKlass* k = op->klass();1254assert_different_registers(res, klass_RInfo, k_RInfo, Rtemp);12551256ciMethodData* md;1257ciProfileData* data;1258int mdo_offset_bias = 0;12591260Label done;12611262Label profile_cast_failure, profile_cast_success;1263Label *failure_target = op->should_profile() ? &profile_cast_failure : &done;1264Label *success_target = op->should_profile() ? &profile_cast_success : &done;12651266__ movs(res, obj);12671268if (op->should_profile()) {1269typecheck_profile_helper1(op->profiled_method(), op->profiled_bci(), md, data, mdo_offset_bias, res, klass_RInfo, Rtemp, &done);1270} else {1271__ b(done, eq);1272}12731274if (k->is_loaded()) {1275__ mov_metadata(k_RInfo, k->constant_encoding());1276} else {1277op->info_for_patch()->add_register_oop(FrameMap::as_oop_opr(res));1278klass2reg_with_patching(k_RInfo, op->info_for_patch());1279}1280__ load_klass(klass_RInfo, res);12811282if (!op->should_profile()) {1283__ mov(res, 0);1284}12851286if (op->fast_check()) {1287__ cmp(klass_RInfo, k_RInfo);1288if (!op->should_profile()) {1289set_instanceof_result(_masm, res, eq);1290} else {1291__ b(profile_cast_failure, ne);1292}1293} else if (k->is_loaded()) {1294__ ldr(Rtemp, Address(klass_RInfo, k->super_check_offset()));1295if (in_bytes(Klass::secondary_super_cache_offset()) != (int) k->super_check_offset()) {1296__ cmp(Rtemp, k_RInfo);1297if (!op->should_profile()) {1298set_instanceof_result(_masm, res, eq);1299} else {1300__ b(profile_cast_failure, ne);1301}1302} else {1303__ cmp(klass_RInfo, k_RInfo);1304__ cond_cmp(Rtemp, k_RInfo, ne);1305if (!op->should_profile()) {1306set_instanceof_result(_masm, res, eq);1307}1308__ b(*success_target, eq);1309assert(klass_RInfo == R0 && k_RInfo == R1, "runtime call setup");1310__ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);1311if (!op->should_profile()) {1312move_regs(R0, res);1313} else {1314__ cbz(R0, *failure_target);1315}1316}1317} else {1318__ ldr_u32(Rtemp, Address(k_RInfo, Klass::super_check_offset_offset()));1319// check for immediate positive hit1320__ cmp(klass_RInfo, k_RInfo);1321if (!op->should_profile()) {1322__ ldr(res, Address(klass_RInfo, Rtemp), ne);1323__ cond_cmp(res, k_RInfo, ne);1324set_instanceof_result(_masm, res, eq);1325} else {1326__ ldr(Rtemp, Address(klass_RInfo, Rtemp), ne);1327__ cond_cmp(Rtemp, k_RInfo, ne);1328}1329__ b(*success_target, eq);1330// check for immediate negative hit1331if (op->should_profile()) {1332__ ldr_u32(Rtemp, Address(k_RInfo, Klass::super_check_offset_offset()));1333}1334__ cmp(Rtemp, in_bytes(Klass::secondary_super_cache_offset()));1335if (!op->should_profile()) {1336__ mov(res, 0, ne);1337}1338__ b(*failure_target, ne);1339// slow case1340assert(klass_RInfo == R0 && k_RInfo == R1, "runtime call setup");1341__ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);1342if (!op->should_profile()) {1343move_regs(R0, res);1344}1345if (op->should_profile()) {1346__ cbz(R0, *failure_target);1347}1348}13491350if (op->should_profile()) {1351Label done_ok, done_failure;1352Register mdo = klass_RInfo, recv = k_RInfo, tmp1 = Rtemp;1353typecheck_profile_helper2(md, data, mdo_offset_bias, mdo, recv, res, tmp1,1354&profile_cast_success, &profile_cast_failure,1355&done_ok, &done_failure);1356__ bind(done_failure);1357__ mov(res, 0);1358__ b(done);1359__ bind(done_ok);1360__ mov(res, 1);1361}1362__ bind(done);1363break;1364}1365default:1366ShouldNotReachHere();1367}1368}136913701371void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) {1372// if (*addr == cmpval) {1373// *addr = newval;1374// dest = 1;1375// } else {1376// dest = 0;1377// }1378// FIXME: membar_release1379__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), Rtemp);1380Register addr = op->addr()->is_register() ?1381op->addr()->as_pointer_register() :1382op->addr()->as_address_ptr()->base()->as_pointer_register();1383assert(op->addr()->is_register() || op->addr()->as_address_ptr()->disp() == 0, "unexpected disp");1384assert(op->addr()->is_register() || op->addr()->as_address_ptr()->index() == LIR_OprDesc::illegalOpr(), "unexpected index");1385if (op->code() == lir_cas_int || op->code() == lir_cas_obj) {1386Register cmpval = op->cmp_value()->as_register();1387Register newval = op->new_value()->as_register();1388Register dest = op->result_opr()->as_register();1389assert_different_registers(dest, addr, cmpval, newval, Rtemp);13901391__ atomic_cas_bool(cmpval, newval, addr, 0, Rtemp); // Rtemp free by default at C1 LIR layer1392__ mov(dest, 1, eq);1393__ mov(dest, 0, ne);1394} else if (op->code() == lir_cas_long) {1395assert(VM_Version::supports_cx8(), "wrong machine");1396Register cmp_value_lo = op->cmp_value()->as_register_lo();1397Register cmp_value_hi = op->cmp_value()->as_register_hi();1398Register new_value_lo = op->new_value()->as_register_lo();1399Register new_value_hi = op->new_value()->as_register_hi();1400Register dest = op->result_opr()->as_register();1401Register tmp_lo = op->tmp1()->as_register_lo();1402Register tmp_hi = op->tmp1()->as_register_hi();14031404assert_different_registers(tmp_lo, tmp_hi, cmp_value_lo, cmp_value_hi, dest, new_value_lo, new_value_hi, addr);1405assert(tmp_hi->encoding() == tmp_lo->encoding() + 1, "non aligned register pair");1406assert(new_value_hi->encoding() == new_value_lo->encoding() + 1, "non aligned register pair");1407assert((tmp_lo->encoding() & 0x1) == 0, "misaligned register pair");1408assert((new_value_lo->encoding() & 0x1) == 0, "misaligned register pair");1409__ atomic_cas64(tmp_lo, tmp_hi, dest, cmp_value_lo, cmp_value_hi,1410new_value_lo, new_value_hi, addr, 0);1411} else {1412Unimplemented();1413}1414// FIXME: is full membar really needed instead of just membar_acquire?1415__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad | MacroAssembler::StoreStore), Rtemp);1416}141714181419void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type) {1420AsmCondition acond = al;1421AsmCondition ncond = nv;1422if (opr1 != opr2) {1423switch (condition) {1424case lir_cond_equal: acond = eq; ncond = ne; break;1425case lir_cond_notEqual: acond = ne; ncond = eq; break;1426case lir_cond_less: acond = lt; ncond = ge; break;1427case lir_cond_lessEqual: acond = le; ncond = gt; break;1428case lir_cond_greaterEqual: acond = ge; ncond = lt; break;1429case lir_cond_greater: acond = gt; ncond = le; break;1430case lir_cond_aboveEqual: acond = hs; ncond = lo; break;1431case lir_cond_belowEqual: acond = ls; ncond = hi; break;1432default: ShouldNotReachHere();1433}1434}14351436for (;;) { // two iterations only1437if (opr1 == result) {1438// do nothing1439} else if (opr1->is_single_cpu()) {1440__ mov(result->as_register(), opr1->as_register(), acond);1441} else if (opr1->is_double_cpu()) {1442__ long_move(result->as_register_lo(), result->as_register_hi(),1443opr1->as_register_lo(), opr1->as_register_hi(), acond);1444} else if (opr1->is_single_stack()) {1445__ ldr(result->as_register(), frame_map()->address_for_slot(opr1->single_stack_ix()), acond);1446} else if (opr1->is_double_stack()) {1447__ ldr(result->as_register_lo(),1448frame_map()->address_for_slot(opr1->double_stack_ix(), lo_word_offset_in_bytes), acond);1449__ ldr(result->as_register_hi(),1450frame_map()->address_for_slot(opr1->double_stack_ix(), hi_word_offset_in_bytes), acond);1451} else if (opr1->is_illegal()) {1452// do nothing: this part of the cmove has been optimized away in the peephole optimizer1453} else {1454assert(opr1->is_constant(), "must be");1455LIR_Const* c = opr1->as_constant_ptr();14561457switch (c->type()) {1458case T_INT:1459__ mov_slow(result->as_register(), c->as_jint(), acond);1460break;1461case T_LONG:1462__ mov_slow(result->as_register_lo(), c->as_jint_lo(), acond);1463__ mov_slow(result->as_register_hi(), c->as_jint_hi(), acond);1464break;1465case T_OBJECT:1466__ mov_oop(result->as_register(), c->as_jobject(), 0, acond);1467break;1468case T_FLOAT:1469#ifdef __SOFTFP__1470// not generated now.1471__ mov_slow(result->as_register(), c->as_jint(), acond);1472#else1473__ mov_float(result->as_float_reg(), c->as_jfloat(), acond);1474#endif // __SOFTFP__1475break;1476case T_DOUBLE:1477#ifdef __SOFTFP__1478// not generated now.1479__ mov_slow(result->as_register_lo(), c->as_jint_lo(), acond);1480__ mov_slow(result->as_register_hi(), c->as_jint_hi(), acond);1481#else1482__ mov_double(result->as_double_reg(), c->as_jdouble(), acond);1483#endif // __SOFTFP__1484break;1485default:1486ShouldNotReachHere();1487}1488}14891490// Negate the condition and repeat the algorithm with the second operand1491if (opr1 == opr2) { break; }1492opr1 = opr2;1493acond = ncond;1494}1495}14961497#ifdef ASSERT1498static int reg_size(LIR_Opr op) {1499switch (op->type()) {1500case T_FLOAT:1501case T_INT: return BytesPerInt;1502case T_LONG:1503case T_DOUBLE: return BytesPerLong;1504case T_OBJECT:1505case T_ARRAY:1506case T_METADATA: return BytesPerWord;1507case T_ADDRESS:1508case T_ILLEGAL: // fall through1509default: ShouldNotReachHere(); return -1;1510}1511}1512#endif15131514void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest, CodeEmitInfo* info, bool pop_fpu_stack) {1515assert(info == NULL, "unused on this code path");1516assert(dest->is_register(), "wrong items state");15171518if (right->is_address()) {1519// special case for adding shifted/extended register1520const Register res = dest->as_pointer_register();1521const Register lreg = left->as_pointer_register();1522const LIR_Address* addr = right->as_address_ptr();15231524assert(addr->base()->as_pointer_register() == lreg && addr->index()->is_register() && addr->disp() == 0, "must be");15251526int scale = addr->scale();1527AsmShift shift = lsl;152815291530assert(reg_size(addr->base()) == reg_size(addr->index()), "should be");1531assert(reg_size(addr->base()) == reg_size(dest), "should be");1532assert(reg_size(dest) == wordSize, "should be");15331534AsmOperand operand(addr->index()->as_pointer_register(), shift, scale);1535switch (code) {1536case lir_add: __ add(res, lreg, operand); break;1537case lir_sub: __ sub(res, lreg, operand); break;1538default: ShouldNotReachHere();1539}15401541} else if (left->is_address()) {1542assert(code == lir_sub && right->is_single_cpu(), "special case used by strength_reduce_multiply()");1543const LIR_Address* addr = left->as_address_ptr();1544const Register res = dest->as_register();1545const Register rreg = right->as_register();1546assert(addr->base()->as_register() == rreg && addr->index()->is_register() && addr->disp() == 0, "must be");1547__ rsb(res, rreg, AsmOperand(addr->index()->as_register(), lsl, addr->scale()));15481549} else if (dest->is_single_cpu()) {1550assert(left->is_single_cpu(), "unexpected left operand");15511552const Register res = dest->as_register();1553const Register lreg = left->as_register();15541555if (right->is_single_cpu()) {1556const Register rreg = right->as_register();1557switch (code) {1558case lir_add: __ add_32(res, lreg, rreg); break;1559case lir_sub: __ sub_32(res, lreg, rreg); break;1560case lir_mul: __ mul_32(res, lreg, rreg); break;1561default: ShouldNotReachHere();1562}1563} else {1564assert(right->is_constant(), "must be");1565const jint c = right->as_constant_ptr()->as_jint();1566if (!Assembler::is_arith_imm_in_range(c)) {1567BAILOUT("illegal arithmetic operand");1568}1569switch (code) {1570case lir_add: __ add_32(res, lreg, c); break;1571case lir_sub: __ sub_32(res, lreg, c); break;1572default: ShouldNotReachHere();1573}1574}15751576} else if (dest->is_double_cpu()) {1577Register res_lo = dest->as_register_lo();1578Register res_hi = dest->as_register_hi();1579Register lreg_lo = left->as_register_lo();1580Register lreg_hi = left->as_register_hi();1581if (right->is_double_cpu()) {1582Register rreg_lo = right->as_register_lo();1583Register rreg_hi = right->as_register_hi();1584if (res_lo == lreg_hi || res_lo == rreg_hi) {1585res_lo = Rtemp;1586}1587switch (code) {1588case lir_add:1589__ adds(res_lo, lreg_lo, rreg_lo);1590__ adc(res_hi, lreg_hi, rreg_hi);1591break;1592case lir_sub:1593__ subs(res_lo, lreg_lo, rreg_lo);1594__ sbc(res_hi, lreg_hi, rreg_hi);1595break;1596default:1597ShouldNotReachHere();1598}1599} else {1600assert(right->is_constant(), "must be");1601assert((right->as_constant_ptr()->as_jlong() >> 32) == 0, "out of range");1602const jint c = (jint) right->as_constant_ptr()->as_jlong();1603if (res_lo == lreg_hi) {1604res_lo = Rtemp;1605}1606switch (code) {1607case lir_add:1608__ adds(res_lo, lreg_lo, c);1609__ adc(res_hi, lreg_hi, 0);1610break;1611case lir_sub:1612__ subs(res_lo, lreg_lo, c);1613__ sbc(res_hi, lreg_hi, 0);1614break;1615default:1616ShouldNotReachHere();1617}1618}1619move_regs(res_lo, dest->as_register_lo());16201621} else if (dest->is_single_fpu()) {1622assert(left->is_single_fpu(), "must be");1623assert(right->is_single_fpu(), "must be");1624const FloatRegister res = dest->as_float_reg();1625const FloatRegister lreg = left->as_float_reg();1626const FloatRegister rreg = right->as_float_reg();1627switch (code) {1628case lir_add: __ add_float(res, lreg, rreg); break;1629case lir_sub: __ sub_float(res, lreg, rreg); break;1630case lir_mul: __ mul_float(res, lreg, rreg); break;1631case lir_div: __ div_float(res, lreg, rreg); break;1632default: ShouldNotReachHere();1633}1634} else if (dest->is_double_fpu()) {1635assert(left->is_double_fpu(), "must be");1636assert(right->is_double_fpu(), "must be");1637const FloatRegister res = dest->as_double_reg();1638const FloatRegister lreg = left->as_double_reg();1639const FloatRegister rreg = right->as_double_reg();1640switch (code) {1641case lir_add: __ add_double(res, lreg, rreg); break;1642case lir_sub: __ sub_double(res, lreg, rreg); break;1643case lir_mul: __ mul_double(res, lreg, rreg); break;1644case lir_div: __ div_double(res, lreg, rreg); break;1645default: ShouldNotReachHere();1646}1647} else {1648ShouldNotReachHere();1649}1650}165116521653void LIR_Assembler::intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr unused, LIR_Opr dest, LIR_Op* op) {1654switch (code) {1655case lir_abs:1656__ abs_double(dest->as_double_reg(), value->as_double_reg());1657break;1658case lir_sqrt:1659__ sqrt_double(dest->as_double_reg(), value->as_double_reg());1660break;1661default:1662ShouldNotReachHere();1663}1664}166516661667void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest) {1668assert(dest->is_register(), "wrong items state");1669assert(left->is_register(), "wrong items state");16701671if (dest->is_single_cpu()) {16721673const Register res = dest->as_register();1674const Register lreg = left->as_register();16751676if (right->is_single_cpu()) {1677const Register rreg = right->as_register();1678switch (code) {1679case lir_logic_and: __ and_32(res, lreg, rreg); break;1680case lir_logic_or: __ orr_32(res, lreg, rreg); break;1681case lir_logic_xor: __ eor_32(res, lreg, rreg); break;1682default: ShouldNotReachHere();1683}1684} else {1685assert(right->is_constant(), "must be");1686const uint c = (uint)right->as_constant_ptr()->as_jint();1687switch (code) {1688case lir_logic_and: __ and_32(res, lreg, c); break;1689case lir_logic_or: __ orr_32(res, lreg, c); break;1690case lir_logic_xor: __ eor_32(res, lreg, c); break;1691default: ShouldNotReachHere();1692}1693}1694} else {1695assert(dest->is_double_cpu(), "should be");1696Register res_lo = dest->as_register_lo();16971698assert (dest->type() == T_LONG, "unexpected result type");1699assert (left->type() == T_LONG, "unexpected left type");1700assert (right->type() == T_LONG, "unexpected right type");17011702const Register res_hi = dest->as_register_hi();1703const Register lreg_lo = left->as_register_lo();1704const Register lreg_hi = left->as_register_hi();17051706if (right->is_register()) {1707const Register rreg_lo = right->as_register_lo();1708const Register rreg_hi = right->as_register_hi();1709if (res_lo == lreg_hi || res_lo == rreg_hi) {1710res_lo = Rtemp; // Temp register helps to avoid overlap between result and input1711}1712switch (code) {1713case lir_logic_and:1714__ andr(res_lo, lreg_lo, rreg_lo);1715__ andr(res_hi, lreg_hi, rreg_hi);1716break;1717case lir_logic_or:1718__ orr(res_lo, lreg_lo, rreg_lo);1719__ orr(res_hi, lreg_hi, rreg_hi);1720break;1721case lir_logic_xor:1722__ eor(res_lo, lreg_lo, rreg_lo);1723__ eor(res_hi, lreg_hi, rreg_hi);1724break;1725default:1726ShouldNotReachHere();1727}1728move_regs(res_lo, dest->as_register_lo());1729} else {1730assert(right->is_constant(), "must be");1731const jint c_lo = (jint) right->as_constant_ptr()->as_jlong();1732const jint c_hi = (jint) (right->as_constant_ptr()->as_jlong() >> 32);1733// Case for logic_or from do_ClassIDIntrinsic()1734if (c_hi == 0 && AsmOperand::is_rotated_imm(c_lo)) {1735switch (code) {1736case lir_logic_and:1737__ andr(res_lo, lreg_lo, c_lo);1738__ mov(res_hi, 0);1739break;1740case lir_logic_or:1741__ orr(res_lo, lreg_lo, c_lo);1742break;1743case lir_logic_xor:1744__ eor(res_lo, lreg_lo, c_lo);1745break;1746default:1747ShouldNotReachHere();1748}1749} else if (code == lir_logic_and &&1750c_hi == -1 &&1751(AsmOperand::is_rotated_imm(c_lo) ||1752AsmOperand::is_rotated_imm(~c_lo))) {1753// Another case which handles logic_and from do_ClassIDIntrinsic()1754if (AsmOperand::is_rotated_imm(c_lo)) {1755__ andr(res_lo, lreg_lo, c_lo);1756} else {1757__ bic(res_lo, lreg_lo, ~c_lo);1758}1759if (res_hi != lreg_hi) {1760__ mov(res_hi, lreg_hi);1761}1762} else {1763BAILOUT("64 bit constant cannot be inlined");1764}1765}1766}1767}1768176917701771void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Op2* op) {1772if (opr1->is_single_cpu()) {1773if (opr2->is_constant()) {1774switch (opr2->as_constant_ptr()->type()) {1775case T_INT: {1776const jint c = opr2->as_constant_ptr()->as_jint();1777if (Assembler::is_arith_imm_in_range(c)) {1778__ cmp_32(opr1->as_register(), c);1779} else if (Assembler::is_arith_imm_in_range(-c)) {1780__ cmn_32(opr1->as_register(), -c);1781} else {1782// This can happen when compiling lookupswitch1783__ mov_slow(Rtemp, c);1784__ cmp_32(opr1->as_register(), Rtemp);1785}1786break;1787}1788case T_OBJECT:1789assert(opr2->as_constant_ptr()->as_jobject() == NULL, "cannot handle otherwise");1790__ cmp(opr1->as_register(), 0);1791break;1792case T_METADATA:1793assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "Only equality tests");1794assert(opr2->as_constant_ptr()->as_metadata() == NULL, "cannot handle otherwise");1795__ cmp(opr1->as_register(), 0);1796break;1797default:1798ShouldNotReachHere();1799}1800} else if (opr2->is_single_cpu()) {1801if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) {1802assert(opr2->type() == T_OBJECT || opr2->type() == T_ARRAY, "incompatibe type");1803__ cmpoop(opr1->as_register(), opr2->as_register());1804} else if (opr1->type() == T_METADATA || opr1->type() == T_ADDRESS) {1805assert(opr2->type() == T_METADATA || opr2->type() == T_ADDRESS, "incompatibe type");1806__ cmp(opr1->as_register(), opr2->as_register());1807} else {1808assert(opr2->type() != T_OBJECT && opr2->type() != T_ARRAY && opr2->type() != T_METADATA && opr2->type() != T_ADDRESS, "incompatibe type");1809__ cmp_32(opr1->as_register(), opr2->as_register());1810}1811} else {1812ShouldNotReachHere();1813}1814} else if (opr1->is_double_cpu()) {1815Register xlo = opr1->as_register_lo();1816Register xhi = opr1->as_register_hi();1817if (opr2->is_constant() && opr2->as_jlong() == 0) {1818assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "cannot handle otherwise");1819__ orrs(Rtemp, xlo, xhi);1820} else if (opr2->is_register()) {1821Register ylo = opr2->as_register_lo();1822Register yhi = opr2->as_register_hi();1823if (condition == lir_cond_equal || condition == lir_cond_notEqual) {1824__ teq(xhi, yhi);1825__ teq(xlo, ylo, eq);1826} else {1827__ subs(xlo, xlo, ylo);1828__ sbcs(xhi, xhi, yhi);1829}1830} else {1831ShouldNotReachHere();1832}1833} else if (opr1->is_single_fpu()) {1834if (opr2->is_constant()) {1835assert(opr2->as_jfloat() == 0.0f, "cannot handle otherwise");1836__ cmp_zero_float(opr1->as_float_reg());1837} else {1838__ cmp_float(opr1->as_float_reg(), opr2->as_float_reg());1839}1840} else if (opr1->is_double_fpu()) {1841if (opr2->is_constant()) {1842assert(opr2->as_jdouble() == 0.0, "cannot handle otherwise");1843__ cmp_zero_double(opr1->as_double_reg());1844} else {1845__ cmp_double(opr1->as_double_reg(), opr2->as_double_reg());1846}1847} else {1848ShouldNotReachHere();1849}1850}18511852void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst, LIR_Op2* op) {1853const Register res = dst->as_register();1854if (code == lir_cmp_fd2i || code == lir_ucmp_fd2i) {1855comp_op(lir_cond_unknown, left, right, op);1856__ fmstat();1857if (code == lir_ucmp_fd2i) { // unordered is less1858__ mvn(res, 0, lt);1859__ mov(res, 1, ge);1860} else { // unordered is greater1861__ mov(res, 1, cs);1862__ mvn(res, 0, cc);1863}1864__ mov(res, 0, eq);18651866} else {1867assert(code == lir_cmp_l2i, "must be");18681869Label done;1870const Register xlo = left->as_register_lo();1871const Register xhi = left->as_register_hi();1872const Register ylo = right->as_register_lo();1873const Register yhi = right->as_register_hi();1874__ cmp(xhi, yhi);1875__ mov(res, 1, gt);1876__ mvn(res, 0, lt);1877__ b(done, ne);1878__ subs(res, xlo, ylo);1879__ mov(res, 1, hi);1880__ mvn(res, 0, lo);1881__ bind(done);1882}1883}188418851886void LIR_Assembler::align_call(LIR_Code code) {1887// Not needed1888}188918901891void LIR_Assembler::call(LIR_OpJavaCall *op, relocInfo::relocType rtype) {1892int ret_addr_offset = __ patchable_call(op->addr(), rtype);1893assert(ret_addr_offset == __ offset(), "embedded return address not allowed");1894add_call_info_here(op->info());1895}189618971898void LIR_Assembler::ic_call(LIR_OpJavaCall *op) {1899bool near_range = __ cache_fully_reachable();1900address oop_address = pc();19011902bool use_movw = VM_Version::supports_movw();19031904// Ricklass may contain something that is not a metadata pointer so1905// mov_metadata can't be used1906InlinedAddress value((address)Universe::non_oop_word());1907InlinedAddress addr(op->addr());1908if (use_movw) {1909__ movw(Ricklass, ((unsigned int)Universe::non_oop_word()) & 0xffff);1910__ movt(Ricklass, ((unsigned int)Universe::non_oop_word()) >> 16);1911} else {1912// No movw/movt, must be load a pc relative value but no1913// relocation so no metadata table to load from.1914// Use a b instruction rather than a bl, inline constant after the1915// branch, use a PC relative ldr to load the constant, arrange for1916// the call to return after the constant(s).1917__ ldr_literal(Ricklass, value);1918}1919__ relocate(virtual_call_Relocation::spec(oop_address));1920if (near_range && use_movw) {1921__ bl(op->addr());1922} else {1923Label call_return;1924__ adr(LR, call_return);1925if (near_range) {1926__ b(op->addr());1927} else {1928__ indirect_jump(addr, Rtemp);1929__ bind_literal(addr);1930}1931if (!use_movw) {1932__ bind_literal(value);1933}1934__ bind(call_return);1935}1936add_call_info(code_offset(), op->info());1937}19381939void LIR_Assembler::emit_static_call_stub() {1940address call_pc = __ pc();1941address stub = __ start_a_stub(call_stub_size());1942if (stub == NULL) {1943BAILOUT("static call stub overflow");1944}19451946DEBUG_ONLY(int offset = code_offset();)19471948InlinedMetadata metadata_literal(NULL);1949__ relocate(static_stub_Relocation::spec(call_pc));1950// If not a single instruction, NativeMovConstReg::next_instruction_address()1951// must jump over the whole following ldr_literal.1952// (See CompiledStaticCall::set_to_interpreted())1953#ifdef ASSERT1954address ldr_site = __ pc();1955#endif1956__ ldr_literal(Rmethod, metadata_literal);1957assert(nativeMovConstReg_at(ldr_site)->next_instruction_address() == __ pc(), "Fix ldr_literal or its parsing");1958bool near_range = __ cache_fully_reachable();1959InlinedAddress dest((address)-1);1960if (near_range) {1961address branch_site = __ pc();1962__ b(branch_site); // b to self maps to special NativeJump -1 destination1963} else {1964__ indirect_jump(dest, Rtemp);1965}1966__ bind_literal(metadata_literal); // includes spec_for_immediate reloc1967if (!near_range) {1968__ bind_literal(dest); // special NativeJump -1 destination1969}19701971assert(code_offset() - offset <= call_stub_size(), "overflow");1972__ end_a_stub();1973}19741975void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) {1976assert(exceptionOop->as_register() == Rexception_obj, "must match");1977assert(exceptionPC->as_register() == Rexception_pc, "must match");1978info->add_register_oop(exceptionOop);19791980Runtime1::StubID handle_id = compilation()->has_fpu_code() ?1981Runtime1::handle_exception_id :1982Runtime1::handle_exception_nofpu_id;1983Label return_address;1984__ adr(Rexception_pc, return_address);1985__ call(Runtime1::entry_for(handle_id), relocInfo::runtime_call_type);1986__ bind(return_address);1987add_call_info_here(info); // for exception handler1988}19891990void LIR_Assembler::unwind_op(LIR_Opr exceptionOop) {1991assert(exceptionOop->as_register() == Rexception_obj, "must match");1992__ b(_unwind_handler_entry);1993}19941995void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) {1996AsmShift shift = lsl;1997switch (code) {1998case lir_shl: shift = lsl; break;1999case lir_shr: shift = asr; break;2000case lir_ushr: shift = lsr; break;2001default: ShouldNotReachHere();2002}20032004if (dest->is_single_cpu()) {2005__ andr(Rtemp, count->as_register(), 31);2006__ mov(dest->as_register(), AsmOperand(left->as_register(), shift, Rtemp));2007} else if (dest->is_double_cpu()) {2008Register dest_lo = dest->as_register_lo();2009Register dest_hi = dest->as_register_hi();2010Register src_lo = left->as_register_lo();2011Register src_hi = left->as_register_hi();2012Register Rcount = count->as_register();2013// Resolve possible register conflicts2014if (shift == lsl && dest_hi == src_lo) {2015dest_hi = Rtemp;2016} else if (shift != lsl && dest_lo == src_hi) {2017dest_lo = Rtemp;2018} else if (dest_lo == src_lo && dest_hi == src_hi) {2019dest_lo = Rtemp;2020} else if (dest_lo == Rcount || dest_hi == Rcount) {2021Rcount = Rtemp;2022}2023__ andr(Rcount, count->as_register(), 63);2024__ long_shift(dest_lo, dest_hi, src_lo, src_hi, shift, Rcount);2025move_regs(dest_lo, dest->as_register_lo());2026move_regs(dest_hi, dest->as_register_hi());2027} else {2028ShouldNotReachHere();2029}2030}203120322033void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, jint count, LIR_Opr dest) {2034AsmShift shift = lsl;2035switch (code) {2036case lir_shl: shift = lsl; break;2037case lir_shr: shift = asr; break;2038case lir_ushr: shift = lsr; break;2039default: ShouldNotReachHere();2040}20412042if (dest->is_single_cpu()) {2043count &= 31;2044if (count != 0) {2045__ mov(dest->as_register(), AsmOperand(left->as_register(), shift, count));2046} else {2047move_regs(left->as_register(), dest->as_register());2048}2049} else if (dest->is_double_cpu()) {2050count &= 63;2051if (count != 0) {2052Register dest_lo = dest->as_register_lo();2053Register dest_hi = dest->as_register_hi();2054Register src_lo = left->as_register_lo();2055Register src_hi = left->as_register_hi();2056// Resolve possible register conflicts2057if (shift == lsl && dest_hi == src_lo) {2058dest_hi = Rtemp;2059} else if (shift != lsl && dest_lo == src_hi) {2060dest_lo = Rtemp;2061}2062__ long_shift(dest_lo, dest_hi, src_lo, src_hi, shift, count);2063move_regs(dest_lo, dest->as_register_lo());2064move_regs(dest_hi, dest->as_register_hi());2065} else {2066__ long_move(dest->as_register_lo(), dest->as_register_hi(),2067left->as_register_lo(), left->as_register_hi());2068}2069} else {2070ShouldNotReachHere();2071}2072}207320742075// Saves 4 given registers in reserved argument area.2076void LIR_Assembler::save_in_reserved_area(Register r1, Register r2, Register r3, Register r4) {2077verify_reserved_argument_area_size(4);2078__ stmia(SP, RegisterSet(r1) | RegisterSet(r2) | RegisterSet(r3) | RegisterSet(r4));2079}20802081// Restores 4 given registers from reserved argument area.2082void LIR_Assembler::restore_from_reserved_area(Register r1, Register r2, Register r3, Register r4) {2083__ ldmia(SP, RegisterSet(r1) | RegisterSet(r2) | RegisterSet(r3) | RegisterSet(r4), no_writeback);2084}208520862087void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {2088ciArrayKlass* default_type = op->expected_type();2089Register src = op->src()->as_register();2090Register src_pos = op->src_pos()->as_register();2091Register dst = op->dst()->as_register();2092Register dst_pos = op->dst_pos()->as_register();2093Register length = op->length()->as_register();2094Register tmp = op->tmp()->as_register();2095Register tmp2 = Rtemp;20962097assert(src == R0 && src_pos == R1 && dst == R2 && dst_pos == R3, "code assumption");20982099CodeStub* stub = op->stub();21002101int flags = op->flags();2102BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL;2103if (basic_type == T_ARRAY) basic_type = T_OBJECT;21042105// If we don't know anything or it's an object array, just go through the generic arraycopy2106if (default_type == NULL) {21072108// save arguments, because they will be killed by a runtime call2109save_in_reserved_area(R0, R1, R2, R3);21102111// pass length argument on SP[0]2112__ str(length, Address(SP, -2*wordSize, pre_indexed)); // 2 words for a proper stack alignment21132114address copyfunc_addr = StubRoutines::generic_arraycopy();2115assert(copyfunc_addr != NULL, "generic arraycopy stub required");2116#ifndef PRODUCT2117if (PrintC1Statistics) {2118__ inc_counter((address)&Runtime1::_generic_arraycopystub_cnt, tmp, tmp2);2119}2120#endif // !PRODUCT2121// the stub is in the code cache so close enough2122__ call(copyfunc_addr, relocInfo::runtime_call_type);21232124__ add(SP, SP, 2*wordSize);21252126__ cbz_32(R0, *stub->continuation());21272128__ mvn_32(tmp, R0);2129restore_from_reserved_area(R0, R1, R2, R3); // load saved arguments in slow case only2130__ sub_32(length, length, tmp);2131__ add_32(src_pos, src_pos, tmp);2132__ add_32(dst_pos, dst_pos, tmp);21332134__ b(*stub->entry());21352136__ bind(*stub->continuation());2137return;2138}21392140assert(default_type != NULL && default_type->is_array_klass() && default_type->is_loaded(),2141"must be true at this point");2142int elem_size = type2aelembytes(basic_type);2143int shift = exact_log2(elem_size);21442145// Check for NULL2146if (flags & LIR_OpArrayCopy::src_null_check) {2147if (flags & LIR_OpArrayCopy::dst_null_check) {2148__ cmp(src, 0);2149__ cond_cmp(dst, 0, ne); // make one instruction shorter if both checks are needed2150__ b(*stub->entry(), eq);2151} else {2152__ cbz(src, *stub->entry());2153}2154} else if (flags & LIR_OpArrayCopy::dst_null_check) {2155__ cbz(dst, *stub->entry());2156}21572158// If the compiler was not able to prove that exact type of the source or the destination2159// of the arraycopy is an array type, check at runtime if the source or the destination is2160// an instance type.2161if (flags & LIR_OpArrayCopy::type_check) {2162if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::dst_objarray)) {2163__ load_klass(tmp, dst);2164__ ldr_u32(tmp2, Address(tmp, in_bytes(Klass::layout_helper_offset())));2165__ mov_slow(tmp, Klass::_lh_neutral_value);2166__ cmp_32(tmp2, tmp);2167__ b(*stub->entry(), ge);2168}21692170if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::src_objarray)) {2171__ load_klass(tmp, src);2172__ ldr_u32(tmp2, Address(tmp, in_bytes(Klass::layout_helper_offset())));2173__ mov_slow(tmp, Klass::_lh_neutral_value);2174__ cmp_32(tmp2, tmp);2175__ b(*stub->entry(), ge);2176}2177}21782179// Check if negative2180const int all_positive_checks = LIR_OpArrayCopy::src_pos_positive_check |2181LIR_OpArrayCopy::dst_pos_positive_check |2182LIR_OpArrayCopy::length_positive_check;2183switch (flags & all_positive_checks) {2184case LIR_OpArrayCopy::src_pos_positive_check:2185__ branch_if_negative_32(src_pos, *stub->entry());2186break;2187case LIR_OpArrayCopy::dst_pos_positive_check:2188__ branch_if_negative_32(dst_pos, *stub->entry());2189break;2190case LIR_OpArrayCopy::length_positive_check:2191__ branch_if_negative_32(length, *stub->entry());2192break;2193case LIR_OpArrayCopy::src_pos_positive_check | LIR_OpArrayCopy::dst_pos_positive_check:2194__ branch_if_any_negative_32(src_pos, dst_pos, tmp, *stub->entry());2195break;2196case LIR_OpArrayCopy::src_pos_positive_check | LIR_OpArrayCopy::length_positive_check:2197__ branch_if_any_negative_32(src_pos, length, tmp, *stub->entry());2198break;2199case LIR_OpArrayCopy::dst_pos_positive_check | LIR_OpArrayCopy::length_positive_check:2200__ branch_if_any_negative_32(dst_pos, length, tmp, *stub->entry());2201break;2202case all_positive_checks:2203__ branch_if_any_negative_32(src_pos, dst_pos, length, tmp, *stub->entry());2204break;2205default:2206assert((flags & all_positive_checks) == 0, "the last option");2207}22082209// Range checks2210if (flags & LIR_OpArrayCopy::src_range_check) {2211__ ldr_s32(tmp2, Address(src, arrayOopDesc::length_offset_in_bytes()));2212__ add_32(tmp, src_pos, length);2213__ cmp_32(tmp, tmp2);2214__ b(*stub->entry(), hi);2215}2216if (flags & LIR_OpArrayCopy::dst_range_check) {2217__ ldr_s32(tmp2, Address(dst, arrayOopDesc::length_offset_in_bytes()));2218__ add_32(tmp, dst_pos, length);2219__ cmp_32(tmp, tmp2);2220__ b(*stub->entry(), hi);2221}22222223// Check if src and dst are of the same type2224if (flags & LIR_OpArrayCopy::type_check) {2225// We don't know the array types are compatible2226if (basic_type != T_OBJECT) {2227// Simple test for basic type arrays2228if (UseCompressedClassPointers) {2229// We don't need decode because we just need to compare2230__ ldr_u32(tmp, Address(src, oopDesc::klass_offset_in_bytes()));2231__ ldr_u32(tmp2, Address(dst, oopDesc::klass_offset_in_bytes()));2232__ cmp_32(tmp, tmp2);2233} else {2234__ load_klass(tmp, src);2235__ load_klass(tmp2, dst);2236__ cmp(tmp, tmp2);2237}2238__ b(*stub->entry(), ne);2239} else {2240// For object arrays, if src is a sub class of dst then we can2241// safely do the copy.2242Label cont, slow;22432244address copyfunc_addr = StubRoutines::checkcast_arraycopy();22452246__ load_klass(tmp, src);2247__ load_klass(tmp2, dst);22482249// We are at a call so all live registers are saved before we2250// get here2251assert_different_registers(tmp, tmp2, R6, altFP_7_11);22522253__ check_klass_subtype_fast_path(tmp, tmp2, R6, altFP_7_11, &cont, copyfunc_addr == NULL ? stub->entry() : &slow, NULL);22542255__ mov(R6, R0);2256__ mov(altFP_7_11, R1);2257__ mov(R0, tmp);2258__ mov(R1, tmp2);2259__ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type); // does not blow any registers except R0, LR and Rtemp2260__ cmp_32(R0, 0);2261__ mov(R0, R6);2262__ mov(R1, altFP_7_11);22632264if (copyfunc_addr != NULL) { // use stub if available2265// src is not a sub class of dst so we have to do a2266// per-element check.22672268__ b(cont, ne);22692270__ bind(slow);22712272int mask = LIR_OpArrayCopy::src_objarray|LIR_OpArrayCopy::dst_objarray;2273if ((flags & mask) != mask) {2274// Check that at least both of them object arrays.2275assert(flags & mask, "one of the two should be known to be an object array");22762277if (!(flags & LIR_OpArrayCopy::src_objarray)) {2278__ load_klass(tmp, src);2279} else if (!(flags & LIR_OpArrayCopy::dst_objarray)) {2280__ load_klass(tmp, dst);2281}2282int lh_offset = in_bytes(Klass::layout_helper_offset());22832284__ ldr_u32(tmp2, Address(tmp, lh_offset));22852286jint objArray_lh = Klass::array_layout_helper(T_OBJECT);2287__ mov_slow(tmp, objArray_lh);2288__ cmp_32(tmp, tmp2);2289__ b(*stub->entry(), ne);2290}22912292save_in_reserved_area(R0, R1, R2, R3);22932294Register src_ptr = R0;2295Register dst_ptr = R1;2296Register len = R2;2297Register chk_off = R3;2298Register super_k = tmp;22992300__ add(src_ptr, src, arrayOopDesc::base_offset_in_bytes(basic_type));2301__ add_ptr_scaled_int32(src_ptr, src_ptr, src_pos, shift);23022303__ add(dst_ptr, dst, arrayOopDesc::base_offset_in_bytes(basic_type));2304__ add_ptr_scaled_int32(dst_ptr, dst_ptr, dst_pos, shift);2305__ load_klass(tmp, dst);23062307int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset());2308int sco_offset = in_bytes(Klass::super_check_offset_offset());23092310__ ldr(super_k, Address(tmp, ek_offset));23112312__ mov(len, length);2313__ ldr_u32(chk_off, Address(super_k, sco_offset));2314__ push(super_k);23152316__ call(copyfunc_addr, relocInfo::runtime_call_type);23172318#ifndef PRODUCT2319if (PrintC1Statistics) {2320Label failed;2321__ cbnz_32(R0, failed);2322__ inc_counter((address)&Runtime1::_arraycopy_checkcast_cnt, tmp, tmp2);2323__ bind(failed);2324}2325#endif // PRODUCT23262327__ add(SP, SP, wordSize); // Drop super_k argument23282329__ cbz_32(R0, *stub->continuation());2330__ mvn_32(tmp, R0);23312332// load saved arguments in slow case only2333restore_from_reserved_area(R0, R1, R2, R3);23342335__ sub_32(length, length, tmp);2336__ add_32(src_pos, src_pos, tmp);2337__ add_32(dst_pos, dst_pos, tmp);23382339#ifndef PRODUCT2340if (PrintC1Statistics) {2341__ inc_counter((address)&Runtime1::_arraycopy_checkcast_attempt_cnt, tmp, tmp2);2342}2343#endif23442345__ b(*stub->entry());23462347__ bind(cont);2348} else {2349__ b(*stub->entry(), eq);2350__ bind(cont);2351}2352}2353}23542355#ifndef PRODUCT2356if (PrintC1Statistics) {2357address counter = Runtime1::arraycopy_count_address(basic_type);2358__ inc_counter(counter, tmp, tmp2);2359}2360#endif // !PRODUCT23612362bool disjoint = (flags & LIR_OpArrayCopy::overlapping) == 0;2363bool aligned = (flags & LIR_OpArrayCopy::unaligned) == 0;2364const char *name;2365address entry = StubRoutines::select_arraycopy_function(basic_type, aligned, disjoint, name, false);23662367Register src_ptr = R0;2368Register dst_ptr = R1;2369Register len = R2;23702371__ add(src_ptr, src, arrayOopDesc::base_offset_in_bytes(basic_type));2372__ add_ptr_scaled_int32(src_ptr, src_ptr, src_pos, shift);23732374__ add(dst_ptr, dst, arrayOopDesc::base_offset_in_bytes(basic_type));2375__ add_ptr_scaled_int32(dst_ptr, dst_ptr, dst_pos, shift);23762377__ mov(len, length);23782379__ call(entry, relocInfo::runtime_call_type);23802381__ bind(*stub->continuation());2382}23832384#ifdef ASSERT2385// emit run-time assertion2386void LIR_Assembler::emit_assert(LIR_OpAssert* op) {2387assert(op->code() == lir_assert, "must be");23882389if (op->in_opr1()->is_valid()) {2390assert(op->in_opr2()->is_valid(), "both operands must be valid");2391comp_op(op->condition(), op->in_opr1(), op->in_opr2(), op);2392} else {2393assert(op->in_opr2()->is_illegal(), "both operands must be illegal");2394assert(op->condition() == lir_cond_always, "no other conditions allowed");2395}23962397Label ok;2398if (op->condition() != lir_cond_always) {2399AsmCondition acond = al;2400switch (op->condition()) {2401case lir_cond_equal: acond = eq; break;2402case lir_cond_notEqual: acond = ne; break;2403case lir_cond_less: acond = lt; break;2404case lir_cond_lessEqual: acond = le; break;2405case lir_cond_greaterEqual: acond = ge; break;2406case lir_cond_greater: acond = gt; break;2407case lir_cond_aboveEqual: acond = hs; break;2408case lir_cond_belowEqual: acond = ls; break;2409default: ShouldNotReachHere();2410}2411__ b(ok, acond);2412}2413if (op->halt()) {2414const char* str = __ code_string(op->msg());2415__ stop(str);2416} else {2417breakpoint();2418}2419__ bind(ok);2420}2421#endif // ASSERT24222423void LIR_Assembler::emit_updatecrc32(LIR_OpUpdateCRC32* op) {2424fatal("CRC32 intrinsic is not implemented on this platform");2425}24262427void LIR_Assembler::emit_lock(LIR_OpLock* op) {2428Register obj = op->obj_opr()->as_pointer_register();2429Register hdr = op->hdr_opr()->as_pointer_register();2430Register lock = op->lock_opr()->as_pointer_register();2431Register tmp = op->scratch_opr()->is_illegal() ? noreg :2432op->scratch_opr()->as_pointer_register();24332434if (!UseFastLocking) {2435__ b(*op->stub()->entry());2436} else if (op->code() == lir_lock) {2437assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");2438int null_check_offset = __ lock_object(hdr, obj, lock, tmp, *op->stub()->entry());2439if (op->info() != NULL) {2440add_debug_info_for_null_check(null_check_offset, op->info());2441}2442} else if (op->code() == lir_unlock) {2443__ unlock_object(hdr, obj, lock, tmp, *op->stub()->entry());2444} else {2445ShouldNotReachHere();2446}2447__ bind(*op->stub()->continuation());2448}244924502451void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {2452ciMethod* method = op->profiled_method();2453int bci = op->profiled_bci();2454ciMethod* callee = op->profiled_callee();24552456// Update counter for all call types2457ciMethodData* md = method->method_data_or_null();2458assert(md != NULL, "Sanity");2459ciProfileData* data = md->bci_to_data(bci);2460assert(data != NULL && data->is_CounterData(), "need CounterData for calls");2461assert(op->mdo()->is_single_cpu(), "mdo must be allocated");2462Register mdo = op->mdo()->as_register();2463assert(op->tmp1()->is_register(), "tmp1 must be allocated");2464Register tmp1 = op->tmp1()->as_pointer_register();2465assert_different_registers(mdo, tmp1);2466__ mov_metadata(mdo, md->constant_encoding());2467int mdo_offset_bias = 0;2468int max_offset = 4096;2469if (md->byte_offset_of_slot(data, CounterData::count_offset()) + data->size_in_bytes() >= max_offset) {2470// The offset is large so bias the mdo by the base of the slot so2471// that the ldr can use an immediate offset to reference the slots of the data2472mdo_offset_bias = md->byte_offset_of_slot(data, CounterData::count_offset());2473__ mov_slow(tmp1, mdo_offset_bias);2474__ add(mdo, mdo, tmp1);2475}24762477Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);2478// Perform additional virtual call profiling for invokevirtual and2479// invokeinterface bytecodes2480if (op->should_profile_receiver_type()) {2481assert(op->recv()->is_single_cpu(), "recv must be allocated");2482Register recv = op->recv()->as_register();2483assert_different_registers(mdo, tmp1, recv);2484assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls");2485ciKlass* known_klass = op->known_holder();2486if (C1OptimizeVirtualCallProfiling && known_klass != NULL) {2487// We know the type that will be seen at this call site; we can2488// statically update the MethodData* rather than needing to do2489// dynamic tests on the receiver type24902491// NOTE: we should probably put a lock around this search to2492// avoid collisions by concurrent compilations2493ciVirtualCallData* vc_data = (ciVirtualCallData*) data;2494uint i;2495for (i = 0; i < VirtualCallData::row_limit(); i++) {2496ciKlass* receiver = vc_data->receiver(i);2497if (known_klass->equals(receiver)) {2498Address data_addr(mdo, md->byte_offset_of_slot(data,2499VirtualCallData::receiver_count_offset(i)) -2500mdo_offset_bias);2501__ ldr(tmp1, data_addr);2502__ add(tmp1, tmp1, DataLayout::counter_increment);2503__ str(tmp1, data_addr);2504return;2505}2506}25072508// Receiver type not found in profile data; select an empty slot25092510// Note that this is less efficient than it should be because it2511// always does a write to the receiver part of the2512// VirtualCallData rather than just the first time2513for (i = 0; i < VirtualCallData::row_limit(); i++) {2514ciKlass* receiver = vc_data->receiver(i);2515if (receiver == NULL) {2516Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)) -2517mdo_offset_bias);2518__ mov_metadata(tmp1, known_klass->constant_encoding());2519__ str(tmp1, recv_addr);2520Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)) -2521mdo_offset_bias);2522__ ldr(tmp1, data_addr);2523__ add(tmp1, tmp1, DataLayout::counter_increment);2524__ str(tmp1, data_addr);2525return;2526}2527}2528} else {2529__ load_klass(recv, recv);2530Label update_done;2531type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &update_done);2532// Receiver did not match any saved receiver and there is no empty row for it.2533// Increment total counter to indicate polymorphic case.2534__ ldr(tmp1, counter_addr);2535__ add(tmp1, tmp1, DataLayout::counter_increment);2536__ str(tmp1, counter_addr);25372538__ bind(update_done);2539}2540} else {2541// Static call2542__ ldr(tmp1, counter_addr);2543__ add(tmp1, tmp1, DataLayout::counter_increment);2544__ str(tmp1, counter_addr);2545}2546}25472548void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {2549fatal("Type profiling not implemented on this platform");2550}25512552void LIR_Assembler::emit_delay(LIR_OpDelay*) {2553Unimplemented();2554}255525562557void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst) {2558Address mon_addr = frame_map()->address_for_monitor_lock(monitor_no);2559__ add_slow(dst->as_pointer_register(), mon_addr.base(), mon_addr.disp());2560}256125622563void LIR_Assembler::align_backward_branch_target() {2564// Some ARM processors do better with 8-byte branch target alignment2565__ align(8);2566}256725682569void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest, LIR_Opr tmp) {2570// tmp must be unused2571assert(tmp->is_illegal(), "wasting a register if tmp is allocated");25722573if (left->is_single_cpu()) {2574assert (dest->type() == T_INT, "unexpected result type");2575assert (left->type() == T_INT, "unexpected left type");2576__ neg_32(dest->as_register(), left->as_register());2577} else if (left->is_double_cpu()) {2578Register dest_lo = dest->as_register_lo();2579Register dest_hi = dest->as_register_hi();2580Register src_lo = left->as_register_lo();2581Register src_hi = left->as_register_hi();2582if (dest_lo == src_hi) {2583dest_lo = Rtemp;2584}2585__ rsbs(dest_lo, src_lo, 0);2586__ rsc(dest_hi, src_hi, 0);2587move_regs(dest_lo, dest->as_register_lo());2588} else if (left->is_single_fpu()) {2589__ neg_float(dest->as_float_reg(), left->as_float_reg());2590} else if (left->is_double_fpu()) {2591__ neg_double(dest->as_double_reg(), left->as_double_reg());2592} else {2593ShouldNotReachHere();2594}2595}259625972598void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {2599assert(patch_code == lir_patch_none, "Patch code not supported");2600LIR_Address* addr = addr_opr->as_address_ptr();2601if (addr->index()->is_illegal()) {2602jint c = addr->disp();2603if (!Assembler::is_arith_imm_in_range(c)) {2604BAILOUT("illegal arithmetic operand");2605}2606__ add(dest->as_pointer_register(), addr->base()->as_pointer_register(), c);2607} else {2608assert(addr->disp() == 0, "cannot handle otherwise");2609__ add(dest->as_pointer_register(), addr->base()->as_pointer_register(),2610AsmOperand(addr->index()->as_pointer_register(), lsl, addr->scale()));2611}2612}261326142615void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) {2616assert(!tmp->is_valid(), "don't need temporary");2617__ call(dest);2618if (info != NULL) {2619add_call_info_here(info);2620}2621}262226232624void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) {2625assert(src->is_double_cpu() && dest->is_address() ||2626src->is_address() && dest->is_double_cpu(),2627"Simple move_op is called for all other cases");26282629int null_check_offset;2630if (dest->is_address()) {2631// Store2632const LIR_Address* addr = dest->as_address_ptr();2633const Register src_lo = src->as_register_lo();2634const Register src_hi = src->as_register_hi();2635assert(addr->index()->is_illegal() && addr->disp() == 0, "The address is simple already");26362637if (src_lo < src_hi) {2638null_check_offset = __ offset();2639__ stmia(addr->base()->as_register(), RegisterSet(src_lo) | RegisterSet(src_hi));2640} else {2641assert(src_lo < Rtemp, "Rtemp is higher than any allocatable register");2642__ mov(Rtemp, src_hi);2643null_check_offset = __ offset();2644__ stmia(addr->base()->as_register(), RegisterSet(src_lo) | RegisterSet(Rtemp));2645}2646} else {2647// Load2648const LIR_Address* addr = src->as_address_ptr();2649const Register dest_lo = dest->as_register_lo();2650const Register dest_hi = dest->as_register_hi();2651assert(addr->index()->is_illegal() && addr->disp() == 0, "The address is simple already");26522653null_check_offset = __ offset();2654if (dest_lo < dest_hi) {2655__ ldmia(addr->base()->as_register(), RegisterSet(dest_lo) | RegisterSet(dest_hi));2656} else {2657assert(dest_lo < Rtemp, "Rtemp is higher than any allocatable register");2658__ ldmia(addr->base()->as_register(), RegisterSet(dest_lo) | RegisterSet(Rtemp));2659__ mov(dest_hi, Rtemp);2660}2661}26622663if (info != NULL) {2664add_debug_info_for_null_check(null_check_offset, info);2665}2666}266726682669void LIR_Assembler::membar() {2670__ membar(MacroAssembler::StoreLoad, Rtemp);2671}26722673void LIR_Assembler::membar_acquire() {2674__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::LoadLoad | MacroAssembler::LoadStore), Rtemp);2675}26762677void LIR_Assembler::membar_release() {2678__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), Rtemp);2679}26802681void LIR_Assembler::membar_loadload() {2682__ membar(MacroAssembler::LoadLoad, Rtemp);2683}26842685void LIR_Assembler::membar_storestore() {2686__ membar(MacroAssembler::StoreStore, Rtemp);2687}26882689void LIR_Assembler::membar_loadstore() {2690__ membar(MacroAssembler::LoadStore, Rtemp);2691}26922693void LIR_Assembler::membar_storeload() {2694__ membar(MacroAssembler::StoreLoad, Rtemp);2695}26962697void LIR_Assembler::on_spin_wait() {2698Unimplemented();2699}27002701void LIR_Assembler::get_thread(LIR_Opr result_reg) {2702// Not used on ARM2703Unimplemented();2704}27052706void LIR_Assembler::peephole(LIR_List* lir) {2707LIR_OpList* inst = lir->instructions_list();2708const int inst_length = inst->length();2709for (int i = 0; i < inst_length; i++) {2710LIR_Op* op = inst->at(i);2711switch (op->code()) {2712case lir_cmp: {2713// Replace:2714// cmp rX, y2715// cmove [EQ] y, z, rX2716// with2717// cmp rX, y2718// cmove [EQ] illegalOpr, z, rX2719//2720// or2721// cmp rX, y2722// cmove [NE] z, y, rX2723// with2724// cmp rX, y2725// cmove [NE] z, illegalOpr, rX2726//2727// moves from illegalOpr should be removed when converting LIR to native assembly27282729LIR_Op2* cmp = op->as_Op2();2730assert(cmp != NULL, "cmp LIR instruction is not an op2");27312732if (i + 1 < inst_length) {2733LIR_Op2* cmove = inst->at(i + 1)->as_Op2();2734if (cmove != NULL && cmove->code() == lir_cmove) {2735LIR_Opr cmove_res = cmove->result_opr();2736bool res_is_op1 = cmove_res == cmp->in_opr1();2737bool res_is_op2 = cmove_res == cmp->in_opr2();2738LIR_Opr cmp_res, cmp_arg;2739if (res_is_op1) {2740cmp_res = cmp->in_opr1();2741cmp_arg = cmp->in_opr2();2742} else if (res_is_op2) {2743cmp_res = cmp->in_opr2();2744cmp_arg = cmp->in_opr1();2745} else {2746cmp_res = LIR_OprFact::illegalOpr;2747cmp_arg = LIR_OprFact::illegalOpr;2748}27492750if (cmp_res != LIR_OprFact::illegalOpr) {2751LIR_Condition cond = cmove->condition();2752if (cond == lir_cond_equal && cmove->in_opr1() == cmp_arg) {2753cmove->set_in_opr1(LIR_OprFact::illegalOpr);2754} else if (cond == lir_cond_notEqual && cmove->in_opr2() == cmp_arg) {2755cmove->set_in_opr2(LIR_OprFact::illegalOpr);2756}2757}2758}2759}2760break;2761}27622763default:2764break;2765}2766}2767}27682769void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp) {2770assert(src->is_address(), "sanity");2771Address addr = as_Address(src->as_address_ptr());27722773if (code == lir_xchg) {2774} else {2775assert (!data->is_oop(), "xadd for oops");2776}27772778__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreStore | MacroAssembler::LoadStore), Rtemp);27792780Label retry;2781__ bind(retry);27822783if (data->type() == T_INT || data->is_oop()) {2784Register dst = dest->as_register();2785Register new_val = noreg;2786__ ldrex(dst, addr);2787if (code == lir_xadd) {2788Register tmp_reg = tmp->as_register();2789if (data->is_constant()) {2790assert_different_registers(dst, tmp_reg);2791__ add_32(tmp_reg, dst, data->as_constant_ptr()->as_jint());2792} else {2793assert_different_registers(dst, tmp_reg, data->as_register());2794__ add_32(tmp_reg, dst, data->as_register());2795}2796new_val = tmp_reg;2797} else {2798if (UseCompressedOops && data->is_oop()) {2799new_val = tmp->as_pointer_register();2800} else {2801new_val = data->as_register();2802}2803assert_different_registers(dst, new_val);2804}2805__ strex(Rtemp, new_val, addr);28062807} else if (data->type() == T_LONG) {2808Register dst_lo = dest->as_register_lo();2809Register new_val_lo = noreg;2810Register dst_hi = dest->as_register_hi();28112812assert(dst_hi->encoding() == dst_lo->encoding() + 1, "non aligned register pair");2813assert((dst_lo->encoding() & 0x1) == 0, "misaligned register pair");28142815__ bind(retry);2816__ ldrexd(dst_lo, addr);2817if (code == lir_xadd) {2818Register tmp_lo = tmp->as_register_lo();2819Register tmp_hi = tmp->as_register_hi();28202821assert(tmp_hi->encoding() == tmp_lo->encoding() + 1, "non aligned register pair");2822assert((tmp_lo->encoding() & 0x1) == 0, "misaligned register pair");28232824if (data->is_constant()) {2825jlong c = data->as_constant_ptr()->as_jlong();2826assert((jlong)((jint)c) == c, "overflow");2827assert_different_registers(dst_lo, dst_hi, tmp_lo, tmp_hi);2828__ adds(tmp_lo, dst_lo, (jint)c);2829__ adc(tmp_hi, dst_hi, 0);2830} else {2831Register new_val_lo = data->as_register_lo();2832Register new_val_hi = data->as_register_hi();2833__ adds(tmp_lo, dst_lo, new_val_lo);2834__ adc(tmp_hi, dst_hi, new_val_hi);2835assert_different_registers(dst_lo, dst_hi, tmp_lo, tmp_hi, new_val_lo, new_val_hi);2836}2837new_val_lo = tmp_lo;2838} else {2839new_val_lo = data->as_register_lo();2840Register new_val_hi = data->as_register_hi();28412842assert_different_registers(dst_lo, dst_hi, new_val_lo, new_val_hi);2843assert(new_val_hi->encoding() == new_val_lo->encoding() + 1, "non aligned register pair");2844assert((new_val_lo->encoding() & 0x1) == 0, "misaligned register pair");2845}2846__ strexd(Rtemp, new_val_lo, addr);2847} else {2848ShouldNotReachHere();2849}28502851__ cbnz_32(Rtemp, retry);2852__ membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad | MacroAssembler::StoreStore), Rtemp);28532854}28552856#undef __285728582859