/*
 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "precompiled.hpp"
#include "c1/c1_Compilation.hpp"
#include "c1/c1_Instruction.hpp"
#include "c1/c1_InstructionPrinter.hpp"
#include "c1/c1_LIRAssembler.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "c1/c1_ValueStack.hpp"
#include "ci/ciInstance.hpp"
#ifdef TARGET_ARCH_x86
# include "nativeInst_x86.hpp"
# include "vmreg_x86.inline.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "nativeInst_sparc.hpp"
# include "vmreg_sparc.inline.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "nativeInst_zero.hpp"
# include "vmreg_zero.inline.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "nativeInst_arm.hpp"
# include "vmreg_arm.inline.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "nativeInst_ppc.hpp"
# include "vmreg_ppc.inline.hpp"
#endif


void LIR_Assembler::patching_epilog(PatchingStub* patch, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) {
  // we must have enough patching space so that call can be inserted
  while ((intx) _masm->pc() - (intx) patch->pc_start() < NativeCall::instruction_size) {
    _masm->nop();
  }
  patch->install(_masm, patch_code, obj, info);
  append_code_stub(patch);

#ifdef ASSERT
  Bytecodes::Code code = info->scope()->method()->java_code_at_bci(info->stack()->bci());
  if (patch->id() == PatchingStub::access_field_id) {
    switch (code) {
      case Bytecodes::_putstatic:
      case Bytecodes::_getstatic:
      case Bytecodes::_putfield:
      case Bytecodes::_getfield:
        break;
      default:
        ShouldNotReachHere();
    }
  } else if (patch->id() == PatchingStub::load_klass_id) {
    switch (code) {
      case Bytecodes::_new:
      case Bytecodes::_anewarray:
      case Bytecodes::_multianewarray:
      case Bytecodes::_instanceof:
      case Bytecodes::_checkcast:
        break;
      default:
        ShouldNotReachHere();
    }
  } else if (patch->id() == PatchingStub::load_mirror_id) {
    switch (code) {
      case Bytecodes::_putstatic:
      case Bytecodes::_getstatic:
      case Bytecodes::_ldc:
      case Bytecodes::_ldc_w:
        break;
      default:
        ShouldNotReachHere();
    }
  } else if (patch->id() == PatchingStub::load_appendix_id) {
    Bytecodes::Code bc_raw = info->scope()->method()->raw_code_at_bci(info->stack()->bci());
    assert(Bytecodes::has_optional_appendix(bc_raw), "unexpected appendix resolution");
  } else {
    ShouldNotReachHere();
  }
#endif
}

PatchingStub::PatchID LIR_Assembler::patching_id(CodeEmitInfo* info) {
  IRScope* scope = info->scope();
  Bytecodes::Code bc_raw = scope->method()->raw_code_at_bci(info->stack()->bci());
  if (Bytecodes::has_optional_appendix(bc_raw)) {
    return PatchingStub::load_appendix_id;
  }
  return PatchingStub::load_mirror_id;
}

//---------------------------------------------------------------


LIR_Assembler::LIR_Assembler(Compilation* c):
   _compilation(c)
 , _masm(c->masm())
 , _bs(Universe::heap()->barrier_set())
 , _frame_map(c->frame_map())
 , _current_block(NULL)
 , _pending_non_safepoint(NULL)
 , _pending_non_safepoint_offset(0)
{
  _slow_case_stubs = new CodeStubList();
}


LIR_Assembler::~LIR_Assembler() {
}


void LIR_Assembler::check_codespace() {
  CodeSection* cs = _masm->code_section();
  if (cs->remaining() < (int)(NOT_LP64(1*K)LP64_ONLY(2*K))) {
    BAILOUT("CodeBuffer overflow");
  }
}


void LIR_Assembler::append_code_stub(CodeStub* stub) {
  _slow_case_stubs->append(stub);
}

void LIR_Assembler::emit_stubs(CodeStubList* stub_list) {
  for (int m = 0; m < stub_list->length(); m++) {
    CodeStub* s = (*stub_list)[m];

    check_codespace();
    CHECK_BAILOUT();

#ifndef PRODUCT
    if (CommentedAssembly) {
      stringStream st;
      s->print_name(&st);
      st.print(" slow case");
      _masm->block_comment(st.as_string());
    }
#endif
    s->emit_code(this);
#ifdef ASSERT
    s->assert_no_unbound_labels();
#endif
  }
}


void LIR_Assembler::emit_slow_case_stubs() {
  emit_stubs(_slow_case_stubs);
}


bool LIR_Assembler::needs_icache(ciMethod* method) const {
  return !method->is_static();
}


int LIR_Assembler::code_offset() const {
  return _masm->offset();
}


address LIR_Assembler::pc() const {
  return _masm->pc();
}

// To bang the stack of this compiled method we use the stack size
// that the interpreter would need in case of a deoptimization. This
// removes the need to bang the stack in the deoptimization blob which
// in turn simplifies stack overflow handling.
int LIR_Assembler::bang_size_in_bytes() const {
  return MAX2(initial_frame_size_in_bytes(), _compilation->interpreter_frame_size());
}

void LIR_Assembler::emit_exception_entries(ExceptionInfoList* info_list) {
  for (int i = 0; i < info_list->length(); i++) {
    XHandlers* handlers = info_list->at(i)->exception_handlers();

    for (int j = 0; j < handlers->length(); j++) {
      XHandler* handler = handlers->handler_at(j);
      assert(handler->lir_op_id() != -1, "handler not processed by LinearScan");
      assert(handler->entry_code() == NULL ||
             handler->entry_code()->instructions_list()->last()->code() == lir_branch ||
             handler->entry_code()->instructions_list()->last()->code() == lir_delay_slot, "last operation must be branch");

      if (handler->entry_pco() == -1) {
        // entry code not emitted yet
        if (handler->entry_code() != NULL && handler->entry_code()->instructions_list()->length() > 1) {
          handler->set_entry_pco(code_offset());
          if (CommentedAssembly) {
            _masm->block_comment("Exception adapter block");
          }
          emit_lir_list(handler->entry_code());
        } else {
          handler->set_entry_pco(handler->entry_block()->exception_handler_pco());
        }

        assert(handler->entry_pco() != -1, "must be set now");
      }
    }
  }
}


void LIR_Assembler::emit_code(BlockList* hir) {
  if (PrintLIR) {
    print_LIR(hir);
  }

  int n = hir->length();
  for (int i = 0; i < n; i++) {
    emit_block(hir->at(i));
    CHECK_BAILOUT();
  }

  flush_debug_info(code_offset());

  DEBUG_ONLY(check_no_unbound_labels());
}


void LIR_Assembler::emit_block(BlockBegin* block) {
  if (block->is_set(BlockBegin::backward_branch_target_flag)) {
    align_backward_branch_target();
  }

  // if this block is the start of an exception handler, record the
  // PC offset of the first instruction for later construction of
  // the ExceptionHandlerTable
  if (block->is_set(BlockBegin::exception_entry_flag)) {
    block->set_exception_handler_pco(code_offset());
  }

#ifndef PRODUCT
  if (PrintLIRWithAssembly) {
    // don't print Phi's
    InstructionPrinter ip(false);
    block->print(ip);
  }
#endif /* PRODUCT */

  assert(block->lir() != NULL, "must have LIR");
  X86_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed"));

