Path: blob/master/src/hotspot/cpu/arm/c1_LIRGenerator_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_FrameMap.hpp"28#include "c1/c1_Instruction.hpp"29#include "c1/c1_LIRAssembler.hpp"30#include "c1/c1_LIRGenerator.hpp"31#include "c1/c1_Runtime1.hpp"32#include "c1/c1_ValueStack.hpp"33#include "ci/ciArray.hpp"34#include "ci/ciObjArrayKlass.hpp"35#include "ci/ciTypeArrayKlass.hpp"36#include "ci/ciUtilities.hpp"37#include "gc/shared/c1/barrierSetC1.hpp"38#include "gc/shared/cardTable.hpp"39#include "gc/shared/cardTableBarrierSet.hpp"40#include "runtime/sharedRuntime.hpp"41#include "runtime/stubRoutines.hpp"42#include "utilities/powerOfTwo.hpp"43#include "vmreg_arm.inline.hpp"4445#ifdef ASSERT46#define __ gen()->lir(__FILE__, __LINE__)->47#else48#define __ gen()->lir()->49#endif5051void LIRItem::load_byte_item() {52load_item();53}5455void LIRItem::load_nonconstant() {56LIR_Opr r = value()->operand();57if (_gen->can_inline_as_constant(value())) {58if (!r->is_constant()) {59r = LIR_OprFact::value_type(value()->type());60}61_result = r;62} else {63load_item();64}65}6667//--------------------------------------------------------------68// LIRGenerator69//--------------------------------------------------------------707172LIR_Opr LIRGenerator::exceptionOopOpr() {73return FrameMap::Exception_oop_opr;74}7576LIR_Opr LIRGenerator::exceptionPcOpr() {77return FrameMap::Exception_pc_opr;78}7980LIR_Opr LIRGenerator::syncLockOpr() {81return new_register(T_INT);82}8384LIR_Opr LIRGenerator::syncTempOpr() {85return new_register(T_OBJECT);86}8788LIR_Opr LIRGenerator::getThreadTemp() {89return LIR_OprFact::illegalOpr;90}9192LIR_Opr LIRGenerator::atomicLockOpr() {93return LIR_OprFact::illegalOpr;94}9596LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) {97LIR_Opr opr;98switch (type->tag()) {99case intTag: opr = FrameMap::Int_result_opr; break;100case objectTag: opr = FrameMap::Object_result_opr; break;101case longTag: opr = FrameMap::Long_result_opr; break;102case floatTag: opr = FrameMap::Float_result_opr; break;103case doubleTag: opr = FrameMap::Double_result_opr; break;104case addressTag:105default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr;106}107assert(opr->type_field() == as_OprType(as_BasicType(type)), "type mismatch");108return opr;109}110111112LIR_Opr LIRGenerator::rlock_byte(BasicType type) {113return new_register(T_INT);114}115116117//--------- loading items into registers --------------------------------118119120bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const {121return false;122}123124125bool LIRGenerator::can_inline_as_constant(Value v) const {126if (v->type()->as_IntConstant() != NULL) {127return Assembler::is_arith_imm_in_range(v->type()->as_IntConstant()->value());128} else if (v->type()->as_ObjectConstant() != NULL) {129return v->type()->as_ObjectConstant()->value()->is_null_object();130} else if (v->type()->as_FloatConstant() != NULL) {131return v->type()->as_FloatConstant()->value() == 0.0f;132} else if (v->type()->as_DoubleConstant() != NULL) {133return v->type()->as_DoubleConstant()->value() == 0.0;134}135return false;136}137138139bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const {140ShouldNotCallThis(); // Not used on ARM141return false;142}143144145146147LIR_Opr LIRGenerator::safepoint_poll_register() {148return LIR_OprFact::illegalOpr;149}150151152static LIR_Opr make_constant(BasicType type, jlong c) {153switch (type) {154case T_ADDRESS:155case T_OBJECT: return LIR_OprFact::intptrConst(c);156case T_LONG: return LIR_OprFact::longConst(c);157case T_INT: return LIR_OprFact::intConst(c);158default: ShouldNotReachHere();159return LIR_OprFact::intConst(-1);160}161}162163164165void LIRGenerator::add_large_constant(LIR_Opr src, int c, LIR_Opr dest) {166assert(c != 0, "must be");167// Find first non-zero bit168int shift = 0;169while ((c & (3 << shift)) == 0) {170shift += 2;171}172// Add the least significant part of the constant173int mask = 0xff << shift;174__ add(src, LIR_OprFact::intConst(c & mask), dest);175// Add up to 3 other parts of the constant;176// each of them can be represented as rotated_imm177if (c & (mask << 8)) {178__ add(dest, LIR_OprFact::intConst(c & (mask << 8)), dest);179}180if (c & (mask << 16)) {181__ add(dest, LIR_OprFact::intConst(c & (mask << 16)), dest);182}183if (c & (mask << 24)) {184__ add(dest, LIR_OprFact::intConst(c & (mask << 24)), dest);185}186}187188static LIR_Address* make_address(LIR_Opr base, LIR_Opr index, LIR_Address::Scale scale, BasicType type) {189return new LIR_Address(base, index, scale, 0, type);190}191192LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,193int shift, int disp, BasicType type) {194assert(base->is_register(), "must be");195196if (index->is_constant()) {197disp += index->as_constant_ptr()->as_jint() << shift;198index = LIR_OprFact::illegalOpr;199}200201if (base->type() == T_LONG) {202LIR_Opr tmp = new_register(T_INT);203__ convert(Bytecodes::_l2i, base, tmp);204base = tmp;205}206if (index != LIR_OprFact::illegalOpr && index->type() == T_LONG) {207LIR_Opr tmp = new_register(T_INT);208__ convert(Bytecodes::_l2i, index, tmp);209index = tmp;210}211// At this point base and index should be all ints and not constants212assert(base->is_single_cpu() && !base->is_constant(), "base should be an non-constant int");213assert(index->is_illegal() || (index->type() == T_INT && !index->is_constant()), "index should be an non-constant int");214215int max_disp;216bool disp_is_in_range;217bool embedded_shift;218219switch (type) {220case T_BYTE:221case T_SHORT:222case T_CHAR:223max_disp = 256; // ldrh, ldrsb encoding has 8-bit offset224embedded_shift = false;225break;226case T_FLOAT:227case T_DOUBLE:228max_disp = 1024; // flds, fldd have 8-bit offset multiplied by 4229embedded_shift = false;230break;231case T_LONG:232max_disp = 4096;233embedded_shift = false;234break;235default:236max_disp = 4096; // ldr, ldrb allow 12-bit offset237embedded_shift = true;238}239240disp_is_in_range = (-max_disp < disp && disp < max_disp);241242if (index->is_register()) {243LIR_Opr tmp = new_pointer_register();244if (!disp_is_in_range) {245add_large_constant(base, disp, tmp);246base = tmp;247disp = 0;248}249LIR_Address* addr = make_address(base, index, (LIR_Address::Scale)shift, type);250if (disp == 0 && embedded_shift) {251// can use ldr/str instruction with register index252return addr;253} else {254LIR_Opr tmp = new_pointer_register();255__ add(base, LIR_OprFact::address(addr), tmp); // add with shifted/extended register256return new LIR_Address(tmp, disp, type);257}258}259260// If the displacement is too large to be inlined into LDR instruction,261// generate large constant with additional sequence of ADD instructions262int excess_disp = disp & ~(max_disp - 1);263if (excess_disp != 0) {264LIR_Opr tmp = new_pointer_register();265add_large_constant(base, excess_disp, tmp);266base = tmp;267}268return new LIR_Address(base, disp & (max_disp - 1), type);269}270271272LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, BasicType type) {273int base_offset = arrayOopDesc::base_offset_in_bytes(type);274int elem_size = type2aelembytes(type);275276if (index_opr->is_constant()) {277int offset = base_offset + index_opr->as_constant_ptr()->as_jint() * elem_size;278return generate_address(array_opr, offset, type);279} else {280assert(index_opr->is_register(), "must be");281int scale = exact_log2(elem_size);282return generate_address(array_opr, index_opr, scale, base_offset, type);283}284}285286287LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) {288assert(type == T_LONG || type == T_INT, "should be");289LIR_Opr r = make_constant(type, x);290bool imm_in_range = AsmOperand::is_rotated_imm(x);291if (!imm_in_range) {292LIR_Opr tmp = new_register(type);293__ move(r, tmp);294return tmp;295}296return r;297}298299300void LIRGenerator::increment_counter(address counter, BasicType type, int step) {301LIR_Opr pointer = new_pointer_register();302__ move(LIR_OprFact::intptrConst(counter), pointer);303LIR_Address* addr = new LIR_Address(pointer, type);304increment_counter(addr, step);305}306307308void LIRGenerator::increment_counter(LIR_Address* addr, int step) {309LIR_Opr temp = new_register(addr->type());310__ move(addr, temp);311__ add(temp, make_constant(addr->type(), step), temp);312__ move(temp, addr);313}314315316void LIRGenerator::cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info) {317__ load(new LIR_Address(base, disp, T_INT), FrameMap::LR_opr, info);318__ cmp(condition, FrameMap::LR_opr, c);319}320321322void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, int disp, BasicType type, CodeEmitInfo* info) {323__ load(new LIR_Address(base, disp, type), FrameMap::LR_opr, info);324__ cmp(condition, reg, FrameMap::LR_opr);325}326327328bool LIRGenerator::strength_reduce_multiply(LIR_Opr left, jint c, LIR_Opr result, LIR_Opr tmp) {329assert(left != result, "should be different registers");330if (is_power_of_2(c + 1)) {331LIR_Address::Scale scale = (LIR_Address::Scale) log2i_exact(c + 1);332LIR_Address* addr = new LIR_Address(left, left, scale, 0, T_INT);333__ sub(LIR_OprFact::address(addr), left, result); // rsb with shifted register334return true;335} else if (is_power_of_2(c - 1)) {336LIR_Address::Scale scale = (LIR_Address::Scale) log2i_exact(c - 1);337LIR_Address* addr = new LIR_Address(left, left, scale, 0, T_INT);338__ add(left, LIR_OprFact::address(addr), result); // add with shifted register339return true;340}341return false;342}343344345void LIRGenerator::store_stack_parameter(LIR_Opr item, ByteSize offset_from_sp) {346assert(item->type() == T_INT, "other types are not expected");347__ store(item, new LIR_Address(FrameMap::SP_opr, in_bytes(offset_from_sp), item->type()));348}349350void LIRGenerator::set_card(LIR_Opr value, LIR_Address* card_addr) {351assert(CardTable::dirty_card_val() == 0,352"Cannot use the register containing the card table base address directly");353if((ci_card_table_address_as<intx>() & 0xff) == 0) {354// If the card table base address is aligned to 256 bytes, we can use the register355// that contains the card_table_base_address.356__ move(value, card_addr);357} else {358// Otherwise we need to create a register containing that value.359LIR_Opr tmp_zero = new_register(T_INT);360__ move(LIR_OprFact::intConst(CardTable::dirty_card_val()), tmp_zero);361__ move(tmp_zero, card_addr);362}363}364365void LIRGenerator::CardTableBarrierSet_post_barrier_helper(LIR_OprDesc* addr, LIR_Const* card_table_base) {366assert(addr->is_register(), "must be a register at this point");367368LIR_Opr tmp = FrameMap::LR_ptr_opr;369370bool load_card_table_base_const = VM_Version::supports_movw();371if (load_card_table_base_const) {372__ move((LIR_Opr)card_table_base, tmp);373} else {374__ move(new LIR_Address(FrameMap::Rthread_opr, in_bytes(JavaThread::card_table_base_offset()), T_ADDRESS), tmp);375}376377// Use unsigned type T_BOOLEAN here rather than (signed) T_BYTE since signed load378// byte instruction does not support the addressing mode we need.379LIR_Address* card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTable::card_shift, 0, T_BOOLEAN);380if (UseCondCardMark) {381LIR_Opr cur_value = new_register(T_INT);382__ move(card_addr, cur_value);383384LabelObj* L_already_dirty = new LabelObj();385__ cmp(lir_cond_equal, cur_value, LIR_OprFact::intConst(CardTable::dirty_card_val()));386__ branch(lir_cond_equal, L_already_dirty->label());387set_card(tmp, card_addr);388__ branch_destination(L_already_dirty->label());389} else {390set_card(tmp, card_addr);391}392}393394void LIRGenerator::array_store_check(LIR_Opr value, LIR_Opr array, CodeEmitInfo* store_check_info, ciMethod* profiled_method, int profiled_bci) {395LIR_Opr tmp1 = FrameMap::R0_oop_opr;396LIR_Opr tmp2 = FrameMap::R1_oop_opr;397LIR_Opr tmp3 = LIR_OprFact::illegalOpr;398__ store_check(value, array, tmp1, tmp2, tmp3, store_check_info, profiled_method, profiled_bci);399}400401//----------------------------------------------------------------------402// visitor functions403//----------------------------------------------------------------------404405void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {406assert(x->is_pinned(),"");407LIRItem obj(x->obj(), this);408obj.load_item();409set_no_result(x);410411LIR_Opr lock = new_pointer_register();412LIR_Opr hdr = new_pointer_register();413414// Need a scratch register for biased locking on arm415LIR_Opr scratch = LIR_OprFact::illegalOpr;416if(UseBiasedLocking) {417scratch = new_pointer_register();418} else {419scratch = atomicLockOpr();420}421422CodeEmitInfo* info_for_exception = NULL;423if (x->needs_null_check()) {424info_for_exception = state_for(x);425}426427CodeEmitInfo* info = state_for(x, x->state(), true);428monitor_enter(obj.result(), lock, hdr, scratch,429x->monitor_no(), info_for_exception, info);430}431432433void LIRGenerator::do_MonitorExit(MonitorExit* x) {434assert(x->is_pinned(),"");435LIRItem obj(x->obj(), this);436obj.dont_load_item();437set_no_result(x);438439LIR_Opr obj_temp = new_pointer_register();440LIR_Opr lock = new_pointer_register();441LIR_Opr hdr = new_pointer_register();442443monitor_exit(obj_temp, lock, hdr, atomicLockOpr(), x->monitor_no());444}445446447// _ineg, _lneg, _fneg, _dneg448void LIRGenerator::do_NegateOp(NegateOp* x) {449#ifdef __SOFTFP__450address runtime_func = NULL;451ValueTag tag = x->type()->tag();452if (tag == floatTag) {453runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::fneg);454} else if (tag == doubleTag) {455runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::dneg);456}457if (runtime_func != NULL) {458set_result(x, call_runtime(x->x(), runtime_func, x->type(), NULL));459return;460}461#endif // __SOFTFP__462LIRItem value(x->x(), this);463value.load_item();464LIR_Opr reg = rlock_result(x);465__ negate(value.result(), reg);466}467468469// for _fadd, _fmul, _fsub, _fdiv, _frem470// _dadd, _dmul, _dsub, _ddiv, _drem471void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) {472address runtime_func;473switch (x->op()) {474case Bytecodes::_frem:475runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::frem);476break;477case Bytecodes::_drem:478runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::drem);479break;480#ifdef __SOFTFP__481// Call function compiled with -msoft-float.482483// __aeabi_XXXX_glibc: Imported code from glibc soft-fp bundle for calculation accuracy improvement. See CR 6757269.484485case Bytecodes::_fadd:486runtime_func = CAST_FROM_FN_PTR(address, __aeabi_fadd_glibc);487break;488case Bytecodes::_fmul:489runtime_func = CAST_FROM_FN_PTR(address, __aeabi_fmul);490break;491case Bytecodes::_fsub:492runtime_func = CAST_FROM_FN_PTR(address, __aeabi_fsub_glibc);493break;494case Bytecodes::_fdiv:495runtime_func = CAST_FROM_FN_PTR(address, __aeabi_fdiv);496break;497case Bytecodes::_dadd:498runtime_func = CAST_FROM_FN_PTR(address, __aeabi_dadd_glibc);499break;500case Bytecodes::_dmul:501runtime_func = CAST_FROM_FN_PTR(address, __aeabi_dmul);502break;503case Bytecodes::_dsub:504runtime_func = CAST_FROM_FN_PTR(address, __aeabi_dsub_glibc);505break;506case Bytecodes::_ddiv:507runtime_func = CAST_FROM_FN_PTR(address, __aeabi_ddiv);508break;509default:510ShouldNotReachHere();511#else // __SOFTFP__512default: {513LIRItem left(x->x(), this);514LIRItem right(x->y(), this);515left.load_item();516right.load_item();517rlock_result(x);518arithmetic_op_fpu(x->op(), x->operand(), left.result(), right.result());519return;520}521#endif // __SOFTFP__522}523524LIR_Opr result = call_runtime(x->x(), x->y(), runtime_func, x->type(), NULL);525set_result(x, result);526}527528529void LIRGenerator::make_div_by_zero_check(LIR_Opr right_arg, BasicType type, CodeEmitInfo* info) {530assert(right_arg->is_register(), "must be");531__ cmp(lir_cond_equal, right_arg, make_constant(type, 0));532__ branch(lir_cond_equal, new DivByZeroStub(info));533}534535536// for _ladd, _lmul, _lsub, _ldiv, _lrem537void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) {538CodeEmitInfo* info = NULL;539if (x->op() == Bytecodes::_ldiv || x->op() == Bytecodes::_lrem) {540info = state_for(x);541}542543switch (x->op()) {544case Bytecodes::_ldiv:545case Bytecodes::_lrem: {546LIRItem right(x->y(), this);547right.load_item();548make_div_by_zero_check(right.result(), T_LONG, info);549}550// Fall through551case Bytecodes::_lmul: {552address entry;553switch (x->op()) {554case Bytecodes::_lrem:555entry = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);556break;557case Bytecodes::_ldiv:558entry = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);559break;560case Bytecodes::_lmul:561entry = CAST_FROM_FN_PTR(address, SharedRuntime::lmul);562break;563default:564ShouldNotReachHere();565return;566}567LIR_Opr result = call_runtime(x->y(), x->x(), entry, x->type(), NULL);568set_result(x, result);569break;570}571case Bytecodes::_ladd:572case Bytecodes::_lsub: {573LIRItem left(x->x(), this);574LIRItem right(x->y(), this);575left.load_item();576right.load_item();577rlock_result(x);578arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), NULL);579break;580}581default:582ShouldNotReachHere();583}584}585586587// for: _iadd, _imul, _isub, _idiv, _irem588void LIRGenerator::do_ArithmeticOp_Int(ArithmeticOp* x) {589bool is_div_rem = x->op() == Bytecodes::_idiv || x->op() == Bytecodes::_irem;590LIRItem left(x->x(), this);591LIRItem right(x->y(), this);592LIRItem* left_arg = &left;593LIRItem* right_arg = &right;594595// Test if instr is commutative and if we should swap596if (x->is_commutative() && left.is_constant()) {597left_arg = &right;598right_arg = &left;599}600601if (is_div_rem) {602CodeEmitInfo* info = state_for(x);603if (x->op() == Bytecodes::_idiv && right_arg->is_constant() && is_power_of_2(right_arg->get_jint_constant())) {604left_arg->load_item();605right_arg->dont_load_item();606LIR_Opr tmp = LIR_OprFact::illegalOpr;607LIR_Opr result = rlock_result(x);608__ idiv(left_arg->result(), right_arg->result(), result, tmp, info);609} else {610left_arg->load_item_force(FrameMap::R0_opr);611right_arg->load_item_force(FrameMap::R2_opr);612LIR_Opr tmp = FrameMap::R1_opr;613LIR_Opr result = rlock_result(x);614LIR_Opr out_reg;615if (x->op() == Bytecodes::_irem) {616out_reg = FrameMap::R0_opr;617__ irem(left_arg->result(), right_arg->result(), out_reg, tmp, info);618} else { // (x->op() == Bytecodes::_idiv)619out_reg = FrameMap::R1_opr;620__ idiv(left_arg->result(), right_arg->result(), out_reg, tmp, info);621}622__ move(out_reg, result);623}624625626} else {627left_arg->load_item();628if (x->op() == Bytecodes::_imul && right_arg->is_constant()) {629jint c = right_arg->get_jint_constant();630if (c > 0 && c < max_jint && (is_power_of_2(c) || is_power_of_2(c - 1) || is_power_of_2(c + 1))) {631right_arg->dont_load_item();632} else {633right_arg->load_item();634}635} else {636right_arg->load_nonconstant();637}638rlock_result(x);639assert(right_arg->is_constant() || right_arg->is_register(), "wrong state of right");640arithmetic_op_int(x->op(), x->operand(), left_arg->result(), right_arg->result(), NULL);641}642}643644645void LIRGenerator::do_ArithmeticOp(ArithmeticOp* x) {646ValueTag tag = x->type()->tag();647assert(x->x()->type()->tag() == tag && x->y()->type()->tag() == tag, "wrong parameters");648switch (tag) {649case floatTag:650case doubleTag: do_ArithmeticOp_FPU(x); return;651case longTag: do_ArithmeticOp_Long(x); return;652case intTag: do_ArithmeticOp_Int(x); return;653default: ShouldNotReachHere(); return;654}655}656657658// _ishl, _lshl, _ishr, _lshr, _iushr, _lushr659void LIRGenerator::do_ShiftOp(ShiftOp* x) {660LIRItem value(x->x(), this);661LIRItem count(x->y(), this);662663if (value.type()->is_long()) {664count.set_destroys_register();665}666667if (count.is_constant()) {668assert(count.type()->as_IntConstant() != NULL, "should be");669count.dont_load_item();670} else {671count.load_item();672}673value.load_item();674675LIR_Opr res = rlock_result(x);676shift_op(x->op(), res, value.result(), count.result(), LIR_OprFact::illegalOpr);677}678679680// _iand, _land, _ior, _lor, _ixor, _lxor681void LIRGenerator::do_LogicOp(LogicOp* x) {682LIRItem left(x->x(), this);683LIRItem right(x->y(), this);684685left.load_item();686687right.load_nonconstant();688689logic_op(x->op(), rlock_result(x), left.result(), right.result());690}691692693// _lcmp, _fcmpl, _fcmpg, _dcmpl, _dcmpg694void LIRGenerator::do_CompareOp(CompareOp* x) {695#ifdef __SOFTFP__696address runtime_func;697switch (x->op()) {698case Bytecodes::_fcmpl:699runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::fcmpl);700break;701case Bytecodes::_fcmpg:702runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::fcmpg);703break;704case Bytecodes::_dcmpl:705runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::dcmpl);706break;707case Bytecodes::_dcmpg:708runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::dcmpg);709break;710case Bytecodes::_lcmp: {711LIRItem left(x->x(), this);712LIRItem right(x->y(), this);713left.load_item();714right.load_nonconstant();715LIR_Opr reg = rlock_result(x);716__ lcmp2int(left.result(), right.result(), reg);717return;718}719default:720ShouldNotReachHere();721}722LIR_Opr result = call_runtime(x->x(), x->y(), runtime_func, x->type(), NULL);723set_result(x, result);724#else // __SOFTFP__725LIRItem left(x->x(), this);726LIRItem right(x->y(), this);727left.load_item();728729right.load_nonconstant();730731LIR_Opr reg = rlock_result(x);732733if (x->x()->type()->is_float_kind()) {734Bytecodes::Code code = x->op();735__ fcmp2int(left.result(), right.result(), reg, (code == Bytecodes::_fcmpl || code == Bytecodes::_dcmpl));736} else if (x->x()->type()->tag() == longTag) {737__ lcmp2int(left.result(), right.result(), reg);738} else {739ShouldNotReachHere();740}741#endif // __SOFTFP__742}743744LIR_Opr LIRGenerator::atomic_cmpxchg(BasicType type, LIR_Opr addr, LIRItem& cmp_value, LIRItem& new_value) {745LIR_Opr ill = LIR_OprFact::illegalOpr; // for convenience746LIR_Opr tmp1 = LIR_OprFact::illegalOpr;747LIR_Opr tmp2 = LIR_OprFact::illegalOpr;748new_value.load_item();749cmp_value.load_item();750LIR_Opr result = new_register(T_INT);751if (type == T_OBJECT || type == T_ARRAY) {752__ cas_obj(addr, cmp_value.result(), new_value.result(), new_register(T_INT), new_register(T_INT), result);753} else if (type == T_INT) {754__ cas_int(addr->as_address_ptr()->base(), cmp_value.result(), new_value.result(), tmp1, tmp1, result);755} else if (type == T_LONG) {756tmp1 = new_register(T_LONG);757__ cas_long(addr->as_address_ptr()->base(), cmp_value.result(), new_value.result(), tmp1, tmp2, result);758} else {759ShouldNotReachHere();760}761return result;762}763764LIR_Opr LIRGenerator::atomic_xchg(BasicType type, LIR_Opr addr, LIRItem& value) {765bool is_oop = type == T_OBJECT || type == T_ARRAY;766LIR_Opr result = new_register(type);767value.load_item();768assert(type == T_INT || is_oop || (type == T_LONG && VM_Version::supports_ldrexd()), "unexpected type");769LIR_Opr tmp = (UseCompressedOops && is_oop) ? new_pointer_register() : LIR_OprFact::illegalOpr;770__ xchg(addr, value.result(), result, tmp);771return result;772}773774LIR_Opr LIRGenerator::atomic_add(BasicType type, LIR_Opr addr, LIRItem& value) {775LIR_Opr result = new_register(type);776value.load_item();777assert(type == T_INT || (type == T_LONG && VM_Version::supports_ldrexd ()), "unexpected type");778LIR_Opr tmp = new_register(type);779__ xadd(addr, value.result(), result, tmp);780return result;781}782783void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {784address runtime_func;785switch (x->id()) {786case vmIntrinsics::_dabs: {787#ifdef __SOFTFP__788runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::dabs);789break;790#else791assert(x->number_of_arguments() == 1, "wrong type");792LIRItem value(x->argument_at(0), this);793value.load_item();794__ abs(value.result(), rlock_result(x), LIR_OprFact::illegalOpr);795return;796#endif // __SOFTFP__797}798case vmIntrinsics::_dsqrt: {799#ifdef __SOFTFP__800runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::dsqrt);801break;802#else803assert(x->number_of_arguments() == 1, "wrong type");804LIRItem value(x->argument_at(0), this);805value.load_item();806__ sqrt(value.result(), rlock_result(x), LIR_OprFact::illegalOpr);807return;808#endif // __SOFTFP__809}810case vmIntrinsics::_dsin:811runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);812break;813case vmIntrinsics::_dcos:814runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);815break;816case vmIntrinsics::_dtan:817runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);818break;819case vmIntrinsics::_dlog:820runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::dlog);821break;822case vmIntrinsics::_dlog10:823runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10);824break;825case vmIntrinsics::_dexp:826runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::dexp);827break;828case vmIntrinsics::_dpow:829runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::dpow);830break;831default:832ShouldNotReachHere();833return;834}835836LIR_Opr result;837if (x->number_of_arguments() == 1) {838result = call_runtime(x->argument_at(0), runtime_func, x->type(), NULL);839} else {840assert(x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow, "unexpected intrinsic");841result = call_runtime(x->argument_at(0), x->argument_at(1), runtime_func, x->type(), NULL);842}843set_result(x, result);844}845846void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {847fatal("FMA intrinsic is not implemented on this platform");848}849850void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {851fatal("vectorizedMismatch intrinsic is not implemented on this platform");852}853854void LIRGenerator::do_ArrayCopy(Intrinsic* x) {855CodeEmitInfo* info = state_for(x, x->state());856assert(x->number_of_arguments() == 5, "wrong type");857LIRItem src(x->argument_at(0), this);858LIRItem src_pos(x->argument_at(1), this);859LIRItem dst(x->argument_at(2), this);860LIRItem dst_pos(x->argument_at(3), this);861LIRItem length(x->argument_at(4), this);862863// We put arguments into the same registers which are used for a Java call.864// Note: we used fixed registers for all arguments because all registers865// are caller-saved, so register allocator treats them all as used.866src.load_item_force (FrameMap::R0_oop_opr);867src_pos.load_item_force(FrameMap::R1_opr);868dst.load_item_force (FrameMap::R2_oop_opr);869dst_pos.load_item_force(FrameMap::R3_opr);870length.load_item_force (FrameMap::R4_opr);871LIR_Opr tmp = (FrameMap::R5_opr);872set_no_result(x);873874int flags;875ciArrayKlass* expected_type;876arraycopy_helper(x, &flags, &expected_type);877__ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(),878tmp, expected_type, flags, info);879}880881void LIRGenerator::do_update_CRC32(Intrinsic* x) {882fatal("CRC32 intrinsic is not implemented on this platform");883}884885void LIRGenerator::do_update_CRC32C(Intrinsic* x) {886Unimplemented();887}888889void LIRGenerator::do_Convert(Convert* x) {890address runtime_func;891switch (x->op()) {892case Bytecodes::_l2f:893runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::l2f);894break;895case Bytecodes::_l2d:896runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::l2d);897break;898case Bytecodes::_f2l:899runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);900break;901case Bytecodes::_d2l:902runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);903break;904#ifdef __SOFTFP__905case Bytecodes::_f2d:906runtime_func = CAST_FROM_FN_PTR(address, __aeabi_f2d);907break;908case Bytecodes::_d2f:909runtime_func = CAST_FROM_FN_PTR(address, __aeabi_d2f);910break;911case Bytecodes::_i2f:912runtime_func = CAST_FROM_FN_PTR(address, __aeabi_i2f);913break;914case Bytecodes::_i2d:915runtime_func = CAST_FROM_FN_PTR(address, __aeabi_i2d);916break;917case Bytecodes::_f2i:918runtime_func = CAST_FROM_FN_PTR(address, __aeabi_f2iz);919break;920case Bytecodes::_d2i:921// This is implemented in hard float in assembler on arm but a call922// on other platforms.923runtime_func = CAST_FROM_FN_PTR(address, SharedRuntime::d2i);924break;925#endif // __SOFTFP__926default: {927LIRItem value(x->value(), this);928value.load_item();929LIR_Opr reg = rlock_result(x);930__ convert(x->op(), value.result(), reg, NULL);931return;932}933}934935LIR_Opr result = call_runtime(x->value(), runtime_func, x->type(), NULL);936set_result(x, result);937}938939940void LIRGenerator::do_NewInstance(NewInstance* x) {941print_if_not_loaded(x);942943CodeEmitInfo* info = state_for(x, x->state());944LIR_Opr reg = result_register_for(x->type()); // R0 is required by runtime call in NewInstanceStub::emit_code945LIR_Opr klass_reg = FrameMap::R1_metadata_opr; // R1 is required by runtime call in NewInstanceStub::emit_code946LIR_Opr tmp1 = new_register(objectType);947LIR_Opr tmp2 = new_register(objectType);948LIR_Opr tmp3 = FrameMap::LR_oop_opr;949950new_instance(reg, x->klass(), x->is_unresolved(), tmp1, tmp2, tmp3,951LIR_OprFact::illegalOpr, klass_reg, info);952953LIR_Opr result = rlock_result(x);954__ move(reg, result);955}956957958void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {959// Evaluate state_for() first, because it can emit code960// with the same fixed registers that are used here (R1, R2)961CodeEmitInfo* info = state_for(x, x->state());962LIRItem length(x->length(), this);963964length.load_item_force(FrameMap::R2_opr); // R2 is required by runtime call in NewTypeArrayStub::emit_code965LIR_Opr len = length.result();966967LIR_Opr reg = result_register_for(x->type()); // R0 is required by runtime call in NewTypeArrayStub::emit_code968LIR_Opr klass_reg = FrameMap::R1_metadata_opr; // R1 is required by runtime call in NewTypeArrayStub::emit_code969970LIR_Opr tmp1 = new_register(objectType);971LIR_Opr tmp2 = new_register(objectType);972LIR_Opr tmp3 = FrameMap::LR_oop_opr;973LIR_Opr tmp4 = LIR_OprFact::illegalOpr;974975BasicType elem_type = x->elt_type();976__ metadata2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg);977978CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);979__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);980981LIR_Opr result = rlock_result(x);982__ move(reg, result);983}984985986void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {987// Evaluate state_for() first, because it can emit code988// with the same fixed registers that are used here (R1, R2)989CodeEmitInfo* info = state_for(x, x->state());990LIRItem length(x->length(), this);991992length.load_item_force(FrameMap::R2_opr); // R2 is required by runtime call in NewObjectArrayStub::emit_code993LIR_Opr len = length.result();994995CodeEmitInfo* patching_info = NULL;996if (!x->klass()->is_loaded() || PatchALot) {997patching_info = state_for(x, x->state_before());998}9991000LIR_Opr reg = result_register_for(x->type()); // R0 is required by runtime call in NewObjectArrayStub::emit_code1001LIR_Opr klass_reg = FrameMap::R1_metadata_opr; // R1 is required by runtime call in NewObjectArrayStub::emit_code10021003LIR_Opr tmp1 = new_register(objectType);1004LIR_Opr tmp2 = new_register(objectType);1005LIR_Opr tmp3 = FrameMap::LR_oop_opr;1006LIR_Opr tmp4 = LIR_OprFact::illegalOpr;10071008CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info);1009ciMetadata* obj = ciObjArrayKlass::make(x->klass());1010if (obj == ciEnv::unloaded_ciobjarrayklass()) {1011BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error");1012}1013klass2reg_with_patching(klass_reg, obj, patching_info);1014__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path);10151016LIR_Opr result = rlock_result(x);1017__ move(reg, result);1018}101910201021void LIRGenerator::do_NewMultiArray(NewMultiArray* x) {1022Values* dims = x->dims();1023int i = dims->length();1024LIRItemList* items = new LIRItemList(i, i, NULL);1025while (i-- > 0) {1026LIRItem* size = new LIRItem(dims->at(i), this);1027items->at_put(i, size);1028}10291030// Need to get the info before, as the items may become invalid through item_free1031CodeEmitInfo* patching_info = NULL;1032if (!x->klass()->is_loaded() || PatchALot) {1033patching_info = state_for(x, x->state_before());10341035// Cannot re-use same xhandlers for multiple CodeEmitInfos, so1036// clone all handlers (NOTE: Usually this is handled transparently1037// by the CodeEmitInfo cloning logic in CodeStub constructors but1038// is done explicitly here because a stub isn't being used).1039x->set_exception_handlers(new XHandlers(x->exception_handlers()));1040}10411042i = dims->length();1043while (i-- > 0) {1044LIRItem* size = items->at(i);1045size->load_item();1046LIR_Opr sz = size->result();1047assert(sz->type() == T_INT, "should be");1048store_stack_parameter(sz, in_ByteSize(i * BytesPerInt));1049}10501051CodeEmitInfo* info = state_for(x, x->state());1052LIR_Opr klass_reg = FrameMap::R0_metadata_opr;1053klass2reg_with_patching(klass_reg, x->klass(), patching_info);10541055LIR_Opr rank = FrameMap::R2_opr;1056__ move(LIR_OprFact::intConst(x->rank()), rank);1057LIR_Opr varargs = FrameMap::SP_opr;1058LIR_OprList* args = new LIR_OprList(3);1059args->append(klass_reg);1060args->append(rank);1061args->append(varargs);1062LIR_Opr reg = result_register_for(x->type());1063__ call_runtime(Runtime1::entry_for(Runtime1::new_multi_array_id),1064LIR_OprFact::illegalOpr, reg, args, info);10651066LIR_Opr result = rlock_result(x);1067__ move(reg, result);1068}106910701071void LIRGenerator::do_BlockBegin(BlockBegin* x) {1072// nothing to do for now1073}107410751076void LIRGenerator::do_CheckCast(CheckCast* x) {1077LIRItem obj(x->obj(), this);1078CodeEmitInfo* patching_info = NULL;1079if (!x->klass()->is_loaded() || (PatchALot && !x->is_incompatible_class_change_check() && !x->is_invokespecial_receiver_check())) {1080patching_info = state_for(x, x->state_before());1081}10821083obj.load_item();10841085CodeEmitInfo* info_for_exception =1086(x->needs_exception_state() ? state_for(x) :1087state_for(x, x->state_before(), true /*ignore_xhandler*/));10881089CodeStub* stub;1090if (x->is_incompatible_class_change_check()) {1091assert(patching_info == NULL, "can't patch this");1092stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id,1093LIR_OprFact::illegalOpr, info_for_exception);1094} else if (x->is_invokespecial_receiver_check()) {1095assert(patching_info == NULL, "can't patch this");1096stub = new DeoptimizeStub(info_for_exception,1097Deoptimization::Reason_class_check,1098Deoptimization::Action_none);1099} else {1100stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id,1101LIR_OprFact::illegalOpr, info_for_exception);1102}11031104LIR_Opr out_reg = rlock_result(x);1105LIR_Opr tmp1 = FrameMap::R0_oop_opr;1106LIR_Opr tmp2 = FrameMap::R1_oop_opr;1107LIR_Opr tmp3 = LIR_OprFact::illegalOpr;11081109__ checkcast(out_reg, obj.result(), x->klass(), tmp1, tmp2, tmp3, x->direct_compare(),1110info_for_exception, patching_info, stub, x->profiled_method(), x->profiled_bci());1111}111211131114void LIRGenerator::do_InstanceOf(InstanceOf* x) {1115LIRItem obj(x->obj(), this);1116CodeEmitInfo* patching_info = NULL;1117if (!x->klass()->is_loaded() || PatchALot) {1118patching_info = state_for(x, x->state_before());1119}11201121obj.load_item();1122LIR_Opr out_reg = rlock_result(x);1123LIR_Opr tmp1 = FrameMap::R0_oop_opr;1124LIR_Opr tmp2 = FrameMap::R1_oop_opr;1125LIR_Opr tmp3 = LIR_OprFact::illegalOpr;11261127__ instanceof(out_reg, obj.result(), x->klass(), tmp1, tmp2, tmp3,1128x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci());1129}113011311132#ifdef __SOFTFP__1133// Turn operator if (f <op> g) into runtime call:1134// call _aeabi_fcmp<op>(f, g)1135// cmp(eq, 1)1136// branch(eq, true path).1137void LIRGenerator::do_soft_float_compare(If* x) {1138assert(x->number_of_sux() == 2, "inconsistency");1139ValueTag tag = x->x()->type()->tag();1140If::Condition cond = x->cond();1141address runtime_func;1142// unordered comparison gets the wrong answer because aeabi functions1143// return false.1144bool unordered_is_true = x->unordered_is_true();1145// reverse of condition for ne1146bool compare_to_zero = false;1147switch (lir_cond(cond)) {1148case lir_cond_notEqual:1149compare_to_zero = true; // fall through1150case lir_cond_equal:1151runtime_func = tag == floatTag ?1152CAST_FROM_FN_PTR(address, __aeabi_fcmpeq):1153CAST_FROM_FN_PTR(address, __aeabi_dcmpeq);1154break;1155case lir_cond_less:1156if (unordered_is_true) {1157runtime_func = tag == floatTag ?1158CAST_FROM_FN_PTR(address, SharedRuntime::unordered_fcmplt):1159CAST_FROM_FN_PTR(address, SharedRuntime::unordered_dcmplt);1160} else {1161runtime_func = tag == floatTag ?1162CAST_FROM_FN_PTR(address, __aeabi_fcmplt):1163CAST_FROM_FN_PTR(address, __aeabi_dcmplt);1164}1165break;1166case lir_cond_lessEqual:1167if (unordered_is_true) {1168runtime_func = tag == floatTag ?1169CAST_FROM_FN_PTR(address, SharedRuntime::unordered_fcmple):1170CAST_FROM_FN_PTR(address, SharedRuntime::unordered_dcmple);1171} else {1172runtime_func = tag == floatTag ?1173CAST_FROM_FN_PTR(address, __aeabi_fcmple):1174CAST_FROM_FN_PTR(address, __aeabi_dcmple);1175}1176break;1177case lir_cond_greaterEqual:1178if (unordered_is_true) {1179runtime_func = tag == floatTag ?1180CAST_FROM_FN_PTR(address, SharedRuntime::unordered_fcmpge):1181CAST_FROM_FN_PTR(address, SharedRuntime::unordered_dcmpge);1182} else {1183runtime_func = tag == floatTag ?1184CAST_FROM_FN_PTR(address, __aeabi_fcmpge):1185CAST_FROM_FN_PTR(address, __aeabi_dcmpge);1186}1187break;1188case lir_cond_greater:1189if (unordered_is_true) {1190runtime_func = tag == floatTag ?1191CAST_FROM_FN_PTR(address, SharedRuntime::unordered_fcmpgt):1192CAST_FROM_FN_PTR(address, SharedRuntime::unordered_dcmpgt);1193} else {1194runtime_func = tag == floatTag ?1195CAST_FROM_FN_PTR(address, __aeabi_fcmpgt):1196CAST_FROM_FN_PTR(address, __aeabi_dcmpgt);1197}1198break;1199case lir_cond_aboveEqual:1200case lir_cond_belowEqual:1201ShouldNotReachHere(); // We're not going to get these.1202default:1203assert(lir_cond(cond) == lir_cond_always, "must be");1204ShouldNotReachHere();1205}1206set_no_result(x);12071208// add safepoint before generating condition code so it can be recomputed1209if (x->is_safepoint()) {1210increment_backedge_counter(state_for(x, x->state_before()), x->profiled_bci());1211__ safepoint(LIR_OprFact::illegalOpr, state_for(x, x->state_before()));1212}1213// Call float compare function, returns (1,0) if true or false.1214LIR_Opr result = call_runtime(x->x(), x->y(), runtime_func, intType, NULL);1215__ cmp(lir_cond_equal, result,1216compare_to_zero ?1217LIR_OprFact::intConst(0) : LIR_OprFact::intConst(1));1218profile_branch(x, cond);1219move_to_phi(x->state());1220__ branch(lir_cond_equal, x->tsux());1221}1222#endif // __SOFTFP__12231224void LIRGenerator::do_If(If* x) {1225assert(x->number_of_sux() == 2, "inconsistency");1226ValueTag tag = x->x()->type()->tag();12271228#ifdef __SOFTFP__1229if (tag == floatTag || tag == doubleTag) {1230do_soft_float_compare(x);1231assert(x->default_sux() == x->fsux(), "wrong destination above");1232__ jump(x->default_sux());1233return;1234}1235#endif // __SOFTFP__12361237LIRItem xitem(x->x(), this);1238LIRItem yitem(x->y(), this);1239LIRItem* xin = &xitem;1240LIRItem* yin = &yitem;1241If::Condition cond = x->cond();12421243if (tag == longTag) {1244if (cond == If::gtr || cond == If::leq) {1245cond = Instruction::mirror(cond);1246xin = &yitem;1247yin = &xitem;1248}1249xin->set_destroys_register();1250}12511252xin->load_item();1253LIR_Opr left = xin->result();1254LIR_Opr right;12551256if (tag == longTag && yin->is_constant() && yin->get_jlong_constant() == 0 &&1257(cond == If::eql || cond == If::neq)) {1258// inline long zero1259right = LIR_OprFact::value_type(yin->value()->type());1260} else {1261yin->load_nonconstant();1262right = yin->result();1263}12641265set_no_result(x);12661267// add safepoint before generating condition code so it can be recomputed1268if (x->is_safepoint()) {1269increment_backedge_counter_conditionally(lir_cond(cond), left, right, state_for(x, x->state_before()),1270x->tsux()->bci(), x->fsux()->bci(), x->profiled_bci());1271__ safepoint(LIR_OprFact::illegalOpr, state_for(x, x->state_before()));1272}12731274__ cmp(lir_cond(cond), left, right);1275profile_branch(x, cond);1276move_to_phi(x->state());1277if (x->x()->type()->is_float_kind()) {1278__ branch(lir_cond(cond), x->tsux(), x->usux());1279} else {1280__ branch(lir_cond(cond), x->tsux());1281}1282assert(x->default_sux() == x->fsux(), "wrong destination above");1283__ jump(x->default_sux());1284}128512861287LIR_Opr LIRGenerator::getThreadPointer() {1288return FrameMap::Rthread_opr;1289}12901291void LIRGenerator::trace_block_entry(BlockBegin* block) {1292__ move(LIR_OprFact::intConst(block->block_id()), FrameMap::R0_opr);1293LIR_OprList* args = new LIR_OprList(1);1294args->append(FrameMap::R0_opr);1295address func = CAST_FROM_FN_PTR(address, Runtime1::trace_block_entry);1296__ call_runtime_leaf(func, getThreadTemp(), LIR_OprFact::illegalOpr, args);1297}129812991300void LIRGenerator::volatile_field_store(LIR_Opr value, LIR_Address* address,1301CodeEmitInfo* info) {1302if (value->is_double_cpu()) {1303assert(address->index()->is_illegal(), "should have a constant displacement");1304LIR_Address* store_addr = NULL;1305if (address->disp() != 0) {1306LIR_Opr tmp = new_pointer_register();1307add_large_constant(address->base(), address->disp(), tmp);1308store_addr = new LIR_Address(tmp, (intx)0, address->type());1309} else {1310// address->disp() can be 0, if the address is referenced using the unsafe intrinsic1311store_addr = address;1312}1313__ volatile_store_mem_reg(value, store_addr, info);1314return;1315}1316__ store(value, address, info, lir_patch_none);1317}13181319void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result,1320CodeEmitInfo* info) {1321if (result->is_double_cpu()) {1322assert(address->index()->is_illegal(), "should have a constant displacement");1323LIR_Address* load_addr = NULL;1324if (address->disp() != 0) {1325LIR_Opr tmp = new_pointer_register();1326add_large_constant(address->base(), address->disp(), tmp);1327load_addr = new LIR_Address(tmp, (intx)0, address->type());1328} else {1329// address->disp() can be 0, if the address is referenced using the unsafe intrinsic1330load_addr = address;1331}1332__ volatile_load_mem_reg(load_addr, result, info);1333return;1334}1335__ load(address, result, info, lir_patch_none);1336}133713381339