Path: blob/master/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp
40930 views
/*1* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2014, Red Hat Inc. All rights reserved.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425#include "precompiled.hpp"26#include "asm/macroAssembler.inline.hpp"27#include "c1/c1_Compilation.hpp"28#include "c1/c1_FrameMap.hpp"29#include "c1/c1_Instruction.hpp"30#include "c1/c1_LIRAssembler.hpp"31#include "c1/c1_LIRGenerator.hpp"32#include "c1/c1_Runtime1.hpp"33#include "c1/c1_ValueStack.hpp"34#include "ci/ciArray.hpp"35#include "ci/ciObjArrayKlass.hpp"36#include "ci/ciTypeArrayKlass.hpp"37#include "runtime/sharedRuntime.hpp"38#include "runtime/stubRoutines.hpp"39#include "utilities/powerOfTwo.hpp"40#include "vmreg_aarch64.inline.hpp"4142#ifdef ASSERT43#define __ gen()->lir(__FILE__, __LINE__)->44#else45#define __ gen()->lir()->46#endif4748// Item will be loaded into a byte register; Intel only49void LIRItem::load_byte_item() {50load_item();51}525354void LIRItem::load_nonconstant() {55LIR_Opr r = value()->operand();56if (r->is_constant()) {57_result = r;58} else {59load_item();60}61}6263//--------------------------------------------------------------64// LIRGenerator65//--------------------------------------------------------------666768LIR_Opr LIRGenerator::exceptionOopOpr() { return FrameMap::r0_oop_opr; }69LIR_Opr LIRGenerator::exceptionPcOpr() { return FrameMap::r3_opr; }70LIR_Opr LIRGenerator::divInOpr() { Unimplemented(); return LIR_OprFact::illegalOpr; }71LIR_Opr LIRGenerator::divOutOpr() { Unimplemented(); return LIR_OprFact::illegalOpr; }72LIR_Opr LIRGenerator::remOutOpr() { Unimplemented(); return LIR_OprFact::illegalOpr; }73LIR_Opr LIRGenerator::shiftCountOpr() { Unimplemented(); return LIR_OprFact::illegalOpr; }74LIR_Opr LIRGenerator::syncLockOpr() { return new_register(T_INT); }75LIR_Opr LIRGenerator::syncTempOpr() { return FrameMap::r0_opr; }76LIR_Opr LIRGenerator::getThreadTemp() { return LIR_OprFact::illegalOpr; }777879LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) {80LIR_Opr opr;81switch (type->tag()) {82case intTag: opr = FrameMap::r0_opr; break;83case objectTag: opr = FrameMap::r0_oop_opr; break;84case longTag: opr = FrameMap::long0_opr; break;85case floatTag: opr = FrameMap::fpu0_float_opr; break;86case doubleTag: opr = FrameMap::fpu0_double_opr; break;8788case addressTag:89default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr;90}9192assert(opr->type_field() == as_OprType(as_BasicType(type)), "type mismatch");93return opr;94}959697LIR_Opr LIRGenerator::rlock_byte(BasicType type) {98LIR_Opr reg = new_register(T_INT);99set_vreg_flag(reg, LIRGenerator::byte_reg);100return reg;101}102103104//--------- loading items into registers --------------------------------105106107bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const {108if (v->type()->as_IntConstant() != NULL) {109return v->type()->as_IntConstant()->value() == 0L;110} else if (v->type()->as_LongConstant() != NULL) {111return v->type()->as_LongConstant()->value() == 0L;112} else if (v->type()->as_ObjectConstant() != NULL) {113return v->type()->as_ObjectConstant()->value()->is_null_object();114} else {115return false;116}117}118119bool LIRGenerator::can_inline_as_constant(Value v) const {120// FIXME: Just a guess121if (v->type()->as_IntConstant() != NULL) {122return Assembler::operand_valid_for_add_sub_immediate(v->type()->as_IntConstant()->value());123} else if (v->type()->as_LongConstant() != NULL) {124return v->type()->as_LongConstant()->value() == 0L;125} else if (v->type()->as_ObjectConstant() != NULL) {126return v->type()->as_ObjectConstant()->value()->is_null_object();127} else {128return false;129}130}131132133bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const { return false; }134135136LIR_Opr LIRGenerator::safepoint_poll_register() {137return LIR_OprFact::illegalOpr;138}139140141LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,142int shift, int disp, BasicType type) {143assert(base->is_register(), "must be");144intx large_disp = disp;145146// accumulate fixed displacements147if (index->is_constant()) {148LIR_Const *constant = index->as_constant_ptr();149if (constant->type() == T_INT) {150large_disp += index->as_jint() << shift;151} else {152assert(constant->type() == T_LONG, "should be");153jlong c = index->as_jlong() << shift;154if ((jlong)((jint)c) == c) {155large_disp += c;156index = LIR_OprFact::illegalOpr;157} else {158LIR_Opr tmp = new_register(T_LONG);159__ move(index, tmp);160index = tmp;161// apply shift and displacement below162}163}164}165166if (index->is_register()) {167// apply the shift and accumulate the displacement168if (shift > 0) {169LIR_Opr tmp = new_pointer_register();170__ shift_left(index, shift, tmp);171index = tmp;172}173if (large_disp != 0) {174LIR_Opr tmp = new_pointer_register();175if (Assembler::operand_valid_for_add_sub_immediate(large_disp)) {176__ add(index, LIR_OprFact::intptrConst(large_disp), tmp);177index = tmp;178} else {179__ move(LIR_OprFact::intptrConst(large_disp), tmp);180__ add(tmp, index, tmp);181index = tmp;182}183large_disp = 0;184}185} else if (large_disp != 0 && !Address::offset_ok_for_immed(large_disp, shift)) {186// index is illegal so replace it with the displacement loaded into a register187index = new_pointer_register();188__ move(LIR_OprFact::intptrConst(large_disp), index);189large_disp = 0;190}191192// at this point we either have base + index or base + displacement193if (large_disp == 0 && index->is_register()) {194return new LIR_Address(base, index, type);195} else {196assert(Address::offset_ok_for_immed(large_disp, 0), "must be");197return new LIR_Address(base, large_disp, type);198}199}200201LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr,202BasicType type) {203int offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type);204int elem_size = type2aelembytes(type);205int shift = exact_log2(elem_size);206207LIR_Address* addr;208if (index_opr->is_constant()) {209addr = new LIR_Address(array_opr,210offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type);211} else {212if (offset_in_bytes) {213LIR_Opr tmp = new_pointer_register();214__ add(array_opr, LIR_OprFact::intConst(offset_in_bytes), tmp);215array_opr = tmp;216offset_in_bytes = 0;217}218addr = new LIR_Address(array_opr,219index_opr,220LIR_Address::scale(type),221offset_in_bytes, type);222}223return addr;224}225226LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) {227LIR_Opr r;228if (type == T_LONG) {229r = LIR_OprFact::longConst(x);230if (!Assembler::operand_valid_for_logical_immediate(false, x)) {231LIR_Opr tmp = new_register(type);232__ move(r, tmp);233return tmp;234}235} else if (type == T_INT) {236r = LIR_OprFact::intConst(x);237if (!Assembler::operand_valid_for_logical_immediate(true, x)) {238// This is all rather nasty. We don't know whether our constant239// is required for a logical or an arithmetic operation, wo we240// don't know what the range of valid values is!!241LIR_Opr tmp = new_register(type);242__ move(r, tmp);243return tmp;244}245} else {246ShouldNotReachHere();247r = NULL; // unreachable248}249return r;250}251252253254void LIRGenerator::increment_counter(address counter, BasicType type, int step) {255LIR_Opr pointer = new_pointer_register();256__ move(LIR_OprFact::intptrConst(counter), pointer);257LIR_Address* addr = new LIR_Address(pointer, type);258increment_counter(addr, step);259}260261262void LIRGenerator::increment_counter(LIR_Address* addr, int step) {263LIR_Opr imm = NULL;264switch(addr->type()) {265case T_INT:266imm = LIR_OprFact::intConst(step);267break;268case T_LONG:269imm = LIR_OprFact::longConst(step);270break;271default:272ShouldNotReachHere();273}274LIR_Opr reg = new_register(addr->type());275__ load(addr, reg);276__ add(reg, imm, reg);277__ store(reg, addr);278}279280void LIRGenerator::cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info) {281LIR_Opr reg = new_register(T_INT);282__ load(generate_address(base, disp, T_INT), reg, info);283__ cmp(condition, reg, LIR_OprFact::intConst(c));284}285286void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, int disp, BasicType type, CodeEmitInfo* info) {287LIR_Opr reg1 = new_register(T_INT);288__ load(generate_address(base, disp, type), reg1, info);289__ cmp(condition, reg, reg1);290}291292293bool LIRGenerator::strength_reduce_multiply(LIR_Opr left, jint c, LIR_Opr result, LIR_Opr tmp) {294295if (is_power_of_2(c - 1)) {296__ shift_left(left, exact_log2(c - 1), tmp);297__ add(tmp, left, result);298return true;299} else if (is_power_of_2(c + 1)) {300__ shift_left(left, exact_log2(c + 1), tmp);301__ sub(tmp, left, result);302return true;303} else {304return false;305}306}307308void LIRGenerator::store_stack_parameter (LIR_Opr item, ByteSize offset_from_sp) {309BasicType type = item->type();310__ store(item, new LIR_Address(FrameMap::sp_opr, in_bytes(offset_from_sp), type));311}312313void LIRGenerator::array_store_check(LIR_Opr value, LIR_Opr array, CodeEmitInfo* store_check_info, ciMethod* profiled_method, int profiled_bci) {314LIR_Opr tmp1 = new_register(objectType);315LIR_Opr tmp2 = new_register(objectType);316LIR_Opr tmp3 = new_register(objectType);317__ store_check(value, array, tmp1, tmp2, tmp3, store_check_info, profiled_method, profiled_bci);318}319320//----------------------------------------------------------------------321// visitor functions322//----------------------------------------------------------------------323324void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {325assert(x->is_pinned(),"");326LIRItem obj(x->obj(), this);327obj.load_item();328329set_no_result(x);330331// "lock" stores the address of the monitor stack slot, so this is not an oop332LIR_Opr lock = new_register(T_INT);333// Need a scratch register for biased locking334LIR_Opr scratch = LIR_OprFact::illegalOpr;335if (UseBiasedLocking) {336scratch = new_register(T_INT);337}338339CodeEmitInfo* info_for_exception = NULL;340if (x->needs_null_check()) {341info_for_exception = state_for(x);342}343// this CodeEmitInfo must not have the xhandlers because here the344// object is already locked (xhandlers expect object to be unlocked)345CodeEmitInfo* info = state_for(x, x->state(), true);346monitor_enter(obj.result(), lock, syncTempOpr(), scratch,347x->monitor_no(), info_for_exception, info);348}349350351void LIRGenerator::do_MonitorExit(MonitorExit* x) {352assert(x->is_pinned(),"");353354LIRItem obj(x->obj(), this);355obj.dont_load_item();356357LIR_Opr lock = new_register(T_INT);358LIR_Opr obj_temp = new_register(T_INT);359set_no_result(x);360monitor_exit(obj_temp, lock, syncTempOpr(), LIR_OprFact::illegalOpr, x->monitor_no());361}362363364void LIRGenerator::do_NegateOp(NegateOp* x) {365366LIRItem from(x->x(), this);367from.load_item();368LIR_Opr result = rlock_result(x);369__ negate (from.result(), result);370371}372373// for _fadd, _fmul, _fsub, _fdiv, _frem374// _dadd, _dmul, _dsub, _ddiv, _drem375void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) {376377if (x->op() == Bytecodes::_frem || x->op() == Bytecodes::_drem) {378// float remainder is implemented as a direct call into the runtime379LIRItem right(x->x(), this);380LIRItem left(x->y(), this);381382BasicTypeList signature(2);383if (x->op() == Bytecodes::_frem) {384signature.append(T_FLOAT);385signature.append(T_FLOAT);386} else {387signature.append(T_DOUBLE);388signature.append(T_DOUBLE);389}390CallingConvention* cc = frame_map()->c_calling_convention(&signature);391392const LIR_Opr result_reg = result_register_for(x->type());393left.load_item_force(cc->at(1));394right.load_item();395396__ move(right.result(), cc->at(0));397398address entry;399if (x->op() == Bytecodes::_frem) {400entry = CAST_FROM_FN_PTR(address, SharedRuntime::frem);401} else {402entry = CAST_FROM_FN_PTR(address, SharedRuntime::drem);403}404405LIR_Opr result = rlock_result(x);406__ call_runtime_leaf(entry, getThreadTemp(), result_reg, cc->args());407__ move(result_reg, result);408409return;410}411412LIRItem left(x->x(), this);413LIRItem right(x->y(), this);414LIRItem* left_arg = &left;415LIRItem* right_arg = &right;416417// Always load right hand side.418right.load_item();419420if (!left.is_register())421left.load_item();422423LIR_Opr reg = rlock(x);424425arithmetic_op_fpu(x->op(), reg, left.result(), right.result());426427set_result(x, round_item(reg));428}429430// for _ladd, _lmul, _lsub, _ldiv, _lrem431void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) {432433// missing test if instr is commutative and if we should swap434LIRItem left(x->x(), this);435LIRItem right(x->y(), this);436437if (x->op() == Bytecodes::_ldiv || x->op() == Bytecodes::_lrem) {438439left.load_item();440bool need_zero_check = true;441if (right.is_constant()) {442jlong c = right.get_jlong_constant();443// no need to do div-by-zero check if the divisor is a non-zero constant444if (c != 0) need_zero_check = false;445// do not load right if the divisor is a power-of-2 constant446if (c > 0 && is_power_of_2(c)) {447right.dont_load_item();448} else {449right.load_item();450}451} else {452right.load_item();453}454if (need_zero_check) {455CodeEmitInfo* info = state_for(x);456__ cmp(lir_cond_equal, right.result(), LIR_OprFact::longConst(0));457__ branch(lir_cond_equal, new DivByZeroStub(info));458}459460rlock_result(x);461switch (x->op()) {462case Bytecodes::_lrem:463__ rem (left.result(), right.result(), x->operand());464break;465case Bytecodes::_ldiv:466__ div (left.result(), right.result(), x->operand());467break;468default:469ShouldNotReachHere();470break;471}472473474} else {475assert (x->op() == Bytecodes::_lmul || x->op() == Bytecodes::_ladd || x->op() == Bytecodes::_lsub,476"expect lmul, ladd or lsub");477// add, sub, mul478left.load_item();479if (! right.is_register()) {480if (x->op() == Bytecodes::_lmul481|| ! right.is_constant()482|| ! Assembler::operand_valid_for_add_sub_immediate(right.get_jlong_constant())) {483right.load_item();484} else { // add, sub485assert (x->op() == Bytecodes::_ladd || x->op() == Bytecodes::_lsub, "expect ladd or lsub");486// don't load constants to save register487right.load_nonconstant();488}489}490rlock_result(x);491arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), NULL);492}493}494495// for: _iadd, _imul, _isub, _idiv, _irem496void LIRGenerator::do_ArithmeticOp_Int(ArithmeticOp* x) {497498// Test if instr is commutative and if we should swap499LIRItem left(x->x(), this);500LIRItem right(x->y(), this);501LIRItem* left_arg = &left;502LIRItem* right_arg = &right;503if (x->is_commutative() && left.is_stack() && right.is_register()) {504// swap them if left is real stack (or cached) and right is real register(not cached)505left_arg = &right;506right_arg = &left;507}508509left_arg->load_item();510511// do not need to load right, as we can handle stack and constants512if (x->op() == Bytecodes::_idiv || x->op() == Bytecodes::_irem) {513514rlock_result(x);515bool need_zero_check = true;516if (right.is_constant()) {517jint c = right.get_jint_constant();518// no need to do div-by-zero check if the divisor is a non-zero constant519if (c != 0) need_zero_check = false;520// do not load right if the divisor is a power-of-2 constant521if (c > 0 && is_power_of_2(c)) {522right_arg->dont_load_item();523} else {524right_arg->load_item();525}526} else {527right_arg->load_item();528}529if (need_zero_check) {530CodeEmitInfo* info = state_for(x);531__ cmp(lir_cond_equal, right_arg->result(), LIR_OprFact::longConst(0));532__ branch(lir_cond_equal, new DivByZeroStub(info));533}534535LIR_Opr ill = LIR_OprFact::illegalOpr;536if (x->op() == Bytecodes::_irem) {537__ irem(left_arg->result(), right_arg->result(), x->operand(), ill, NULL);538} else if (x->op() == Bytecodes::_idiv) {539__ idiv(left_arg->result(), right_arg->result(), x->operand(), ill, NULL);540}541542} else if (x->op() == Bytecodes::_iadd || x->op() == Bytecodes::_isub) {543if (right.is_constant()544&& Assembler::operand_valid_for_add_sub_immediate(right.get_jint_constant())) {545right.load_nonconstant();546} else {547right.load_item();548}549rlock_result(x);550arithmetic_op_int(x->op(), x->operand(), left_arg->result(), right_arg->result(), LIR_OprFact::illegalOpr);551} else {552assert (x->op() == Bytecodes::_imul, "expect imul");553if (right.is_constant()) {554jint c = right.get_jint_constant();555if (c > 0 && c < max_jint && (is_power_of_2(c) || is_power_of_2(c - 1) || is_power_of_2(c + 1))) {556right_arg->dont_load_item();557} else {558// Cannot use constant op.559right_arg->load_item();560}561} else {562right.load_item();563}564rlock_result(x);565arithmetic_op_int(x->op(), x->operand(), left_arg->result(), right_arg->result(), new_register(T_INT));566}567}568569void LIRGenerator::do_ArithmeticOp(ArithmeticOp* x) {570// when an operand with use count 1 is the left operand, then it is571// likely that no move for 2-operand-LIR-form is necessary572if (x->is_commutative() && x->y()->as_Constant() == NULL && x->x()->use_count() > x->y()->use_count()) {573x->swap_operands();574}575576ValueTag tag = x->type()->tag();577assert(x->x()->type()->tag() == tag && x->y()->type()->tag() == tag, "wrong parameters");578switch (tag) {579case floatTag:580case doubleTag: do_ArithmeticOp_FPU(x); return;581case longTag: do_ArithmeticOp_Long(x); return;582case intTag: do_ArithmeticOp_Int(x); return;583default: ShouldNotReachHere(); return;584}585}586587// _ishl, _lshl, _ishr, _lshr, _iushr, _lushr588void LIRGenerator::do_ShiftOp(ShiftOp* x) {589590LIRItem left(x->x(), this);591LIRItem right(x->y(), this);592593left.load_item();594595rlock_result(x);596if (right.is_constant()) {597right.dont_load_item();598599switch (x->op()) {600case Bytecodes::_ishl: {601int c = right.get_jint_constant() & 0x1f;602__ shift_left(left.result(), c, x->operand());603break;604}605case Bytecodes::_ishr: {606int c = right.get_jint_constant() & 0x1f;607__ shift_right(left.result(), c, x->operand());608break;609}610case Bytecodes::_iushr: {611int c = right.get_jint_constant() & 0x1f;612__ unsigned_shift_right(left.result(), c, x->operand());613break;614}615case Bytecodes::_lshl: {616int c = right.get_jint_constant() & 0x3f;617__ shift_left(left.result(), c, x->operand());618break;619}620case Bytecodes::_lshr: {621int c = right.get_jint_constant() & 0x3f;622__ shift_right(left.result(), c, x->operand());623break;624}625case Bytecodes::_lushr: {626int c = right.get_jint_constant() & 0x3f;627__ unsigned_shift_right(left.result(), c, x->operand());628break;629}630default:631ShouldNotReachHere();632}633} else {634right.load_item();635LIR_Opr tmp = new_register(T_INT);636switch (x->op()) {637case Bytecodes::_ishl: {638__ logical_and(right.result(), LIR_OprFact::intConst(0x1f), tmp);639__ shift_left(left.result(), tmp, x->operand(), tmp);640break;641}642case Bytecodes::_ishr: {643__ logical_and(right.result(), LIR_OprFact::intConst(0x1f), tmp);644__ shift_right(left.result(), tmp, x->operand(), tmp);645break;646}647case Bytecodes::_iushr: {648__ logical_and(right.result(), LIR_OprFact::intConst(0x1f), tmp);649__ unsigned_shift_right(left.result(), tmp, x->operand(), tmp);650break;651}652case Bytecodes::_lshl: {653__ logical_and(right.result(), LIR_OprFact::intConst(0x3f), tmp);654__ shift_left(left.result(), tmp, x->operand(), tmp);655break;656}657case Bytecodes::_lshr: {658__ logical_and(right.result(), LIR_OprFact::intConst(0x3f), tmp);659__ shift_right(left.result(), tmp, x->operand(), tmp);660break;661}662case Bytecodes::_lushr: {663__ logical_and(right.result(), LIR_OprFact::intConst(0x3f), tmp);664__ unsigned_shift_right(left.result(), tmp, x->operand(), tmp);665break;666}667default:668ShouldNotReachHere();669}670}671}672673// _iand, _land, _ior, _lor, _ixor, _lxor674void LIRGenerator::do_LogicOp(LogicOp* x) {675676LIRItem left(x->x(), this);677LIRItem right(x->y(), this);678679left.load_item();680681rlock_result(x);682if (right.is_constant()683&& ((right.type()->tag() == intTag684&& Assembler::operand_valid_for_logical_immediate(true, right.get_jint_constant()))685|| (right.type()->tag() == longTag686&& Assembler::operand_valid_for_logical_immediate(false, right.get_jlong_constant())))) {687right.dont_load_item();688} else {689right.load_item();690}691switch (x->op()) {692case Bytecodes::_iand:693case Bytecodes::_land:694__ logical_and(left.result(), right.result(), x->operand()); break;695case Bytecodes::_ior:696case Bytecodes::_lor:697__ logical_or (left.result(), right.result(), x->operand()); break;698case Bytecodes::_ixor:699case Bytecodes::_lxor:700__ logical_xor(left.result(), right.result(), x->operand()); break;701default: Unimplemented();702}703}704705// _lcmp, _fcmpl, _fcmpg, _dcmpl, _dcmpg706void LIRGenerator::do_CompareOp(CompareOp* x) {707LIRItem left(x->x(), this);708LIRItem right(x->y(), this);709ValueTag tag = x->x()->type()->tag();710if (tag == longTag) {711left.set_destroys_register();712}713left.load_item();714right.load_item();715LIR_Opr reg = rlock_result(x);716717if (x->x()->type()->is_float_kind()) {718Bytecodes::Code code = x->op();719__ fcmp2int(left.result(), right.result(), reg, (code == Bytecodes::_fcmpl || code == Bytecodes::_dcmpl));720} else if (x->x()->type()->tag() == longTag) {721__ lcmp2int(left.result(), right.result(), reg);722} else {723Unimplemented();724}725}726727LIR_Opr LIRGenerator::atomic_cmpxchg(BasicType type, LIR_Opr addr, LIRItem& cmp_value, LIRItem& new_value) {728LIR_Opr ill = LIR_OprFact::illegalOpr; // for convenience729new_value.load_item();730cmp_value.load_item();731LIR_Opr result = new_register(T_INT);732if (is_reference_type(type)) {733__ cas_obj(addr, cmp_value.result(), new_value.result(), new_register(T_INT), new_register(T_INT), result);734} else if (type == T_INT) {735__ cas_int(addr->as_address_ptr()->base(), cmp_value.result(), new_value.result(), ill, ill);736} else if (type == T_LONG) {737__ cas_long(addr->as_address_ptr()->base(), cmp_value.result(), new_value.result(), ill, ill);738} else {739ShouldNotReachHere();740Unimplemented();741}742__ logical_xor(FrameMap::r8_opr, LIR_OprFact::intConst(1), result);743return result;744}745746LIR_Opr LIRGenerator::atomic_xchg(BasicType type, LIR_Opr addr, LIRItem& value) {747bool is_oop = is_reference_type(type);748LIR_Opr result = new_register(type);749value.load_item();750assert(type == T_INT || is_oop LP64_ONLY( || type == T_LONG ), "unexpected type");751LIR_Opr tmp = new_register(T_INT);752__ xchg(addr, value.result(), result, tmp);753return result;754}755756LIR_Opr LIRGenerator::atomic_add(BasicType type, LIR_Opr addr, LIRItem& value) {757LIR_Opr result = new_register(type);758value.load_item();759assert(type == T_INT LP64_ONLY( || type == T_LONG ), "unexpected type");760LIR_Opr tmp = new_register(T_INT);761__ xadd(addr, value.result(), result, tmp);762return result;763}764765void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {766assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type");767if (x->id() == vmIntrinsics::_dexp || x->id() == vmIntrinsics::_dlog ||768x->id() == vmIntrinsics::_dpow || x->id() == vmIntrinsics::_dcos ||769x->id() == vmIntrinsics::_dsin || x->id() == vmIntrinsics::_dtan ||770x->id() == vmIntrinsics::_dlog10) {771do_LibmIntrinsic(x);772return;773}774switch (x->id()) {775case vmIntrinsics::_dabs:776case vmIntrinsics::_dsqrt: {777assert(x->number_of_arguments() == 1, "wrong type");778LIRItem value(x->argument_at(0), this);779value.load_item();780LIR_Opr dst = rlock_result(x);781782switch (x->id()) {783case vmIntrinsics::_dsqrt: {784__ sqrt(value.result(), dst, LIR_OprFact::illegalOpr);785break;786}787case vmIntrinsics::_dabs: {788__ abs(value.result(), dst, LIR_OprFact::illegalOpr);789break;790}791default:792ShouldNotReachHere();793}794break;795}796default:797ShouldNotReachHere();798}799}800801void LIRGenerator::do_LibmIntrinsic(Intrinsic* x) {802LIRItem value(x->argument_at(0), this);803value.set_destroys_register();804805LIR_Opr calc_result = rlock_result(x);806LIR_Opr result_reg = result_register_for(x->type());807808CallingConvention* cc = NULL;809810if (x->id() == vmIntrinsics::_dpow) {811LIRItem value1(x->argument_at(1), this);812813value1.set_destroys_register();814815BasicTypeList signature(2);816signature.append(T_DOUBLE);817signature.append(T_DOUBLE);818cc = frame_map()->c_calling_convention(&signature);819value.load_item_force(cc->at(0));820value1.load_item_force(cc->at(1));821} else {822BasicTypeList signature(1);823signature.append(T_DOUBLE);824cc = frame_map()->c_calling_convention(&signature);825value.load_item_force(cc->at(0));826}827828switch (x->id()) {829case vmIntrinsics::_dexp:830if (StubRoutines::dexp() != NULL) {831__ call_runtime_leaf(StubRoutines::dexp(), getThreadTemp(), result_reg, cc->args());832} else {833__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dexp), getThreadTemp(), result_reg, cc->args());834}835break;836case vmIntrinsics::_dlog:837if (StubRoutines::dlog() != NULL) {838__ call_runtime_leaf(StubRoutines::dlog(), getThreadTemp(), result_reg, cc->args());839} else {840__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog), getThreadTemp(), result_reg, cc->args());841}842break;843case vmIntrinsics::_dlog10:844if (StubRoutines::dlog10() != NULL) {845__ call_runtime_leaf(StubRoutines::dlog10(), getThreadTemp(), result_reg, cc->args());846} else {847__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10), getThreadTemp(), result_reg, cc->args());848}849break;850case vmIntrinsics::_dpow:851if (StubRoutines::dpow() != NULL) {852__ call_runtime_leaf(StubRoutines::dpow(), getThreadTemp(), result_reg, cc->args());853} else {854__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), getThreadTemp(), result_reg, cc->args());855}856break;857case vmIntrinsics::_dsin:858if (StubRoutines::dsin() != NULL) {859__ call_runtime_leaf(StubRoutines::dsin(), getThreadTemp(), result_reg, cc->args());860} else {861__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), getThreadTemp(), result_reg, cc->args());862}863break;864case vmIntrinsics::_dcos:865if (StubRoutines::dcos() != NULL) {866__ call_runtime_leaf(StubRoutines::dcos(), getThreadTemp(), result_reg, cc->args());867} else {868__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), getThreadTemp(), result_reg, cc->args());869}870break;871case vmIntrinsics::_dtan:872if (StubRoutines::dtan() != NULL) {873__ call_runtime_leaf(StubRoutines::dtan(), getThreadTemp(), result_reg, cc->args());874} else {875__ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), getThreadTemp(), result_reg, cc->args());876}877break;878default: ShouldNotReachHere();879}880__ move(result_reg, calc_result);881}882883884void LIRGenerator::do_ArrayCopy(Intrinsic* x) {885assert(x->number_of_arguments() == 5, "wrong type");886887// Make all state_for calls early since they can emit code888CodeEmitInfo* info = state_for(x, x->state());889890LIRItem src(x->argument_at(0), this);891LIRItem src_pos(x->argument_at(1), this);892LIRItem dst(x->argument_at(2), this);893LIRItem dst_pos(x->argument_at(3), this);894LIRItem length(x->argument_at(4), this);895896// operands for arraycopy must use fixed registers, otherwise897// LinearScan will fail allocation (because arraycopy always needs a898// call)899900// The java calling convention will give us enough registers901// so that on the stub side the args will be perfect already.902// On the other slow/special case side we call C and the arg903// positions are not similar enough to pick one as the best.904// Also because the java calling convention is a "shifted" version905// of the C convention we can process the java args trivially into C906// args without worry of overwriting during the xfer907908src.load_item_force (FrameMap::as_oop_opr(j_rarg0));909src_pos.load_item_force (FrameMap::as_opr(j_rarg1));910dst.load_item_force (FrameMap::as_oop_opr(j_rarg2));911dst_pos.load_item_force (FrameMap::as_opr(j_rarg3));912length.load_item_force (FrameMap::as_opr(j_rarg4));913914LIR_Opr tmp = FrameMap::as_opr(j_rarg5);915916set_no_result(x);917918int flags;919ciArrayKlass* expected_type;920arraycopy_helper(x, &flags, &expected_type);921922__ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint923}924925void LIRGenerator::do_update_CRC32(Intrinsic* x) {926assert(UseCRC32Intrinsics, "why are we here?");927// Make all state_for calls early since they can emit code928LIR_Opr result = rlock_result(x);929int flags = 0;930switch (x->id()) {931case vmIntrinsics::_updateCRC32: {932LIRItem crc(x->argument_at(0), this);933LIRItem val(x->argument_at(1), this);934// val is destroyed by update_crc32935val.set_destroys_register();936crc.load_item();937val.load_item();938__ update_crc32(crc.result(), val.result(), result);939break;940}941case vmIntrinsics::_updateBytesCRC32:942case vmIntrinsics::_updateByteBufferCRC32: {943bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32);944945LIRItem crc(x->argument_at(0), this);946LIRItem buf(x->argument_at(1), this);947LIRItem off(x->argument_at(2), this);948LIRItem len(x->argument_at(3), this);949buf.load_item();950off.load_nonconstant();951952LIR_Opr index = off.result();953int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0;954if(off.result()->is_constant()) {955index = LIR_OprFact::illegalOpr;956offset += off.result()->as_jint();957}958LIR_Opr base_op = buf.result();959960if (index->is_valid()) {961LIR_Opr tmp = new_register(T_LONG);962__ convert(Bytecodes::_i2l, index, tmp);963index = tmp;964}965966if (offset) {967LIR_Opr tmp = new_pointer_register();968__ add(base_op, LIR_OprFact::intConst(offset), tmp);969base_op = tmp;970offset = 0;971}972973LIR_Address* a = new LIR_Address(base_op,974index,975offset,976T_BYTE);977BasicTypeList signature(3);978signature.append(T_INT);979signature.append(T_ADDRESS);980signature.append(T_INT);981CallingConvention* cc = frame_map()->c_calling_convention(&signature);982const LIR_Opr result_reg = result_register_for(x->type());983984LIR_Opr addr = new_pointer_register();985__ leal(LIR_OprFact::address(a), addr);986987crc.load_item_force(cc->at(0));988__ move(addr, cc->at(1));989len.load_item_force(cc->at(2));990991__ call_runtime_leaf(StubRoutines::updateBytesCRC32(), getThreadTemp(), result_reg, cc->args());992__ move(result_reg, result);993994break;995}996default: {997ShouldNotReachHere();998}999}1000}10011002void LIRGenerator::do_update_CRC32C(Intrinsic* x) {1003assert(UseCRC32CIntrinsics, "why are we here?");1004// Make all state_for calls early since they can emit code1005LIR_Opr result = rlock_result(x);1006int flags = 0;1007switch (x->id()) {1008case vmIntrinsics::_updateBytesCRC32C:1009case vmIntrinsics::_updateDirectByteBufferCRC32C: {1010bool is_updateBytes = (x->id() == vmIntrinsics::_updateBytesCRC32C);1011int offset = is_updateBytes ? arrayOopDesc::base_offset_in_bytes(T_BYTE) : 0;10121013LIRItem crc(x->argument_at(0), this);1014LIRItem buf(x->argument_at(1), this);1015LIRItem off(x->argument_at(2), this);1016LIRItem end(x->argument_at(3), this);10171018buf.load_item();1019off.load_nonconstant();1020end.load_nonconstant();10211022// len = end - off1023LIR_Opr len = end.result();1024LIR_Opr tmpA = new_register(T_INT);1025LIR_Opr tmpB = new_register(T_INT);1026__ move(end.result(), tmpA);1027__ move(off.result(), tmpB);1028__ sub(tmpA, tmpB, tmpA);1029len = tmpA;10301031LIR_Opr index = off.result();1032if(off.result()->is_constant()) {1033index = LIR_OprFact::illegalOpr;1034offset += off.result()->as_jint();1035}1036LIR_Opr base_op = buf.result();10371038if (index->is_valid()) {1039LIR_Opr tmp = new_register(T_LONG);1040__ convert(Bytecodes::_i2l, index, tmp);1041index = tmp;1042}10431044if (offset) {1045LIR_Opr tmp = new_pointer_register();1046__ add(base_op, LIR_OprFact::intConst(offset), tmp);1047base_op = tmp;1048offset = 0;1049}10501051LIR_Address* a = new LIR_Address(base_op,1052index,1053offset,1054T_BYTE);1055BasicTypeList signature(3);1056signature.append(T_INT);1057signature.append(T_ADDRESS);1058signature.append(T_INT);1059CallingConvention* cc = frame_map()->c_calling_convention(&signature);1060const LIR_Opr result_reg = result_register_for(x->type());10611062LIR_Opr addr = new_pointer_register();1063__ leal(LIR_OprFact::address(a), addr);10641065crc.load_item_force(cc->at(0));1066__ move(addr, cc->at(1));1067__ move(len, cc->at(2));10681069__ call_runtime_leaf(StubRoutines::updateBytesCRC32C(), getThreadTemp(), result_reg, cc->args());1070__ move(result_reg, result);10711072break;1073}1074default: {1075ShouldNotReachHere();1076}1077}1078}10791080void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {1081assert(x->number_of_arguments() == 3, "wrong type");1082assert(UseFMA, "Needs FMA instructions support.");1083LIRItem value(x->argument_at(0), this);1084LIRItem value1(x->argument_at(1), this);1085LIRItem value2(x->argument_at(2), this);10861087value.load_item();1088value1.load_item();1089value2.load_item();10901091LIR_Opr calc_input = value.result();1092LIR_Opr calc_input1 = value1.result();1093LIR_Opr calc_input2 = value2.result();1094LIR_Opr calc_result = rlock_result(x);10951096switch (x->id()) {1097case vmIntrinsics::_fmaD: __ fmad(calc_input, calc_input1, calc_input2, calc_result); break;1098case vmIntrinsics::_fmaF: __ fmaf(calc_input, calc_input1, calc_input2, calc_result); break;1099default: ShouldNotReachHere();1100}1101}11021103void LIRGenerator::do_vectorizedMismatch(Intrinsic* x) {1104fatal("vectorizedMismatch intrinsic is not implemented on this platform");1105}11061107// _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f1108// _i2b, _i2c, _i2s1109void LIRGenerator::do_Convert(Convert* x) {1110LIRItem value(x->value(), this);1111value.load_item();1112LIR_Opr input = value.result();1113LIR_Opr result = rlock(x);11141115// arguments of lir_convert1116LIR_Opr conv_input = input;1117LIR_Opr conv_result = result;11181119__ convert(x->op(), conv_input, conv_result);11201121assert(result->is_virtual(), "result must be virtual register");1122set_result(x, result);1123}11241125void LIRGenerator::do_NewInstance(NewInstance* x) {1126#ifndef PRODUCT1127if (PrintNotLoaded && !x->klass()->is_loaded()) {1128tty->print_cr(" ###class not loaded at new bci %d", x->printable_bci());1129}1130#endif1131CodeEmitInfo* info = state_for(x, x->state());1132LIR_Opr reg = result_register_for(x->type());1133new_instance(reg, x->klass(), x->is_unresolved(),1134FrameMap::r2_oop_opr,1135FrameMap::r5_oop_opr,1136FrameMap::r4_oop_opr,1137LIR_OprFact::illegalOpr,1138FrameMap::r3_metadata_opr, info);1139LIR_Opr result = rlock_result(x);1140__ move(reg, result);1141}11421143void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {1144CodeEmitInfo* info = state_for(x, x->state());11451146LIRItem length(x->length(), this);1147length.load_item_force(FrameMap::r19_opr);11481149LIR_Opr reg = result_register_for(x->type());1150LIR_Opr tmp1 = FrameMap::r2_oop_opr;1151LIR_Opr tmp2 = FrameMap::r4_oop_opr;1152LIR_Opr tmp3 = FrameMap::r5_oop_opr;1153LIR_Opr tmp4 = reg;1154LIR_Opr klass_reg = FrameMap::r3_metadata_opr;1155LIR_Opr len = length.result();1156BasicType elem_type = x->elt_type();11571158__ metadata2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg);11591160CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);1161__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);11621163LIR_Opr result = rlock_result(x);1164__ move(reg, result);1165}11661167void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {1168LIRItem length(x->length(), this);1169// in case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction1170// and therefore provide the state before the parameters have been consumed1171CodeEmitInfo* patching_info = NULL;1172if (!x->klass()->is_loaded() || PatchALot) {1173patching_info = state_for(x, x->state_before());1174}11751176CodeEmitInfo* info = state_for(x, x->state());11771178LIR_Opr reg = result_register_for(x->type());1179LIR_Opr tmp1 = FrameMap::r2_oop_opr;1180LIR_Opr tmp2 = FrameMap::r4_oop_opr;1181LIR_Opr tmp3 = FrameMap::r5_oop_opr;1182LIR_Opr tmp4 = reg;1183LIR_Opr klass_reg = FrameMap::r3_metadata_opr;11841185length.load_item_force(FrameMap::r19_opr);1186LIR_Opr len = length.result();11871188CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info);1189ciKlass* obj = (ciKlass*) ciObjArrayKlass::make(x->klass());1190if (obj == ciEnv::unloaded_ciobjarrayklass()) {1191BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error");1192}1193klass2reg_with_patching(klass_reg, obj, patching_info);1194__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path);11951196LIR_Opr result = rlock_result(x);1197__ move(reg, result);1198}119912001201void LIRGenerator::do_NewMultiArray(NewMultiArray* x) {1202Values* dims = x->dims();1203int i = dims->length();1204LIRItemList* items = new LIRItemList(i, i, NULL);1205while (i-- > 0) {1206LIRItem* size = new LIRItem(dims->at(i), this);1207items->at_put(i, size);1208}12091210// Evaluate state_for early since it may emit code.1211CodeEmitInfo* patching_info = NULL;1212if (!x->klass()->is_loaded() || PatchALot) {1213patching_info = state_for(x, x->state_before());12141215// Cannot re-use same xhandlers for multiple CodeEmitInfos, so1216// clone all handlers (NOTE: Usually this is handled transparently1217// by the CodeEmitInfo cloning logic in CodeStub constructors but1218// is done explicitly here because a stub isn't being used).1219x->set_exception_handlers(new XHandlers(x->exception_handlers()));1220}1221CodeEmitInfo* info = state_for(x, x->state());12221223i = dims->length();1224while (i-- > 0) {1225LIRItem* size = items->at(i);1226size->load_item();12271228store_stack_parameter(size->result(), in_ByteSize(i*4));1229}12301231LIR_Opr klass_reg = FrameMap::r0_metadata_opr;1232klass2reg_with_patching(klass_reg, x->klass(), patching_info);12331234LIR_Opr rank = FrameMap::r19_opr;1235__ move(LIR_OprFact::intConst(x->rank()), rank);1236LIR_Opr varargs = FrameMap::r2_opr;1237__ move(FrameMap::sp_opr, varargs);1238LIR_OprList* args = new LIR_OprList(3);1239args->append(klass_reg);1240args->append(rank);1241args->append(varargs);1242LIR_Opr reg = result_register_for(x->type());1243__ call_runtime(Runtime1::entry_for(Runtime1::new_multi_array_id),1244LIR_OprFact::illegalOpr,1245reg, args, info);12461247LIR_Opr result = rlock_result(x);1248__ move(reg, result);1249}12501251void LIRGenerator::do_BlockBegin(BlockBegin* x) {1252// nothing to do for now1253}12541255void LIRGenerator::do_CheckCast(CheckCast* x) {1256LIRItem obj(x->obj(), this);12571258CodeEmitInfo* patching_info = NULL;1259if (!x->klass()->is_loaded() || (PatchALot && !x->is_incompatible_class_change_check() && !x->is_invokespecial_receiver_check())) {1260// must do this before locking the destination register as an oop register,1261// and before the obj is loaded (the latter is for deoptimization)1262patching_info = state_for(x, x->state_before());1263}1264obj.load_item();12651266// info for exceptions1267CodeEmitInfo* info_for_exception =1268(x->needs_exception_state() ? state_for(x) :1269state_for(x, x->state_before(), true /*ignore_xhandler*/));12701271CodeStub* stub;1272if (x->is_incompatible_class_change_check()) {1273assert(patching_info == NULL, "can't patch this");1274stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, info_for_exception);1275} else if (x->is_invokespecial_receiver_check()) {1276assert(patching_info == NULL, "can't patch this");1277stub = new DeoptimizeStub(info_for_exception,1278Deoptimization::Reason_class_check,1279Deoptimization::Action_none);1280} else {1281stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception);1282}1283LIR_Opr reg = rlock_result(x);1284LIR_Opr tmp3 = LIR_OprFact::illegalOpr;1285if (!x->klass()->is_loaded() || UseCompressedClassPointers) {1286tmp3 = new_register(objectType);1287}1288__ checkcast(reg, obj.result(), x->klass(),1289new_register(objectType), new_register(objectType), tmp3,1290x->direct_compare(), info_for_exception, patching_info, stub,1291x->profiled_method(), x->profiled_bci());1292}12931294void LIRGenerator::do_InstanceOf(InstanceOf* x) {1295LIRItem obj(x->obj(), this);12961297// result and test object may not be in same register1298LIR_Opr reg = rlock_result(x);1299CodeEmitInfo* patching_info = NULL;1300if ((!x->klass()->is_loaded() || PatchALot)) {1301// must do this before locking the destination register as an oop register1302patching_info = state_for(x, x->state_before());1303}1304obj.load_item();1305LIR_Opr tmp3 = LIR_OprFact::illegalOpr;1306if (!x->klass()->is_loaded() || UseCompressedClassPointers) {1307tmp3 = new_register(objectType);1308}1309__ instanceof(reg, obj.result(), x->klass(),1310new_register(objectType), new_register(objectType), tmp3,1311x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci());1312}13131314void LIRGenerator::do_If(If* x) {1315assert(x->number_of_sux() == 2, "inconsistency");1316ValueTag tag = x->x()->type()->tag();1317bool is_safepoint = x->is_safepoint();13181319If::Condition cond = x->cond();13201321LIRItem xitem(x->x(), this);1322LIRItem yitem(x->y(), this);1323LIRItem* xin = &xitem;1324LIRItem* yin = &yitem;13251326if (tag == longTag) {1327// for longs, only conditions "eql", "neq", "lss", "geq" are valid;1328// mirror for other conditions1329if (cond == If::gtr || cond == If::leq) {1330cond = Instruction::mirror(cond);1331xin = &yitem;1332yin = &xitem;1333}1334xin->set_destroys_register();1335}1336xin->load_item();13371338if (tag == longTag) {1339if (yin->is_constant()1340&& Assembler::operand_valid_for_add_sub_immediate(yin->get_jlong_constant())) {1341yin->dont_load_item();1342} else {1343yin->load_item();1344}1345} else if (tag == intTag) {1346if (yin->is_constant()1347&& Assembler::operand_valid_for_add_sub_immediate(yin->get_jint_constant())) {1348yin->dont_load_item();1349} else {1350yin->load_item();1351}1352} else {1353yin->load_item();1354}13551356set_no_result(x);13571358LIR_Opr left = xin->result();1359LIR_Opr right = yin->result();13601361// add safepoint before generating condition code so it can be recomputed1362if (x->is_safepoint()) {1363// increment backedge counter if needed1364increment_backedge_counter_conditionally(lir_cond(cond), left, right, state_for(x, x->state_before()),1365x->tsux()->bci(), x->fsux()->bci(), x->profiled_bci());1366__ safepoint(LIR_OprFact::illegalOpr, state_for(x, x->state_before()));1367}13681369__ cmp(lir_cond(cond), left, right);1370// Generate branch profiling. Profiling code doesn't kill flags.1371profile_branch(x, cond);1372move_to_phi(x->state());1373if (x->x()->type()->is_float_kind()) {1374__ branch(lir_cond(cond), x->tsux(), x->usux());1375} else {1376__ branch(lir_cond(cond), x->tsux());1377}1378assert(x->default_sux() == x->fsux(), "wrong destination above");1379__ jump(x->default_sux());1380}13811382LIR_Opr LIRGenerator::getThreadPointer() {1383return FrameMap::as_pointer_opr(rthread);1384}13851386void LIRGenerator::trace_block_entry(BlockBegin* block) { Unimplemented(); }13871388void LIRGenerator::volatile_field_store(LIR_Opr value, LIR_Address* address,1389CodeEmitInfo* info) {1390__ volatile_store_mem_reg(value, address, info);1391}13921393void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result,1394CodeEmitInfo* info) {1395// 8179954: We need to make sure that the code generated for1396// volatile accesses forms a sequentially-consistent set of1397// operations when combined with STLR and LDAR. Without a leading1398// membar it's possible for a simple Dekker test to fail if loads1399// use LD;DMB but stores use STLR. This can happen if C2 compiles1400// the stores in one method and C1 compiles the loads in another.1401if (!CompilerConfig::is_c1_only_no_jvmci()) {1402__ membar();1403}1404__ volatile_load_mem_reg(address, result, info);1405}140614071408