#ifndef PRODUCT
  if (CommentedAssembly) {
    stringStream st;
    st.print_cr(" block B%d [%d, %d]", block->block_id(), block->bci(), block->end()->printable_bci());
    _masm->block_comment(st.as_string());
  }
#endif

  emit_lir_list(block->lir());

  X86_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed"));
}


void LIR_Assembler::emit_lir_list(LIR_List* list) {
  peephole(list);

  int n = list->length();
  for (int i = 0; i < n; i++) {
    LIR_Op* op = list->at(i);

    check_codespace();
    CHECK_BAILOUT();

#ifndef PRODUCT
    if (CommentedAssembly) {
      // Don't record out every op since that's too verbose.  Print
      // branches since they include block and stub names.  Also print
      // patching moves since they generate funny looking code.
      if (op->code() == lir_branch ||
          (op->code() == lir_move && op->as_Op1()->patch_code() != lir_patch_none)) {
        stringStream st;
        op->print_on(&st);
        _masm->block_comment(st.as_string());
      }
    }
    if (PrintLIRWithAssembly) {
      // print out the LIR operation followed by the resulting assembly
      list->at(i)->print(); tty->cr();
    }
#endif /* PRODUCT */

    op->emit_code(this);

    if (compilation()->debug_info_recorder()->recording_non_safepoints()) {
      process_debug_info(op);
    }

#ifndef PRODUCT
    if (PrintLIRWithAssembly) {
      _masm->code()->decode();
    }
#endif /* PRODUCT */
  }
}

