Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
32285 views
/*1* Copyright (c) 2005, 2016, 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 "c1/c1_Compilation.hpp"26#include "c1/c1_FrameMap.hpp"27#include "c1/c1_Instruction.hpp"28#include "c1/c1_LIRAssembler.hpp"29#include "c1/c1_LIRGenerator.hpp"30#include "c1/c1_Runtime1.hpp"31#include "c1/c1_ValueStack.hpp"32#include "ci/ciArray.hpp"33#include "ci/ciObjArrayKlass.hpp"34#include "ci/ciTypeArrayKlass.hpp"35#include "runtime/sharedRuntime.hpp"36#include "runtime/stubRoutines.hpp"37#include "vmreg_sparc.inline.hpp"3839#ifdef ASSERT40#define __ gen()->lir(__FILE__, __LINE__)->41#else42#define __ gen()->lir()->43#endif4445void LIRItem::load_byte_item() {46// byte loads use same registers as other loads47load_item();48}495051void LIRItem::load_nonconstant() {52LIR_Opr r = value()->operand();53if (_gen->can_inline_as_constant(value())) {54if (!r->is_constant()) {55r = LIR_OprFact::value_type(value()->type());56}57_result = r;58} else {59load_item();60}61}626364//--------------------------------------------------------------65// LIRGenerator66//--------------------------------------------------------------6768LIR_Opr LIRGenerator::exceptionOopOpr() { return FrameMap::Oexception_opr; }69LIR_Opr LIRGenerator::exceptionPcOpr() { return FrameMap::Oissuing_pc_opr; }70LIR_Opr LIRGenerator::syncTempOpr() { return new_register(T_OBJECT); }71LIR_Opr LIRGenerator::getThreadTemp() { return rlock_callee_saved(T_INT); }7273LIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) {74LIR_Opr opr;75switch (type->tag()) {76case intTag: opr = callee ? FrameMap::I0_opr : FrameMap::O0_opr; break;77case objectTag: opr = callee ? FrameMap::I0_oop_opr : FrameMap::O0_oop_opr; break;78case longTag: opr = callee ? FrameMap::in_long_opr : FrameMap::out_long_opr; break;79case floatTag: opr = FrameMap::F0_opr; break;80case doubleTag: opr = FrameMap::F0_double_opr; break;8182case addressTag:83default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr;84}8586assert(opr->type_field() == as_OprType(as_BasicType(type)), "type mismatch");87return opr;88}8990LIR_Opr LIRGenerator::rlock_callee_saved(BasicType type) {91LIR_Opr reg = new_register(type);92set_vreg_flag(reg, callee_saved);93return reg;94}959697LIR_Opr LIRGenerator::rlock_byte(BasicType type) {98return new_register(T_INT);99}100101102103104105//--------- loading items into registers --------------------------------106107// SPARC cannot inline all constants108bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const {109if (v->type()->as_IntConstant() != NULL) {110return v->type()->as_IntConstant()->value() == 0;111} else if (v->type()->as_LongConstant() != NULL) {112return v->type()->as_LongConstant()->value() == 0L;113} else if (v->type()->as_ObjectConstant() != NULL) {114return v->type()->as_ObjectConstant()->value()->is_null_object();115} else {116return false;117}118}119120121// only simm13 constants can be inlined122bool LIRGenerator:: can_inline_as_constant(Value i) const {123if (i->type()->as_IntConstant() != NULL) {124return Assembler::is_simm13(i->type()->as_IntConstant()->value());125} else {126return can_store_as_constant(i, as_BasicType(i->type()));127}128}129130131bool LIRGenerator:: can_inline_as_constant(LIR_Const* c) const {132if (c->type() == T_INT) {133return Assembler::is_simm13(c->as_jint());134}135return false;136}137138139LIR_Opr LIRGenerator::safepoint_poll_register() {140return new_register(T_INT);141}142143144145LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,146int shift, int disp, BasicType type) {147assert(base->is_register(), "must be");148149// accumulate fixed displacements150if (index->is_constant()) {151disp += index->as_constant_ptr()->as_jint() << shift;152index = LIR_OprFact::illegalOpr;153}154155if (index->is_register()) {156// apply the shift and accumulate the displacement157if (shift > 0) {158LIR_Opr tmp = new_pointer_register();159__ shift_left(index, shift, tmp);160index = tmp;161}162if (disp != 0) {163LIR_Opr tmp = new_pointer_register();164if (Assembler::is_simm13(disp)) {165__ add(tmp, LIR_OprFact::intptrConst(disp), tmp);166index = tmp;167} else {168__ move(LIR_OprFact::intptrConst(disp), tmp);169__ add(tmp, index, tmp);170index = tmp;171}172disp = 0;173}174} else if (disp != 0 && !Assembler::is_simm13(disp)) {175// index is illegal so replace it with the displacement loaded into a register176index = new_pointer_register();177__ move(LIR_OprFact::intptrConst(disp), index);178disp = 0;179}180181// at this point we either have base + index or base + displacement182if (disp == 0) {183return new LIR_Address(base, index, type);184} else {185assert(Assembler::is_simm13(disp), "must be");186return new LIR_Address(base, disp, type);187}188}189190191LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr,192BasicType type, bool needs_card_mark) {193int elem_size = type2aelembytes(type);194int shift = exact_log2(elem_size);195196LIR_Opr base_opr;197int offset = arrayOopDesc::base_offset_in_bytes(type);198199if (index_opr->is_constant()) {200int i = index_opr->as_constant_ptr()->as_jint();201int array_offset = i * elem_size;202if (Assembler::is_simm13(array_offset + offset)) {203base_opr = array_opr;204offset = array_offset + offset;205} else {206base_opr = new_pointer_register();207if (Assembler::is_simm13(array_offset)) {208__ add(array_opr, LIR_OprFact::intptrConst(array_offset), base_opr);209} else {210__ move(LIR_OprFact::intptrConst(array_offset), base_opr);211__ add(base_opr, array_opr, base_opr);212}213}214} else {215#ifdef _LP64216if (index_opr->type() == T_INT) {217LIR_Opr tmp = new_register(T_LONG);218__ convert(Bytecodes::_i2l, index_opr, tmp);219index_opr = tmp;220}221#endif222223base_opr = new_pointer_register();224assert (index_opr->is_register(), "Must be register");225if (shift > 0) {226__ shift_left(index_opr, shift, base_opr);227__ add(base_opr, array_opr, base_opr);228} else {229__ add(index_opr, array_opr, base_opr);230}231}232if (needs_card_mark) {233LIR_Opr ptr = new_pointer_register();234__ add(base_opr, LIR_OprFact::intptrConst(offset), ptr);235return new LIR_Address(ptr, type);236} else {237return new LIR_Address(base_opr, offset, type);238}239}240241LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) {242LIR_Opr r;243if (type == T_LONG) {244r = LIR_OprFact::longConst(x);245} else if (type == T_INT) {246r = LIR_OprFact::intConst(x);247} else {248ShouldNotReachHere();249}250if (!Assembler::is_simm13(x)) {251LIR_Opr tmp = new_register(type);252__ move(r, tmp);253return tmp;254}255return r;256}257258void LIRGenerator::increment_counter(address counter, BasicType type, int step) {259LIR_Opr pointer = new_pointer_register();260__ move(LIR_OprFact::intptrConst(counter), pointer);261LIR_Address* addr = new LIR_Address(pointer, type);262increment_counter(addr, step);263}264265void LIRGenerator::increment_counter(LIR_Address* addr, int step) {266LIR_Opr temp = new_register(addr->type());267__ move(addr, temp);268__ add(temp, load_immediate(step, addr->type()), temp);269__ move(temp, addr);270}271272void LIRGenerator::cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info) {273LIR_Opr o7opr = FrameMap::O7_opr;274__ load(new LIR_Address(base, disp, T_INT), o7opr, info);275__ cmp(condition, o7opr, c);276}277278279void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, int disp, BasicType type, CodeEmitInfo* info) {280LIR_Opr o7opr = FrameMap::O7_opr;281__ load(new LIR_Address(base, disp, type), o7opr, info);282__ cmp(condition, reg, o7opr);283}284285286void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, LIR_Opr disp, BasicType type, CodeEmitInfo* info) {287LIR_Opr o7opr = FrameMap::O7_opr;288__ load(new LIR_Address(base, disp, type), o7opr, info);289__ cmp(condition, reg, o7opr);290}291292293bool LIRGenerator::strength_reduce_multiply(LIR_Opr left, int c, LIR_Opr result, LIR_Opr tmp) {294assert(left != result, "should be different registers");295if (is_power_of_2(c + 1)) {296__ shift_left(left, log2_int(c + 1), result);297__ sub(result, left, result);298return true;299} else if (is_power_of_2(c - 1)) {300__ shift_left(left, log2_int(c - 1), result);301__ add(result, left, result);302return true;303}304return false;305}306307308void LIRGenerator::store_stack_parameter (LIR_Opr item, ByteSize offset_from_sp) {309BasicType t = item->type();310LIR_Opr sp_opr = FrameMap::SP_opr;311if ((t == T_LONG || t == T_DOUBLE) &&312((in_bytes(offset_from_sp) - STACK_BIAS) % 8 != 0)) {313__ unaligned_move(item, new LIR_Address(sp_opr, in_bytes(offset_from_sp), t));314} else {315__ move(item, new LIR_Address(sp_opr, in_bytes(offset_from_sp), t));316}317}318319//----------------------------------------------------------------------320// visitor functions321//----------------------------------------------------------------------322323324void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {325assert(x->is_pinned(),"");326bool needs_range_check = x->compute_needs_range_check();327bool use_length = x->length() != NULL;328bool obj_store = x->elt_type() == T_ARRAY || x->elt_type() == T_OBJECT;329bool needs_store_check = obj_store && (x->value()->as_Constant() == NULL ||330!get_jobject_constant(x->value())->is_null_object() ||331x->should_profile());332333LIRItem array(x->array(), this);334LIRItem index(x->index(), this);335LIRItem value(x->value(), this);336LIRItem length(this);337338array.load_item();339index.load_nonconstant();340341if (use_length && needs_range_check) {342length.set_instruction(x->length());343length.load_item();344}345if (needs_store_check || x->check_boolean()) {346value.load_item();347} else {348value.load_for_store(x->elt_type());349}350351set_no_result(x);352353// the CodeEmitInfo must be duplicated for each different354// LIR-instruction because spilling can occur anywhere between two355// instructions and so the debug information must be different356CodeEmitInfo* range_check_info = state_for(x);357CodeEmitInfo* null_check_info = NULL;358if (x->needs_null_check()) {359null_check_info = new CodeEmitInfo(range_check_info);360}361362// emit array address setup early so it schedules better363LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), obj_store);364365if (GenerateRangeChecks && needs_range_check) {366if (use_length) {367__ cmp(lir_cond_belowEqual, length.result(), index.result());368__ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result()));369} else {370array_range_check(array.result(), index.result(), null_check_info, range_check_info);371// range_check also does the null check372null_check_info = NULL;373}374}375376if (GenerateArrayStoreCheck && needs_store_check) {377LIR_Opr tmp1 = FrameMap::G1_opr;378LIR_Opr tmp2 = FrameMap::G3_opr;379LIR_Opr tmp3 = FrameMap::G5_opr;380381CodeEmitInfo* store_check_info = new CodeEmitInfo(range_check_info);382__ store_check(value.result(), array.result(), tmp1, tmp2, tmp3, store_check_info, x->profiled_method(), x->profiled_bci());383}384385if (obj_store) {386// Needs GC write barriers.387pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */,388true /* do_load */, false /* patch */, NULL);389}390LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);391__ move(result, array_addr, null_check_info);392if (obj_store) {393// Precise card mark394post_barrier(LIR_OprFact::address(array_addr), value.result());395}396}397398399void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {400assert(x->is_pinned(),"");401LIRItem obj(x->obj(), this);402obj.load_item();403404set_no_result(x);405406LIR_Opr lock = FrameMap::G1_opr;407LIR_Opr scratch = FrameMap::G3_opr;408LIR_Opr hdr = FrameMap::G4_opr;409410CodeEmitInfo* info_for_exception = NULL;411if (x->needs_null_check()) {412info_for_exception = state_for(x);413}414415// this CodeEmitInfo must not have the xhandlers because here the416// object is already locked (xhandlers expects object to be unlocked)417CodeEmitInfo* info = state_for(x, x->state(), true);418monitor_enter(obj.result(), lock, hdr, scratch, x->monitor_no(), info_for_exception, info);419}420421422void LIRGenerator::do_MonitorExit(MonitorExit* x) {423assert(x->is_pinned(),"");424LIRItem obj(x->obj(), this);425obj.dont_load_item();426427set_no_result(x);428LIR_Opr lock = FrameMap::G1_opr;429LIR_Opr hdr = FrameMap::G3_opr;430LIR_Opr obj_temp = FrameMap::G4_opr;431monitor_exit(obj_temp, lock, hdr, LIR_OprFact::illegalOpr, x->monitor_no());432}433434435// _ineg, _lneg, _fneg, _dneg436void LIRGenerator::do_NegateOp(NegateOp* x) {437LIRItem value(x->x(), this);438value.load_item();439LIR_Opr reg = rlock_result(x);440__ negate(value.result(), reg);441}442443444445// for _fadd, _fmul, _fsub, _fdiv, _frem446// _dadd, _dmul, _dsub, _ddiv, _drem447void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) {448switch (x->op()) {449case Bytecodes::_fadd:450case Bytecodes::_fmul:451case Bytecodes::_fsub:452case Bytecodes::_fdiv:453case Bytecodes::_dadd:454case Bytecodes::_dmul:455case Bytecodes::_dsub:456case Bytecodes::_ddiv: {457LIRItem left(x->x(), this);458LIRItem right(x->y(), this);459left.load_item();460right.load_item();461rlock_result(x);462arithmetic_op_fpu(x->op(), x->operand(), left.result(), right.result(), x->is_strictfp());463}464break;465466case Bytecodes::_frem:467case Bytecodes::_drem: {468address entry;469switch (x->op()) {470case Bytecodes::_frem:471entry = CAST_FROM_FN_PTR(address, SharedRuntime::frem);472break;473case Bytecodes::_drem:474entry = CAST_FROM_FN_PTR(address, SharedRuntime::drem);475break;476default:477ShouldNotReachHere();478}479LIR_Opr result = call_runtime(x->x(), x->y(), entry, x->type(), NULL);480set_result(x, result);481}482break;483484default: ShouldNotReachHere();485}486}487488489// for _ladd, _lmul, _lsub, _ldiv, _lrem490void LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) {491switch (x->op()) {492case Bytecodes::_lrem:493case Bytecodes::_lmul:494case Bytecodes::_ldiv: {495496if (x->op() == Bytecodes::_ldiv || x->op() == Bytecodes::_lrem) {497LIRItem right(x->y(), this);498right.load_item();499500CodeEmitInfo* info = state_for(x);501LIR_Opr item = right.result();502assert(item->is_register(), "must be");503__ cmp(lir_cond_equal, item, LIR_OprFact::longConst(0));504__ branch(lir_cond_equal, T_LONG, new DivByZeroStub(info));505}506507address entry;508switch (x->op()) {509case Bytecodes::_lrem:510entry = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);511break; // check if dividend is 0 is done elsewhere512case Bytecodes::_ldiv:513entry = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);514break; // check if dividend is 0 is done elsewhere515case Bytecodes::_lmul:516entry = CAST_FROM_FN_PTR(address, SharedRuntime::lmul);517break;518default:519ShouldNotReachHere();520}521522// order of arguments to runtime call is reversed.523LIR_Opr result = call_runtime(x->y(), x->x(), entry, x->type(), NULL);524set_result(x, result);525break;526}527case Bytecodes::_ladd:528case Bytecodes::_lsub: {529LIRItem left(x->x(), this);530LIRItem right(x->y(), this);531left.load_item();532right.load_item();533rlock_result(x);534535arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), NULL);536break;537}538default: ShouldNotReachHere();539}540}541542543// Returns if item is an int constant that can be represented by a simm13544static bool is_simm13(LIR_Opr item) {545if (item->is_constant() && item->type() == T_INT) {546return Assembler::is_simm13(item->as_constant_ptr()->as_jint());547} else {548return false;549}550}551552553// for: _iadd, _imul, _isub, _idiv, _irem554void LIRGenerator::do_ArithmeticOp_Int(ArithmeticOp* x) {555bool is_div_rem = x->op() == Bytecodes::_idiv || x->op() == Bytecodes::_irem;556LIRItem left(x->x(), this);557LIRItem right(x->y(), this);558// missing test if instr is commutative and if we should swap559right.load_nonconstant();560assert(right.is_constant() || right.is_register(), "wrong state of right");561left.load_item();562rlock_result(x);563if (is_div_rem) {564CodeEmitInfo* info = state_for(x);565LIR_Opr tmp = FrameMap::G1_opr;566if (x->op() == Bytecodes::_irem) {567__ irem(left.result(), right.result(), x->operand(), tmp, info);568} else if (x->op() == Bytecodes::_idiv) {569__ idiv(left.result(), right.result(), x->operand(), tmp, info);570}571} else {572arithmetic_op_int(x->op(), x->operand(), left.result(), right.result(), FrameMap::G1_opr);573}574}575576577void LIRGenerator::do_ArithmeticOp(ArithmeticOp* x) {578ValueTag tag = x->type()->tag();579assert(x->x()->type()->tag() == tag && x->y()->type()->tag() == tag, "wrong parameters");580switch (tag) {581case floatTag:582case doubleTag: do_ArithmeticOp_FPU(x); return;583case longTag: do_ArithmeticOp_Long(x); return;584case intTag: do_ArithmeticOp_Int(x); return;585}586ShouldNotReachHere();587}588589590// _ishl, _lshl, _ishr, _lshr, _iushr, _lushr591void LIRGenerator::do_ShiftOp(ShiftOp* x) {592LIRItem value(x->x(), this);593LIRItem count(x->y(), this);594// Long shift destroys count register595if (value.type()->is_long()) {596count.set_destroys_register();597}598value.load_item();599// the old backend doesn't support this600if (count.is_constant() && count.type()->as_IntConstant() != NULL && value.type()->is_int()) {601jint c = count.get_jint_constant() & 0x1f;602assert(c >= 0 && c < 32, "should be small");603count.dont_load_item();604} else {605count.load_item();606}607LIR_Opr reg = rlock_result(x);608shift_op(x->op(), reg, value.result(), count.result(), LIR_OprFact::illegalOpr);609}610611612// _iand, _land, _ior, _lor, _ixor, _lxor613void LIRGenerator::do_LogicOp(LogicOp* x) {614LIRItem left(x->x(), this);615LIRItem right(x->y(), this);616617left.load_item();618right.load_nonconstant();619LIR_Opr reg = rlock_result(x);620621logic_op(x->op(), reg, left.result(), right.result());622}623624625626// _lcmp, _fcmpl, _fcmpg, _dcmpl, _dcmpg627void LIRGenerator::do_CompareOp(CompareOp* x) {628LIRItem left(x->x(), this);629LIRItem right(x->y(), this);630left.load_item();631right.load_item();632LIR_Opr reg = rlock_result(x);633if (x->x()->type()->is_float_kind()) {634Bytecodes::Code code = x->op();635__ fcmp2int(left.result(), right.result(), reg, (code == Bytecodes::_fcmpl || code == Bytecodes::_dcmpl));636} else if (x->x()->type()->tag() == longTag) {637__ lcmp2int(left.result(), right.result(), reg);638} else {639Unimplemented();640}641}642643644void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {645assert(x->number_of_arguments() == 4, "wrong type");646LIRItem obj (x->argument_at(0), this); // object647LIRItem offset(x->argument_at(1), this); // offset of field648LIRItem cmp (x->argument_at(2), this); // value to compare with field649LIRItem val (x->argument_at(3), this); // replace field with val if matches cmp650651// Use temps to avoid kills652LIR_Opr t1 = FrameMap::G1_opr;653LIR_Opr t2 = FrameMap::G3_opr;654LIR_Opr addr = new_pointer_register();655656// get address of field657obj.load_item();658offset.load_item();659cmp.load_item();660val.load_item();661662__ add(obj.result(), offset.result(), addr);663664if (type == objectType) { // Write-barrier needed for Object fields.665pre_barrier(addr, LIR_OprFact::illegalOpr /* pre_val */,666true /* do_load */, false /* patch */, NULL);667}668669if (type == objectType)670__ cas_obj(addr, cmp.result(), val.result(), t1, t2);671else if (type == intType)672__ cas_int(addr, cmp.result(), val.result(), t1, t2);673else if (type == longType)674__ cas_long(addr, cmp.result(), val.result(), t1, t2);675else {676ShouldNotReachHere();677}678// generate conditional move of boolean result679LIR_Opr result = rlock_result(x);680__ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),681result, as_BasicType(type));682if (type == objectType) { // Write-barrier needed for Object fields.683// Precise card mark since could either be object or array684post_barrier(addr, val.result());685}686}687688689void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {690switch (x->id()) {691case vmIntrinsics::_dabs:692case vmIntrinsics::_dsqrt: {693assert(x->number_of_arguments() == 1, "wrong type");694LIRItem value(x->argument_at(0), this);695value.load_item();696LIR_Opr dst = rlock_result(x);697698switch (x->id()) {699case vmIntrinsics::_dsqrt: {700__ sqrt(value.result(), dst, LIR_OprFact::illegalOpr);701break;702}703case vmIntrinsics::_dabs: {704__ abs(value.result(), dst, LIR_OprFact::illegalOpr);705break;706}707}708break;709}710case vmIntrinsics::_dlog10: // fall through711case vmIntrinsics::_dlog: // fall through712case vmIntrinsics::_dsin: // fall through713case vmIntrinsics::_dtan: // fall through714case vmIntrinsics::_dcos: // fall through715case vmIntrinsics::_dexp: {716assert(x->number_of_arguments() == 1, "wrong type");717718address runtime_entry = NULL;719switch (x->id()) {720case vmIntrinsics::_dsin:721runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);722break;723case vmIntrinsics::_dcos:724runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);725break;726case vmIntrinsics::_dtan:727runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);728break;729case vmIntrinsics::_dlog:730runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog);731break;732case vmIntrinsics::_dlog10:733runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10);734break;735case vmIntrinsics::_dexp:736runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dexp);737break;738default:739ShouldNotReachHere();740}741742LIR_Opr result = call_runtime(x->argument_at(0), runtime_entry, x->type(), NULL);743set_result(x, result);744break;745}746case vmIntrinsics::_dpow: {747assert(x->number_of_arguments() == 2, "wrong type");748address runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dpow);749LIR_Opr result = call_runtime(x->argument_at(0), x->argument_at(1), runtime_entry, x->type(), NULL);750set_result(x, result);751break;752}753}754}755756757void LIRGenerator::do_ArrayCopy(Intrinsic* x) {758assert(x->number_of_arguments() == 5, "wrong type");759760// Make all state_for calls early since they can emit code761CodeEmitInfo* info = state_for(x, x->state());762763// Note: spill caller save before setting the item764LIRItem src (x->argument_at(0), this);765LIRItem src_pos (x->argument_at(1), this);766LIRItem dst (x->argument_at(2), this);767LIRItem dst_pos (x->argument_at(3), this);768LIRItem length (x->argument_at(4), this);769// load all values in callee_save_registers, as this makes the770// parameter passing to the fast case simpler771src.load_item_force (rlock_callee_saved(T_OBJECT));772src_pos.load_item_force (rlock_callee_saved(T_INT));773dst.load_item_force (rlock_callee_saved(T_OBJECT));774dst_pos.load_item_force (rlock_callee_saved(T_INT));775length.load_item_force (rlock_callee_saved(T_INT));776777int flags;778ciArrayKlass* expected_type;779arraycopy_helper(x, &flags, &expected_type);780781__ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(),782length.result(), rlock_callee_saved(T_INT),783expected_type, flags, info);784set_no_result(x);785}786787void LIRGenerator::do_update_CRC32(Intrinsic* x) {788fatal("CRC32 intrinsic is not implemented on this platform");789}790791// _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f792// _i2b, _i2c, _i2s793void LIRGenerator::do_Convert(Convert* x) {794795switch (x->op()) {796case Bytecodes::_f2l:797case Bytecodes::_d2l:798case Bytecodes::_d2i:799case Bytecodes::_l2f:800case Bytecodes::_l2d: {801802address entry;803switch (x->op()) {804case Bytecodes::_l2f:805entry = CAST_FROM_FN_PTR(address, SharedRuntime::l2f);806break;807case Bytecodes::_l2d:808entry = CAST_FROM_FN_PTR(address, SharedRuntime::l2d);809break;810case Bytecodes::_f2l:811entry = CAST_FROM_FN_PTR(address, SharedRuntime::f2l);812break;813case Bytecodes::_d2l:814entry = CAST_FROM_FN_PTR(address, SharedRuntime::d2l);815break;816case Bytecodes::_d2i:817entry = CAST_FROM_FN_PTR(address, SharedRuntime::d2i);818break;819default:820ShouldNotReachHere();821}822LIR_Opr result = call_runtime(x->value(), entry, x->type(), NULL);823set_result(x, result);824break;825}826827case Bytecodes::_i2f:828case Bytecodes::_i2d: {829LIRItem value(x->value(), this);830831LIR_Opr reg = rlock_result(x);832// To convert an int to double, we need to load the 32-bit int833// from memory into a single precision floating point register834// (even numbered). Then the sparc fitod instruction takes care835// of the conversion. This is a bit ugly, but is the best way to836// get the int value in a single precision floating point register837value.load_item();838LIR_Opr tmp = force_to_spill(value.result(), T_FLOAT);839__ convert(x->op(), tmp, reg);840break;841}842break;843844case Bytecodes::_i2l:845case Bytecodes::_i2b:846case Bytecodes::_i2c:847case Bytecodes::_i2s:848case Bytecodes::_l2i:849case Bytecodes::_f2d:850case Bytecodes::_d2f: { // inline code851LIRItem value(x->value(), this);852853value.load_item();854LIR_Opr reg = rlock_result(x);855__ convert(x->op(), value.result(), reg, false);856}857break;858859case Bytecodes::_f2i: {860LIRItem value (x->value(), this);861value.set_destroys_register();862value.load_item();863LIR_Opr reg = rlock_result(x);864set_vreg_flag(reg, must_start_in_memory);865__ convert(x->op(), value.result(), reg, false);866}867break;868869default: ShouldNotReachHere();870}871}872873874void LIRGenerator::do_NewInstance(NewInstance* x) {875print_if_not_loaded(x);876877// This instruction can be deoptimized in the slow path : use878// O0 as result register.879const LIR_Opr reg = result_register_for(x->type());880881CodeEmitInfo* info = state_for(x, x->state());882LIR_Opr tmp1 = FrameMap::G1_oop_opr;883LIR_Opr tmp2 = FrameMap::G3_oop_opr;884LIR_Opr tmp3 = FrameMap::G4_oop_opr;885LIR_Opr tmp4 = FrameMap::O1_oop_opr;886LIR_Opr klass_reg = FrameMap::G5_metadata_opr;887new_instance(reg, x->klass(), x->is_unresolved(), tmp1, tmp2, tmp3, tmp4, klass_reg, info);888LIR_Opr result = rlock_result(x);889__ move(reg, result);890}891892893void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {894// Evaluate state_for early since it may emit code895CodeEmitInfo* info = state_for(x, x->state());896897LIRItem length(x->length(), this);898length.load_item();899900LIR_Opr reg = result_register_for(x->type());901LIR_Opr tmp1 = FrameMap::G1_oop_opr;902LIR_Opr tmp2 = FrameMap::G3_oop_opr;903LIR_Opr tmp3 = FrameMap::G4_oop_opr;904LIR_Opr tmp4 = FrameMap::O1_oop_opr;905LIR_Opr klass_reg = FrameMap::G5_metadata_opr;906LIR_Opr len = length.result();907BasicType elem_type = x->elt_type();908909__ metadata2reg(ciTypeArrayKlass::make(elem_type)->constant_encoding(), klass_reg);910911CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);912__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);913914LIR_Opr result = rlock_result(x);915__ move(reg, result);916}917918919void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {920// Evaluate state_for early since it may emit code.921CodeEmitInfo* info = state_for(x, x->state());922// in case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction923// and therefore provide the state before the parameters have been consumed924CodeEmitInfo* patching_info = NULL;925if (!x->klass()->is_loaded() || PatchALot) {926patching_info = state_for(x, x->state_before());927}928929LIRItem length(x->length(), this);930length.load_item();931932const LIR_Opr reg = result_register_for(x->type());933LIR_Opr tmp1 = FrameMap::G1_oop_opr;934LIR_Opr tmp2 = FrameMap::G3_oop_opr;935LIR_Opr tmp3 = FrameMap::G4_oop_opr;936LIR_Opr tmp4 = FrameMap::O1_oop_opr;937LIR_Opr klass_reg = FrameMap::G5_metadata_opr;938LIR_Opr len = length.result();939940CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info);941ciMetadata* obj = ciObjArrayKlass::make(x->klass());942if (obj == ciEnv::unloaded_ciobjarrayklass()) {943BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error");944}945klass2reg_with_patching(klass_reg, obj, patching_info);946__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path);947948LIR_Opr result = rlock_result(x);949__ move(reg, result);950}951952953void LIRGenerator::do_NewMultiArray(NewMultiArray* x) {954Values* dims = x->dims();955int i = dims->length();956LIRItemList* items = new LIRItemList(dims->length(), NULL);957while (i-- > 0) {958LIRItem* size = new LIRItem(dims->at(i), this);959items->at_put(i, size);960}961962// Evaluate state_for early since it may emit code.963CodeEmitInfo* patching_info = NULL;964if (!x->klass()->is_loaded() || PatchALot) {965patching_info = state_for(x, x->state_before());966967// Cannot re-use same xhandlers for multiple CodeEmitInfos, so968// clone all handlers (NOTE: Usually this is handled transparently969// by the CodeEmitInfo cloning logic in CodeStub constructors but970// is done explicitly here because a stub isn't being used).971x->set_exception_handlers(new XHandlers(x->exception_handlers()));972}973CodeEmitInfo* info = state_for(x, x->state());974975i = dims->length();976while (i-- > 0) {977LIRItem* size = items->at(i);978size->load_item();979store_stack_parameter (size->result(),980in_ByteSize(STACK_BIAS +981frame::memory_parameter_word_sp_offset * wordSize +982i * sizeof(jint)));983}984985// This instruction can be deoptimized in the slow path : use986// O0 as result register.987const LIR_Opr klass_reg = FrameMap::O0_metadata_opr;988klass2reg_with_patching(klass_reg, x->klass(), patching_info);989LIR_Opr rank = FrameMap::O1_opr;990__ move(LIR_OprFact::intConst(x->rank()), rank);991LIR_Opr varargs = FrameMap::as_pointer_opr(O2);992int offset_from_sp = (frame::memory_parameter_word_sp_offset * wordSize) + STACK_BIAS;993__ add(FrameMap::SP_opr,994LIR_OprFact::intptrConst(offset_from_sp),995varargs);996LIR_OprList* args = new LIR_OprList(3);997args->append(klass_reg);998args->append(rank);999args->append(varargs);1000const LIR_Opr reg = result_register_for(x->type());1001__ call_runtime(Runtime1::entry_for(Runtime1::new_multi_array_id),1002LIR_OprFact::illegalOpr,1003reg, args, info);10041005LIR_Opr result = rlock_result(x);1006__ move(reg, result);1007}100810091010void LIRGenerator::do_BlockBegin(BlockBegin* x) {1011}101210131014void LIRGenerator::do_CheckCast(CheckCast* x) {1015LIRItem obj(x->obj(), this);1016CodeEmitInfo* patching_info = NULL;1017if (!x->klass()->is_loaded() || (PatchALot && !x->is_incompatible_class_change_check())) {1018// must do this before locking the destination register as an oop register,1019// and before the obj is loaded (so x->obj()->item() is valid for creating a debug info location)1020patching_info = state_for(x, x->state_before());1021}1022obj.load_item();1023LIR_Opr out_reg = rlock_result(x);1024CodeStub* stub;1025CodeEmitInfo* info_for_exception =1026(x->needs_exception_state() ? state_for(x) :1027state_for(x, x->state_before(), true /*ignore_xhandler*/));10281029if (x->is_incompatible_class_change_check()) {1030assert(patching_info == NULL, "can't patch this");1031stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, info_for_exception);1032} else if (x->is_invokespecial_receiver_check()) {1033assert(patching_info == NULL, "can't patch this");1034stub = new DeoptimizeStub(info_for_exception);1035} else {1036stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception);1037}1038LIR_Opr tmp1 = FrameMap::G1_oop_opr;1039LIR_Opr tmp2 = FrameMap::G3_oop_opr;1040LIR_Opr tmp3 = FrameMap::G4_oop_opr;1041__ checkcast(out_reg, obj.result(), x->klass(), tmp1, tmp2, tmp3,1042x->direct_compare(), info_for_exception, patching_info, stub,1043x->profiled_method(), x->profiled_bci());1044}104510461047void LIRGenerator::do_InstanceOf(InstanceOf* x) {1048LIRItem obj(x->obj(), this);1049CodeEmitInfo* patching_info = NULL;1050if (!x->klass()->is_loaded() || PatchALot) {1051patching_info = state_for(x, x->state_before());1052}1053// ensure the result register is not the input register because the result is initialized before the patching safepoint1054obj.load_item();1055LIR_Opr out_reg = rlock_result(x);1056LIR_Opr tmp1 = FrameMap::G1_oop_opr;1057LIR_Opr tmp2 = FrameMap::G3_oop_opr;1058LIR_Opr tmp3 = FrameMap::G4_oop_opr;1059__ instanceof(out_reg, obj.result(), x->klass(), tmp1, tmp2, tmp3,1060x->direct_compare(), patching_info,1061x->profiled_method(), x->profiled_bci());1062}106310641065void LIRGenerator::do_If(If* x) {1066assert(x->number_of_sux() == 2, "inconsistency");1067ValueTag tag = x->x()->type()->tag();1068LIRItem xitem(x->x(), this);1069LIRItem yitem(x->y(), this);1070LIRItem* xin = &xitem;1071LIRItem* yin = &yitem;1072If::Condition cond = x->cond();10731074if (tag == longTag) {1075// for longs, only conditions "eql", "neq", "lss", "geq" are valid;1076// mirror for other conditions1077if (cond == If::gtr || cond == If::leq) {1078// swap inputs1079cond = Instruction::mirror(cond);1080xin = &yitem;1081yin = &xitem;1082}1083xin->set_destroys_register();1084}10851086LIR_Opr left = LIR_OprFact::illegalOpr;1087LIR_Opr right = LIR_OprFact::illegalOpr;10881089xin->load_item();1090left = xin->result();10911092if (is_simm13(yin->result())) {1093// inline int constants which are small enough to be immediate operands1094right = LIR_OprFact::value_type(yin->value()->type());1095} else if (tag == longTag && yin->is_constant() && yin->get_jlong_constant() == 0 &&1096(cond == If::eql || cond == If::neq)) {1097// inline long zero1098right = LIR_OprFact::value_type(yin->value()->type());1099} else if (tag == objectTag && yin->is_constant() && (yin->get_jobject_constant()->is_null_object())) {1100right = LIR_OprFact::value_type(yin->value()->type());1101} else {1102yin->load_item();1103right = yin->result();1104}1105set_no_result(x);11061107// add safepoint before generating condition code so it can be recomputed1108if (x->is_safepoint()) {1109// increment backedge counter if needed1110increment_backedge_counter(state_for(x, x->state_before()), x->profiled_bci());1111__ safepoint(new_register(T_INT), state_for(x, x->state_before()));1112}11131114__ cmp(lir_cond(cond), left, right);1115// Generate branch profiling. Profiling code doesn't kill flags.1116profile_branch(x, cond);1117move_to_phi(x->state());1118if (x->x()->type()->is_float_kind()) {1119__ branch(lir_cond(cond), right->type(), x->tsux(), x->usux());1120} else {1121__ branch(lir_cond(cond), right->type(), x->tsux());1122}1123assert(x->default_sux() == x->fsux(), "wrong destination above");1124__ jump(x->default_sux());1125}112611271128LIR_Opr LIRGenerator::getThreadPointer() {1129return FrameMap::as_pointer_opr(G2);1130}113111321133void LIRGenerator::trace_block_entry(BlockBegin* block) {1134__ move(LIR_OprFact::intConst(block->block_id()), FrameMap::O0_opr);1135LIR_OprList* args = new LIR_OprList(1);1136args->append(FrameMap::O0_opr);1137address func = CAST_FROM_FN_PTR(address, Runtime1::trace_block_entry);1138__ call_runtime_leaf(func, rlock_callee_saved(T_INT), LIR_OprFact::illegalOpr, args);1139}114011411142void LIRGenerator::volatile_field_store(LIR_Opr value, LIR_Address* address,1143CodeEmitInfo* info) {1144#ifdef _LP641145__ store(value, address, info);1146#else1147__ volatile_store_mem_reg(value, address, info);1148#endif1149}11501151void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result,1152CodeEmitInfo* info) {1153#ifdef _LP641154__ load(address, result, info);1155#else1156__ volatile_load_mem_reg(address, result, info);1157#endif1158}115911601161void LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data,1162BasicType type, bool is_volatile) {1163LIR_Opr base_op = src;1164LIR_Opr index_op = offset;11651166bool is_obj = (type == T_ARRAY || type == T_OBJECT);1167#ifndef _LP641168if (is_volatile && type == T_LONG) {1169__ volatile_store_unsafe_reg(data, src, offset, type, NULL, lir_patch_none);1170} else1171#endif1172{1173if (type == T_BOOLEAN) {1174type = T_BYTE;1175}1176LIR_Address* addr;1177if (type == T_ARRAY || type == T_OBJECT) {1178LIR_Opr tmp = new_pointer_register();1179__ add(base_op, index_op, tmp);1180addr = new LIR_Address(tmp, type);1181} else {1182addr = new LIR_Address(base_op, index_op, type);1183}11841185if (is_obj) {1186pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,1187true /* do_load */, false /* patch */, NULL);1188// _bs->c1_write_barrier_pre(this, LIR_OprFact::address(addr));1189}1190__ move(data, addr);1191if (is_obj) {1192// This address is precise1193post_barrier(LIR_OprFact::address(addr), data);1194}1195}1196}119711981199void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset,1200BasicType type, bool is_volatile) {1201#ifndef _LP641202if (is_volatile && type == T_LONG) {1203__ volatile_load_unsafe_reg(src, offset, dst, type, NULL, lir_patch_none);1204} else1205#endif1206{1207LIR_Address* addr = new LIR_Address(src, offset, type);1208__ load(addr, dst);1209}1210}12111212void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {1213BasicType type = x->basic_type();1214LIRItem src(x->object(), this);1215LIRItem off(x->offset(), this);1216LIRItem value(x->value(), this);12171218src.load_item();1219value.load_item();1220off.load_nonconstant();12211222LIR_Opr dst = rlock_result(x, type);1223LIR_Opr data = value.result();1224bool is_obj = (type == T_ARRAY || type == T_OBJECT);1225LIR_Opr offset = off.result();12261227// Because we want a 2-arg form of xchg1228__ move(data, dst);12291230assert (!x->is_add() && (type == T_INT || (is_obj LP64_ONLY(&& UseCompressedOops))), "unexpected type");1231LIR_Address* addr;1232if (offset->is_constant()) {12331234#ifdef _LP641235jlong l = offset->as_jlong();1236assert((jlong)((jint)l) == l, "offset too large for constant");1237jint c = (jint)l;1238#else1239jint c = offset->as_jint();1240#endif1241addr = new LIR_Address(src.result(), c, type);1242} else {1243addr = new LIR_Address(src.result(), offset, type);1244}12451246LIR_Opr tmp = LIR_OprFact::illegalOpr;1247LIR_Opr ptr = LIR_OprFact::illegalOpr;12481249if (is_obj) {1250// Do the pre-write barrier, if any.1251// barriers on sparc don't work with a base + index address1252tmp = FrameMap::G3_opr;1253ptr = new_pointer_register();1254__ add(src.result(), off.result(), ptr);1255pre_barrier(ptr, LIR_OprFact::illegalOpr /* pre_val */,1256true /* do_load */, false /* patch */, NULL);1257}1258__ xchg(LIR_OprFact::address(addr), dst, dst, tmp);1259if (is_obj) {1260// Seems to be a precise address1261post_barrier(ptr, data);1262}1263}126412651266