c1_LIRGenerator_x86.cpp revision 362:f8199438385b
11541Srgrimes/*
21541Srgrimes * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
31541Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
41541Srgrimes *
51541Srgrimes * This code is free software; you can redistribute it and/or modify it
61541Srgrimes * under the terms of the GNU General Public License version 2 only, as
71541Srgrimes * published by the Free Software Foundation.
81541Srgrimes *
91541Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT
101541Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
111541Srgrimes * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
121541Srgrimes * version 2 for more details (a copy is included in the LICENSE file that
131541Srgrimes * accompanied this code).
141541Srgrimes *
151541Srgrimes * You should have received a copy of the GNU General Public License version
161541Srgrimes * 2 along with this work; if not, write to the Free Software Foundation,
171541Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
181541Srgrimes *
191541Srgrimes * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
201541Srgrimes * CA 95054 USA or visit www.sun.com if you need additional information or
211541Srgrimes * have any questions.
221541Srgrimes *
231541Srgrimes */
241541Srgrimes
251541Srgrimes# include "incls/_precompiled.incl"
261541Srgrimes# include "incls/_c1_LIRGenerator_x86.cpp.incl"
271541Srgrimes
281541Srgrimes#ifdef ASSERT
291541Srgrimes#define __ gen()->lir(__FILE__, __LINE__)->
301541Srgrimes#else
311541Srgrimes#define __ gen()->lir()->
321541Srgrimes#endif
331541Srgrimes
341541Srgrimes// Item will be loaded into a byte register; Intel only
351541Srgrimesvoid LIRItem::load_byte_item() {
3622521Sdyson  load_item();
3747964Smckusick  LIR_Opr res = result();
381541Srgrimes
391541Srgrimes  if (!res->is_virtual() || !_gen->is_vreg_flag_set(res, LIRGenerator::byte_reg)) {
4022521Sdyson    // make sure that it is a byte register
411541Srgrimes    assert(!value()->type()->is_float() && !value()->type()->is_double(),
421541Srgrimes           "can't load floats in byte register");
431541Srgrimes    LIR_Opr reg = _gen->rlock_byte(T_BYTE);
443305Sphk    __ move(res, reg);
451541Srgrimes
461541Srgrimes    _result = reg;
471541Srgrimes  }
481541Srgrimes}
491541Srgrimes
501541Srgrimes
511541Srgrimesvoid LIRItem::load_nonconstant() {
5212662Sdg  LIR_Opr r = value()->operand();
5325930Sdfr  if (r->is_constant()) {
5425930Sdfr    _result = r;
5525930Sdfr  } else {
5625930Sdfr    load_item();
5725930Sdfr  }
581541Srgrimes}
591541Srgrimes
609336Sdfr//--------------------------------------------------------------
611541Srgrimes//               LIRGenerator
621541Srgrimes//--------------------------------------------------------------
631541Srgrimes
649336Sdfr
651541SrgrimesLIR_Opr LIRGenerator::exceptionOopOpr() { return FrameMap::rax_oop_opr; }
6612911SphkLIR_Opr LIRGenerator::exceptionPcOpr()  { return FrameMap::rdx_opr; }
6712588SbdeLIR_Opr LIRGenerator::divInOpr()        { return FrameMap::rax_opr; }
6812588SbdeLIR_Opr LIRGenerator::divOutOpr()       { return FrameMap::rax_opr; }
691541SrgrimesLIR_Opr LIRGenerator::remOutOpr()       { return FrameMap::rdx_opr; }
7042957SdillonLIR_Opr LIRGenerator::shiftCountOpr()   { return FrameMap::rcx_opr; }
719336SdfrLIR_Opr LIRGenerator::syncTempOpr()     { return FrameMap::rax_opr; }
721541SrgrimesLIR_Opr LIRGenerator::getThreadTemp()   { return LIR_OprFact::illegalOpr; }
731541Srgrimes
7425930Sdfr
7525930SdfrLIR_Opr LIRGenerator::result_register_for(ValueType* type, bool callee) {
7625930Sdfr  LIR_Opr opr;
7725930Sdfr  switch (type->tag()) {
7836563Speter    case intTag:     opr = FrameMap::rax_opr;          break;
7936563Speter    case objectTag:  opr = FrameMap::rax_oop_opr;      break;
8036563Speter    case longTag:    opr = FrameMap::long0_opr;        break;
8136563Speter    case floatTag:   opr = UseSSE >= 1 ? FrameMap::xmm0_float_opr  : FrameMap::fpu0_float_opr;  break;
8236563Speter    case doubleTag:  opr = UseSSE >= 2 ? FrameMap::xmm0_double_opr : FrameMap::fpu0_double_opr;  break;
8336563Speter
8436563Speter    case addressTag:
8525930Sdfr    default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr;
8646349Salc  }
8732755Sdyson
8832755Sdyson  assert(opr->type_field() == as_OprType(as_BasicType(type)), "type mismatch");
8932755Sdyson  return opr;
9034206Sdyson}
9136563Speter
9236563Speter
9336563SpeterLIR_Opr LIRGenerator::rlock_byte(BasicType type) {
9436563Speter  LIR_Opr reg = new_register(T_INT);
9536563Speter  set_vreg_flag(reg, LIRGenerator::byte_reg);
9625930Sdfr  return reg;
9736563Speter}
9836563Speter
9936563Speter
10036563Speter//--------- loading items into registers --------------------------------
10136563Speter
10236563Speter
10336563Speter// i486 instructions can inline constants
10436563Speterbool LIRGenerator::can_store_as_constant(Value v, BasicType type) const {
10532286Sdyson  if (type == T_SHORT || type == T_CHAR) {
10636563Speter    // there is no immediate move of word values in asembler_i486.?pp
10725930Sdfr    return false;
10825930Sdfr  }
10936563Speter  Constant* c = v->as_Constant();
11036563Speter  if (c && c->state() == NULL) {
11136563Speter    // constants of any type can be stored directly, except for
11246349Salc    // unloaded object constants.
11346349Salc    return true;
11446349Salc  }
11534206Sdyson  return false;
11646349Salc}
11746349Salc
11846349Salc
11946349Salcbool LIRGenerator::can_inline_as_constant(Value v) const {
12046349Salc  if (v->type()->tag() == longTag) return false;
12146349Salc  return v->type()->tag() != objectTag ||
12246349Salc    (v->type()->is_constant() && v->type()->as_ObjectType()->constant_value()->is_null_object());
12346349Salc}
12446349Salc
12546349Salc
12646349Salcbool LIRGenerator::can_inline_as_constant(LIR_Const* c) const {
12746349Salc  if (c->type() == T_LONG) return false;
12846349Salc  return c->type() != T_OBJECT || c->as_jobject() == NULL;
12946349Salc}
13046349Salc
13146349Salc
13246349SalcLIR_Opr LIRGenerator::safepoint_poll_register() {
13346349Salc  return LIR_OprFact::illegalOpr;
13446349Salc}
13546349Salc
13634206Sdyson
13734206SdysonLIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
13834206Sdyson                                            int shift, int disp, BasicType type) {
13942957Sdillon  assert(base->is_register(), "must be");
14025930Sdfr  if (index->is_constant()) {
14134206Sdyson    return new LIR_Address(base,
14236563Speter                           (index->as_constant_ptr()->as_jint() << shift) + disp,
14334206Sdyson                           type);
14432755Sdyson  } else {
14536563Speter    return new LIR_Address(base, index, (LIR_Address::Scale)shift, disp, type);
14632755Sdyson  }
14732755Sdyson}
14836563Speter
14936563Speter
15032755SdysonLIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr,
15132755Sdyson                                              BasicType type, bool needs_card_mark) {
15236563Speter  int offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type);
15325930Sdfr
15436563Speter  LIR_Address* addr;
15534206Sdyson  if (index_opr->is_constant()) {
15632755Sdyson    int elem_size = type2aelembytes(type);
15742957Sdillon    addr = new LIR_Address(array_opr,
15834206Sdyson                           offset_in_bytes + index_opr->as_jint() * elem_size, type);
15942957Sdillon  } else {
16042957Sdillon#ifdef _LP64
16142957Sdillon    if (index_opr->type() == T_INT) {
16242957Sdillon      LIR_Opr tmp = new_register(T_LONG);
16342957Sdillon      __ convert(Bytecodes::_i2l, index_opr, tmp);
16442957Sdillon      index_opr = tmp;
16534206Sdyson    }
16642957Sdillon#endif // _LP64
16734206Sdyson    addr =  new LIR_Address(array_opr,
16845347Sjulian                            index_opr,
16945347Sjulian                            LIR_Address::scale(type),
17045347Sjulian                            offset_in_bytes, type);
17145347Sjulian  }
17245347Sjulian  if (needs_card_mark) {
17345347Sjulian    // This store will need a precise card mark, so go ahead and
17436563Speter    // compute the full adddres instead of computing once for the
17534206Sdyson    // store and again for the card mark.
17634206Sdyson    LIR_Opr tmp = new_pointer_register();
17734206Sdyson    __ leal(LIR_OprFact::address(addr), tmp);
17834206Sdyson    return new LIR_Address(tmp, 0, type);
17936563Speter  } else {
18034206Sdyson    return addr;
18134206Sdyson  }
18234206Sdyson}
18334206Sdyson
18445347Sjulian
18545347Sjulianvoid LIRGenerator::increment_counter(address counter, int step) {
18645347Sjulian  LIR_Opr pointer = new_pointer_register();
18734206Sdyson  __ move(LIR_OprFact::intptrConst(counter), pointer);
18834206Sdyson  LIR_Address* addr = new LIR_Address(pointer, 0, T_INT);
18945347Sjulian  increment_counter(addr, step);
19045347Sjulian}
19146349Salc
19245347Sjulian
19346349Salcvoid LIRGenerator::increment_counter(LIR_Address* addr, int step) {
19445347Sjulian  __ add((LIR_Opr)addr, LIR_OprFact::intConst(step), (LIR_Opr)addr);
19546349Salc}
19646349Salc
19734206Sdyson
19834206Sdysonvoid LIRGenerator::cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info) {
19925930Sdfr  __ cmp_mem_int(condition, base, disp, c, info);
20034206Sdyson}
20134206Sdyson
20234206Sdyson
20334206Sdysonvoid LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, int disp, BasicType type, CodeEmitInfo* info) {
20434206Sdyson  __ cmp_reg_mem(condition, reg, new LIR_Address(base, disp, type), info);
20534206Sdyson}
20634206Sdyson
20734206Sdyson
20834206Sdysonvoid LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, LIR_Opr disp, BasicType type, CodeEmitInfo* info) {
20934206Sdyson  __ cmp_reg_mem(condition, reg, new LIR_Address(base, disp, type), info);
21034206Sdyson}
21134206Sdyson
21234206Sdyson
21334206Sdysonbool LIRGenerator::strength_reduce_multiply(LIR_Opr left, int c, LIR_Opr result, LIR_Opr tmp) {
21434206Sdyson  if (tmp->is_valid()) {
21534206Sdyson    if (is_power_of_2(c + 1)) {
21634206Sdyson      __ move(left, tmp);
21738799Sdfr      __ shift_left(left, log2_intptr(c + 1), left);
21834206Sdyson      __ sub(left, tmp, result);
21934206Sdyson      return true;
22034206Sdyson    } else if (is_power_of_2(c - 1)) {
22125930Sdfr      __ move(left, tmp);
22225930Sdfr      __ shift_left(left, log2_intptr(c - 1), left);
22325930Sdfr      __ add(left, tmp, result);
22425930Sdfr      return true;
22525930Sdfr    }
22625930Sdfr  }
22734206Sdyson  return false;
22834096Smsmith}
22934096Smsmith
23034096Smsmith
23136563Spetervoid LIRGenerator::store_stack_parameter (LIR_Opr item, ByteSize offset_from_sp) {
23236563Speter  BasicType type = item->type();
23336563Speter  __ store(item, new LIR_Address(FrameMap::rsp_opr, in_bytes(offset_from_sp), type));
23436563Speter}
23536563Speter
23636563Speter//----------------------------------------------------------------------
23736563Speter//             visitor functions
23836563Speter//----------------------------------------------------------------------
23934096Smsmith
24034206Sdyson
24134206Sdysonvoid LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
24234206Sdyson  assert(x->is_root(),"");
24334206Sdyson  bool needs_range_check = true;
24436563Speter  bool use_length = x->length() != NULL;
24546349Salc  bool obj_store = x->elt_type() == T_ARRAY || x->elt_type() == T_OBJECT;
24634206Sdyson  bool needs_store_check = obj_store && (x->value()->as_Constant() == NULL ||
24736563Speter                                         !get_jobject_constant(x->value())->is_null_object());
24836563Speter
24936563Speter  LIRItem array(x->array(), this);
25036563Speter  LIRItem index(x->index(), this);
25146349Salc  LIRItem value(x->value(), this);
25236563Speter  LIRItem length(this);
25334206Sdyson
25436563Speter  array.load_item();
25546349Salc  index.load_nonconstant();
25636563Speter
25736563Speter  if (use_length) {
25836563Speter    needs_range_check = x->compute_needs_range_check();
25936563Speter    if (needs_range_check) {
26036563Speter      length.set_instruction(x->length());
26134206Sdyson      length.load_item();
26236563Speter    }
26346349Salc  }
26434206Sdyson  if (needs_store_check) {
26536563Speter    value.load_item();
26636563Speter  } else {
26736563Speter    value.load_for_store(x->elt_type());
26834206Sdyson  }
26934206Sdyson
27034206Sdyson  set_no_result(x);
27134206Sdyson
27234206Sdyson  // the CodeEmitInfo must be duplicated for each different
27334206Sdyson  // LIR-instruction because spilling can occur anywhere between two
27446349Salc  // instructions and so the debug information must be different
27546349Salc  CodeEmitInfo* range_check_info = state_for(x);
27646349Salc  CodeEmitInfo* null_check_info = NULL;
27746349Salc  if (x->needs_null_check()) {
27846349Salc    null_check_info = new CodeEmitInfo(range_check_info);
27946349Salc  }
28046349Salc
28146349Salc  // emit array address setup early so it schedules better
28246349Salc  LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), obj_store);
28346349Salc
28434206Sdyson  if (GenerateRangeChecks && needs_range_check) {
28534206Sdyson    if (use_length) {
28634206Sdyson      __ cmp(lir_cond_belowEqual, length.result(), index.result());
28742957Sdillon      __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result()));
28834206Sdyson    } else {
28934206Sdyson      array_range_check(array.result(), index.result(), null_check_info, range_check_info);
29036563Speter      // range_check also does the null check
29134206Sdyson      null_check_info = NULL;
29234206Sdyson    }
29336563Speter  }
29434206Sdyson
29534206Sdyson  if (GenerateArrayStoreCheck && needs_store_check) {
29646349Salc    LIR_Opr tmp1 = new_register(objectType);
29736563Speter    LIR_Opr tmp2 = new_register(objectType);
29834206Sdyson    LIR_Opr tmp3 = new_register(objectType);
29934206Sdyson
30036563Speter    CodeEmitInfo* store_check_info = new CodeEmitInfo(range_check_info);
30134206Sdyson    __ store_check(value.result(), array.result(), tmp1, tmp2, tmp3, store_check_info);
30234206Sdyson  }
30334206Sdyson
30434206Sdyson  if (obj_store) {
30534206Sdyson    // Needs GC write barriers.
30634206Sdyson    pre_barrier(LIR_OprFact::address(array_addr), false, NULL);
30736563Speter    __ move(value.result(), array_addr, null_check_info);
30834206Sdyson    // Seems to be a precise
30934206Sdyson    post_barrier(LIR_OprFact::address(array_addr), value.result());
31042957Sdillon  } else {
31134206Sdyson    __ move(value.result(), array_addr, null_check_info);
31234206Sdyson  }
31336563Speter}
31434206Sdyson
31534206Sdyson
31636563Spetervoid LIRGenerator::do_MonitorEnter(MonitorEnter* x) {
31734206Sdyson  assert(x->is_root(),"");
31834206Sdyson  LIRItem obj(x->obj(), this);
31936563Speter  obj.load_item();
32034206Sdyson
32136563Speter  set_no_result(x);
32234096Smsmith
32334096Smsmith  // "lock" stores the address of the monitor stack slot, so this is not an oop
32434096Smsmith  LIR_Opr lock = new_register(T_INT);
3251541Srgrimes  // Need a scratch register for biased locking on x86
3261541Srgrimes  LIR_Opr scratch = LIR_OprFact::illegalOpr;
3271549Srgrimes  if (UseBiasedLocking) {
32846349Salc    scratch = new_register(T_INT);
3291541Srgrimes  }
3301541Srgrimes
3311541Srgrimes  CodeEmitInfo* info_for_exception = NULL;
3321541Srgrimes  if (x->needs_null_check()) {
3331541Srgrimes    info_for_exception = state_for(x, x->lock_stack_before());
3341541Srgrimes  }
33541791Sdt  // this CodeEmitInfo must not have the xhandlers because here the
3361549Srgrimes  // object is already locked (xhandlers expect object to be unlocked)
3371541Srgrimes  CodeEmitInfo* info = state_for(x, x->state(), true);
3381541Srgrimes  monitor_enter(obj.result(), lock, syncTempOpr(), scratch,
3399336Sdfr                        x->monitor_no(), info_for_exception, info);
3405455Sdg}
34146349Salc
34246349Salc
3431541Srgrimesvoid LIRGenerator::do_MonitorExit(MonitorExit* x) {
3441541Srgrimes  assert(x->is_root(),"");
3451541Srgrimes
3461541Srgrimes  LIRItem obj(x->obj(), this);
3471541Srgrimes  obj.dont_load_item();
3481541Srgrimes
3491541Srgrimes  LIR_Opr lock = new_register(T_INT);
35036473Speter  LIR_Opr obj_temp = new_register(T_INT);
3511541Srgrimes  set_no_result(x);
3521541Srgrimes  monitor_exit(obj_temp, lock, syncTempOpr(), x->monitor_no());
35336176Speter}
35436176Speter
3559336Sdfr
35636473Speter// _ineg, _lneg, _fneg, _dneg
35736473Spetervoid LIRGenerator::do_NegateOp(NegateOp* x) {
35836473Speter  LIRItem value(x->x(), this);
3599428Sdfr  value.set_destroys_register();
3601541Srgrimes  value.load_item();
3611541Srgrimes  LIR_Opr reg = rlock(x);
3621541Srgrimes  __ negate(value.result(), reg);
3631541Srgrimes
3641541Srgrimes  set_result(x, round_item(reg));
3651541Srgrimes}
3661541Srgrimes
3671541Srgrimes
3681541Srgrimes// for  _fadd, _fmul, _fsub, _fdiv, _frem
3691541Srgrimes//      _dadd, _dmul, _dsub, _ddiv, _drem
3701541Srgrimesvoid LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) {
3711541Srgrimes  LIRItem left(x->x(),  this);
3721541Srgrimes  LIRItem right(x->y(), this);
3731541Srgrimes  LIRItem* left_arg  = &left;
3741541Srgrimes  LIRItem* right_arg = &right;
3751541Srgrimes  assert(!left.is_stack() || !right.is_stack(), "can't both be memory operands");
3761541Srgrimes  bool must_load_both = (x->op() == Bytecodes::_frem || x->op() == Bytecodes::_drem);
37710219Sdfr  if (left.is_register() || x->x()->type()->is_constant() || must_load_both) {
3781541Srgrimes    left.load_item();
3799336Sdfr  } else {
3809336Sdfr    left.dont_load_item();
3819336Sdfr  }
3829336Sdfr
3833305Sphk  // do not load right operand if it is a constant.  only 0 and 1 are
3843305Sphk  // loaded because there are special instructions for loading them
3851541Srgrimes  // without memory access (not needed for SSE2 instructions)
3861541Srgrimes  bool must_load_right = false;
3871541Srgrimes  if (right.is_constant()) {
3883305Sphk    LIR_Const* c = right.result()->as_constant_ptr();
3893305Sphk    assert(c != NULL, "invalid constant");
3901541Srgrimes    assert(c->type() == T_FLOAT || c->type() == T_DOUBLE, "invalid type");
39118397Snate
3921541Srgrimes    if (c->type() == T_FLOAT) {
3933305Sphk      must_load_right = UseSSE < 1 && (c->is_one_float() || c->is_zero_float());
3943305Sphk    } else {
3951541Srgrimes      must_load_right = UseSSE < 2 && (c->is_one_double() || c->is_zero_double());
39618397Snate    }
3979336Sdfr  }
3989336Sdfr
3993305Sphk  if (must_load_both) {
4003305Sphk    // frem and drem destroy also right operand, so move it to a new register
4011541Srgrimes    right.set_destroys_register();
40218397Snate    right.load_item();
4031541Srgrimes  } else if (right.is_register() || must_load_right) {
4041541Srgrimes    right.load_item();
4051541Srgrimes  } else {
4061541Srgrimes    right.dont_load_item();
4071541Srgrimes  }
4081541Srgrimes  LIR_Opr reg = rlock(x);
4091541Srgrimes  LIR_Opr tmp = LIR_OprFact::illegalOpr;
4101541Srgrimes  if (x->is_strictfp() && (x->op() == Bytecodes::_dmul || x->op() == Bytecodes::_ddiv)) {
4111541Srgrimes    tmp = new_register(T_DOUBLE);
4129336Sdfr  }
4131541Srgrimes
4149336Sdfr  if ((UseSSE >= 1 && x->op() == Bytecodes::_frem) || (UseSSE >= 2 && x->op() == Bytecodes::_drem)) {
4151541Srgrimes    // special handling for frem and drem: no SSE instruction, so must use FPU with temporary fpu stack slots
4161541Srgrimes    LIR_Opr fpu0, fpu1;
4171541Srgrimes    if (x->op() == Bytecodes::_frem) {
4181541Srgrimes      fpu0 = LIR_OprFact::single_fpu(0);
4191541Srgrimes      fpu1 = LIR_OprFact::single_fpu(1);
4201541Srgrimes    } else {
4219336Sdfr      fpu0 = LIR_OprFact::double_fpu(0);
4229336Sdfr      fpu1 = LIR_OprFact::double_fpu(1);
4233305Sphk    }
4243305Sphk    __ move(right.result(), fpu1); // order of left and right operand is important!
4251541Srgrimes    __ move(left.result(), fpu0);
4261541Srgrimes    __ rem (fpu0, fpu1, fpu0);
4271541Srgrimes    __ move(fpu0, reg);
4281541Srgrimes
4299336Sdfr  } else {
4303305Sphk    arithmetic_op_fpu(x->op(), reg, left.result(), right.result(), x->is_strictfp(), tmp);
4313305Sphk  }
4321541Srgrimes
4331541Srgrimes  set_result(x, round_item(reg));
4341541Srgrimes}
4351541Srgrimes
4361541Srgrimes
4371541Srgrimes// for  _ladd, _lmul, _lsub, _ldiv, _lrem
4389336Sdfrvoid LIRGenerator::do_ArithmeticOp_Long(ArithmeticOp* x) {
4391541Srgrimes  if (x->op() == Bytecodes::_ldiv || x->op() == Bytecodes::_lrem ) {
4409336Sdfr    // long division is implemented as a direct call into the runtime
4411541Srgrimes    LIRItem left(x->x(), this);
4421541Srgrimes    LIRItem right(x->y(), this);
4433305Sphk
44422521Sdyson    // the check for division by zero destroys the right operand
4453305Sphk    right.set_destroys_register();
4461541Srgrimes
4471541Srgrimes    BasicTypeList signature(2);
4481541Srgrimes    signature.append(T_LONG);
4491541Srgrimes    signature.append(T_LONG);
4501541Srgrimes    CallingConvention* cc = frame_map()->c_calling_convention(&signature);
4511541Srgrimes
4529336Sdfr    // check for division by zero (destroys registers of right operand!)
4531541Srgrimes    CodeEmitInfo* info = state_for(x);
4541541Srgrimes
4551541Srgrimes    const LIR_Opr result_reg = result_register_for(x->type());
4561541Srgrimes    left.load_item_force(cc->at(1));
4579336Sdfr    right.load_item();
4581541Srgrimes
45913612Smpp    __ move(right.result(), cc->at(0));
4605455Sdg
4611541Srgrimes    __ cmp(lir_cond_equal, right.result(), LIR_OprFact::longConst(0));
4621541Srgrimes    __ branch(lir_cond_equal, T_LONG, new DivByZeroStub(info));
4631541Srgrimes
4641541Srgrimes    address entry;
4658692Sdg    switch (x->op()) {
4661541Srgrimes    case Bytecodes::_lrem:
4675455Sdg      entry = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
46846580Sphk      break; // check if dividend is 0 is done elsewhere
4695455Sdg    case Bytecodes::_ldiv:
4705455Sdg      entry = CAST_FROM_FN_PTR(address, SharedRuntime::ldiv);
4711541Srgrimes      break; // check if dividend is 0 is done elsewhere
4721541Srgrimes    case Bytecodes::_lmul:
47322521Sdyson      entry = CAST_FROM_FN_PTR(address, SharedRuntime::lmul);
4745471Sdg      break;
4751541Srgrimes    default:
4761541Srgrimes      ShouldNotReachHere();
4771541Srgrimes    }
4781541Srgrimes
4791541Srgrimes    LIR_Opr result = rlock_result(x);
48046349Salc    __ call_runtime_leaf(entry, getThreadTemp(), result_reg, cc->args());
48146349Salc    __ move(result_reg, result);
48246349Salc  } else if (x->op() == Bytecodes::_lmul) {
48346349Salc    // missing test if instr is commutative and if we should swap
48446349Salc    LIRItem left(x->x(), this);
4851541Srgrimes    LIRItem right(x->y(), this);
48646349Salc
48746349Salc    // right register is destroyed by the long mul, so it must be
48846349Salc    // copied to a new register.
48946349Salc    right.set_destroys_register();
49046349Salc
49146349Salc    left.load_item();
4928692Sdg    right.load_item();
49346349Salc
49446349Salc    LIR_Opr reg = FrameMap::long0_opr;
4957871Sdg    arithmetic_op_long(x->op(), reg, left.result(), right.result(), NULL);
4967871Sdg    LIR_Opr result = rlock_result(x);
49742957Sdillon    __ move(reg, result);
49825930Sdfr  } else {
49946349Salc    // missing test if instr is commutative and if we should swap
50046349Salc    LIRItem left(x->x(), this);
50125930Sdfr    LIRItem right(x->y(), this);
50246349Salc
5037871Sdg    left.load_item();
50432755Sdyson    // dont load constants to save register
50532755Sdyson    right.load_nonconstant();
50632755Sdyson    rlock_result(x);
50732755Sdyson    arithmetic_op_long(x->op(), x->operand(), left.result(), right.result(), NULL);
50832755Sdyson  }
50932755Sdyson}
51032755Sdyson
5111541Srgrimes
51246349Salc
51346349Salc// for: _iadd, _imul, _isub, _idiv, _irem
51446349Salcvoid LIRGenerator::do_ArithmeticOp_Int(ArithmeticOp* x) {
51546349Salc  if (x->op() == Bytecodes::_idiv || x->op() == Bytecodes::_irem) {
51646349Salc    // The requirements for division and modulo
51746349Salc    // input : rax,: dividend                         min_int
51846349Salc    //         reg: divisor   (may not be rax,/rdx)   -1
51946349Salc    //
52046349Salc    // output: rax,: quotient  (= rax, idiv reg)       min_int
52146349Salc    //         rdx: remainder (= rax, irem reg)       0
52246349Salc
52346349Salc    // rax, and rdx will be destroyed
52446349Salc
5251541Srgrimes    // Note: does this invalidate the spec ???
5261541Srgrimes    LIRItem right(x->y(), this);
5271541Srgrimes    LIRItem left(x->x() , this);   // visit left second, so that the is_register test is valid
5281541Srgrimes
5291541Srgrimes    // call state_for before load_item_force because state_for may
5301541Srgrimes    // force the evaluation of other instructions that are needed for
5311541Srgrimes    // correct debug info.  Otherwise the live range of the fix
5327871Sdg    // register might be too long.
53332755Sdyson    CodeEmitInfo* info = state_for(x);
53432755Sdyson
53532755Sdyson    left.load_item_force(divInOpr());
53632755Sdyson
53732755Sdyson    right.load_item();
53832755Sdyson
53932755Sdyson    LIR_Opr result = rlock_result(x);
54032755Sdyson    LIR_Opr result_reg;
5411541Srgrimes    if (x->op() == Bytecodes::_idiv) {
5421541Srgrimes      result_reg = divOutOpr();
5431541Srgrimes    } else {
5441541Srgrimes      result_reg = remOutOpr();
5451541Srgrimes    }
5461541Srgrimes
54724577Sdfr    if (!ImplicitDiv0Checks) {
54824577Sdfr      __ cmp(lir_cond_equal, right.result(), LIR_OprFact::intConst(0));
54924577Sdfr      __ branch(lir_cond_equal, T_INT, new DivByZeroStub(info));
55024577Sdfr    }
55136979Sbde    LIR_Opr tmp = FrameMap::rdx_opr; // idiv and irem use rdx in their implementation
5529336Sdfr    if (x->op() == Bytecodes::_irem) {
5535455Sdg      __ irem(left.result(), right.result(), result_reg, tmp, info);
5541541Srgrimes    } else if (x->op() == Bytecodes::_idiv) {
5559336Sdfr      __ idiv(left.result(), right.result(), result_reg, tmp, info);
5567871Sdg    } else {
5579336Sdfr      ShouldNotReachHere();
5589336Sdfr    }
5599336Sdfr
56032912Stegge    __ move(result_reg, result);
56132912Stegge  } else {
56232912Stegge    // missing test if instr is commutative and if we should swap
56332755Sdyson    LIRItem left(x->x(),  this);
56446349Salc    LIRItem right(x->y(), this);
56532755Sdyson    LIRItem* left_arg = &left;
56632755Sdyson    LIRItem* right_arg = &right;
56732755Sdyson    if (x->is_commutative() && left.is_stack() && right.is_register()) {
56832755Sdyson      // swap them if left is real stack (or cached) and right is real register(not cached)
56932755Sdyson      left_arg = &right;
57032755Sdyson      right_arg = &left;
57132755Sdyson    }
57246349Salc
57346349Salc    left_arg->load_item();
57446349Salc
57546349Salc    // do not need to load right, as we can handle stack and constants
57632755Sdyson    if (x->op() == Bytecodes::_imul ) {
57732755Sdyson      // check if we can use shift instead
57832755Sdyson      bool use_constant = false;
57932755Sdyson      bool use_tmp = false;
58024577Sdfr      if (right_arg->is_constant()) {
58132755Sdyson        int iconst = right_arg->get_jint_constant();
58232755Sdyson        if (iconst > 0) {
58332755Sdyson          if (is_power_of_2(iconst)) {
58446349Salc            use_constant = true;
58546349Salc          } else if (is_power_of_2(iconst - 1) || is_power_of_2(iconst + 1)) {
58646349Salc            use_constant = true;
58746349Salc            use_tmp = true;
58846349Salc          }
58946349Salc        }
59046349Salc      }
59146349Salc      if (use_constant) {
59246349Salc        right_arg->dont_load_item();
59346349Salc      } else {
59446349Salc        right_arg->load_item();
59546349Salc      }
59646349Salc      LIR_Opr tmp = LIR_OprFact::illegalOpr;
59746349Salc      if (use_tmp) {
59846349Salc        tmp = new_register(T_INT);
59946349Salc      }
60046349Salc      rlock_result(x);
60146349Salc
60232755Sdyson      arithmetic_op_int(x->op(), x->operand(), left_arg->result(), right_arg->result(), tmp);
6031541Srgrimes    } else {
60432912Stegge      right_arg->dont_load_item();
60546349Salc      rlock_result(x);
60646349Salc      LIR_Opr tmp = LIR_OprFact::illegalOpr;
60746349Salc      arithmetic_op_int(x->op(), x->operand(), left_arg->result(), right_arg->result(), tmp);
60846349Salc    }
60946349Salc  }
61032912Stegge}
6119336Sdfr
6121541Srgrimes
6131541Srgrimesvoid LIRGenerator::do_ArithmeticOp(ArithmeticOp* x) {
6141541Srgrimes  // when an operand with use count 1 is the left operand, then it is
6151541Srgrimes  // likely that no move for 2-operand-LIR-form is necessary
6161541Srgrimes  if (x->is_commutative() && x->y()->as_Constant() == NULL && x->x()->use_count() > x->y()->use_count()) {
6179336Sdfr    x->swap_operands();
6181541Srgrimes  }
6191541Srgrimes
62039782Smckusick  ValueTag tag = x->type()->tag();
6219336Sdfr  assert(x->x()->type()->tag() == tag && x->y()->type()->tag() == tag, "wrong parameters");
6229336Sdfr  switch (tag) {
6239336Sdfr    case floatTag:
6249336Sdfr    case doubleTag:  do_ArithmeticOp_FPU(x);  return;
6259336Sdfr    case longTag:    do_ArithmeticOp_Long(x); return;
6261541Srgrimes    case intTag:     do_ArithmeticOp_Int(x);  return;
6278692Sdg  }
6281541Srgrimes  ShouldNotReachHere();
6295455Sdg}
63046580Sphk
6316148Sdg
6325455Sdg// _ishl, _lshl, _ishr, _lshr, _iushr, _lushr
6331541Srgrimesvoid LIRGenerator::do_ShiftOp(ShiftOp* x) {
6341541Srgrimes  // count must always be in rcx
6355471Sdg  LIRItem value(x->x(), this);
6365471Sdg  LIRItem count(x->y(), this);
6371541Srgrimes
6381541Srgrimes  ValueTag elemType = x->type()->tag();
6391541Srgrimes  bool must_load_count = !count.is_constant() || elemType == longTag;
64026469Sdfr  if (must_load_count) {
64146349Salc    // count for long must be in register
64246349Salc    count.load_item_force(shiftCountOpr());
64346349Salc  } else {
64446349Salc    count.dont_load_item();
64546349Salc  }
64646349Salc  value.load_item();
64746349Salc  LIR_Opr reg = rlock_result(x);
64846349Salc
64946349Salc  shift_op(x->op(), reg, value.result(), count.result(), LIR_OprFact::illegalOpr);
65046349Salc}
65126469Sdfr
65226469Sdfr
65346349Salc// _iand, _land, _ior, _lor, _ixor, _lxor
65446349Salcvoid LIRGenerator::do_LogicOp(LogicOp* x) {
6551541Srgrimes  // when an operand with use count 1 is the left operand, then it is
6563305Sphk  // likely that no move for 2-operand-LIR-form is necessary
6579336Sdfr  if (x->is_commutative() && x->y()->as_Constant() == NULL && x->x()->use_count() > x->y()->use_count()) {
6583305Sphk    x->swap_operands();
6591541Srgrimes  }
6601541Srgrimes
6611541Srgrimes  LIRItem left(x->x(), this);
66234206Sdyson  LIRItem right(x->y(), this);
6631541Srgrimes
6641541Srgrimes  left.load_item();
6651541Srgrimes  right.load_nonconstant();
6661541Srgrimes  LIR_Opr reg = rlock_result(x);
6671541Srgrimes
6681541Srgrimes  logic_op(x->op(), reg, left.result(), right.result());
6691541Srgrimes}
6701541Srgrimes
67146349Salc
67246349Salc
67346349Salc// _lcmp, _fcmpl, _fcmpg, _dcmpl, _dcmpg
67446349Salcvoid LIRGenerator::do_CompareOp(CompareOp* x) {
6759336Sdfr  LIRItem left(x->x(), this);
6769336Sdfr  LIRItem right(x->y(), this);
6771541Srgrimes  ValueTag tag = x->x()->type()->tag();
6783305Sphk  if (tag == longTag) {
6799336Sdfr    left.set_destroys_register();
6803305Sphk  }
68132755Sdyson  left.load_item();
6821541Srgrimes  right.load_item();
6831541Srgrimes  LIR_Opr reg = rlock_result(x);
6841541Srgrimes
6851541Srgrimes  if (x->x()->type()->is_float_kind()) {
6861541Srgrimes    Bytecodes::Code code = x->op();
6871541Srgrimes    __ fcmp2int(left.result(), right.result(), reg, (code == Bytecodes::_fcmpl || code == Bytecodes::_dcmpl));
6881541Srgrimes  } else if (x->x()->type()->tag() == longTag) {
6891549Srgrimes    __ lcmp2int(left.result(), right.result(), reg);
6901541Srgrimes  } else {
6911541Srgrimes    Unimplemented();
6921541Srgrimes  }
6931541Srgrimes}
6941541Srgrimes
6951541Srgrimes
6961541Srgrimesvoid LIRGenerator::do_AttemptUpdate(Intrinsic* x) {
6971541Srgrimes  assert(x->number_of_arguments() == 3, "wrong type");
69846349Salc  LIRItem obj       (x->argument_at(0), this);  // AtomicLong object
69946349Salc  LIRItem cmp_value (x->argument_at(1), this);  // value to compare with field
7001541Srgrimes  LIRItem new_value (x->argument_at(2), this);  // replace field with new_value if it matches cmp_value
70146349Salc
7021541Srgrimes  // compare value must be in rdx,eax (hi,lo); may be destroyed by cmpxchg8 instruction
70346349Salc  cmp_value.load_item_force(FrameMap::long0_opr);
7041541Srgrimes
7051541Srgrimes  // new value must be in rcx,ebx (hi,lo)
7061541Srgrimes  new_value.load_item_force(FrameMap::long1_opr);
7079336Sdfr
70811921Sphk  // object pointer register is overwritten with field address
70946349Salc  obj.load_item();
7109336Sdfr
7111541Srgrimes  // generate compare-and-swap; produces zero condition if swap occurs
7121541Srgrimes  int value_offset = sun_misc_AtomicLongCSImpl::value_offset();
7131541Srgrimes  LIR_Opr addr = obj.result();
7141541Srgrimes  __ add(addr, LIR_OprFact::intConst(value_offset), addr);
7151541Srgrimes  LIR_Opr t1 = LIR_OprFact::illegalOpr;  // no temp needed
7161541Srgrimes  LIR_Opr t2 = LIR_OprFact::illegalOpr;  // no temp needed
7171541Srgrimes  __ cas_long(addr, cmp_value.result(), new_value.result(), t1, t2);
7181541Srgrimes
7191541Srgrimes  // generate conditional move of boolean result
7201541Srgrimes  LIR_Opr result = rlock_result(x);
7211541Srgrimes  __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result);
7221541Srgrimes}
7231541Srgrimes
72436176Speter
72536176Spetervoid LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
7269336Sdfr  assert(x->number_of_arguments() == 4, "wrong type");
7271541Srgrimes  LIRItem obj   (x->argument_at(0), this);  // object
7281541Srgrimes  LIRItem offset(x->argument_at(1), this);  // offset of field
7291541Srgrimes  LIRItem cmp   (x->argument_at(2), this);  // value to compare with field
7303305Sphk  LIRItem val   (x->argument_at(3), this);  // replace field with val if matches cmp
7313305Sphk
7321541Srgrimes  assert(obj.type()->tag() == objectTag, "invalid type");
7331541Srgrimes
7341541Srgrimes  // In 64bit the type can be long, sparc doesn't have this assert
7351541Srgrimes  // assert(offset.type()->tag() == intTag, "invalid type");
7363305Sphk
7373305Sphk  assert(cmp.type()->tag() == type->tag(), "invalid type");
7381541Srgrimes  assert(val.type()->tag() == type->tag(), "invalid type");
7391541Srgrimes
7401541Srgrimes  // get address of field
7411541Srgrimes  obj.load_item();
7421541Srgrimes  offset.load_nonconstant();
7431541Srgrimes
74436473Speter  if (type == objectType) {
74536473Speter    cmp.load_item_force(FrameMap::rax_oop_opr);
7461541Srgrimes    val.load_item();
7471541Srgrimes  } else if (type == intType) {
7481541Srgrimes    cmp.load_item_force(FrameMap::rax_opr);
7491541Srgrimes    val.load_item();
7501541Srgrimes  } else if (type == longType) {
7511541Srgrimes    cmp.load_item_force(FrameMap::long0_opr);
7521541Srgrimes    val.load_item_force(FrameMap::long1_opr);
7531541Srgrimes  } else {
7541541Srgrimes    ShouldNotReachHere();
7551541Srgrimes  }
7561541Srgrimes
75746349Salc  LIR_Opr addr = new_pointer_register();
7589428Sdfr  __ move(obj.result(), addr);
75946349Salc  __ add(addr, offset.result(), addr);
7601541Srgrimes
7611541Srgrimes  if (type == objectType) {  // Write-barrier needed for Object fields.
7621541Srgrimes    // Do the pre-write barrier, if any.
7631541Srgrimes    pre_barrier(addr, false, NULL);
7641541Srgrimes  }
7659336Sdfr
7661541Srgrimes  LIR_Opr ill = LIR_OprFact::illegalOpr;  // for convenience
7679336Sdfr  if (type == objectType)
7681541Srgrimes    __ cas_obj(addr, cmp.result(), val.result(), ill, ill);
7691541Srgrimes  else if (type == intType)
7701541Srgrimes    __ cas_int(addr, cmp.result(), val.result(), ill, ill);
7711541Srgrimes  else if (type == longType)
7721541Srgrimes    __ cas_long(addr, cmp.result(), val.result(), ill, ill);
7733305Sphk  else {
7743305Sphk    ShouldNotReachHere();
7751541Srgrimes  }
7761541Srgrimes
7771541Srgrimes  // generate conditional move of boolean result
7781541Srgrimes  LIR_Opr result = rlock_result(x);
7799336Sdfr  __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result);
7809336Sdfr  if (type == objectType) {   // Write-barrier needed for Object fields.
7819336Sdfr    // Seems to be precise
7829336Sdfr    post_barrier(addr, val.result());
7839336Sdfr  }
7849336Sdfr}
7859336Sdfr
7861541Srgrimes
7871541Srgrimesvoid LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
7881541Srgrimes  assert(x->number_of_arguments() == 1, "wrong type");
7891541Srgrimes  LIRItem value(x->argument_at(0), this);
7901541Srgrimes
79146349Salc  bool use_fpu = false;
79246349Salc  if (UseSSE >= 2) {
79346349Salc    switch(x->id()) {
79446349Salc      case vmIntrinsics::_dsin:
79546349Salc      case vmIntrinsics::_dcos:
79646349Salc      case vmIntrinsics::_dtan:
79746349Salc      case vmIntrinsics::_dlog:
79846349Salc      case vmIntrinsics::_dlog10:
79946349Salc        use_fpu = true;
80046349Salc    }
80146349Salc  } else {
80246349Salc    value.set_destroys_register();
80346349Salc  }
80446349Salc
80546349Salc  value.load_item();
80646349Salc
8078692Sdg  LIR_Opr calc_input = value.result();
80825023Sdfr  LIR_Opr calc_result = rlock_result(x);
80941026Speter
81046349Salc  // sin and cos need two free fpu stack slots, so register two temporary operands
81146349Salc  LIR_Opr tmp1 = FrameMap::caller_save_fpu_reg_at(0);
81246349Salc  LIR_Opr tmp2 = FrameMap::caller_save_fpu_reg_at(1);
81346349Salc
81446349Salc  if (use_fpu) {
81546349Salc    LIR_Opr tmp = FrameMap::fpu0_double_opr;
81646349Salc    __ move(calc_input, tmp);
81746349Salc
81846349Salc    calc_input = tmp;
81946349Salc    calc_result = tmp;
82046349Salc    tmp1 = FrameMap::caller_save_fpu_reg_at(1);
82146349Salc    tmp2 = FrameMap::caller_save_fpu_reg_at(2);
82246349Salc  }
82346349Salc
8248692Sdg  switch(x->id()) {
82546349Salc    case vmIntrinsics::_dabs:   __ abs  (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
82646349Salc    case vmIntrinsics::_dsqrt:  __ sqrt (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
82746349Salc    case vmIntrinsics::_dsin:   __ sin  (calc_input, calc_result, tmp1, tmp2);              break;
82846349Salc    case vmIntrinsics::_dcos:   __ cos  (calc_input, calc_result, tmp1, tmp2);              break;
82946349Salc    case vmIntrinsics::_dtan:   __ tan  (calc_input, calc_result, tmp1, tmp2);              break;
83046349Salc    case vmIntrinsics::_dlog:   __ log  (calc_input, calc_result, LIR_OprFact::illegalOpr); break;
83146349Salc    case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, LIR_OprFact::illegalOpr); break;
83246349Salc    default:                    ShouldNotReachHere();
83346349Salc  }
83446349Salc
83546349Salc  if (use_fpu) {
83646349Salc    __ move(calc_result, x->operand());
83746349Salc  }
83846349Salc}
83946349Salc
84046349Salc
84146349Salcvoid LIRGenerator::do_ArrayCopy(Intrinsic* x) {
84246349Salc  assert(x->number_of_arguments() == 5, "wrong type");
84346349Salc  LIRItem src(x->argument_at(0), this);
84446349Salc  LIRItem src_pos(x->argument_at(1), this);
84546349Salc  LIRItem dst(x->argument_at(2), this);
84646349Salc  LIRItem dst_pos(x->argument_at(3), this);
84746349Salc  LIRItem length(x->argument_at(4), this);
8488692Sdg
84946349Salc  // operands for arraycopy must use fixed registers, otherwise
85046349Salc  // LinearScan will fail allocation (because arraycopy always needs a
85146349Salc  // call)
85246349Salc
85346349Salc#ifndef _LP64
85446349Salc  src.load_item_force     (FrameMap::rcx_oop_opr);
85546349Salc  src_pos.load_item_force (FrameMap::rdx_opr);
85646349Salc  dst.load_item_force     (FrameMap::rax_oop_opr);
85746349Salc  dst_pos.load_item_force (FrameMap::rbx_opr);
85846349Salc  length.load_item_force  (FrameMap::rdi_opr);
8591541Srgrimes  LIR_Opr tmp =           (FrameMap::rsi_opr);
8601541Srgrimes#else
8611541Srgrimes
8621541Srgrimes  // The java calling convention will give us enough registers
8631541Srgrimes  // so that on the stub side the args will be perfect already.
8641541Srgrimes  // On the other slow/special case side we call C and the arg
8651541Srgrimes  // positions are not similar enough to pick one as the best.
8668692Sdg  // Also because the java calling convention is a "shifted" version
86745347Sjulian  // of the C convention we can process the java args trivially into C
86845347Sjulian  // args without worry of overwriting during the xfer
86945347Sjulian
87045347Sjulian  src.load_item_force     (FrameMap::as_oop_opr(j_rarg0));
87145347Sjulian  src_pos.load_item_force (FrameMap::as_opr(j_rarg1));
87245347Sjulian  dst.load_item_force     (FrameMap::as_oop_opr(j_rarg2));
87341791Sdt  dst_pos.load_item_force (FrameMap::as_opr(j_rarg3));
87441791Sdt  length.load_item_force  (FrameMap::as_opr(j_rarg4));
87545347Sjulian
87645347Sjulian  LIR_Opr tmp =           FrameMap::as_opr(j_rarg5);
87731617Sdyson#endif // LP64
8781541Srgrimes
87931617Sdyson  set_no_result(x);
88031617Sdyson
88131617Sdyson  int flags;
88246349Salc  ciArrayKlass* expected_type;
88346349Salc  arraycopy_helper(x, &flags, &expected_type);
88446349Salc
88546349Salc  CodeEmitInfo* info = state_for(x, x->state()); // we may want to have stack (deoptimization?)
88646349Salc  __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint
88746349Salc}
88846349Salc
88946349Salc
89046349Salc// _i2l, _i2f, _i2d, _l2i, _l2f, _l2d, _f2i, _f2l, _f2d, _d2i, _d2l, _d2f
89146349Salc// _i2b, _i2c, _i2s
89246349SalcLIR_Opr fixed_register_for(BasicType type) {
89331617Sdyson  switch (type) {
89442957Sdillon    case T_FLOAT:  return FrameMap::fpu0_float_opr;
89531617Sdyson    case T_DOUBLE: return FrameMap::fpu0_double_opr;
89631617Sdyson    case T_INT:    return FrameMap::rax_opr;
89747964Smckusick    case T_LONG:   return FrameMap::long0_opr;
89831617Sdyson    default:       ShouldNotReachHere(); return LIR_OprFact::illegalOpr;
89931617Sdyson  }
90031617Sdyson}
90131617Sdyson
90231617Sdysonvoid LIRGenerator::do_Convert(Convert* x) {
9031541Srgrimes  // flags that vary for the different operations and different SSE-settings
9041541Srgrimes  bool fixed_input, fixed_result, round_result, needs_stub;
9051541Srgrimes
9061541Srgrimes  switch (x->op()) {
9079336Sdfr    case Bytecodes::_i2l: // fall through
9081541Srgrimes    case Bytecodes::_l2i: // fall through
9099336Sdfr    case Bytecodes::_i2b: // fall through
9101541Srgrimes    case Bytecodes::_i2c: // fall through
9111541Srgrimes    case Bytecodes::_i2s: fixed_input = false;       fixed_result = false;       round_result = false;      needs_stub = false; break;
9121541Srgrimes
9131541Srgrimes    case Bytecodes::_f2d: fixed_input = UseSSE == 1; fixed_result = false;       round_result = false;      needs_stub = false; break;
9141541Srgrimes    case Bytecodes::_d2f: fixed_input = false;       fixed_result = UseSSE == 1; round_result = UseSSE < 1; needs_stub = false; break;
9151541Srgrimes    case Bytecodes::_i2f: fixed_input = false;       fixed_result = false;       round_result = UseSSE < 1; needs_stub = false; break;
9161541Srgrimes    case Bytecodes::_i2d: fixed_input = false;       fixed_result = false;       round_result = false;      needs_stub = false; break;
9171541Srgrimes    case Bytecodes::_f2i: fixed_input = false;       fixed_result = false;       round_result = false;      needs_stub = true;  break;
9183305Sphk    case Bytecodes::_d2i: fixed_input = false;       fixed_result = false;       round_result = false;      needs_stub = true;  break;
9193305Sphk    case Bytecodes::_l2f: fixed_input = false;       fixed_result = UseSSE >= 1; round_result = UseSSE < 1; needs_stub = false; break;
9201541Srgrimes    case Bytecodes::_l2d: fixed_input = false;       fixed_result = UseSSE >= 2; round_result = UseSSE < 2; needs_stub = false; break;
9211541Srgrimes    case Bytecodes::_f2l: fixed_input = true;        fixed_result = true;        round_result = false;      needs_stub = false; break;
9221541Srgrimes    case Bytecodes::_d2l: fixed_input = true;        fixed_result = true;        round_result = false;      needs_stub = false; break;
9231541Srgrimes    default: ShouldNotReachHere();
9241541Srgrimes  }
92534206Sdyson
9263305Sphk  LIRItem value(x->value(), this);
92739781Smckusick  value.load_item();
9283305Sphk  LIR_Opr input = value.result();
9291541Srgrimes  LIR_Opr result = rlock(x);
9301541Srgrimes
9311541Srgrimes  // arguments of lir_convert
9321541Srgrimes  LIR_Opr conv_input = input;
93334206Sdyson  LIR_Opr conv_result = result;
93434206Sdyson  ConversionStub* stub = NULL;
93545347Sjulian
93645347Sjulian  if (fixed_input) {
93745347Sjulian    conv_input = fixed_register_for(input->type());
93845347Sjulian    __ move(input, conv_input);
93945347Sjulian  }
94045347Sjulian
94145347Sjulian  assert(fixed_result == false || round_result == false, "cannot set both");
94245347Sjulian  if (fixed_result) {
94345347Sjulian    conv_result = fixed_register_for(result->type());
94445347Sjulian  } else if (round_result) {
94545347Sjulian    result = new_register(result->type());
94646349Salc    set_vreg_flag(result, must_start_in_memory);
9471541Srgrimes  }
94845347Sjulian
94944679Sjulian  if (needs_stub) {
95017186Sdfr    stub = new ConversionStub(x->op(), conv_input, conv_result);
95117186Sdfr  }
95217186Sdfr
95317186Sdfr  __ convert(x->op(), conv_input, conv_result, stub);
95417186Sdfr
95517186Sdfr  if (result != conv_result) {
9561541Srgrimes    __ move(conv_result, result);
95746349Salc  }
95846349Salc
95946349Salc  assert(result->is_virtual(), "result must be virtual register");
9601541Srgrimes  set_result(x, result);
9611541Srgrimes}
96234206Sdyson
96346349Salc
96447964Smckusickvoid LIRGenerator::do_NewInstance(NewInstance* x) {
9653305Sphk  if (PrintNotLoaded && !x->klass()->is_loaded()) {
9661541Srgrimes    tty->print_cr("   ###class not loaded at new bci %d", x->bci());
9679336Sdfr  }
9689336Sdfr  CodeEmitInfo* info = state_for(x, x->state());
9699336Sdfr  LIR_Opr reg = result_register_for(x->type());
9709336Sdfr  LIR_Opr klass_reg = new_register(objectType);
9719336Sdfr  new_instance(reg, x->klass(),
9721541Srgrimes                       FrameMap::rcx_oop_opr,
9731541Srgrimes                       FrameMap::rdi_oop_opr,
9749336Sdfr                       FrameMap::rsi_oop_opr,
97546580Sphk                       LIR_OprFact::illegalOpr,
97646349Salc                       FrameMap::rdx_oop_opr, info);
9771541Srgrimes  LIR_Opr result = rlock_result(x);
97846349Salc  __ move(reg, result);
9791541Srgrimes}
9801541Srgrimes
9811541Srgrimes
9821541Srgrimesvoid LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
9831541Srgrimes  CodeEmitInfo* info = state_for(x, x->state());
9841541Srgrimes
9851541Srgrimes  LIRItem length(x->length(), this);
9861541Srgrimes  length.load_item_force(FrameMap::rbx_opr);
9871541Srgrimes
9881541Srgrimes  LIR_Opr reg = result_register_for(x->type());
9891541Srgrimes  LIR_Opr tmp1 = FrameMap::rcx_oop_opr;
99012911Sphk  LIR_Opr tmp2 = FrameMap::rsi_oop_opr;
9911541Srgrimes  LIR_Opr tmp3 = FrameMap::rdi_oop_opr;
9921541Srgrimes  LIR_Opr tmp4 = reg;
9931541Srgrimes  LIR_Opr klass_reg = FrameMap::rdx_oop_opr;
9941541Srgrimes  LIR_Opr len = length.result();
9951541Srgrimes  BasicType elem_type = x->elt_type();
9961541Srgrimes
9971541Srgrimes  __ oop2reg(ciTypeArrayKlass::make(elem_type)->encoding(), klass_reg);
99832755Sdyson
99932755Sdyson  CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
10001541Srgrimes  __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);
100132755Sdyson
100232755Sdyson  LIR_Opr result = rlock_result(x);
100332755Sdyson  __ move(reg, result);
10041541Srgrimes}
10051541Srgrimes
10061541Srgrimes
10071541Srgrimesvoid LIRGenerator::do_NewObjectArray(NewObjectArray* x) {
10081541Srgrimes  LIRItem length(x->length(), this);
10091541Srgrimes  // in case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction
10101541Srgrimes  // and therefore provide the state before the parameters have been consumed
101146349Salc  CodeEmitInfo* patching_info = NULL;
10121541Srgrimes  if (!x->klass()->is_loaded() || PatchALot) {
101346349Salc    patching_info =  state_for(x, x->state_before());
10145455Sdg  }
101541791Sdt
101632755Sdyson  CodeEmitInfo* info = state_for(x, x->state());
101746349Salc
101832755Sdyson  const LIR_Opr reg = result_register_for(x->type());
101941791Sdt  LIR_Opr tmp1 = FrameMap::rcx_oop_opr;
102032755Sdyson  LIR_Opr tmp2 = FrameMap::rsi_oop_opr;
10211541Srgrimes  LIR_Opr tmp3 = FrameMap::rdi_oop_opr;
10221541Srgrimes  LIR_Opr tmp4 = reg;
10231541Srgrimes  LIR_Opr klass_reg = FrameMap::rdx_oop_opr;
10241541Srgrimes
10251541Srgrimes  length.load_item_force(FrameMap::rbx_opr);
10261541Srgrimes  LIR_Opr len = length.result();
10271541Srgrimes
10281549Srgrimes  CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info);
10291541Srgrimes  ciObject* obj = (ciObject*) ciObjArrayKlass::make(x->klass());
10301541Srgrimes  if (obj == ciEnv::unloaded_ciobjarrayklass()) {
10311541Srgrimes    BAILOUT("encountered unloaded_ciobjarrayklass due to out of memory error");
10321541Srgrimes  }
10331541Srgrimes  jobject2reg_with_patching(klass_reg, obj, patching_info);
10341541Srgrimes  __ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, T_OBJECT, klass_reg, slow_path);
10351541Srgrimes
10361541Srgrimes  LIR_Opr result = rlock_result(x);
10371541Srgrimes  __ move(reg, result);
10381541Srgrimes}
10391541Srgrimes
104032755Sdyson
104132755Sdysonvoid LIRGenerator::do_NewMultiArray(NewMultiArray* x) {
104232755Sdyson  Values* dims = x->dims();
104332755Sdyson  int i = dims->length();
10441541Srgrimes  LIRItemList* items = new LIRItemList(dims->length(), NULL);
10451541Srgrimes  while (i-- > 0) {
10461541Srgrimes    LIRItem* size = new LIRItem(dims->at(i), this);
10471541Srgrimes    items->at_put(i, size);
10481541Srgrimes  }
10491541Srgrimes
10501541Srgrimes  // need to get the info before, as the items may become invalid through item_free
10511541Srgrimes  CodeEmitInfo* patching_info = NULL;
10521541Srgrimes  if (!x->klass()->is_loaded() || PatchALot) {
10531541Srgrimes    patching_info = state_for(x, x->state_before());
10541541Srgrimes
10551541Srgrimes    // cannot re-use same xhandlers for multiple CodeEmitInfos, so
10561541Srgrimes    // clone all handlers.
10571541Srgrimes    x->set_exception_handlers(new XHandlers(x->exception_handlers()));
10581541Srgrimes  }
10591541Srgrimes
10601541Srgrimes  CodeEmitInfo* info = state_for(x, x->state());
10611541Srgrimes
10621541Srgrimes  i = dims->length();
10631541Srgrimes  while (i-- > 0) {
10641541Srgrimes    LIRItem* size = items->at(i);
10651541Srgrimes    size->load_nonconstant();
10661541Srgrimes
10671541Srgrimes    store_stack_parameter(size->result(), in_ByteSize(i*4));
10681541Srgrimes  }
10691541Srgrimes
10701541Srgrimes  LIR_Opr reg = result_register_for(x->type());
10711541Srgrimes  jobject2reg_with_patching(reg, x->klass(), patching_info);
10721541Srgrimes
10731541Srgrimes  LIR_Opr rank = FrameMap::rbx_opr;
10741541Srgrimes  __ move(LIR_OprFact::intConst(x->rank()), rank);
10751541Srgrimes  LIR_Opr varargs = FrameMap::rcx_opr;
10761541Srgrimes  __ move(FrameMap::rsp_opr, varargs);
10771541Srgrimes  LIR_OprList* args = new LIR_OprList(3);
10781541Srgrimes  args->append(reg);
10791541Srgrimes  args->append(rank);
10801541Srgrimes  args->append(varargs);
10811541Srgrimes  __ call_runtime(Runtime1::entry_for(Runtime1::new_multi_array_id),
10821541Srgrimes                  LIR_OprFact::illegalOpr,
10831541Srgrimes                  reg, args, info);
10841541Srgrimes
10851541Srgrimes  LIR_Opr result = rlock_result(x);
10861541Srgrimes  __ move(reg, result);
10871541Srgrimes}
10881541Srgrimes
10891541Srgrimes
10901541Srgrimesvoid LIRGenerator::do_BlockBegin(BlockBegin* x) {
10911541Srgrimes  // nothing to do for now
109246349Salc}
109346349Salc
109446349Salc
10951541Srgrimesvoid LIRGenerator::do_CheckCast(CheckCast* x) {
10961549Srgrimes  LIRItem obj(x->obj(), this);
109746580Sphk
10981541Srgrimes  CodeEmitInfo* patching_info = NULL;
10991541Srgrimes  if (!x->klass()->is_loaded() || (PatchALot && !x->is_incompatible_class_change_check())) {
110046580Sphk    // must do this before locking the destination register as an oop register,
11011541Srgrimes    // and before the obj is loaded (the latter is for deoptimization)
110219449Sdfr    patching_info = state_for(x, x->state_before());
110319449Sdfr  }
110419449Sdfr  obj.load_item();
110519449Sdfr
110619449Sdfr  // info for exceptions
110719449Sdfr  CodeEmitInfo* info_for_exception = state_for(x, x->state()->copy_locks());
11081541Srgrimes
11091541Srgrimes  CodeStub* stub;
11101541Srgrimes  if (x->is_incompatible_class_change_check()) {
111144679Sjulian    assert(patching_info == NULL, "can't patch this");
111219449Sdfr    stub = new SimpleExceptionStub(Runtime1::throw_incompatible_class_change_error_id, LIR_OprFact::illegalOpr, info_for_exception);
111319449Sdfr  } else {
111419449Sdfr    stub = new SimpleExceptionStub(Runtime1::throw_class_cast_exception_id, obj.result(), info_for_exception);
111519449Sdfr  }
111619449Sdfr  LIR_Opr reg = rlock_result(x);
111719449Sdfr  __ checkcast(reg, obj.result(), x->klass(),
111819449Sdfr               new_register(objectType), new_register(objectType),
111919449Sdfr               !x->klass()->is_loaded() ? new_register(objectType) : LIR_OprFact::illegalOpr,
112019449Sdfr               x->direct_compare(), info_for_exception, patching_info, stub,
11211541Srgrimes               x->profiled_method(), x->profiled_bci());
112219449Sdfr}
112319449Sdfr
112419449Sdfr
112519449Sdfrvoid LIRGenerator::do_InstanceOf(InstanceOf* x) {
112619449Sdfr  LIRItem obj(x->obj(), this);
112719449Sdfr
112819449Sdfr  // result and test object may not be in same register
112919449Sdfr  LIR_Opr reg = rlock_result(x);
113019449Sdfr  CodeEmitInfo* patching_info = NULL;
113119449Sdfr  if ((!x->klass()->is_loaded() || PatchALot)) {
113219449Sdfr    // must do this before locking the destination register as an oop register
113319449Sdfr    patching_info = state_for(x, x->state_before());
113419449Sdfr  }
113525023Sdfr  obj.load_item();
113619449Sdfr  LIR_Opr tmp = new_register(objectType);
113719449Sdfr  __ instanceof(reg, obj.result(), x->klass(),
113819449Sdfr                tmp, new_register(objectType), LIR_OprFact::illegalOpr,
113919449Sdfr                x->direct_compare(), patching_info);
114019449Sdfr}
114119449Sdfr
114219449Sdfr
114319449Sdfrvoid LIRGenerator::do_If(If* x) {
114419449Sdfr  assert(x->number_of_sux() == 2, "inconsistency");
114519449Sdfr  ValueTag tag = x->x()->type()->tag();
114619449Sdfr  bool is_safepoint = x->is_safepoint();
114719449Sdfr
114819449Sdfr  If::Condition cond = x->cond();
114919449Sdfr
115019449Sdfr  LIRItem xitem(x->x(), this);
115119449Sdfr  LIRItem yitem(x->y(), this);
115219449Sdfr  LIRItem* xin = &xitem;
115319449Sdfr  LIRItem* yin = &yitem;
115419449Sdfr
115519449Sdfr  if (tag == longTag) {
115619449Sdfr    // for longs, only conditions "eql", "neq", "lss", "geq" are valid;
115719449Sdfr    // mirror for other conditions
115819449Sdfr    if (cond == If::gtr || cond == If::leq) {
115919449Sdfr      cond = Instruction::mirror(cond);
116019449Sdfr      xin = &yitem;
116119449Sdfr      yin = &xitem;
116219449Sdfr    }
116319449Sdfr    xin->set_destroys_register();
116419449Sdfr  }
116519449Sdfr  xin->load_item();
116646580Sphk  if (tag == longTag && yin->is_constant() && yin->get_jlong_constant() == 0 && (cond == If::eql || cond == If::neq)) {
116719449Sdfr    // inline long zero
116819449Sdfr    yin->dont_load_item();
116919449Sdfr  } else if (tag == longTag || tag == floatTag || tag == doubleTag) {
117019449Sdfr    // longs cannot handle constants at right side
117119449Sdfr    yin->load_item();
117219449Sdfr  } else {
117319449Sdfr    yin->dont_load_item();
117419449Sdfr  }
117519449Sdfr
117619449Sdfr  // add safepoint before generating condition code so it can be recomputed
117719449Sdfr  if (x->is_safepoint()) {
117819449Sdfr    // increment backedge counter if needed
117919449Sdfr    increment_backedge_counter(state_for(x, x->state_before()));
118019449Sdfr
118119449Sdfr    __ safepoint(LIR_OprFact::illegalOpr, state_for(x, x->state_before()));
118219449Sdfr  }
118319449Sdfr  set_no_result(x);
11841541Srgrimes
11851541Srgrimes  LIR_Opr left = xin->result();
11861541Srgrimes  LIR_Opr right = yin->result();
11871541Srgrimes  __ cmp(lir_cond(cond), left, right);
11881541Srgrimes  profile_branch(x, cond);
11891541Srgrimes  move_to_phi(x->state());
11909336Sdfr  if (x->x()->type()->is_float_kind()) {
11911541Srgrimes    __ branch(lir_cond(cond), right->type(), x->tsux(), x->usux());
11921541Srgrimes  } else {
11931541Srgrimes    __ branch(lir_cond(cond), right->type(), x->tsux());
11941541Srgrimes  }
11951541Srgrimes  assert(x->default_sux() == x->fsux(), "wrong destination above");
11968876Srgrimes  __ jump(x->default_sux());
119719449Sdfr}
119819449Sdfr
11991541Srgrimes
120019449SdfrLIR_Opr LIRGenerator::getThreadPointer() {
12019336Sdfr#ifdef _LP64
12029336Sdfr  return FrameMap::as_pointer_opr(r15_thread);
120319449Sdfr#else
120419449Sdfr  LIR_Opr result = new_register(T_INT);
12059336Sdfr  __ get_thread(result);
120619449Sdfr  return result;
120719449Sdfr#endif //
12081541Srgrimes}
12091541Srgrimes
12101541Srgrimesvoid LIRGenerator::trace_block_entry(BlockBegin* block) {
12111541Srgrimes  store_stack_parameter(LIR_OprFact::intConst(block->block_id()), in_ByteSize(0));
12121541Srgrimes  LIR_OprList* args = new LIR_OprList();
12131541Srgrimes  address func = CAST_FROM_FN_PTR(address, Runtime1::trace_block_entry);
12141541Srgrimes  __ call_runtime_leaf(func, LIR_OprFact::illegalOpr, LIR_OprFact::illegalOpr, args);
12151541Srgrimes}
121644679Sjulian
12173305Sphk
12181541Srgrimesvoid LIRGenerator::volatile_field_store(LIR_Opr value, LIR_Address* address,
12191541Srgrimes                                        CodeEmitInfo* info) {
122044679Sjulian  if (address->type() == T_LONG) {
122144679Sjulian    address = new LIR_Address(address->base(),
12221541Srgrimes                              address->index(), address->scale(),
12231541Srgrimes                              address->disp(), T_DOUBLE);
122446349Salc    // Transfer the value atomically by using FP moves.  This means
12251541Srgrimes    // the value has to be moved between CPU and FPU registers.  It
12261541Srgrimes    // always has to be moved through spill slot since there's no
12271541Srgrimes    // quick way to pack the value into an SSE register.
12281541Srgrimes    LIR_Opr temp_double = new_register(T_DOUBLE);
12291541Srgrimes    LIR_Opr spill = new_register(T_LONG);
12301541Srgrimes    set_vreg_flag(spill, must_start_in_memory);
12311541Srgrimes    __ move(value, spill);
12321541Srgrimes    __ volatile_move(spill, temp_double, T_LONG);
12331541Srgrimes    __ volatile_move(temp_double, LIR_OprFact::address(address), T_LONG, info);
12341541Srgrimes  } else {
12351541Srgrimes    __ store(value, address, info);
12361541Srgrimes  }
123746349Salc}
123846349Salc
123946349Salc
124046349Salc
124146349Salcvoid LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result,
124246349Salc                                       CodeEmitInfo* info) {
124346349Salc  if (address->type() == T_LONG) {
124444679Sjulian    address = new LIR_Address(address->base(),
124544679Sjulian                              address->index(), address->scale(),
12461541Srgrimes                              address->disp(), T_DOUBLE);
12471541Srgrimes    // Transfer the value atomically by using FP moves.  This means
12481541Srgrimes    // the value has to be moved between CPU and FPU registers.  In
12493664Sphk    // SSE0 and SSE1 mode it has to be moved through spill slot but in
12503664Sphk    // SSE2+ mode it can be moved directly.
12513664Sphk    LIR_Opr temp_double = new_register(T_DOUBLE);
12523664Sphk    __ volatile_move(LIR_OprFact::address(address), temp_double, T_LONG, info);
12531541Srgrimes    __ volatile_move(temp_double, result, T_LONG);
12543664Sphk    if (UseSSE < 2) {
12551541Srgrimes      // no spill slot needed in SSE2 mode because xmm->cpu register move is possible
12569336Sdfr      set_vreg_flag(result, must_start_in_memory);
12573664Sphk    }
12583664Sphk  } else {
12593664Sphk    __ load(address, result, info);
12603664Sphk  }
12613664Sphk}
12629336Sdfr
12639336Sdfrvoid LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset,
12649336Sdfr                                     BasicType type, bool is_volatile) {
12653664Sphk  if (is_volatile && type == T_LONG) {
12663664Sphk    LIR_Address* addr = new LIR_Address(src, offset, T_DOUBLE);
12679336Sdfr    LIR_Opr tmp = new_register(T_DOUBLE);
12683664Sphk    __ load(addr, tmp);
12693664Sphk    LIR_Opr spill = new_register(T_LONG);
12703664Sphk    set_vreg_flag(spill, must_start_in_memory);
12713664Sphk    __ move(tmp, spill);
12723664Sphk    __ move(spill, dst);
12733664Sphk  } else {
12743664Sphk    LIR_Address* addr = new LIR_Address(src, offset, type);
12753664Sphk    __ load(addr, dst);
12761541Srgrimes  }
12771541Srgrimes}
12781541Srgrimes
12799336Sdfr
12801541Srgrimesvoid LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data,
12811541Srgrimes                                     BasicType type, bool is_volatile) {
12821541Srgrimes  if (is_volatile && type == T_LONG) {
12831541Srgrimes    LIR_Address* addr = new LIR_Address(src, offset, T_DOUBLE);
12841541Srgrimes    LIR_Opr tmp = new_register(T_DOUBLE);
128546349Salc    LIR_Opr spill = new_register(T_DOUBLE);
128646349Salc    set_vreg_flag(spill, must_start_in_memory);
128746349Salc    __ move(data, spill);
128846349Salc    __ move(spill, tmp);
128946349Salc    __ move(tmp, addr);
129046349Salc  } else {
12911541Srgrimes    LIR_Address* addr = new LIR_Address(src, offset, type);
129246349Salc    bool is_obj = (type == T_ARRAY || type == T_OBJECT);
129346349Salc    if (is_obj) {
129446349Salc      // Do the pre-write barrier, if any.
129546349Salc      pre_barrier(LIR_OprFact::address(addr), false, NULL);
129646349Salc      __ move(data, addr);
129746349Salc      assert(src->is_register(), "must be register");
129846349Salc      // Seems to be a precise address
12991541Srgrimes      post_barrier(LIR_OprFact::address(addr), data);
13001541Srgrimes    } else {
13011541Srgrimes      __ move(data, addr);
13029336Sdfr    }
13031541Srgrimes  }
13041541Srgrimes}
130518397Snate