#ifdef ASSERT
void LIR_Assembler::check_no_unbound_labels() {
  CHECK_BAILOUT();

  for (int i = 0; i < _branch_target_blocks.length() - 1; i++) {
    if (!_branch_target_blocks.at(i)->label()->is_bound()) {
      tty->print_cr("label of block B%d is not bound", _branch_target_blocks.at(i)->block_id());
      assert(false, "unbound label");
    }
  }
}
#endif

//----------------------------------debug info--------------------------------


void LIR_Assembler::add_debug_info_for_branch(CodeEmitInfo* info) {
  _masm->code_section()->relocate(pc(), relocInfo::poll_type);
  int pc_offset = code_offset();
  flush_debug_info(pc_offset);
  info->record_debug_info(compilation()->debug_info_recorder(), pc_offset);
  if (info->exception_handlers() != NULL) {
    compilation()->add_exception_handlers_for_pco(pc_offset, info->exception_handlers());
  }
}


void LIR_Assembler::add_call_info(int pc_offset, CodeEmitInfo* cinfo) {
  flush_debug_info(pc_offset);
  cinfo->record_debug_info(compilation()->debug_info_recorder(), pc_offset);
  if (cinfo->exception_handlers() != NULL) {
    compilation()->add_exception_handlers_for_pco(pc_offset, cinfo->exception_handlers());
  }
}

static ValueStack* debug_info(Instruction* ins) {
  StateSplit* ss = ins->as_StateSplit();
  if (ss != NULL) return ss->state();
  return ins->state_before();
}

void LIR_Assembler::process_debug_info(LIR_Op* op) {
  Instruction* src = op->source();
  if (src == NULL)  return;
  int pc_offset = code_offset();
  if (_pending_non_safepoint == src) {
    _pending_non_safepoint_offset = pc_offset;
    return;
  }
  ValueStack* vstack = debug_info(src);
  if (vstack == NULL)  return;
  if (_pending_non_safepoint != NULL) {
    // Got some old debug info.  Get rid of it.
    if (debug_info(_pending_non_safepoint) == vstack) {
      _pending_non_safepoint_offset = pc_offset;
      return;
    }
    if (_pending_non_safepoint_offset < pc_offset) {
      record_non_safepoint_debug_info();
    }
    _pending_non_safepoint = NULL;
  }
  // Remember the debug info.
  if (pc_offset > compilation()->debug_info_recorder()->last_pc_offset()) {
    _pending_non_safepoint = src;
    _pending_non_safepoint_offset = pc_offset;
  }
}

// Index caller states in s, where 0 is the oldest, 1 its callee, etc.
// Return NULL if n is too large.
// Returns the caller_bci for the next-younger state, also.
static ValueStack* nth_oldest(ValueStack* s, int n, int& bci_result) {
  ValueStack* t = s;
  for (int i = 0; i < n; i++) {
    if (t == NULL)  break;
    t = t->caller_state();
  }
  if (t == NULL)  return NULL;
  for (;;) {
    ValueStack* tc = t->caller_state();
    if (tc == NULL)  return s;
    t = tc;
    bci_result = tc->bci();
    s = s->caller_state();
  }
}

void LIR_Assembler::record_non_safepoint_debug_info() {
  int         pc_offset = _pending_non_safepoint_offset;
  ValueStack* vstack    = debug_info(_pending_non_safepoint);
  int         bci       = vstack->bci();

  DebugInformationRecorder* debug_info = compilation()->debug_info_recorder();
  assert(debug_info->recording_non_safepoints(), "sanity");

  debug_info->add_non_safepoint(pc_offset);

  // Visit scopes from oldest to youngest.
  for (int n = 0; ; n++) {
    int s_bci = bci;
    ValueStack* s = nth_oldest(vstack, n, s_bci);
    if (s == NULL)  break;
    IRScope* scope = s->scope();
    //Always pass false for reexecute since these ScopeDescs are never used for deopt
    debug_info->describe_scope(pc_offset, scope->method(), s->bci(), false/*reexecute*/);
  }

  debug_info->end_non_safepoint(pc_offset);
}


void LIR_Assembler::add_debug_info_for_null_check_here(CodeEmitInfo* cinfo) {
  add_debug_info_for_null_check(code_offset(), cinfo);
}

void LIR_Assembler::add_debug_info_for_null_check(int pc_offset, CodeEmitInfo* cinfo) {
  ImplicitNullCheckStub* stub = new ImplicitNullCheckStub(pc_offset, cinfo);
  append_code_stub(stub);
}

void LIR_Assembler::add_debug_info_for_div0_here(CodeEmitInfo* info) {
  add_debug_info_for_div0(code_offset(), info);
}

void LIR_Assembler::add_debug_info_for_div0(int pc_offset, CodeEmitInfo* cinfo) {
  DivByZeroStub* stub = new DivByZeroStub(pc_offset, cinfo);
  append_code_stub(stub);
}

void LIR_Assembler::emit_rtcall(LIR_OpRTCall* op) {
  rt_call(op->result_opr(), op->addr(), op->arguments(), op->tmp(), op->info());
}


void LIR_Assembler::emit_call(LIR_OpJavaCall* op) {
  verify_oop_map(op->info());

  if (os::is_MP()) {
    // must align calls sites, otherwise they can't be updated atomically on MP hardware
    align_call(op->code());
  }

  // emit the static call stub stuff out of line
  emit_static_call_stub();
  CHECK_BAILOUT();

  switch (op->code()) {
  case lir_static_call:
  case lir_dynamic_call:
    call(op, relocInfo::static_call_type);
    break;
  case lir_optvirtual_call:
    call(op, relocInfo::opt_virtual_call_type);
    break;
  case lir_icvirtual_call:
    ic_call(op);
    break;
  case lir_virtual_call:
    vtable_call(op);
    break;
  default:
    fatal(err_msg_res("unexpected op code: %s", op->name()));
    break;
  }

  // JSR 292
  // Record if this method has MethodHandle invokes.
  if (op->is_method_handle_invoke()) {
    compilation()->set_has_method_handle_invokes(true);
  }

#if defined(X86) && defined(TIERED)
  // C2 leave fpu stack dirty clean it
  if (UseSSE < 2) {
    int i;
    for ( i = 1; i <= 7 ; i++ ) {
      ffree(i);
    }
    if (!op->result_opr()->is_float_kind()) {
      ffree(0);
    }
  }
#endif // X86 && TIERED
}


void LIR_Assembler::emit_opLabel(LIR_OpLabel* op) {
  _masm->bind (*(op->label()));
}


void LIR_Assembler::emit_op1(LIR_Op1* op) {
  switch (op->code()) {
    case lir_move:
      if (op->move_kind() == lir_move_volatile) {
        assert(op->patch_code() == lir_patch_none, "can't patch volatiles");
        volatile_move_op(op->in_opr(), op->result_opr(), op->type(), op->info());
      } else {
        move_op(op->in_opr(), op->result_opr(), op->type(),
                op->patch_code(), op->info(), op->pop_fpu_stack(),
                op->move_kind() == lir_move_unaligned,
                op->move_kind() == lir_move_wide);
      }
      break;

    case lir_prefetchr:
      prefetchr(op->in_opr());
      break;

    case lir_prefetchw:
      prefetchw(op->in_opr());
      break;

    case lir_roundfp: {
      LIR_OpRoundFP* round_op = op->as_OpRoundFP();
      roundfp_op(round_op->in_opr(), round_op->tmp(), round_op->result_opr(), round_op->pop_fpu_stack());
      break;
    }

    case lir_return:
      return_op(op->in_opr());
      break;

    case lir_safepoint:
      if (compilation()->debug_info_recorder()->last_pc_offset() == code_offset()) {
        _masm->nop();
      }
      safepoint_poll(op->in_opr(), op->info());
      break;

    case lir_fxch:
      fxch(op->in_opr()->as_jint());
      break;

    case lir_fld:
      fld(op->in_opr()->as_jint());
      break;

    case lir_ffree:
      ffree(op->in_opr()->as_jint());
      break;

    case lir_branch:
      break;

    case lir_push:
      push(op->in_opr());
      break;

    case lir_pop:
      pop(op->in_opr());
      break;

    case lir_neg:
      negate(op->in_opr(), op->result_opr());
      break;

    case lir_leal:
      leal(op->in_opr(), op->result_opr());
      break;

    case lir_null_check:
      if (GenerateCompilerNullChecks) {
        add_debug_info_for_null_check_here(op->info());

        if (op->in_opr()->is_single_cpu()) {
          _masm->null_check(op->in_opr()->as_register());
        } else {
          Unimplemented();
        }
      }
      break;

    case lir_monaddr:
      monitor_address(op->in_opr()->as_constant_ptr()->as_jint(), op->result_opr());
      break;

#ifdef SPARC
    case lir_pack64:
      pack64(op->in_opr(), op->result_opr());
      break;

    case lir_unpack64:
      unpack64(op->in_opr(), op->result_opr());
      break;
#endif

    case lir_unwind:
      unwind_op(op->in_opr());
      break;

    default:
      Unimplemented();
      break;
  }
}


void LIR_Assembler::emit_op0(LIR_Op0* op) {
  switch (op->code()) {
    case lir_word_align: {
      while (code_offset() % BytesPerWord != 0) {
        _masm->nop();
      }
      break;
    }

    case lir_nop:
      assert(op->info() == NULL, "not supported");
      _masm->nop();
      break;

    case lir_label:
      Unimplemented();
      break;

    case lir_build_frame:
      build_frame();
      break;

    case lir_std_entry:
      // init offsets
      offsets()->set_value(CodeOffsets::OSR_Entry, _masm->offset());
      _masm->align(CodeEntryAlignment);
      if (needs_icache(compilation()->method())) {
        check_icache();
      }
      offsets()->set_value(CodeOffsets::Verified_Entry, _masm->offset());
      _masm->verified_entry();
      build_frame();
      offsets()->set_value(CodeOffsets::Frame_Complete, _masm->offset());
      break;

    case lir_osr_entry:
      offsets()->set_value(CodeOffsets::OSR_Entry, _masm->offset());
      osr_entry();
      break;

    case lir_24bit_FPU:
      set_24bit_FPU();
      break;

    case lir_reset_FPU:
      reset_FPU();
      break;

    case lir_breakpoint:
      breakpoint();
      break;

    case lir_fpop_raw:
      fpop();
      break;

    case lir_membar:
      membar();
      break;

    case lir_membar_acquire:
      membar_acquire();
      break;

    case lir_membar_release:
      membar_release();
      break;

    case lir_membar_loadload:
      membar_loadload();
      break;

    case lir_membar_storestore:
      membar_storestore();
      break;

    case lir_membar_loadstore:
      membar_loadstore();
      break;

    case lir_membar_storeload:
      membar_storeload();
      break;

    case lir_get_thread:
      get_thread(op->result_opr());
      break;

    default:
      ShouldNotReachHere();
      break;
  }
}


void LIR_Assembler::emit_op2(LIR_Op2* op) {
  switch (op->code()) {
    case lir_cmp:
      if (op->info() != NULL) {
        assert(op->in_opr1()->is_address() || op->in_opr2()->is_address(),
               "shouldn't be codeemitinfo for non-address operands");
        add_debug_info_for_null_check_here(op->info()); // exception possible
      }
      comp_op(op->condition(), op->in_opr1(), op->in_opr2(), op);
      break;

    case lir_cmp_l2i:
    case lir_cmp_fd2i:
    case lir_ucmp_fd2i:
      comp_fl2i(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op);
      break;

    case lir_cmove:
      cmove(op->condition(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->type());
      break;

    case lir_shl:
    case lir_shr:
    case lir_ushr:
      if (op->in_opr2()->is_constant()) {
        shift_op(op->code(), op->in_opr1(), op->in_opr2()->as_constant_ptr()->as_jint(), op->result_opr());
      } else {
        shift_op(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->tmp1_opr());
      }
      break;

    case lir_add:
    case lir_sub:
    case lir_mul:
    case lir_mul_strictfp:
    case lir_div:
    case lir_div_strictfp:
    case lir_rem:
      assert(op->fpu_pop_count() < 2, "");
      arith_op(
        op->code(),
        op->in_opr1(),
        op->in_opr2(),
        op->result_opr(),
        op->info(),
        op->fpu_pop_count() == 1);
      break;

    case lir_abs:
    case lir_sqrt:
    case lir_sin:
    case lir_tan:
    case lir_cos:
    case lir_log:
    case lir_log10:
    case lir_exp:
    case lir_pow:
      intrinsic_op(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op);
      break;

    case lir_logic_and:
    case lir_logic_or:
    case lir_logic_xor:
      logic_op(
        op->code(),
        op->in_opr1(),
        op->in_opr2(),
        op->result_opr());
      break;

    case lir_throw:
      throw_op(op->in_opr1(), op->in_opr2(), op->info());
      break;

    case lir_xadd:
    case lir_xchg:
      atomic_op(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->tmp1_opr());
      break;

    default:
      Unimplemented();
      break;
  }
}


void LIR_Assembler::build_frame() {
  _masm->build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes());
}


void LIR_Assembler::roundfp_op(LIR_Opr src, LIR_Opr tmp, LIR_Opr dest, bool pop_fpu_stack) {
  assert((src->is_single_fpu() && dest->is_single_stack()) ||
         (src->is_double_fpu() && dest->is_double_stack()),
         "round_fp: rounds register -> stack location");

  reg2stack (src, dest, src->type(), pop_fpu_stack);
}


void LIR_Assembler::move_op(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool unaligned, bool wide) {
  if (src->is_register()) {
    if (dest->is_register()) {
      assert(patch_code == lir_patch_none && info == NULL, "no patching and info allowed here");
      reg2reg(src,  dest);
    } else if (dest->is_stack()) {
      assert(patch_code == lir_patch_none && info == NULL, "no patching and info allowed here");
      reg2stack(src, dest, type, pop_fpu_stack);
    } else if (dest->is_address()) {
      reg2mem(src, dest, type, patch_code, info, pop_fpu_stack, wide, unaligned);
    } else {
      ShouldNotReachHere();
    }

  } else if (src->is_stack()) {
    assert(patch_code == lir_patch_none && info == NULL, "no patching and info allowed here");
    if (dest->is_register()) {
      stack2reg(src, dest, type);
    } else if (dest->is_stack()) {
      stack2stack(src, dest, type);
    } else {
      ShouldNotReachHere();
    }

  } else if (src->is_constant()) {
    if (dest->is_register()) {
      const2reg(src, dest, patch_code, info); // patching is possible
    } else if (dest->is_stack()) {
      assert(patch_code == lir_patch_none && info == NULL, "no patching and info allowed here");
      const2stack(src, dest);
    } else if (dest->is_address()) {
      assert(patch_code == lir_patch_none, "no patching allowed here");
      const2mem(src, dest, type, info, wide);
    } else {
      ShouldNotReachHere();
    }

  } else if (src->is_address()) {
    mem2reg(src, dest, type, patch_code, info, wide, unaligned);

  } else {
    ShouldNotReachHere();
  }
}


void LIR_Assembler::verify_oop_map(CodeEmitInfo* info) {
#ifndef PRODUCT
  if (VerifyOops) {
    OopMapStream s(info->oop_map());
    while (!s.is_done()) {
      OopMapValue v = s.current();
      if (v.is_oop()) {
        VMReg r = v.reg();
        if (!r->is_stack()) {
          stringStream st;
          st.print("bad oop %s at %d", r->as_Register()->name(), _masm->offset());
#ifdef SPARC
          _masm->_verify_oop(r->as_Register(), strdup(st.as_string()), __FILE__, __LINE__);
#else
          _masm->verify_oop(r->as_Register());
#endif
        } else {
          _masm->verify_stack_oop(r->reg2stack() * VMRegImpl::stack_slot_size);
        }
      }
      check_codespace();
      CHECK_BAILOUT();

      s.next();
    }
  }
#endif
}
